Compare commits

..

762 commits

Author SHA1 Message Date
a9b16c18ad
bundles/postfix: remove smtp_use_tls option
Log says:

postconf: warning: /etc/postfix/main.cf: support for parameter "smtp_use_tls" will be removed; instead, specify "smtp_tls_security_level"
2024-11-22 20:50:52 +01:00
8f705fc8e3
update mautrix-whatsapp to 0.11.1 2024-11-17 11:48:08 +01:00
b3070a8b8b
bundles/infobeamer-monitor: announce online devices at 09:00 CE(S)T 2024-11-16 14:14:05 +01:00
6a203085b9
bundles/pretalx: we do not need to regenerate_css anymore 2024-11-16 13:35:24 +01:00
669b28f6ed
voc.pretalx: update to 2023.3.1 2024-11-16 13:02:39 +01:00
9884b703cd
update forgejo to 9.0.2 2024-11-16 12:11:01 +01:00
fa63ad72d5
update paperless-ngx to 2.13.5 2024-11-15 10:24:42 +01:00
3a56995ab1
update netbox to 4.1.6 2024-11-15 10:24:28 +01:00
50b71bc8b8
update element-web to 1.11.85 2024-11-15 10:24:13 +01:00
fcd097599d
home.nas: samba share for music videos 2024-11-15 10:17:37 +01:00
563ba266ff
fix icinga2 bundle (gpg key / packages) 2024-11-10 18:56:35 +01:00
209dedccf9
isort the whole repo 2024-11-08 06:39:59 +01:00
e51c24f837
bundles/powerdns: use *repo* commit time instead of *file* commit time for serial 2024-11-08 06:39:05 +01:00
72638e0856
bundles/infobeamer-monitor: add account data monitoring 2024-11-03 17:51:12 +01:00
2c83a5c4fc
voc.infobeamer-cms: prepare for 38c3 2024-10-31 16:58:26 +01:00
ec49c8d3ff
voc.infobeamer-cms: hackint changed their webirc service 2024-10-31 16:36:07 +01:00
46ec4cc2e7
bundles/postgresql: please also always do dumps 2024-10-28 16:55:10 +01:00
e29a838fad
bundles/forgejo: fix website_check_string 2024-10-28 16:54:53 +01:00
f6cb540007
update paperless-ngx to 2.13.0 2024-10-28 16:17:16 +01:00
6eb2c6651b
update netbox to 4.1.4 2024-10-28 16:16:48 +01:00
c006748165
update mautrix-whatsapp to 0.11.0 2024-10-28 16:16:36 +01:00
1be5ab268b
update forgejo to 9.0.1 2024-10-28 16:16:24 +01:00
12c735f4aa
update element-web to 1.11.82 2024-10-28 16:16:10 +01:00
9b0e627274
bundles/homeassistant: ensure virtualenv is in PATH 2024-10-27 17:45:22 +01:00
4f0ced4d9a
bundles/homeassistant: fix version check 2024-10-27 17:37:14 +01:00
af78e959ae Merge pull request 'new-wildcard-sophies-kitchen' (#72) from new-wildcard-sophies-kitchen into main
Reviewed-on: #72
2024-10-27 10:40:32 +00:00
58964cc10f
bundles/rspamd: send dmarc report emails from devnull address 2024-10-27 11:21:12 +01:00
ec8af84fb1
bundles/postfix: add devnull@myhostname mail address 2024-10-27 11:19:42 +01:00
9bfb531214
kunsi-p14s: clean up packages 2024-10-27 11:19:26 +01:00
84867ff1e6
bundles/postfix: provide myhostname from reactor 2024-10-27 11:19:05 +01:00
6647e71484
rottenraptor-server: add docker-immich 2024-10-26 16:28:09 +02:00
2e8cbd6061
add bundle:docker-immich 2024-10-26 16:27:54 +02:00
453d2a7889
home.r630: add docker, fix firewall 2024-10-26 16:27:16 +02:00
4238eeb6d8
add bundle:docker-engine 2024-10-26 16:25:54 +02:00
729b975b77
bundles/redis: ensure protected mode is off 2024-10-26 16:25:06 +02:00
c4e3d0abc2
bundles/nginx: we need a type definition for .mjs 2024-10-26 16:24:47 +02:00
078d52c075
carlene: rework kunsitracker 2024-10-26 08:20:01 +02:00
a83b380490
bundles/nginx: more config options 2024-10-26 08:19:43 +02:00
ed9607433d
rottenraptor-server: add smartd and zfs 2024-10-24 19:25:23 +02:00
d1b369fb26
bundles/smartd: do not try to guess disk names 2024-10-24 19:25:00 +02:00
07a44598d2
rottenraptor-server is in its colo now 2024-10-24 18:18:35 +02:00
e35fbdd183
add rottenraptor-server 2024-10-10 19:40:01 +02:00
c5fb1b8a28
htz-cloud.wireguard: add wg connection to fra-jana 2024-10-10 19:39:38 +02:00
814b67a9d0
voc.infobeamer-cms add v0tti to admins 2024-10-05 16:58:50 +02:00
3ff7db7d6d
bundles/sshmon: more letsencrypt issuer hashes 2024-10-03 22:43:25 +02:00
b57f205696
voc.infobeamer-cms: prepare for mrmcd24 2024-10-02 17:45:58 +02:00
ef8d3368c1
voc.infobeamer-cms: add FAQ entries 2024-10-01 11:03:50 +02:00
a5ea87b4e9
voc.infobeamer-cms: fix mqtt config 2024-10-01 10:53:04 +02:00
df69b876a9
voc.infobeamer-cms: prepare for mrmcd 2024-09-30 22:40:07 +02:00
4fbbf83952
update infobeamer-cms to debian bookworm 2024-09-30 22:24:53 +02:00
a1d1351411
update infobeamer-cms to current version 2024-09-30 22:24:34 +02:00
e2b430fd0e
update travelynx to 2.8.40 2024-09-30 10:21:05 +02:00
663f7eec9f
remove finallycoffee.eu from trusted key servers 2024-09-30 10:20:57 +02:00
95860e978b
remove htz-cloud.afra 2024-09-29 16:17:48 +02:00
52e891d3a7
move afra.berlin redirect to carlene 2024-09-29 16:17:10 +02:00
8ba63e112c
bundles/sshmon: fix SyntaxWarning 2024-09-27 10:22:58 +02:00
67f901c1c9
bundles/powerdnsadmin: fix dependencies 2024-09-27 10:19:01 +02:00
8c28d612cb
groups/sophie: fix group conflict 2024-09-27 10:16:07 +02:00
54f669313a
home.nas: nas dataset goes ssd 2024-09-27 10:15:50 +02:00
7b6d811128
bundles/sshmon: better cpu check 2024-09-27 10:02:27 +02:00
2564f416c2
update paperless to 2.12.1 2024-09-27 08:51:20 +02:00
8a28886012
update netbox to 4.1.2 2024-09-27 08:51:08 +02:00
c699f0d510
update element-web to 1.11.78 2024-09-27 08:50:52 +02:00
4a28bc55c0
bundles/homeassistant: rework check_homeassistant_update 2024-09-27 08:42:58 +02:00
abdc7f751e
update pretalx-halfnarp to 1.1.2 2024-09-25 21:45:52 +02:00
423049667f
bundles/nftables: improve handling for icmp 2024-09-23 18:09:49 +02:00
c6421c7bd4
update travelynx to 2.8.39 2024-09-20 15:34:14 +02:00
95c5b28469
basic monitoring for proxmox-backupstorage 2024-09-20 15:34:12 +02:00
7dc0afe299 Merge pull request 'miniserver: element-web update' (#71) from updates into main
Reviewed-on: #71
2024-09-19 20:59:48 +00:00
Sophie Schiller
0d28883da3 fix name of backup server 2024-09-19 22:55:15 +02:00
Sophie Schiller
8980c05c74 new wildcard for sophie's home infra 2024-09-19 22:52:01 +02:00
9415b281ce
update travelynx to 2.8.38 2024-09-15 13:33:23 +02:00
64fb1906d1
htz-hel.backup-kunsi: move scrub to wednesday 2024-09-15 10:27:08 +02:00
ce76b03fe7
bundles/zfs: configurable scrub time 2024-09-15 10:26:51 +02:00
a712c098c6
update netbox to 4.1.1 2024-09-14 18:32:39 +02:00
ec834f2a92
update element-web to 1.11.77 2024-09-14 18:32:27 +02:00
aa30b78fcf
remove daisy 2024-09-14 18:29:55 +02:00
be3a7a44d6
home.nas: new ssd-based pool 2024-09-12 19:58:15 +02:00
2e72f107e9
update paperles to 2.12.0 2024-09-10 06:15:48 +02:00
07f6fb99f2
bundles/backup-server: more time for monitoring please 2024-09-10 06:14:55 +02:00
3f9f84f230
home.paperless: add proftpd for paperless ingest 2024-09-08 19:42:27 +02:00
40fcaf56ee
add home.fujitsu-n7100 2024-09-08 19:42:15 +02:00
06a94d7cba
home.nas: clean up nodefile 2024-09-08 17:19:13 +02:00
6483f863ff
bundles/rsyslogd: add backups 2024-09-08 17:19:03 +02:00
3a52cf55c4
remove bundle:scansnap 2024-09-08 17:17:25 +02:00
455c5c5ce5
update as3320 and as8881 2024-09-07 13:01:37 +02:00
5e55dc6fb9
update forgejo to 8.0.3 2024-09-07 09:09:03 +02:00
d5881da154
fix sophie backup locations 2024-09-07 09:07:40 +02:00
Sophie Schiller
121a261ecd miniserver: actually use signing key 2024-09-04 23:06:23 +02:00
Sophie Schiller
b9216f230b matrix-media-repo: extend rate limits 2024-09-04 23:06:07 +02:00
Sophie Schiller
497d4fff30 miniserver: element-web update 2024-09-04 21:25:50 +02:00
9f1dc01d6b
bundles/arch-with-gui: s/rfkill/util-linux/ 2024-09-04 20:02:18 +02:00
a7baf225ff
kunsi-p14s: s/ferdi/ferdium/ 2024-09-04 20:00:54 +02:00
331d363a45
bump _.home.kunbox.net 2024-09-04 19:04:47 +02:00
3f02f7b8f5
bundles/icinga2: ignore lines starting with ;; in check_spam_blocklist 2024-09-04 18:56:48 +02:00
b73ac2b7ce
update paperless to 2.11.6 2024-09-04 18:54:18 +02:00
41b76aec9c
update forgejo to 8.0.2 2024-09-04 18:52:10 +02:00
2b5a76ffb0
update netbox to 4.1.0 2024-09-04 18:50:58 +02:00
319dc8ad21
icinga: fix logic error, do not send sms for service problems 2024-09-03 21:09:17 +02:00
bfbbffe22c
home.r630: allow forwarding traffic
So i can actually reach the docker containers running on there
2024-08-31 19:12:05 +02:00
23fb2aba1c
home.nas: add br1139 2024-08-31 13:14:24 +02:00
3d86923e9e
update travelynx to 2.8.35 2024-08-28 15:42:07 +02:00
2fbf122660
update netbox to 4.0.9 2024-08-28 15:41:54 +02:00
4234070514
update element-web to 1.11.76 2024-08-28 15:41:39 +02:00
13bae5c993
bundles/samba: fix typo 2024-08-23 19:47:19 +02:00
aff1329122
add rottenraptor devices 2024-08-23 19:43:27 +02:00
82aeeb585d
add samba share for music on nas 2024-08-23 19:43:04 +02:00
e8983829ed
bundles/infobeamer-monitor: fix maintenance warnings 2024-08-16 14:35:33 +02:00
10b1fb8a5b
remove legacy nodes 2024-08-12 19:39:57 +02:00
c66bc8b5eb
add home.{appletv-wohnzimmer,encoder96} 2024-08-12 19:36:32 +02:00
422303ee5b update pretalx to 2024.2.1 2024-08-10 19:14:57 +02:00
c48e11d787 update paperless to 2.11.4 2024-08-10 19:14:57 +02:00
a8678fc01b update netbox to 4.0.8 2024-08-10 19:14:57 +02:00
6fe0598032 update matrix-media-repo to 1.3.7 2024-08-10 19:14:57 +02:00
6fb8d81159 carlene: fix network config
Apparently, the DC technicians are unable to plug in a server into the
correct network ports after changing disks ...
2024-08-10 19:14:57 +02:00
e4eb00bdbe update forgejo to 8.0.1 2024-08-10 19:14:57 +02:00
94e56fd92d update element-web to 1.11.73 2024-08-10 19:14:57 +02:00
01a8d7a6db add bundle:sdm630_mqtt 2024-08-10 19:14:57 +02:00
f0ebed5dba bundles/sshmon: yet another letsencrypt hash 2024-08-10 19:14:57 +02:00
30cf20c28d bundles/c3voc-addons: add action:apt_execute_update_commands 2024-08-10 19:14:57 +02:00
5af7b92663 bw/data/apt: grafana changed their gpg key 2024-08-10 19:14:57 +02:00
5a1e37a41c bundles/systemd-networkd: remove networkmanager 2024-08-10 19:14:57 +02:00
a1eb9cb3fc bundles/telegraf: add option to opt-out of default metrics 2024-08-10 19:14:57 +02:00
6854bd55ff Merge pull request 'update-miniserver' (#70) from update-miniserver into main
Reviewed-on: #70
2024-08-09 01:00:17 +00:00
Sophie Schiller
fb70a068d8 nodejs: deb-src no longer available 2024-08-09 02:59:52 +02:00
Sophie Schiller
6fa3abc217 hedgedoc: fix install needs 2024-08-09 02:59:52 +02:00
Sophie Schiller
7fd248af8d version bumps on miniserver 2024-08-09 02:59:52 +02:00
98d2bb3942 Merge pull request 'vmhost: document interface change' (#69) from vmhostumzug into main
Reviewed-on: #69
2024-08-09 00:58:34 +00:00
Sophie Schiller
89000c12e6 vmhost: document interface change 2024-08-09 00:56:40 +00:00
fa47322bb0
bundles/raspberrypi: fix config.txt for lcd display 2024-07-31 15:30:48 +02:00
de6073bdcf
bundles/apt: add option to disable unattended upgrades 2024-07-31 14:53:22 +02:00
7649396b8a
bundles/mosquitto: only install telegraf plugin if we have telegraf 2024-07-30 17:55:03 +02:00
b1790ece35
bundles/apt: 32bit raspbian is no longer supported 2024-07-30 17:45:05 +02:00
242279636f
bundles/raspberrypi: things have changed since buster 2024-07-30 17:44:09 +02:00
95bb7c52fe
bundles/apt: add bissing default for update commands 2024-07-22 21:31:27 +02:00
2a8c1ef84b
update mautrix-whatsapp to 0.10.9 2024-07-19 19:22:05 +02:00
c1fc942b1d
update mautrix-telegram to 0.15.2 2024-07-19 19:21:50 +02:00
c4bf96482f
update element-web to 1.11.71 2024-07-19 19:21:37 +02:00
69691f75c5
data/apt: new gpg key for nodesource 2024-07-19 19:20:40 +02:00
263440296d
bundles: no default for nodejs version anymore 2024-07-19 19:20:23 +02:00
55a3e6675f
bundles/nodejs: everything changed, AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 2024-07-19 19:19:45 +02:00
350c436e4d
bundles/apt: add action to execute additional_update_commands 2024-07-19 19:19:14 +02:00
205fea377a
update paperless to 2.11.0 2024-07-12 19:06:55 +02:00
fb46d81f97
update netbox to 4.0.7 2024-07-12 19:06:43 +02:00
466a620bca
update element-web to 1.11.70 2024-07-12 19:06:28 +02:00
04094df418
update matrix-media-repo to 1.3.6 2024-07-12 18:46:10 +02:00
c348953611
bundles/sshmon: even more letsencrypt shenanigans 2024-07-12 18:45:43 +02:00
e4dfd17bb6
bundles/matrix-media-repo: has live config reload 2024-07-12 18:42:31 +02:00
08f2c46c31
bundles/matrix-synapse: media-repo needs more paths now 2024-07-12 18:39:09 +02:00
b2028855d1
bundles/sshmon: new issuer hash for letsencrypt 2024-07-12 18:24:27 +02:00
a472ca4657
bw/bundles/matrix-media-repo: adjust config for 1.3.6 2024-07-12 18:20:53 +02:00
d08e9f12ab
add icinga_options.also_affected_by to systems running in vm on home.nas 2024-07-12 18:13:43 +02:00
2fddd57ed8
bundles/backup-client: only log to logfile when not running in debug mode 2024-07-07 10:23:20 +02:00
5a86e657ff
bundles/mixcloud-downloader: add login via netrc 2024-07-07 10:22:26 +02:00
52b68d6e42
home.nas: clean up smartd config 2024-07-06 10:59:46 +02:00
fbe2197055
add home.r630 2024-07-06 10:56:13 +02:00
ced6479b8e
home.nas: clean up zfs datasets 2024-07-06 09:49:22 +02:00
6e677a7a0b
update paperless-ngx to 2.10.2 2024-07-06 09:45:41 +02:00
c0b3db55ec
update travelynx to 2.7.7 2024-07-06 09:45:18 +02:00
fc4aaf4abb
update netbox to 4.0.6 2024-07-06 09:44:57 +02:00
ce44926920
update forgejo to 7.0.5 2024-07-06 09:44:41 +02:00
4736e3b281
update travelynx to 2.7.6 2024-07-04 11:43:43 +02:00
b3ab18a32c
bundles/nginx: don't cache stuff when running through php 2024-07-01 17:17:30 +02:00
79bb4169a7
ns-mephisto: new ip config 2024-07-01 11:34:36 +02:00
101928339f
bundles/powerdns: fix SyntaxWarning 2024-06-26 07:11:44 +02:00
67198c5fd9
bundles/grafana: needs websockets 2024-06-25 17:32:24 +02:00
791eb8d1a9
bump netbox-dump 2024-06-25 17:10:32 +02:00
0ce0e34382 Merge pull request 'sophiesheomenetwork' (#68) from sophiesheomenetwork into main
Reviewed-on: #68
2024-06-23 12:54:01 +00:00
668ae0432b
htz-hel.backup-kunsi: remove backup target for kunsi-t470 2024-06-23 14:52:09 +02:00
b72d82b894
bundles/routeros: this does not need to be a metadata reactor 2024-06-22 20:39:04 +02:00
d1f182607d
rework netbox-dump script and routeros bundle for better usability 2024-06-22 20:04:51 +02:00
Sophie Schiller
9be31b8850 homeassistant: use correct network interface 2024-06-22 00:51:33 +02:00
Sophie Schiller
182cdada22 homeassistant metadata reshuffle 2024-06-21 21:25:48 +02:00
Sophie Schiller
2c51caa524 update nginx signing key 2024-06-21 20:58:17 +02:00
Sophie Schiller
263301b265 add homeassistant in sophies home 2024-06-21 20:32:06 +02:00
Sophie Schiller
2f4b90c147 miniserver: element update 2024-06-21 19:32:43 +02:00
Sophie Schiller
e5c5672554 add vmhost for sophies home 2024-06-21 19:32:28 +02:00
c47b412cf3
update forgejo to 7.0.4 2024-06-18 20:43:55 +02:00
cda7e3b7fd
update paperless to 2.10.0 2024-06-18 20:43:41 +02:00
e876d39002
update netbox to 4.0.5 2024-06-18 20:43:25 +02:00
b9583d9a64
update element-web to 1.11.69 2024-06-18 20:43:10 +02:00
60a0737187
bundles/jellyfin: fix firewall defaults 2024-06-18 20:40:09 +02:00
52c093427f
ssl: bump _.home.kunbox.net 2024-06-11 17:42:43 +02:00
Sophie Schiller
658acbd12b rechenmonster: add dataset 2024-06-09 10:21:08 +02:00
56df06e981
clean up some nodefiles 2024-06-08 18:50:55 +02:00
d1e28c3f0c
sophie gets her own group 2024-06-08 18:46:51 +02:00
Sophie Schiller
1c2127437c voc.infobeamer-cms: gpn22 2024-05-30 21:44:07 +02:00
Sophie Schiller
768ae0a37a htz-cloud.miniserver: backlinks to social media 2024-05-29 00:02:29 +02:00
bebc603c43
update paperless-ngx to 2.8.6 2024-05-24 17:07:21 +02:00
43fe831395
update netbox to 4.0.3 2024-05-24 17:07:10 +02:00
5b8784e916
update forgejo to 7.0.3 2024-05-24 17:06:53 +02:00
ea21e4b119
update element-web to 1.11.67 2024-05-24 17:06:38 +02:00
a6c1d67b55
remove entropia-jira 2024-05-24 17:03:18 +02:00
a8ef19f4ff
bundles/icinga2: add check_omm 2024-05-24 15:26:35 +02:00
8c42c9411a
bundles/postfix: fix typo 2024-05-24 15:24:14 +02:00
1dce906b3d
bundles/netbox: reindex must be lazy 2024-05-12 19:46:07 +02:00
5c1ff593e1
carlene: add kunsitracker.de 2024-05-12 19:43:07 +02:00
fd1cbcfd50
update paperless to 2.8.3 2024-05-12 19:42:54 +02:00
799f275e4e
update netbox to 4.0.1 2024-05-12 19:42:42 +02:00
cf82ed5dd3
update element-web to 1.11.66 2024-05-12 19:42:24 +02:00
88fce3405e
bundles/netbox: fix f-string 2024-05-12 19:42:04 +02:00
a17833698d
bundles/apt: run autoremove first, then clean cached packages 2024-05-12 19:36:31 +02:00
c806d7b890
bundles/netbox: rework 2024-05-05 16:49:42 +02:00
a8da2aef44
update netbox to 3.7.7 2024-05-05 16:18:27 +02:00
cc9c127296
update forgejo to 7.0.2 2024-05-05 16:18:13 +02:00
35331f5f4c
update ssl configuration of some bundles 2024-05-05 15:49:45 +02:00
dd32ed075b
remove kunsi-p14s 2024-05-04 10:18:18 +02:00
c9b393c6dc
update travelynx to 2.6.9 2024-04-28 21:40:46 +02:00
9e78b9e07b
python3.12 compat 2024-04-28 21:40:35 +02:00
65af9ae0c5
update netbox to 3.7.6 2024-04-28 20:57:44 +02:00
516a543719
update forgejo to 7.0.1 2024-04-28 20:57:31 +02:00
dbf17424d2
update element-web to 1.11.65 2024-04-28 20:57:14 +02:00
09e59af95f
bundles/nginx: listen ... http2; is deprecated 2024-04-24 23:04:06 +02:00
610c1d0978
update forgejo to 1.21.11-1 2024-04-20 18:35:00 +02:00
0bfcd8df45
update travelynx to 2.6.7 2024-04-20 18:31:44 +02:00
27cb0cb0df
update mautrix-whatsapp to 0.10.7 2024-04-20 18:31:30 +02:00
d02d26cb5e
update forgejo to 1.21.11-1 2024-04-20 18:31:13 +02:00
bbc69dfd25
bundles/icinga2: re-add statusmonitor 2024-04-20 18:30:39 +02:00
e64ae3aef7
bundles/icinga2: run check_mounts check as well 2024-04-17 06:42:58 +02:00
1ec545e080
update element-web to 1.11.64 2024-04-17 06:33:37 +02:00
7491ec840c
bundles/dovecot: add full text indexing 2024-04-14 12:17:44 +02:00
a155fe22cb
Revert "home.router: disable pppd restart at night"
This reverts commit 493dc91e0d.
2024-04-14 10:09:08 +02:00
0f9222424e
dns/kunbox.net: add htz-cloud.pirmasens to SPF 2024-04-13 11:05:18 +02:00
6be9fb3614
bundles/pacman: 'dnsutils' is now part of 'bind' 2024-04-09 06:09:03 +02:00
ab61444a1f
bundles/letsencrypt: do not monitor renew timer 2024-04-09 06:06:29 +02:00
f8b833720a
bundles/systemd-timers: better exclude_from_monitoring support 2024-04-09 06:06:02 +02:00
33ae4796d4
update paperless to 2.7.2 2024-04-09 06:03:11 +02:00
8f09170b44
update travelynx to 2.6.5 2024-04-09 06:01:01 +02:00
a6e7359ec0
update netbox to 3.7.5 2024-04-09 06:00:42 +02:00
128ac48fd6
update forgejo to 1.21.10-0 2024-04-09 06:00:23 +02:00
4a44ae1048
kunbox.net: fix tlsrpt address 2024-04-09 06:00:05 +02:00
ed05a74f56
update travelynx to 2.6.4 2024-04-03 17:27:40 +02:00
896781e53d
update travelynx to 2.6.3 2024-04-02 21:54:31 +02:00
c0c83338ad
bundles/icinga2: do not send out URGENT for recovery messages 2024-04-02 15:06:52 +02:00
b028c20758
update element-web to 1.11.63 2024-03-31 13:47:53 +02:00
efeee3fa62
update travelynx to 2.5.23 2024-03-31 13:47:15 +02:00
139d5ff948
htz-cloud.wireguard: actually allow wg.c3voc.de to connect 2024-03-31 12:45:26 +02:00
df8955fa35
bundles/infobeamer-monitor: better state dump output 2024-03-25 14:54:59 +01:00
713f7e02d8
update forgejo to 1.21.8-0 2024-03-24 09:06:48 +01:00
272bccf42d
update paperless-ngx to 2.6.3 2024-03-23 12:19:24 +01:00
a3d582c2c5
update travelynx to 2.5.21 2024-03-23 12:19:10 +01:00
cad026c1ef
update mautrix-whatsapp to 0.10.6 2024-03-23 12:18:49 +01:00
a027faa8ca
fix tests 2024-03-23 10:35:02 +01:00
773e8d118f
add repo.libs.faults.dict_as_toml 2024-03-23 10:34:41 +01:00
1d5bcf74c0
remove bundle:openvpn-client 2024-03-23 10:27:30 +01:00
9b4a473236
htz-cloud.wireguard: add c3voc vpn connection 2024-03-23 10:19:56 +01:00
aa0d4e5a76
kunsi-p14s: set correct ip 2024-03-23 10:19:35 +01:00
e6f6229b87
bundles/wireguard: do not generate PSKs for unmanaged nodes 2024-03-23 10:19:15 +01:00
104d1f11bf
bundles/wireguard: support s2s connection to other services 2024-03-22 22:52:12 +01:00
ae14265abc
bundles/matrix-synapse: add sliding-sync proxy 2024-03-17 18:40:28 +01:00
a4e51c5d54
home.router: remove dns search domain 2024-03-16 14:49:28 +01:00
6296ab583d
add node attribute for all hosts that don't use letsencrypt ssl certs 2024-03-16 11:04:49 +01:00
f5b87d995b
bump _.home.kunbox.net 2024-03-16 11:01:56 +01:00
abb408c907
carlene: ensure kunsi can write to the franzi.business vhost 2024-03-16 10:51:56 +01:00
bd0cb5e1b4
update element-web to 1.11.61 2024-03-16 10:49:04 +01:00
4c5167fefa
update paperless-ngx to 2.6.2 2024-03-16 10:48:26 +01:00
a344bde87d
update netbox to 3.7.4 2024-03-16 10:48:05 +01:00
1573bdc384
update forgejo to 1.21.7-0 2024-03-16 10:47:37 +01:00
4d92211862
home.hass: use pyenv for homeassistant 2024-03-07 08:23:04 +01:00
ac10630fb9
add bundle:pyenv 2024-03-07 08:15:23 +01:00
6b387c9d11
add dummy htz-cloud.molly-connector 2024-03-06 23:02:18 +01:00
0d362bdb22
EOL htz-cloud.sewfile 2024-03-06 20:06:42 +01:00
e386b44442
bundles/paperless: PLEASE just import my files 2024-03-04 21:23:19 +01:00
dd80579fae
bundles/paperless: add missing dependency 2024-03-04 21:23:00 +01:00
faa30962aa
bundles/paperless: restart please 2024-03-04 21:20:39 +01:00
232e087905
bundles/paperless: please, just import documents 2024-03-04 21:02:19 +01:00
e3d7cae251
net.ipv4.ip_forward -> net.ipv4.conf.all.forwarding 2024-03-03 15:44:31 +01:00
0fa9ef91ae
kunsi-p14s: add dataset for nextcloud client 2024-03-03 13:16:53 +01:00
f5a1a50472
carlene: add sewfile zfs dataset 2024-03-03 12:47:24 +01:00
8d8f457468
bundles/nginx: add mjs to mime types 2024-03-03 12:44:41 +01:00
ffc9c1651c
fix some leftover ULA addressing 2024-02-29 07:40:36 +01:00
b34879d0ca
update element-web to 1.11.59 2024-02-29 07:40:19 +01:00
32e67ff5ec
update paperless to 2.5.4 2024-02-29 07:39:05 +01:00
409a1c900a
remove ULA from remaining home nodes 2024-02-26 19:56:23 +01:00
3749be6144
home.router: remove ipv6-only vlan 2024-02-26 19:54:59 +01:00
c5550bf552
bundles/unbound: add option to disable dns64 even when jool is installed 2024-02-26 19:26:01 +01:00
699c7acf93
bundles/radvd: increase intervals again 2024-02-26 19:25:43 +01:00
79c4dcdf97
Revert "change a bunch of nodes to use their ipv6 address as hostname"
This reverts commit e73dcf16e3.
2024-02-26 19:12:13 +01:00
661d8895dc
home.{downloadhelper,paperless}: add ipv6 unique local addresses 2024-02-26 07:49:02 +01:00
a045e701a6
home.router: add bundle:jool, fix dns 2024-02-26 07:30:50 +01:00
575fe91685
bundles/radvd: fix syntax 2024-02-26 07:27:25 +01:00
12c6b5fc54
add bundle:jool 2024-02-26 07:27:18 +01:00
4514541e8f
bundles/radvd: decrease RDNSS lifetime 2024-02-26 06:41:59 +01:00
0d0548311c
bundles/powerdns: add private ipv6 addresses as well 2024-02-26 06:34:30 +01:00
e73dcf16e3
change a bunch of nodes to use their ipv6 address as hostname 2024-02-26 06:34:23 +01:00
decbcf9bfd
Merge branch 'feature/kunsi-ipv6-only-vlan' 2024-02-26 06:04:58 +01:00
304ce8aa54
home.router: a bit more firewall rules 2024-02-25 20:56:13 +01:00
b89ba32f4c
home.router: allow forwarding for new vlan 2024-02-25 20:55:53 +01:00
7c9bb42c03
home.switch-rack: new vlan 2024-02-25 20:51:02 +01:00
9e59bb044a
nodes/home.*: add ipv6 site-local ip addressing and v6-only vlan 2024-02-25 20:50:25 +01:00
9c4d1c94a5
htz-cloud: fix routes for vpn 2024-02-25 19:14:13 +01:00
577a175bd0
update forgejo to 1.21.6-0 2024-02-25 19:04:55 +01:00
182be4e690
update netbox to 3.7.3 2024-02-25 19:02:23 +01:00
6bb72f4b27
update travelynx to 2.5.20 2024-02-25 19:01:53 +01:00
7d4624ce62
remove users/$user/is_admin metadata, directly write sudo_commands instead 2024-02-25 15:29:10 +01:00
02e25f89ff
home.nas: prepare for new NAS disks 2024-02-25 14:47:55 +01:00
c6552e8dd2
bundles/smartd: do not try to monitor encrypted devices 2024-02-25 14:45:47 +01:00
781264432a
kunsi-seibert-x1 -> fkusei-locutus 2024-02-20 16:41:58 +01:00
20b1e5dccc
voc.pretalx: update pretalx to 2024.1.0 2024-02-18 21:38:06 +01:00
281696d411
htz-cloud.afra: fedi.afra.berlin is gone 2024-02-18 21:23:31 +01:00
9df3e5539d
htz-cloud.pirmasens: use domain_aliases to redirect to main domain 2024-02-18 21:21:51 +01:00
b60fb4ff60
update travelynx to 2.5.17 2024-02-17 05:00:03 +01:00
26ee966bd6
bundles/paperless: fix config for static directory 2024-02-17 04:45:54 +01:00
72f756a686
update paperless-ngx to 2.5.3 2024-02-17 04:37:38 +01:00
898ebe4d6b
update element-web to 1.11.58 2024-02-17 04:37:16 +01:00
012726a2ce
bundles/paperless: ensure we run collectstatic and restart services 2024-02-17 04:36:39 +01:00
297726f297
bundles/backup-client: don't monitor backups for nodes which have exclude_from_monitoring 2024-02-13 14:24:27 +01:00
ac7f73588d
update paperless-ngx to 2.5.1 2024-02-13 14:18:45 +01:00
8c4611452e
htz-hel.backup-sophie: allow sophie to access 2024-02-13 14:18:30 +01:00
418015b484
update matrix-media-repo to 1.3.4 2024-02-13 14:14:34 +01:00
698f203936
bundles/nginx: add option to not redirect domain aliases 2024-02-13 14:01:40 +01:00
050931edf2
bundles/nginx: redirect domain_aliases to primary domain 2024-02-13 13:57:53 +01:00
fa375d0d69
carlene: keep git.kunsmann.eu alias around 2024-02-13 13:47:55 +01:00
8f28781572
update travelynx to 2.5.16 2024-02-09 21:02:38 +01:00
2ca460269e
update netbox to 3.7.2 2024-02-09 21:02:02 +01:00
c934bc45aa
update forgejo to 1.21.5-0 2024-02-04 17:40:06 +01:00
e2ed513169
update powerdnsadmin to 0.4.2 2024-02-04 17:27:05 +01:00
512454a949
update paperless-ngx to 2.4.3 2024-02-04 17:26:52 +01:00
80ca8b7e50
update element-web to 1.11.57 2024-02-04 17:26:33 +01:00
8df380357e
update travelynx to 2.5.15 2024-02-04 17:26:13 +01:00
dcb9db3639
bundles/users: source users bashrc after loading global bashrc instead of overwriting it 2024-02-04 17:25:17 +01:00
c02a1f2a90
clean up some users 2024-02-03 19:12:53 +01:00
643151c052
add home.wled-raketenlaemp 2024-01-30 21:02:23 +01:00
a3cc5a9347
bundles/kea-dhcp-server: add kea-lease-list script 2024-01-30 21:01:20 +01:00
e3b63a99c2
carlene: add some mail addresses to blocked 2024-01-23 09:31:02 +01:00
980f4cb41a
bundles/nftables: add "globally blocked ips" 2024-01-23 09:30:41 +01:00
5ffbe50b1e
add bundle:telegraf_airgradient 2024-01-23 09:30:13 +01:00
bb56f0fb9a
bundles/nftables: add feature to block ips 2024-01-21 11:44:13 +01:00
ee58509e93
bundles/postfix: add feature to block email recipients 2024-01-21 11:43:43 +01:00
57c76e5eba
update travelynx to 2.5.11 2024-01-21 11:18:33 +01:00
fa8d05fc74
bundles/mixcloud-downloader: add elisa 2024-01-21 11:17:05 +01:00
8fa488e411
bundles/icinga2: only send sms for HOST alerts 2024-01-21 11:16:46 +01:00
28d4839822
update paperless to 2.4.0 2024-01-20 10:58:46 +01:00
ec183da69b
update netbox to 3.7.1 2024-01-20 10:58:32 +01:00
87e30e84fa
update forgejo to 1.12.4-0 2024-01-20 10:58:12 +01:00
44baf7cbf9
update element-web to 1.11.55 2024-01-20 10:57:56 +01:00
ccfe2ff0b0
home.nas: allow TV to access jellyfin without https
for some reason, connecting to the hostname fails, and connecting to the
ip using https leads to certificate errors
2024-01-15 21:52:48 +01:00
70127f797b
home.kodi-wohnzimmer: set dummy/exclude_from_monitoring 2024-01-13 14:13:08 +01:00
17334a8e3e
update paperless-ngx to 2.3.3 2024-01-13 14:13:05 +01:00
edc95ac2ab
update travelynx to 2.5.10 2024-01-13 14:13:03 +01:00
58d978292a
update element-web to 1.11.53 2024-01-13 14:13:01 +01:00
739ce09e60
bundles/homeassistant: requires ffmpeg now
atleast it's complaining about the lack of ffmpeg in its logs ...
2024-01-13 14:12:59 +01:00
f917f9a2b7
kunsi-p14s: remove voc-tracker-worker
we have a vm for that
2024-01-13 14:12:57 +01:00
Sophie Schiller
e9d4c85676 wled-blobkette is new! 2024-01-13 14:12:20 +01:00
d5491648f2
bundles/mixcloud-downloader: download zotanmew sets 2024-01-03 22:25:59 +01:00
bc63ef97ab
bundles/arch-with-gui: install pipewire-zeroconf 2024-01-03 15:11:05 +01:00
fabe11d5b2
update travelynx to 2.5.9 2024-01-03 14:16:25 +01:00
3bddab5f67
bundles/arch-with-gui: ensure we have avahi installed and running 2024-01-03 12:59:21 +01:00
7c70c600f4
bundles/infobeamer-monitor: only alert online devices once 2024-01-01 11:38:39 +01:00
dfadffd921
add home.lgtv-wohnzimmer 2024-01-01 10:15:56 +01:00
fa107dcc3f
update paperless-ngx to 2.2.1 2024-01-01 10:12:51 +01:00
a05a809131
update travelynx to 2.5.7 2024-01-01 10:12:38 +01:00
adba83feea
update netbox to 3.7.0 2024-01-01 10:12:24 +01:00
4889ea4d31
update mautrix-telegram to 0.15.1 2024-01-01 10:12:03 +01:00
46e00d6fc8
bundles/nodejs: only install nodesource packages if debian does not ship that version 2024-01-01 10:11:11 +01:00
a929f24977
bundles/infobeamer-cms: more and better information 2023-12-31 08:50:45 +01:00
ec1efaafcc
bundles/infobeamer-cms: move static files outside repo root 2023-12-29 08:19:33 +01:00
8dde3dba0b
home.downloadhelper: adjust home ip range 2023-12-28 11:32:44 +01:00
e33cc65cb1
bundles/infobeamer-monitor: only dump state if device is online 2023-12-27 14:55:15 +01:00
2e2e8cf7c0
voc.infobeamer-cms: device has changed 2023-12-27 12:15:42 +01:00
c5ea690621
bundles/infobeamer-cms: less security needed 2023-12-27 12:12:24 +01:00
14c01e3bf0
bundles/infobeamer-monitor: more alerts 2023-12-26 23:16:26 +01:00
9be370f8df
bundles/infobeamer-monitor: improve code a bit 2023-12-26 15:02:56 +01:00
b5475df467
voc.infobeamer-cms: add infobeamer-monitor 2023-12-26 14:50:24 +01:00
2670d60906
bundles/infobeamer-cms: new version requires new configs 2023-12-26 14:49:04 +01:00
3ddc75d846
voc.infobeamer-cms: allow uploads on day 4 as well 2023-12-26 09:14:25 +01:00
Sophie Schiller
66bb1a80c6 voc.infobeamer-cms: move event start date to day 0 2023-12-25 23:00:32 +01:00
d9f9690518
update travelynx to 2.5.4 2023-12-25 10:40:17 +01:00
2875bb7160
update element-web to 1.11.52 2023-12-25 10:28:43 +01:00
8331c04b51
update forgejo to 1.21.3-0 2023-12-25 10:28:25 +01:00
e7e2fd184f
bundles/bird: fix bw test 2023-12-25 10:22:33 +01:00
3b7e14755c
bundles/wireguard: clean up leftovers 2023-12-25 10:19:34 +01:00
9cf5fa2e5f
ssl: bump home.kunbox.net 2023-12-25 10:11:18 +01:00
005804d839
voc.infobeamer-cms: remove device kunsi-dev 2023-12-24 12:10:16 +01:00
41d909f34d
update travelynx to 2.5.3 2023-12-19 07:48:14 +01:00
3ea9da16e8
voc.infobeamer-cms: add all rooms and interrupts 2023-12-18 10:12:17 +01:00
08628f4721
voc.infobeamer-cms: 37C3 2023-12-18 09:13:41 +01:00
2fddfcd4ff
update mautrix-whatsapp to 0.10.5 2023-12-18 06:53:52 +01:00
8ca2cfeeb2
update paperless-ngx to 2.1.3 2023-12-16 12:10:54 +01:00
8435b2401f
update netbox to 3.6.7 2023-12-16 12:09:09 +01:00
50bc26deaf
kunsi-p14s: use net.ifnames=0 2023-12-16 10:41:26 +01:00
b11fece803
EOL GCE 2023-12-16 10:23:44 +01:00
24373d0ac9
bundles/icinga2: 15min downtime is enough for unattended upgrades 2023-12-16 10:19:33 +01:00
5b19b2052d
remove rx300 leftovers 2023-12-13 21:38:13 +01:00
9a026b1fd9
dismantle gce nameservers, part 1 2023-12-13 21:38:08 +01:00
Sophie Schiller
b22ee8aa30 miniserver: new stickers 2023-12-13 21:31:51 +01:00
eb30240dc3
update paperless to 2.1.2 2023-12-13 19:55:30 +01:00
3cff203bec
update forgejo to 1.21.2-1 2023-12-13 19:55:04 +01:00
2fc8b125e3
update forgejo to 1.21.2-0 2023-12-12 07:28:20 +01:00
86b8cd8edf
bundles/wireguard: remove wg_health_check 2023-12-10 17:01:01 +01:00
f3269ce979
bundle/wireguard: fix firewall for home.router 2023-12-10 16:59:53 +01:00
cd48cc5911
bump versatel and telekom ip ranges 2023-12-10 16:59:47 +01:00
2497800f4a
home.router: remove wg external_hostname 2023-12-10 16:59:24 +01:00
493dc91e0d
home.router: disable pppd restart at night 2023-12-10 16:59:14 +01:00
63d42c6b42
bundles/wireguard: add no_autoconnect option 2023-12-10 16:58:52 +01:00
ffb5125ddd
bundles/wireguard: add option to set settings based on a specific peer 2023-12-10 14:48:24 +01:00
0084257872
kunsi-p14s: nftables rules order is important 2023-12-09 13:42:31 +01:00
4e0f286381
update paperless to 2.1.1 2023-12-08 07:56:59 +01:00
c8bb51715e
update netbox to 3.6.6 2023-12-07 21:12:47 +01:00
526a0ec64d
update element-web to 1.11.51 2023-12-07 21:12:36 +01:00
9a3134cf46
update paperless-ngx to v2.1.0 2023-12-07 21:12:27 +01:00
4e50bfe1a2
htz-cloud.wireguard: wg for oneplus7 2023-12-05 07:21:38 +01:00
81bb8653d8
update forgejo to 1.21.1-0 2023-11-29 16:43:08 +01:00
a21102724a
bundles/basic: use metadata.get() 2023-11-29 16:41:03 +01:00
d364b3c152
update mautrix-telegram to 0.15.0 2023-11-29 16:40:43 +01:00
7b646110f9
add home.o2-joggler 2023-11-26 20:33:12 +01:00
308b66c407
bundles/apt: explicitely uninstall python3-packaging 2023-11-26 11:14:17 +01:00
7199371065
update element-web to 1.11.50 2023-11-26 10:41:16 +01:00
22fb8fc162
add home.wled-aftonsparv 2023-11-25 12:40:40 +01:00
935f68ee97
bundles/icinga2: remove map.spam-rbl.com from SPAM BLOCKLIST check
points to sale.domainserviceplatform.com nowadays
2023-11-24 08:23:56 +01:00
1bce530ba1
update matrix-whatsapp to 0.10.4 2023-11-18 14:29:03 +01:00
48b453ceed
update element-web to 1.11.49 2023-11-18 14:28:40 +01:00
9bde59d7e3
carlene: update netbox to 3.6.5 2023-11-12 11:32:27 +01:00
400b10789a
home.paperless: update debian bookworm, update to paperless-ngx 2023-11-12 11:28:40 +01:00
b454fe4745
htz-cloud.{pirmasens,wireguard}: update to debian bookworm 2023-11-12 11:01:50 +01:00
75ef2e7bb9
bundles/wireguard: uninstall dkms package for debian > 11 2023-11-12 11:00:43 +01:00
d6db192f53
automatix fixes 2023-11-12 11:00:37 +01:00
90ca65eb9f
carlene: remove die-brontosaurier-waren-es.org 2023-11-11 21:09:47 +01:00
210f17da53
add ns-sargeras 2023-11-11 20:41:07 +01:00
6f318f21ae
bundles/powerdns: use schema provided by the powerdns package 2023-11-11 20:38:45 +01:00
1ae02ad4ec
bundles/php: some opcache settings 2023-11-11 20:16:33 +01:00
c473f730d2
htz-cloud.pirmasens: move salonkatrin.de to new website 2023-11-11 10:14:00 +01:00
807024eb98
update element-web to 1.11.48 2023-11-08 07:51:11 +01:00
529e999e69
voc.pretalx: more recent versions of everything please 2023-11-08 07:50:18 +01:00
9476771565
update matrix-media-repo to 1.3.3 2023-11-04 14:14:22 +01:00
99ca3b6282
home.nas: get jellyfin hardware transcoding to work 2023-10-30 20:14:15 +01:00
0b155a8a4d
carlene: update travelynx to 2.5.1 2023-10-30 20:14:01 +01:00
Sophie Schiller
60fffd6714 remove phanpy 2023-10-27 19:29:33 +02:00
f9ef74600f
remove c3voc-jira
lives in c3voc infrastructure and monitoring now
2023-10-27 18:54:51 +02:00
32afd183b1
update element-web to 1.11.47 2023-10-27 18:54:33 +02:00
74bcebfd05
update netbox to 3.6.4 2023-10-22 08:59:42 +02:00
01ffa3cc89
update mautrix-whatsapp to 0.10.3 2023-10-22 08:59:29 +02:00
0e03038bdb
bundles/voc-tracker-worker: use EnvironmentFile 2023-10-22 08:58:48 +02:00
ea42188904
bundles/oidentd: disable socket based activation 2023-10-22 08:58:31 +02:00
08bf3b6565
kunsi-p14s: disable ipv6 forwarding, we don't need that 2023-10-16 22:27:09 +02:00
588f1218c2
htz-cloud.wireguard: fix firewall 2023-10-16 22:26:29 +02:00
7a9401cd6c
kunsi-p14s: always have voc ip set up, enable forwarding and nat through wireless interface 2023-10-15 16:09:15 +02:00
ebc59f2843
update element-web to 1.11.46 2023-10-10 16:29:50 +02:00
3ab970a04a
update netbox to 2.4.1 2023-10-09 07:35:52 +02:00
fb55226ba0
update forgejo to 1.20.5 2023-10-09 07:35:50 +02:00
b712142fd1 Merge pull request 'bw/phanpy add fediverse interface' (#65) from phanpy into main
Reviewed-on: #65
2023-10-08 16:00:26 +00:00
Sophie Schiller
34428034dc bw/phanpy add fediverse interface 2023-10-08 16:54:34 +02:00
3c77ff530d
update travelynx to 2.4.0 2023-10-03 14:29:28 +02:00
60a8c70cae
home.winkeeinhorn-vm: send email for node health 2023-10-01 17:00:10 +02:00
3767825b84
ssl: bump *.home.kunbox.net 2023-10-01 16:57:13 +02:00
7cfe098b20
update all the things
* element-web -> 1.11.45
* netbox -> 3.6.3
* travelynx -> 2.3.1
2023-09-30 17:38:54 +02:00
497ecb5279
EOL htz-cloud.pleroma 2023-09-30 17:38:49 +02:00
d88645c7bd
move wireguard connection between kunsi-p14s and htz-cloud.wireguard to port 1194 2023-09-25 10:44:09 +02:00
ad9a920a48
bundles/icinga2: please only use "real" network interfaces instead of some vpn transfer ips 2023-09-24 21:07:21 +02:00
cd48cf495d
rework firewall setup 2023-09-24 21:01:51 +02:00
be62c1270f
remove isc-dhcp-server 2023-09-24 19:25:03 +02:00
b9d4204060
add wireguard connection between htz-cloud.wireguard and kunsi-p14s 2023-09-24 18:58:03 +02:00
a09b5b98ca
bundles/wireguard: disable health_checks if auto_connection is false 2023-09-24 18:57:27 +02:00
458606649e
bundles/wireguard: add option to route networks through vpn 2023-09-24 18:56:50 +02:00
0e40b03060
bundles/wireguard: only try to do full mesh if *we* are doing full mesh 2023-09-24 18:56:18 +02:00
53ff288d89
bundles/systemd-networkd: combine templates for interfaces 2023-09-24 18:54:47 +02:00
e27e374983
bundles/vmhost: qemu-headless does not exist anymore, apparently 2023-09-24 18:49:31 +02:00
d6eb0b4228
bundles/bird: do not auto-generate config if peer does not use bird 2023-09-24 18:48:24 +02:00
4084e764e4
add nginx proxy to jellyfin 2023-09-24 16:48:19 +02:00
361bb6a563
install jellyfin onto home.nas 2023-09-24 15:26:00 +02:00
74baeb4bf4
bundles/apt: suport deb822-style sources 2023-09-24 15:22:14 +02:00
787607b5a1
automatix/upgrade_debian_bookworm: always upgrade zfs pools 2023-09-24 14:49:02 +02:00
c2460e5291
remove *.franzi.business wildcard cert 2023-09-24 10:52:51 +02:00
77ed050ade
install oidentd on carlene, fix dependencies 2023-09-24 10:40:47 +02:00
2d3d0ca02a
EOL OVH, EOL rx300 2023-09-24 10:34:54 +02:00
6f31d6c0e4
add daisy to wireguard mesh 2023-09-23 16:46:45 +02:00
d999895450
home.router: let dyndns have ipv6 please 2023-09-23 16:42:00 +02:00
951d254c7a
add location information to daisy 2023-09-23 15:15:28 +02:00
07de570175
auto-generate full wireguard mesh between all nodes in libs.s2s.WG_AUTOGEN_NODES 2023-09-23 15:06:16 +02:00
e9f3268e15
clean up some leftovers 2023-09-23 15:06:03 +02:00
3a0ed4a7f5
bundles/wireguard: autogenerate port number based on index in WG_AUTOGEN_NODES 2023-09-23 15:04:47 +02:00
d47f7db708
bundles/wireguard: only try to auto-generate ips and ports if nodes are present in WG_AUTOGEN_NODES 2023-09-23 15:04:11 +02:00
0d79216ae5
bundles/wireguard: fix KeyError when running with no peers 2023-09-23 15:03:44 +02:00
799cff884b
remove a bunch of deprecated nodes 2023-09-23 15:03:01 +02:00
667fd6a2f0
update netbox to 3.6.2 2023-09-23 10:14:11 +02:00
4a9596988d
update forgejo to 1.20.4-1 2023-09-23 10:13:56 +02:00
c444722291
add automatix to upgrade to debian bookworm 2023-09-23 10:12:12 +02:00
c59a3038a1
bundles/wide-dhcp-client: fix some bugs 2023-09-23 09:23:41 +02:00
a61a3816ed
hello, daisy! 2023-09-20 18:34:59 +02:00
a926825b4b
libs/defaults: quad9 is apparently half-broken, just use cloudflare instead 2023-09-20 18:21:57 +02:00
dda3c4162c
bundles/postfix: ensure /etc/mailname exists before installing postfix 2023-09-20 17:46:04 +02:00
c6b01aa219
update mautrix-whatsapp to 0.10.2 2023-09-20 14:43:25 +02:00
8d2daeeb77
update mautrix-telegram to 0.14.2 2023-09-20 14:43:02 +02:00
5d69595bbf
update pretalx to 2023.1.3 2023-09-19 15:05:41 +02:00
b17d7bccf6
update travelynx to 2.2.2 2023-09-19 15:05:19 +02:00
aab7a1abc4
update mautrix-whatsapp to 0.10.1 2023-09-19 15:04:57 +02:00
3bf0e1124e
bundles/rspamd: disable greylisting
This only gets in the way. If mail is spam, it will get delivered to the
junk mail folder anyways.
2023-09-17 15:44:43 +02:00
32141b6e98
update element-web and matrix-media-repo 2023-09-16 13:07:50 +02:00
049cc899be
update travelynx to 2.2.1 2023-09-13 17:06:27 +02:00
d4f7f1b08d
update element-web to 1.11.42 2023-09-13 16:03:06 +02:00
40a283d5c9
update element-web to 1.11.41 2023-09-12 20:15:33 +02:00
4f260932c3
bundles/wireguard: health checks for everyone 2023-09-12 20:15:19 +02:00
Sophie Schiller
15eaa94397 miniserter: element-web update 2023-09-12 20:05:43 +02:00
9bde0d9410
home.router: upgrade to bookworm and switch to kea-dhcp-server 2023-09-10 22:02:14 +02:00
aaf67f1a3d
bundles/apt: bookworm has their own firmware repo 2023-09-10 22:00:19 +02:00
234e81431d
bundles/wireguard: easier snat setup 2023-09-10 21:27:03 +02:00
e70a86a6c1
htz-cloud.aurto: remove no longer needed keys 2023-09-10 21:16:02 +02:00
5b1d814d40
bundles/icinga2: more timeout for check_spam_blocklist 2023-09-10 21:15:31 +02:00
563735d31a
add new status page to icinga 2023-09-10 09:48:20 +02:00
b38bc67a60
move aurto to hetzner cloud 2023-09-09 23:02:42 +02:00
7845faeac3
htz-cloud.wireguard: add IPv4 NAT 2023-09-09 23:02:40 +02:00
5238937044
bundles/powerdns: do not put private ipv4 into dns if public ipv6 exists 2023-09-09 23:02:38 +02:00
5fda0ab464
aurto.kunbox.net IN CNAME aurto.htz-cloud.kunbox.net 2023-09-09 23:02:36 +02:00
Sophie Schiller
30604db869 hedgedoc: makee usable on bookworm 2023-09-09 22:42:53 +02:00
e7a652503f
update htz-cloud.{afra,miniserver} to bookworm 2023-09-09 21:09:52 +02:00
54d55bbb8d
update forgejo to 1.20.4 2023-09-09 21:09:30 +02:00
40aeeab265
update matrix-media-repo to 1.3.1 2023-09-09 20:39:23 +02:00
b38ba55ed3
bundles/forgejo: fix missing slash 2023-09-09 20:31:05 +02:00
1f2266302f
s/autojenkins/forgejo-carlene/ 2023-09-09 19:37:44 +02:00
cb6f12b218
add bundle:kea-dhcp-server 2023-09-09 18:40:10 +02:00
d9cb324bb6
update pretalx to 2023.1.0 2023-09-09 17:48:22 +02:00
25a484f04e
remove ovh nodes from monitoring 2023-09-09 17:46:30 +02:00
f061196f0d
bundles/icinga2: add snmp package, needed for check_snmp to work 2023-09-09 17:02:51 +02:00
f2b538a168
bundles/homeassistant: allow more time for checking stuff 2023-09-09 16:54:33 +02:00
711230a472
rx300: disable sms 2023-09-09 16:45:28 +02:00
b3b305076f
move die-brontosaurier-waren-es.org to carlene 2023-09-09 16:44:04 +02:00
20ff2f40f4
add wireguard tunnel between htz-cloud and icinga2 2023-09-09 16:12:28 +02:00
fe4d4abc9c
bundles/wireguard: fix max interface length 2023-09-09 16:10:49 +02:00
a2ceb8cc3a
bundles/bird: announce subnets via all ips 2023-09-09 16:10:33 +02:00
2b51812118
libs.tools.resolve_identifier(): add option to filter out linklocal ips and only physical interfaces 2023-09-09 15:37:37 +02:00
6539923644
update travelynx to 2.2.0 2023-09-09 15:28:29 +02:00
4a0aa81e8d
carlene: add new icinga2 host to ntfy exemptions 2023-09-09 15:28:07 +02:00
bf6ed289e1
bundles/icinga2: fix stupid in check_spam_blocklist 2023-09-09 14:24:34 +02:00
e6e9e425fc
move icinga2 to new host 2023-09-09 14:12:24 +02:00
99e261fe24
libs/s2s: switch to static list of wireguard peers 2023-09-09 14:11:39 +02:00
5db3856218
bundles/icinga2: remove obsolete check 2023-09-09 14:10:58 +02:00
e029329a03
bundles/icinga2: handle dig status messages in check_spam_blocklist 2023-09-09 14:10:27 +02:00
8f500b121c
voc.infobeamer-cms: add hexchen 2023-09-09 13:56:17 +02:00
deb0c7b597
bundles/unbound: ensure /usr/share/dns exists 2023-09-09 13:55:58 +02:00
d1bb94fd74
bundles/icinga2: more auto-generation of stuff 2023-09-09 13:55:16 +02:00
7df6b1d13a
bundles/wireguard: name wg interfaces according to their peers 2023-09-09 13:55:03 +02:00
7b8740601f
carlene: update netbox to 3.6.1 2023-09-07 07:23:19 +02:00
7e335cc3ae
move some stuff from rx300 to carlene 2023-09-03 18:26:54 +02:00
9dacd4a14b
move mta-sts vhost to carlene 2023-09-03 18:22:51 +02:00
e2e5eaa236
bundles/nextcloud: more upload limit please 2023-09-03 18:15:17 +02:00
5863105d64
dns: move kunbox.net to carlene 2023-09-03 18:10:55 +02:00
895f26d2f3
rx300: remove radicale 2023-09-03 17:24:42 +02:00
e087daae94
nextcloud: add cache-control headers to static assets 2023-09-03 12:28:53 +02:00
0964bd1695
update travelynx to 2.1.2 2023-09-03 12:20:40 +02:00
94bee38ca7
bundles/php: fix some typos 2023-09-03 12:20:24 +02:00
a33076186b
bundles/nextcloud: install php-apcu 2023-09-03 12:19:34 +02:00
2d201ebf0e
new access points, who dis? 2023-09-03 12:02:36 +02:00
ad24c0ea5b
add bundle:nextcloud to carlene 2023-09-02 21:14:38 +02:00
0001b5639b
kunsi-p14s: bug has been fixed 2023-09-02 20:49:34 +02:00
ea77c68e16
bundles/nginx: hide content security headers coming from php 2023-09-02 20:49:05 +02:00
72607adbfe
bundles/nginx: allow vhosts to set their own index files 2023-09-02 20:48:41 +02:00
8cfcefcfc4
bundles/matrix-stickerpicker: fix backup paths 2023-09-02 20:48:15 +02:00
b08c9fb5a4
replace matrix-dimension on rx300 with matrix-stickerpicker on carlene 2023-09-02 13:36:15 +02:00
fc75e92a78
dns: new mail server 2023-09-01 06:21:15 +02:00
194c60ddb2
bundles/ntfy: do not create timing logs 2023-09-01 06:20:19 +02:00
59fd245a3f
add dynamic node attribute for last apply
so we can check if something has changed in the repo since the last
apply
2023-09-01 06:16:09 +02:00
43d26650b0
update netbox to 3.6.0 2023-09-01 06:15:54 +02:00
e3784158de
update element-web to 1.11.40 2023-09-01 06:15:38 +02:00
dd8fd452eb
move mail from rx300 to carlene 2023-09-01 05:55:27 +02:00
97afd6c522
bundles/php: add php8.2 2023-09-01 05:54:54 +02:00
a838f6c5bd
bundles/postfixadmin: move vhost generation to reactor 2023-09-01 05:54:23 +02:00
b01dcb0ff9
bundles/nginx: enable creating logs for debugging purposes 2023-09-01 05:53:37 +02:00
553ed05ba2
remove freifunk access points, replace with aruba 2023-08-30 19:39:36 +02:00
01531c62de
bundles/rsyslogd: keep more logfiles 2023-08-28 17:26:34 +02:00
d450a43a96
switches-mikrotik: add rsyslog server 2023-08-28 17:25:34 +02:00
39576fda38
add bundle:rsyslogd 2023-08-28 17:21:48 +02:00
36dac3be7c
bundles/weechat: fix weechat fifo path 2023-08-27 11:13:35 +02:00
ab3f2df29f
update travelynx to 2.1.1 2023-08-27 10:30:22 +02:00
bb478430b9
migrate ntfy from rx300 to carlene 2023-08-27 09:38:06 +02:00
ad2312b715
matrix stuff: make journal usable again 2023-08-27 09:28:57 +02:00
7dda27b69d
migrate miniflux from rx300 to carlene 2023-08-27 09:17:55 +02:00
50cba7cb49
bundles/miniflux: use metadata.get() 2023-08-27 09:17:34 +02:00
0190555f16
bundles/matrix-synapse: do not log every request 2023-08-27 09:17:12 +02:00
757e9e6bb8
bundles/nginx: add option to disable anon_timing log 2023-08-26 17:21:23 +02:00
c6bb00c124
bundles/systemd: ensure we're not logging to syslog 2023-08-26 07:28:12 +02:00
8cf2dde6e0
add bundle:weechat, migrate weechat from rx300 to carlene 2023-08-25 12:52:31 +02:00
c6120accc1
bundles/icinga2: fix monitoring config 2023-08-25 11:11:48 +02:00
d0302d826a
bundles/icinga2: add icingaweb2 monitoring config 2023-08-25 11:09:36 +02:00
Sophie Schiller
0977dd5042 miniserver: move webdump to zfs 2023-08-24 19:30:25 +02:00
Sophie Schiller
48d3f8eee6 miniserver hedgedoc update 2023-08-24 19:13:09 +02:00
bca4d152ea
bundles/zfs: print zfs status output if pool is not online 2023-08-24 07:41:37 +02:00
33d42e2472
bundles/matrix-synapse: ensure we're logging to journal 2023-08-23 17:25:41 +02:00
e754b68f06
carlene: update travelynx to 2.0.3 2023-08-23 17:18:34 +02:00
bf9b9b4189
home.hass: update to bookworm 2023-08-23 17:18:11 +02:00
10a9e61026
bundles/homeassistant: changes for bookworm 2023-08-23 17:17:42 +02:00
daae710624
bundles/forgejo: fix version string in update check 2023-08-23 13:47:38 +02:00
8482f6a270
{c3voc,entropia}-jira: more monitoring 2023-08-23 13:46:44 +02:00
a8adde8c63
update forgejo to 1.20.3-0 2023-08-23 12:40:37 +02:00
6aa0114db5
update mautrix-whatsapp to 0.10.0 2023-08-23 12:39:31 +02:00
7a1dc40584
voc.infobeamer-cms: new domain and update for cccamp23 2023-08-23 12:19:56 +02:00
aecaebcefd
carlene: add web vhost for skye 2023-08-23 12:19:24 +02:00
20d1c0af05
update netbox to 3.5.8 2023-08-23 12:18:58 +02:00
4b6f680248
update element-web to 1.11.39 2023-08-23 12:18:25 +02:00
8ec785ffd8
update element-web to 1.11.38 2023-08-05 08:33:42 +02:00
1834bedf91
remove htz-cloud.luther 2023-08-04 08:07:41 +02:00
726023db17
htz-cloud.miniserver: update hedgedoc to 1.9.9 2023-08-02 19:51:50 +02:00
5604763303
update element-web to 1.11.37 2023-08-02 16:49:29 +02:00
5f0ba20622
move forgejo from rx300 to carlene 2023-08-02 16:38:32 +02:00
d3f55dc821
htz-cloud.afra: add fedi redirects 2023-08-02 16:38:14 +02:00
b692b09c00
rename bundle:gitea to bundle:forgejo 2023-08-02 16:37:48 +02:00
f1045172fd
rx300: delete unused configs 2023-08-02 08:09:30 +02:00
88ccd3ca72
migrate netbox from rx300 to carlene 2023-08-02 08:07:36 +02:00
a16fcdd935
migrate travelynx to carlene 2023-08-01 21:22:28 +02:00
c121110f00
bundles/travelynx: prepare for bookworm 2023-08-01 21:21:31 +02:00
3826ccf4ec
remove reboot mails, noone does care about these anyway 2023-07-26 08:29:37 +02:00
3a8e3ce01b
home.kodi-wohnzimmer: do not reboot automatically 2023-07-26 08:24:25 +02:00
92acae3cbe
move element-web from rx300 to carlene 2023-07-23 15:48:07 +02:00
4b434e7946
bundles/mixcloud-downloader: fix username 2023-07-23 14:04:01 +02:00
00cbabea1b
bundles/mixcloud-downloader: fix duplicate 2023-07-23 14:02:09 +02:00
80e0a29a31
htz-cloud.afra: update element-web to 1.11.36 2023-07-23 13:59:48 +02:00
9d1fc65b82
update mautrix-whatsapp to 0.9.0 2023-07-23 13:59:45 +02:00
21ec75a398
carlene: technician replugged the network cable to the other port :/ 2023-07-23 13:59:40 +02:00
3ab8eb88bd
move matrix from rx300 to carlene 2023-07-23 13:59:37 +02:00
272a11f7d3
bundles/postgresql: remove version-specific options 2023-07-23 13:59:34 +02:00
9aacb8f506
htop: less room for cpus please 2023-07-23 13:59:32 +02:00
76eef92ee2
bundles/postgresql: some improvements 2023-07-23 13:59:29 +02:00
54d0c42da6
bundles/matrix-synapse: auto-trust all own servers as keyservers 2023-07-23 13:59:26 +02:00
Sophie Schiller
f12d19fec6 htz-cloud.miniserver: fix element-web 2023-07-22 15:52:28 +02:00
e9ee2039d5
bundles/smartd: ignore non-digit values in telegraf stats 2023-07-13 21:41:52 +02:00
471e2ba6f6
bundles/{influxdb2,telegraf}: it's always the same, just use 'stable main' 2023-07-13 21:41:22 +02:00
838b61a2b9
bundles/grafana: remove useless "power on hours" graph 2023-07-13 21:40:55 +02:00
8d5fe0d926
carlene: add smartd 2023-07-13 21:31:44 +02:00
6b27128b6d
bundles/systemd-timers: add exclude_from_monitoring 2023-07-13 21:31:25 +02:00
3936e64227
bundles/smartd: use systemd-timers 2023-07-13 21:31:11 +02:00
bbfa985e1d
bundles/smartd: ignore partitions in smartd check 2023-07-13 21:30:49 +02:00
d0825a51ee
bundles/smartd: unit names have changed 2023-07-13 21:30:29 +02:00
14ec3c0ee2
gce: disable ipv6
Because this is "the cloud"™, gce does not support ipv6.
2023-07-13 20:48:04 +02:00
59c913b97c
carlene: add bundle:check-mail-received 2023-07-13 20:28:33 +02:00
97307fc6f3
nodes.py: demagify toml nodes 2023-07-13 20:28:28 +02:00
70bd7d295d
bundles/cron: less strict dependencies 2023-07-13 20:19:17 +02:00
40c90163ad
EHLO carlene 2023-07-13 20:09:04 +02:00
cff3fe558e
bundles/zfs: more ordering please 2023-07-13 20:04:43 +02:00
5fa8c72863
debian bookworm time \o/ 2023-07-13 20:02:38 +02:00
a5677e7d15
ssl: bump _.franzi.business 2023-07-13 08:04:17 +02:00
c6b20aea4e
ssl: bump _.home.kunbox.net 2023-07-13 08:04:04 +02:00
b8600255fc
update netbox to 3.5.6 2023-07-11 05:55:11 +02:00
cba412ecc1
update forgejo to 1.19.4-0 2023-07-11 05:54:44 +02:00
fa4ea575b4
bundles/users: show last five logins on login 2023-07-11 05:40:39 +02:00
Sophie Schiller
e9ee11cd08 element-web updates 2023-07-10 18:45:58 +02:00
d5f5fd853b
bundles/element-web: remove --openssl-legacy-provider 2023-06-29 05:39:30 +02:00
dff2bb0289
htz-cloud.afra: moar power plx 2023-06-29 05:38:55 +02:00
c3fe24c7b9
update element-web to 1.11.34 2023-06-29 05:37:55 +02:00
91b3d2f850
update mautrix-whatsapp to 0.8.6 2023-06-29 05:20:00 +02:00
341a43baf3
update netbox to 3.5.4 2023-06-29 05:18:19 +02:00
3a2006739c
update mautrix-telegram to 0.14.1 2023-06-29 05:17:35 +02:00
8968252ba6
bundles/nginx: fix content_type for logrotate config 2023-06-21 23:27:30 +02:00
6fb982e94c
rx300: update travelynx to 1.32.0 2023-06-21 23:25:26 +02:00
2e6e80d1c5
voc.infobeamer-cms: gpn21 2023-06-21 23:25:19 +02:00
42e20b122c
bundles/icinga2: add non-listing results to check_spam_blocklist 2023-06-21 23:25:12 +02:00
Sophie Schiller
85b95576c4 infobeamer-cms: additional moderators 2023-06-10 11:01:53 +02:00
Sophie Schiller
d17b146476 hedgedoc new release 2023-06-04 23:17:55 +02:00
0ca35a2e7e
update netbox to 3.5.3 2023-06-03 16:31:21 +02:00
d360dfb087
update mautrix-telegram to 0.14.0 2023-06-03 16:31:08 +02:00
712454c1e3
bundles/postgresql: more cache, please 2023-06-03 13:21:23 +02:00
5b9ce2faa1
fix trailing whitespace in tmux.conf of sophie 2023-05-26 10:49:23 +02:00
55f80b468e
bundles/matrix-registration: fix bugs 2023-05-26 10:48:01 +02:00
c3701da258
add htz-cloud.afra 2023-05-26 07:11:25 +02:00
e6111efe2d
bundles/matrix-registration: configurable client_redirect 2023-05-26 07:11:22 +02:00
Sophie Schiller
b8805c6f97 bw/data new tmux theme for sophie 2023-05-25 00:57:51 +02:00
829ebccad6
update travelynx to 1.31.4 2023-05-23 19:33:30 +02:00
926776fba2
update netbox to 3.5.2 2023-05-23 19:29:27 +02:00
9fc0004746
add option to exclude hosts from public status page 2023-05-21 06:59:34 +02:00
b35bfc85e9
ovh.icinga2: fix simple-icinga-dashboard 2023-05-20 20:12:24 +02:00
2607049f8d
add bundle:matrix-registration 2023-05-20 15:15:35 +02:00
6374f6b71e
bundles/matrix-synapse: support home servers without appservices 2023-05-20 15:10:57 +02:00
c44badb1e1
update matrix.org gpg key 2023-05-20 15:07:24 +02:00
6a573b3231
README: add system naming 2023-05-20 15:00:07 +02:00
1708f6ae17
bundles/matrix-synapse: include signing key in backups 2023-05-20 14:23:52 +02:00
3a5c944926
scripts/passwords-for: ensure keys are strings 2023-05-20 14:07:25 +02:00
b1567443ca
bundles/zfs: support other cpu architectures 2023-05-20 12:38:27 +02:00
0db4c19457
htz-cloud.sewfile: update to debian bullseye 2023-05-20 12:19:46 +02:00
b955633a23
automatix/upgrade_debian_bullseye: do zfs another way 2023-05-20 11:47:39 +02:00
2d433264e7
htz-cloud.influxdb: update to debian bullseye 2023-05-20 11:25:43 +02:00
32e6e61a3b
bundles/systemd: fix dependencies 2023-05-20 11:25:26 +02:00
cff42ef0f7
update home.downloadhelper to debian bullseye 2023-05-20 11:13:48 +02:00
c07b428cc9
add automatix script to upgrade systems to debian bullseye 2023-05-20 11:13:42 +02:00
3aedd7395b
update htz-cloud.luther to debian bullseye 2023-05-20 10:53:15 +02:00
048fb83ee7
bundles/apt: support spreading unattended-upgrades in a group 2023-05-20 07:46:23 +02:00
92cca7f396
isort the repo 2023-05-20 07:46:02 +02:00
604170f133
Jenkinsfile: remove isort check, because it behaves differently between venv and non-venv mode 2023-05-20 07:44:23 +02:00
9b1cea1e1d
update mautrix-whatsapp to 0.8.5 2023-05-19 22:01:40 +02:00
a44a3b3024
ns-ghirahim: set postfix relayhost 2023-05-19 21:58:20 +02:00
768a445e84
dns/kunbox.net: fix primary name server 2023-05-16 20:31:05 +02:00
a6f865104c
rename nameservers, once again 2023-05-16 20:05:40 +02:00
1260410eae
bundles/powerdns: split "add ip to autoprimaries" and "fix hostname for autoprimary" 2023-05-16 19:56:21 +02:00
261c284f2f
add ns-digitalocean 2023-05-16 19:25:23 +02:00
6d2cf0fa24
bundles/powerdns: ensure primary servers are in database 2023-05-16 19:25:17 +02:00
f8416215d5
ns-ionos: move powerdnsadmin webinterface to new hostname 2023-05-16 18:08:00 +02:00
a4bb7f89ec
rename ns-primary to ns-ionos 2023-05-16 17:58:31 +02:00
b68a80c8c3
home.nas: replace failed disk 2023-05-16 13:01:04 +02:00
a15cc2f121
wip 2023-05-15 15:56:42 +02:00
1ed9a4ff15
update travelynx to 1.31.2 2023-05-15 12:11:32 +02:00
034047dcd8
update netbox to 3.5.1 2023-05-15 12:09:22 +02:00
6449797b06
update forgejo to 1.19.3-0 2023-05-15 12:09:09 +02:00
77930b9a2f
update element-web to 1.11.32 2023-05-15 12:09:06 +02:00
b2ad9ce3d8
bundles/jugendhackt_tools: fix static root 2023-05-15 12:08:57 +02:00
906994b50f
rx300: add bundle:jugendhackt_tools 2023-05-06 17:27:02 +02:00
714fa88d72
bundles/ntfy: fix directory modes 2023-05-06 17:26:59 +02:00
556e0d75c8
home.nas: add another backup folder 2023-05-06 17:26:57 +02:00
f12a176759
bundles/sysctl: we need 99-sysctl.conf on debian 2023-05-06 17:26:54 +02:00
Sophie Schiller
83930e12bc sophie's desktopbackups 2023-04-29 13:15:36 +02:00
e59aa59124
update grafana gpg key 2023-04-28 16:47:09 +02:00
87184bc07b
update netbox to 3.5.0 2023-04-28 16:45:01 +02:00
5a594ad308
update element-web to 1.11.30 2023-04-28 16:44:48 +02:00
9a32534c49
bundles/icinga2: remove uceprotect level 2 from check_spam_blocklist 2023-04-28 16:42:55 +02:00
7b8eb63672
rx300: update forgejo to 1.19.1-0 2023-04-23 15:16:51 +02:00
acc3f3022a
rx300: update mautrix-whatsapp to 0.8.4 2023-04-23 15:16:25 +02:00
1c42226a42
ssl: bump _.home.kunbox.net 2023-04-23 15:14:10 +02:00
ac8c1fd3f3
ssl: bump _.franzi.business 2023-04-23 15:13:50 +02:00
d78102adb8
voc.pretalx: is bullseye now 2023-04-23 13:22:01 +02:00
f2e238d879
update ALL the things 2023-04-13 17:50:26 +02:00
19feb78bf6 Merge pull request 'htz-cloud.miniserver: remove nonfunctional dimension' (#62) from sophie-dimension-cleanup into main
Reviewed-on: #62
2023-04-09 22:49:10 +00:00
b3e490720e
bundles/icinga2: add notification support via ntfy 2023-04-09 17:32:36 +02:00
25aabad865
voc.infobeamer-cms: add jwacalex 2023-04-09 14:36:14 +02:00
c6cf997102
bundles/ntfy: add option to disable unauthorized writes 2023-04-09 12:24:23 +02:00
f17117d640
add hooks/test_apply_dummy_mode 2023-04-09 12:24:03 +02:00
5ff46edd8c
voc.infobeamer-cms: prepare for easterhegg 2023-04-09 12:10:29 +02:00
4d46401629
bump bundlewrap 2023-04-09 12:10:17 +02:00
3e497c3545
rx300: install ntfy 2023-04-09 12:10:04 +02:00
95d5c0cfc8
bundles/ntfy: update config to more recent version 2023-04-09 12:09:28 +02:00
2297f1dacf
kunsi-p14s: more packages please 2023-04-03 18:39:42 +02:00
d7d46c2681
rx300: update travelynx to 1.30.11 2023-04-03 18:39:14 +02:00
Sophie Schiller
e573f42730 htz-cloud.miniserver: remove nonfunctional dimension 2023-04-02 12:14:27 +02:00
68c4ee9482
update element-web to 1.11.28 2023-04-01 07:08:32 +02:00
a27ac38bec
add bundle:telegraf-monitors-mikrotik 2023-04-01 07:01:03 +02:00
4bcf15a64c
voc.pretalx: do rsync backups, too 2023-04-01 06:59:13 +02:00
9a6be52b05
bundles/backup-client: use set instead of list 2023-04-01 06:58:48 +02:00
60fc0e64e7
bundles/{apt,pacman}: ignore sshd processes spawned by user nobody 2023-04-01 06:50:37 +02:00
28298d3ce6
replace predefined ssh keys with generated ones 2023-03-31 21:45:09 +02:00
8d3e913a8c
kunsi-p14s: br0 contains all wired interfaces 2023-03-31 16:47:43 +02:00
bbbcfee042
add group switches-mikrotik 2023-03-31 16:47:27 +02:00
5af85ad535
remove home.sw02 2023-03-29 18:36:14 +02:00
a9874ce8fb
htz-cloud.influxdb: switch ip has changed 2023-03-29 18:22:34 +02:00
83f720d234
bump netbox-dump 2023-03-29 18:19:17 +02:00
7ff8319f09
home.nas: fix firewall and interface names 2023-03-29 18:19:14 +02:00
9b11e69a73
home.router: fix vlans 2023-03-29 18:19:11 +02:00
3c921e5d2e
rename home.bubble01 to home.mitel-rfp35 2023-03-29 18:19:07 +02:00
5116ba8a27 home.downloadhelper: fix vlan id 2023-03-29 16:17:44 +00:00
7eb2bf68d8 home.switch-rack: use password for authentication 2023-03-29 16:17:44 +00:00
fe7d57aca0 home.downloadhelper: more vlans 2023-03-29 16:17:44 +00:00
f6da1f6d71 home.nas: rotate all the vlans 2023-03-29 16:17:44 +00:00
317a3df11d home.router: rotate all the vlans 2023-03-29 16:17:44 +00:00
fe9716088a home.downloadhelper: rotate all the vlans 2023-03-29 16:17:44 +00:00
64716d12cf bump netbox dump for home.switch-rack 2023-03-29 16:17:44 +00:00
0522425218
rx300: we need bigger emails 2023-03-29 10:48:06 +02:00
ee68c9075b
rx300: update netbox to 3.4.7 2023-03-28 23:17:29 +02:00
6835793d6a
rx300: update travelynx to 1.30.9 2023-03-28 22:16:59 +02:00
6c48c25a94
update element-web to 1.11.26 2023-03-28 19:18:45 +02:00
8ec7f9e992
rx300: update forgejo to 1.19.0-2 2023-03-28 19:18:26 +02:00
f254b9bb12
kunsi-p14s: fix mountpoint for rootfs 2023-03-27 14:09:00 +02:00
ca614efec1
add home.switch-rack 2023-03-26 15:58:29 +02:00
190833c54a
bundles/lldp: do not run for routeros devices 2023-03-26 15:58:09 +02:00
66c6a92ec5
scripts/netbox-dump: also add interface type and ip addresses 2023-03-26 15:21:16 +02:00
a738b49aa4
add scripts/netbox-dump 2023-03-22 21:19:41 +01:00
08aadcaf36
rx300: update netbox to 3.4.6 2023-03-21 07:29:55 +01:00
51cdcba9e9
rx300: update mautrix-whatsapp to 0.8.3 2023-03-21 07:29:37 +01:00
8da5650134
htz-cloud.miniserver: update element-web to 1.11.25 2023-03-21 07:29:15 +01:00
445ec0ea15
rx300: update element-web to 1.11.25 2023-03-19 15:43:50 +01:00
e3b1d14fe7
bundles/miniflux: fix proxy settings 2023-03-19 15:43:34 +01:00
cc49d34475
bundles/matrix-synapse: add script to reset the federation timeout 2023-03-19 15:43:09 +01:00
b1b8df7dd8
remove some old scripts 2023-03-19 15:42:43 +01:00
9c590635b6 kunsi-p14s: install sdl_ttf 2023-03-14 09:24:12 +01:00
de6579140d
rx300: update travelynx to 1.30.7 2023-03-12 10:59:52 +01:00
985bb3cdec
ns-primary: update powerdnsadmin to 0.4.0 2023-03-12 10:59:35 +01:00
5272a212a7
voc.pretalx: update broadcast-tools to 1.1.0 2023-03-07 18:23:22 +01:00
b1d032df90
voc.pretalx: update pretalx to 2.3.2 2023-03-07 18:22:55 +01:00
d4e1da0689
update ALL the things! 2023-03-03 21:23:02 +01:00
460 changed files with 8602 additions and 6293 deletions

View file

@ -22,3 +22,6 @@ indent_size = unset
[*.vault] [*.vault]
end_of_line = unset end_of_line = unset
insert_final_newline = unset insert_final_newline = unset
[*.json]
insert_final_newline = unset

View file

@ -1,26 +0,0 @@
pipeline:
install-deps:
image: python:3.10-slim
commands:
- pip install -r requirements.txt
test-dummymode:
image: python:3.10-slim
commands:
- bw test
environment:
BW_VAULT_DUMMY_MODE: 1
BW_PASS_DUMMY_MODE: 1
test-ignore-missing-faults:
image: python:3.10-slim
commands:
- bw test --ignore-missing-faults
test-determinism:
image: python:3.10-slim
commands:
- bw test --metadata-determinism 3 --config-determinism 3
environment:
BW_VAULT_DUMMY_MODE: 1
BW_PASS_DUMMY_MODE: 1

View file

@ -1,8 +0,0 @@
pipeline:
editorconfig:
image: alpine:latest
commands:
- wget -O ec-linux-amd64.tar.gz https://github.com/editorconfig-checker/editorconfig-checker/releases/latest/download/ec-linux-amd64.tar.gz
- tar -xzf ec-linux-amd64.tar.gz
- rm ec-linux-amd64.tar.gz
- bin/ec-linux-amd64 -no-color -exclude '^bin/'

9
Jenkinsfile vendored
View file

@ -25,15 +25,6 @@ pipeline {
""" """
} }
} }
stage('syntax checking using isort') {
steps {
sh """
. venv/bin/activate
isort --check .
"""
}
}
stage('config and metadata determinism') { stage('config and metadata determinism') {
steps { steps {
sh """ sh """

View file

@ -30,13 +30,13 @@ Rule of thumb: keep ports below 10000 free for stuff that reserves ports.
| 20010 | mautrix-telegram | Bridge | | 20010 | mautrix-telegram | Bridge |
| 20020 | mautrix-whatsapp | Bridge | | 20020 | mautrix-whatsapp | Bridge |
| 20030 | matrix-dimension | Matrix Integrations Manager| | 20030 | matrix-dimension | Matrix Integrations Manager|
| 20070 | matrix-synapse | sliding-sync |
| 20080 | matrix-synapse | client, federation | | 20080 | matrix-synapse | client, federation |
| 20081 | matrix-synapse | prometheus metrics | | 20081 | matrix-synapse | prometheus metrics |
| 20090 | matrix-media-repo | media_repo | | 20090 | matrix-media-repo | media_repo |
| 20090 | matrix-media-repo | prometheus metrics | | 20090 | matrix-media-repo | prometheus metrics |
| 21000 | pleroma | pleroma |
| 21010 | grafana | grafana | | 21010 | grafana | grafana |
| 22000 | gitea | forgejo | | 22000 | forgejo | forgejo |
| 22010 | jenkins-ci | Jenkins CI | | 22010 | jenkins-ci | Jenkins CI |
| 22020 | travelynx | Travelynx Web | | 22020 | travelynx | Travelynx Web |
| 22030 | octoprint | OctoPrint Web Interface | | 22030 | octoprint | OctoPrint Web Interface |
@ -45,8 +45,9 @@ Rule of thumb: keep ports below 10000 free for stuff that reserves ports.
| 22060 | pretalx | gunicorn | | 22060 | pretalx | gunicorn |
| 22070 | paperless-ng | gunicorn | | 22070 | paperless-ng | gunicorn |
| 22080 | netbox | gunicorn | | 22080 | netbox | gunicorn |
| 22100 | woodpecker-server | http | | 22090 | jugendhackt_tools | gunicorn |
| 22101 | woodpecker-server | gRPC | | 22100 | powerdnsadmin | gunicorn |
| 22110 | icinga2-statuspage | gunicorn |
| 22999 | nginx | stub_status | | 22999 | nginx | stub_status |
| 22100 | ntfy | http | | 22100 | ntfy | http |

View file

@ -7,3 +7,16 @@ onto shared webhosting.
`bw test` runs according to Jenkinsfile after every commit. `bw test` runs according to Jenkinsfile after every commit.
[![Build Status](https://jenkins.franzi.business/buildStatus/icon?job=kunsi%2Fbundlewrap%2Fmain)](https://jenkins.franzi.business/job/kunsi/job/bundlewrap/job/main/) [![Build Status](https://jenkins.franzi.business/buildStatus/icon?job=kunsi%2Fbundlewrap%2Fmain)](https://jenkins.franzi.business/job/kunsi/job/bundlewrap/job/main/)
## automatix
Ensure you set `bundlewrap: true` in your `~/.automatix.cfg.yaml`.
## system naming
All systems should be named after their location and use.
For example, influxdb hosted at hetzner cloud will be `htz-cloud.influxdb`.
The only exception to this are name servers, they are named after [demons
in fiction](https://en.wikipedia.org/wiki/List_of_demons_in_fiction).

View file

@ -0,0 +1,45 @@
name: Upgrade to debian bullseye
systems:
node: foonode
always:
- has_zfs=python: NODES.node.has_bundle('zfs')
pipeline:
- manual: "set icinga2 downtime: https://icinga.franzi.business/monitoring/host/schedule-downtime?host={SYSTEMS.node}"
# apply first so we only see the upgrade changes later
- local: bw apply {SYSTEMS.node}
- manual: update debian version in node groups
- local: "bw apply -o bundle:apt -s symlink:/usr/bin/python pkg_apt: -- {SYSTEMS.node}"
# double time!
- remote@node: DEBIAN_FRONTEND=noninteractive apt-get -y -q -o Dpkg::Options::=--force-confold dist-upgrade
- remote@node: DEBIAN_FRONTEND=noninteractive apt-get -y -q -o Dpkg::Options::=--force-confold dist-upgrade
# reboot into bullseye
- remote@node: systemctl reboot
- local: |
exit=1
while [[ $exit -ne 0 ]];
do
sleep 1
ssh {SYSTEMS.node} true
exit=$?
done
# fix zfs and reboot again
- has_zfs?remote@node: zpool import tank -f
- has_zfs?remote@node: zpool upgrade -a
- has_zfs?remote@node: systemctl reboot
- has_zfs?local: |
exit=1
while [[ $exit -ne 0 ]];
do
sleep 1
ssh {SYSTEMS.node} true
exit=$?
done
# final apply
- local: bw apply {SYSTEMS.node}

View file

@ -0,0 +1,9 @@
% for uri in sorted(uris):
Types: ${' '.join(sorted(data.get('types', {'deb'})))}
URIs: ${uri}
Suites: ${os_release}
Components: ${' '.join(sorted(data.get('components', {'main'})))}
Architectures: ${' '.join(sorted(data.get('architectures', {'amd64'})))}
Signed-By: /etc/apt/trusted.gpg.d/${name}.list.asc
% endfor

View file

@ -6,10 +6,10 @@ apt-get update
DEBIAN_FRONTEND=noninteractive apt-get -y -q -o Dpkg::Options::=--force-confold dist-upgrade DEBIAN_FRONTEND=noninteractive apt-get -y -q -o Dpkg::Options::=--force-confold dist-upgrade
DEBIAN_FRONTEND=noninteractive apt-get -y -q autoclean
DEBIAN_FRONTEND=noninteractive apt-get -y -q autoremove DEBIAN_FRONTEND=noninteractive apt-get -y -q autoremove
DEBIAN_FRONTEND=noninteractive apt-get -y -q clean
% if clean_old_kernels: % if clean_old_kernels:
existing=$(dpkg --get-selections | grep -E '^linux-(image|headers)-[0-9]' || true) existing=$(dpkg --get-selections | grep -E '^linux-(image|headers)-[0-9]' || true)

View file

@ -0,0 +1,3 @@
deb http://deb.debian.org/debian/ bookworm main non-free contrib non-free-firmware
deb http://security.debian.org/debian-security bookworm-security main contrib non-free
deb http://deb.debian.org/debian/ bookworm-updates main contrib non-free

View file

@ -1 +0,0 @@
deb http://raspbian.raspberrypi.org/raspbian/ buster main contrib non-free rpi

View file

@ -19,7 +19,7 @@ statusfile="/var/tmp/unattended_upgrades.status"
# Workaround, because /var/tmp is usually 1777 # Workaround, because /var/tmp is usually 1777
[[ "$UID" == 0 ]] && chown root:root "$statusfile" [[ "$UID" == 0 ]] && chown root:root "$statusfile"
logins=$(ps h -C sshd -o euser | awk '$1 != "root" && $1 != "sshd" && $1 != "sshmon"') logins=$(ps h -C sshd -o euser | awk '$1 != "root" && $1 != "sshd" && $1 != "sshmon" && $1 != "nobody"')
if [[ -n "$logins" ]] if [[ -n "$logins" ]]
then then
echo "Will abort now, there are active SSH logins: $logins" echo "Will abort now, there are active SSH logins: $logins"
@ -46,10 +46,6 @@ fi
if [[ -f /var/run/reboot-required ]] && [[ "$auto_reboot_enabled" == "True" ]] if [[ -f /var/run/reboot-required ]] && [[ "$auto_reboot_enabled" == "True" ]]
then then
if [[ -n "$reboot_mail_to" ]]
then
date | mail -s "SYSREBOOTNOW $nodename" "$reboot_mail_to"
fi
systemctl reboot systemctl reboot
fi fi

View file

@ -1,3 +1,2 @@
nodename="${node.name}" nodename="${node.name}"
reboot_mail_to="${node.metadata.get('apt/unattended-upgrades/reboot_mail_to', '')}"
auto_reboot_enabled="${node.metadata.get('apt/unattended-upgrades/reboot_enabled', True)}" auto_reboot_enabled="${node.metadata.get('apt/unattended-upgrades/reboot_enabled', True)}"

View file

@ -4,11 +4,9 @@ supported_os = {
'debian': { 'debian': {
10: 'buster', 10: 'buster',
11: 'bullseye', 11: 'bullseye',
12: 'bookworm',
99: 'unstable', 99: 'unstable',
}, },
'raspbian': {
10: 'buster',
},
} }
try: try:
@ -26,6 +24,10 @@ actions = {
'triggered': True, 'triggered': True,
'cascade_skip': False, 'cascade_skip': False,
}, },
'apt_execute_update_commands': {
'command': ' && '.join(sorted(node.metadata.get('apt/additional_update_commands', {'true'}))),
'triggered': True,
},
} }
files = { files = {
@ -113,7 +115,7 @@ pkg_apt = {
'mtr': {}, 'mtr': {},
'ncdu': {}, 'ncdu': {},
'ncurses-term': {}, 'ncurses-term': {},
'netcat': {}, 'netcat-openbsd': {},
'nmap': {}, 'nmap': {},
'python3': {}, 'python3': {},
'python3-dev': {}, 'python3-dev': {},
@ -152,6 +154,9 @@ pkg_apt = {
'popularity-contest': { 'popularity-contest': {
'installed': False, 'installed': False,
}, },
'python3-packaging': {
'installed': False,
},
'unattended-upgrades': { 'unattended-upgrades': {
'installed': False, 'installed': False,
}, },
@ -168,21 +173,44 @@ if node.os_version[0] >= 11:
} }
for name, data in node.metadata.get('apt/repos', {}).items(): for name, data in node.metadata.get('apt/repos', {}).items():
files['/etc/apt/sources.list.d/{}.list'.format(name)] = { if 'items' in data:
'content_type': 'mako', files['/etc/apt/sources.list.d/{}.list'.format(name)] = {
'content': ("\n".join(sorted(data['items']))).format( 'content_type': 'mako',
os=node.os, 'content': ("\n".join(sorted(data['items']))).format(
os_release=supported_os[node.os][node.os_version[0]], os=node.os,
), os_release=supported_os[node.os][node.os_version[0]],
'triggers': { ),
'action:apt_update', 'triggers': {
}, 'action:apt_update',
} },
}
elif 'uris' in data:
uris = {
x.format(
os=node.os,
os_release=supported_os[node.os][node.os_version[0]],
) for x in data['uris']
}
files['/etc/apt/sources.list.d/{}.sources'.format(name)] = {
'source': 'deb822-sources',
'content_type': 'mako',
'context': {
'data': data,
'name': name,
'os_release': supported_os[node.os][node.os_version[0]],
'uris': uris,
},
'triggers': {
'action:apt_update',
},
}
if data.get('install_gpg_key', True): if data.get('install_gpg_key', True):
files['/etc/apt/sources.list.d/{}.list'.format(name)]['needs'] = { if 'items' in data:
'file:/etc/apt/trusted.gpg.d/{}.list.asc'.format(name), files['/etc/apt/sources.list.d/{}.list'.format(name)]['needs'] = {
} 'file:/etc/apt/trusted.gpg.d/{}.list.asc'.format(name),
}
files['/etc/apt/trusted.gpg.d/{}.list.asc'.format(name)] = { files['/etc/apt/trusted.gpg.d/{}.list.asc'.format(name)] = {
'source': 'gpg-keys/{}.asc'.format(name), 'source': 'gpg-keys/{}.asc'.format(name),

View file

@ -21,16 +21,24 @@ defaults = {
'cron/jobs/upgrade-and-reboot' 'cron/jobs/upgrade-and-reboot'
) )
def patchday(metadata): def patchday(metadata):
if not node.metadata.get('apt/unattended-upgrades/enabled', True):
return {}
day = metadata.get('apt/unattended-upgrades/day') day = metadata.get('apt/unattended-upgrades/day')
hour = metadata.get('apt/unattended-upgrades/hour') hour = metadata.get('apt/unattended-upgrades/hour')
spread = metadata.get('apt/unattended-upgrades/spread_in_group', None)
if spread is not None:
spread_nodes = sorted(repo.nodes_in_group(spread))
day += spread_nodes.index(node)
return { return {
'cron': { 'cron': {
'jobs': { 'jobs': {
'upgrade-and-reboot': '{minute} {hour} * * {day} root /usr/local/sbin/upgrade-and-reboot'.format( 'upgrade-and-reboot': '{minute} {hour} * * {day} root /usr/local/sbin/upgrade-and-reboot'.format(
minute=node.magic_number % 30, minute=node.magic_number % 30,
hour=hour, hour=hour,
day=day, day=day%7,
), ),
}, },
}, },

View file

@ -0,0 +1,5 @@
context.exec = [
{ path = "pactl" args = "load-module module-native-protocol-tcp" }
{ path = "pactl" args = "load-module module-zeroconf-discover" }
{ path = "pactl" args = "load-module module-zeroconf-publish" }
]

View file

@ -44,6 +44,11 @@ directories = {
} }
svc_systemd = { svc_systemd = {
'avahi-daemon': {
'needs': {
'pkg_pacman:avahi',
},
},
'sddm': { 'sddm': {
'needs': { 'needs': {
'pkg_pacman:sddm', 'pkg_pacman:sddm',
@ -61,6 +66,8 @@ git_deploy = {
}, },
} }
files['/etc/pipewire/pipewire-pulse.conf.d/50-network.conf'] = {}
for filename in listdir(join(repo.path, 'data', 'arch-with-gui', 'files', 'fonts')): for filename in listdir(join(repo.path, 'data', 'arch-with-gui', 'files', 'fonts')):
if filename.startswith('.'): if filename.startswith('.'):
continue continue

View file

@ -9,6 +9,14 @@ defaults = {
'icinga_options': { 'icinga_options': {
'exclude_from_monitoring': True, 'exclude_from_monitoring': True,
}, },
'nftables': {
'input': {
'50-avahi': {
'udp dport 5353 accept',
'udp sport 5353 accept',
},
},
},
'pacman': { 'pacman': {
'packages': { 'packages': {
# fonts # fonts
@ -23,8 +31,9 @@ defaults = {
'sddm': {}, 'sddm': {},
# networking # networking
'avahi': {},
'netctl': {}, 'netctl': {},
'rfkill': {}, 'util-linux': {}, # provides rfkill
'wpa_supplicant': {}, 'wpa_supplicant': {},
'wpa_actiond': {}, 'wpa_actiond': {},
@ -45,6 +54,7 @@ defaults = {
'pipewire': {}, 'pipewire': {},
'pipewire-jack': {}, 'pipewire-jack': {},
'pipewire-pulse': {}, 'pipewire-pulse': {},
'pipewire-zeroconf': {},
'qpwgraph': {}, 'qpwgraph': {},
# window management # window management

View file

@ -62,10 +62,13 @@ trap "on_exit" EXIT
# redirect stdout and stderr to logfile # redirect stdout and stderr to logfile
prepare_and_cleanup_logdir prepare_and_cleanup_logdir
logfile="$logdir/backup--$(date '+%F--%H-%M-%S')--$$.log.gz" if [[ -z "$DEBUG" ]]
echo "All log output will go to $logfile" | logger -it backup-client then
exec > >(gzip >"$logfile") logfile="$logdir/backup--$(date '+%F--%H-%M-%S')--$$.log.gz"
exec 2>&1 echo "All log output will go to $logfile" | logger -it backup-client
exec > >(gzip >"$logfile")
exec 2>&1
fi
# this is where the real work starts # this is where the real work starts
ts_begin=$(date +%s) ts_begin=$(date +%s)

View file

@ -19,12 +19,12 @@ else:
if node.metadata.get('backups/exclude_from_backups', False): if node.metadata.get('backups/exclude_from_backups', False):
# make sure nobody tries to do something funny # make sure nobody tries to do something funny
for file in [ for file in {
'/etc/backup.priv', '/etc/backup.priv',
'/usr/local/bin/generate-backup', '/usr/local/bin/generate-backup',
'/usr/local/bin/generate-backup-with-retries', '/usr/local/bin/generate-backup-with-retries',
'/var/tmp/backup.monitoring', # status file '/var/tmp/backup.monitoring', # status file
]: }:
files[file] = { files[file] = {
'delete': True, 'delete': True,
} }
@ -33,14 +33,17 @@ else:
backup_target = repo.get_node(node.metadata.get('backup-client/target')) backup_target = repo.get_node(node.metadata.get('backup-client/target'))
files['/etc/backup.priv'] = { files['/etc/backup.priv'] = {
'content': repo.vault.decrypt_file(join('backup', 'keys', f'{node.name}.key.vault')), 'content': repo.libs.ssh.generate_ed25519_private_key(
node.metadata.get('backup-client/user-name'),
backup_target,
),
'mode': '0400', 'mode': '0400',
} }
files['/usr/local/bin/generate-backup'] = { files['/usr/local/bin/generate-backup'] = {
'content_type': 'mako', 'content_type': 'mako',
'context': { 'context': {
'username': node.metadata['backup-client']['user-name'], 'username': node.metadata.get('backup-client/user-name'),
'server': backup_target.metadata.get('backup-server/my_hostname'), 'server': backup_target.metadata.get('backup-server/my_hostname'),
'port': backup_target.metadata.get('backup-server/my_ssh_port'), 'port': backup_target.metadata.get('backup-server/my_ssh_port'),
'paths': backup_paths, 'paths': backup_paths,

View file

@ -27,9 +27,6 @@ directories['/etc/backup-server/clients'] = {
sudoers = {} sudoers = {}
for nodename, config in node.metadata.get('backup-server/clients', {}).items(): for nodename, config in node.metadata.get('backup-server/clients', {}).items():
with open(join(repo.path, 'data', 'backup', 'keys', f'{nodename}.pub'), 'r') as f:
pubkey = f.read().strip()
sudoers[config['user']] = nodename sudoers[config['user']] = nodename
users[config['user']] = { users[config['user']] = {
@ -41,7 +38,10 @@ for nodename, config in node.metadata.get('backup-server/clients', {}).items():
} }
files[f'/srv/backups/{nodename}/.ssh/authorized_keys'] = { files[f'/srv/backups/{nodename}/.ssh/authorized_keys'] = {
'content': pubkey, 'content': repo.libs.ssh.generate_ed25519_public_key(
config['user'],
node,
),
'owner': config['user'], 'owner': config['user'],
'mode': '0400', 'mode': '0400',
'needs': { 'needs': {

View file

@ -35,8 +35,15 @@ def get_my_clients(metadata):
continue continue
my_clients[rnode.name] = { my_clients[rnode.name] = {
'user': rnode.metadata.get('backup-client/user-name'), 'exclude_from_monitoring': rnode.metadata.get(
'backup-client/exclude_from_monitoring',
rnode.metadata.get(
'icinga_options/exclude_from_monitoring',
False,
),
),
'one_backup_every_hours': rnode.metadata.get('backup-client/one_backup_every_hours', 24), 'one_backup_every_hours': rnode.metadata.get('backup-client/one_backup_every_hours', 24),
'user': rnode.metadata.get('backup-client/user-name'),
'retain': { 'retain': {
'daily': rnode.metadata.get('backups/retain/daily', retain_defaults['daily']), 'daily': rnode.metadata.get('backups/retain/daily', retain_defaults['daily']),
'weekly': rnode.metadata.get('backups/retain/weekly', retain_defaults['weekly']), 'weekly': rnode.metadata.get('backups/retain/weekly', retain_defaults['weekly']),
@ -153,7 +160,7 @@ def monitoring(metadata):
client, client,
config['one_backup_every_hours'], config['one_backup_every_hours'],
), ),
'vars.sshmon_timeout': 20, 'vars.sshmon_timeout': 40,
} }
return { return {

View file

@ -32,8 +32,8 @@ account_guest_in_cpu_meter=0
color_scheme=0 color_scheme=0
enable_mouse=0 enable_mouse=0
delay=10 delay=10
left_meters=Tasks LoadAverage Uptime Memory CPU LeftCPUs CPU left_meters=Tasks LoadAverage Uptime Memory CPU LeftCPUs2 CPU
left_meter_modes=2 2 2 1 1 1 2 left_meter_modes=2 2 2 1 1 1 2
right_meters=Hostname CPU RightCPUs right_meters=Hostname CPU RightCPUs2
right_meter_modes=2 3 1 right_meter_modes=2 3 1
hide_function_bar=0 hide_function_bar=0

View file

@ -29,8 +29,19 @@ files = {
}, },
} }
if node.has_any_bundle([
'dovecot',
'nginx',
'postfix',
]):
actions['generate-dhparam'] = {
'command': 'openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048',
'unless': 'test -f /etc/ssl/certs/dhparam.pem',
}
locale_needs = set() locale_needs = set()
for locale in sorted(node.metadata['locale']['installed']): for locale in sorted(node.metadata.get('locale/installed')):
actions[f'ensure_locale_{locale}_is_enabled'] = { actions[f'ensure_locale_{locale}_is_enabled'] = {
'command': f"sed -i '/{locale}/s/^# *//g' /etc/locale.gen", 'command': f"sed -i '/{locale}/s/^# *//g' /etc/locale.gen",
'unless': f"grep -e '^{locale}' /etc/locale.gen", 'unless': f"grep -e '^{locale}' /etc/locale.gen",
@ -41,17 +52,15 @@ for locale in sorted(node.metadata['locale']['installed']):
} }
locale_needs = {f'action:ensure_locale_{locale}_is_enabled'} locale_needs = {f'action:ensure_locale_{locale}_is_enabled'}
actions = { actions['locale-gen'] = {
'locale-gen': { 'triggered': True,
'triggered': True, 'command': 'locale-gen',
'command': 'locale-gen',
},
} }
description = [] description = []
if not node.metadata.get('icinga_options/exclude_from_monitoring', False): if not node.metadata.get('icinga_options/exclude_from_monitoring', False):
description.append('icingaweb2: https://icinga.kunsmann.eu/monitoring/host/show?host={}'.format(node.name)) description.append('icingaweb2: https://icinga.franzi.business/monitoring/host/show?host={}'.format(node.name))
if node.has_bundle('telegraf'): if node.has_bundle('telegraf'):
description.append('Grafana: https://grafana.kunsmann.eu/d/{}'.format(UUID(int=node.magic_number).hex[:10])) description.append('Grafana: https://grafana.kunsmann.eu/d/{}'.format(UUID(int=node.magic_number).hex[:10]))

View file

@ -19,7 +19,9 @@ protocol static {
ipv4; ipv4;
% for route in sorted(node.metadata.get('bird/static_routes', set())): % for route in sorted(node.metadata.get('bird/static_routes', set())):
route ${route} via ${node.metadata.get('bird/my_ip')}; % for name, config in sorted(node.metadata.get('bird/bgp_neighbors', {}).items()):
route ${route} via ${config['local_ip']};
% endfor
% endfor % endfor
} }
% endif % endif

View file

@ -24,7 +24,7 @@ defaults = {
}, },
'sysctl': { 'sysctl': {
'options': { 'options': {
'net.ipv4.ip_forward': '1', 'net.ipv4.conf.all.forwarding': '1',
'net.ipv6.conf.all.forwarding': '1', 'net.ipv6.conf.all.forwarding': '1',
}, },
}, },
@ -43,6 +43,9 @@ def neighbor_info_from_wireguard(metadata):
except NoSuchNode: except NoSuchNode:
continue continue
if not rnode.has_bundle('bird'):
continue
neighbors[name] = { neighbors[name] = {
'local_ip': config['my_ip'], 'local_ip': config['my_ip'],
'local_as': my_as, 'local_as': my_as,
@ -62,7 +65,10 @@ def neighbor_info_from_wireguard(metadata):
) )
def my_ip(metadata): def my_ip(metadata):
if node.has_bundle('wireguard'): if node.has_bundle('wireguard'):
my_ip = sorted(metadata.get('interfaces/wg0/ips'))[0].split('/')[0] wg_ifaces = sorted({iface for iface in metadata.get('interfaces').keys() if iface.startswith('wg_')})
if not wg_ifaces:
return {}
my_ip = sorted(metadata.get(f'interfaces/{wg_ifaces[0]}/ips'))[0].split('/')[0]
else: else:
my_ip = str(sorted(repo.libs.tools.resolve_identifier(repo, node.name))[0]) my_ip = str(sorted(repo.libs.tools.resolve_identifier(repo, node.name))[0])
@ -84,7 +90,7 @@ def firewall(metadata):
return { return {
'firewall': { 'firewall': {
'port_rules': { 'port_rules': {
'179': atomic(sources), '179/tcp': atomic(sources),
}, },
}, },
} }

View file

@ -1,5 +1,19 @@
from bundlewrap.exceptions import BundleError from bundlewrap.exceptions import BundleError
supported_os = {
'debian': {
10: 'buster',
11: 'bullseye',
12: 'bookworm',
99: 'unstable',
},
}
try:
supported_os[node.os][node.os_version[0]]
except (KeyError, IndexError):
raise BundleError(f'{node.name}: OS {node.os} {node.os_version} is not supported by bundle:apt')
CONFLICTING_BUNDLES = { CONFLICTING_BUNDLES = {
'apt', 'apt',
'nginx', 'nginx',
@ -57,6 +71,18 @@ actions = {
'svc_systemd:', 'svc_systemd:',
}, },
}, },
'apt_update': {
'command': 'apt-get update',
'needed_by': {
'pkg_apt:',
},
'triggered': True,
'cascade_skip': False,
},
'apt_execute_update_commands': {
'command': ' && '.join(sorted(node.metadata.get('apt/additional_update_commands', {'true'}))),
'triggered': True,
},
} }
directories = { directories = {
@ -92,6 +118,30 @@ files = {
}, },
} }
for name, data in node.metadata.get('apt/repos', {}).items():
files['/etc/apt/sources.list.d/{}.list'.format(name)] = {
'content_type': 'mako',
'content': ("\n".join(sorted(data['items']))).format(
os=node.os,
os_release=supported_os[node.os][node.os_version[0]],
),
'triggers': {
'action:apt_update',
},
}
if data.get('install_gpg_key', True):
files['/etc/apt/sources.list.d/{}.list'.format(name)]['needs'] = {
'file:/etc/apt/trusted.gpg.d/{}.list.asc'.format(name),
}
files['/etc/apt/trusted.gpg.d/{}.list.asc'.format(name)] = {
'source': 'gpg-keys/{}.asc'.format(name),
'triggers': {
'action:apt_update',
},
}
for crontab, content in node.metadata.get('cron/jobs', {}).items(): for crontab, content in node.metadata.get('cron/jobs', {}).items():
files['/etc/cron.d/{}'.format(crontab)] = { files['/etc/cron.d/{}'.format(crontab)] = {
'source': 'cron_template', 'source': 'cron_template',

View file

@ -17,7 +17,7 @@ files = {
directories = { directories = {
'/etc/cron.d': { '/etc/cron.d': {
'purge': True, 'purge': True,
'needs': { 'after': {
'pkg_apt:', 'pkg_apt:',
}, },
}, },

View file

@ -1,36 +0,0 @@
<%
import re
from ipaddress import ip_network
%>
ddns-update-style none;
authoritative;
% for interface, subnet in sorted(dhcp_config.get('subnets', {}).items()):
<%
network = ip_network(subnet['subnet'])
%>
# interface ${interface} provides ${subnet['subnet']}
subnet ${network.network_address} netmask ${network.netmask} {
% if subnet.get('range_lower', None) and subnet.get('range_higher', None):
range ${subnet['range_lower']} ${subnet['range_higher']};
% endif
interface "${interface}";
default-lease-time ${subnet.get('default-lease-time', 600)};
max-lease-time ${subnet.get('max-lease-time', 3600)};
% for option, value in sorted(subnet.get('options', {}).items()):
% if re.match('([^0-9\.,\ ])', value):
option ${option} "${value}";
% else:
option ${option} ${value};
% endif
% endfor
}
% endfor
% for identifier, allocation in dhcp_config.get('fixed_allocations', {}).items():
host ${identifier} {
hardware ethernet ${allocation['mac']};
fixed-address ${allocation['ipv4']};
}
% endfor

View file

@ -1,18 +0,0 @@
# Defaults for isc-dhcp-server (sourced by /etc/init.d/isc-dhcp-server)
# Path to dhcpd's config file (default: /etc/dhcp/dhcpd.conf).
#DHCPDv4_CONF=/etc/dhcp/dhcpd.conf
#DHCPDv6_CONF=/etc/dhcp/dhcpd6.conf
# Path to dhcpd's PID file (default: /var/run/dhcpd.pid).
#DHCPDv4_PID=/var/run/dhcpd.pid
#DHCPDv6_PID=/var/run/dhcpd6.pid
# Additional options to start dhcpd with.
# Don't use options -cf or -pf here; use DHCPD_CONF/ DHCPD_PID instead
#OPTIONS=""
# On what interfaces should the DHCP server (dhcpd) serve DHCP requests?
# Separate multiple interfaces with spaces, e.g. "eth0 eth1".
INTERFACESv4="${' '.join(sorted(node.metadata.get('dhcpd/subnets', {})))}"
INTERFACESv6=""

View file

@ -1,41 +0,0 @@
files = {
'/etc/dhcp/dhcpd.conf': {
'content_type': 'mako',
'context': {
'dhcp_config': node.metadata['dhcpd'],
},
'needs': {
'pkg_apt:isc-dhcp-server'
},
'triggers': {
'svc_systemd:isc-dhcp-server:restart',
},
},
'/etc/default/isc-dhcp-server': {
'content_type': 'mako',
'needs': {
'pkg_apt:isc-dhcp-server'
},
'triggers': {
'svc_systemd:isc-dhcp-server:restart',
},
},
}
actions = {
# needed for dhcp-lease-list
'dhcpd_download_oui.txt': {
'command': 'wget http://standards-oui.ieee.org/oui.txt -O /usr/local/etc/oui.txt',
'unless': 'test -f /usr/local/etc/oui.txt',
},
}
svc_systemd = {
'isc-dhcp-server': {
'needs': {
'pkg_apt:isc-dhcp-server',
'file:/etc/dhcp/dhcpd.conf',
'file:/etc/default/isc-dhcp-server',
},
},
}

View file

@ -1,54 +0,0 @@
defaults = {
'apt': {
'packages': {
'isc-dhcp-server': {},
},
},
'bash_aliases': {
'leases': 'sudo dhcp-lease-list | tail -n +4 | sort -k 2,2',
},
}
@metadata_reactor.provides(
'dhcpd/fixed_allocations',
)
def get_static_allocations(metadata):
allocations = {}
for rnode in repo.nodes:
if rnode.metadata.get('location', '') != metadata.get('location', ''):
continue
for iface_name, iface_config in rnode.metadata.get('interfaces', {}).items():
if iface_config.get('dhcp', False):
try:
allocations[f'{rnode.name}_{iface_name}'] = {
'ipv4': sorted(iface_config['ips'])[0],
'mac': iface_config['mac'],
}
except KeyError:
pass
return {
'dhcpd': {
'fixed_allocations': allocations,
}
}
@metadata_reactor.provides(
'nftables/rules/10-dhcpd',
)
def nftables(metadata):
rules = set()
for iface in node.metadata.get('dhcpd/subnets', {}):
rules.add(f'inet filter input udp dport {{ 67, 68 }} iif {iface} accept')
return {
'nftables': {
'rules': {
# can't use port_rules here, because we're generating interface based rules.
'10-dhcpd': sorted(rules),
},
}
}

View file

@ -1,11 +0,0 @@
from bundlewrap.metadata import metadata_to_json
files['/etc/docker/daemon.json'] = {
'content': metadata_to_json({
'iptables': False,
}),
'before': {
'pkg_apt:docker-ce',
'pkg_apt:docker-ce-cli',
}
}

View file

@ -1,36 +0,0 @@
defaults = {
'apt': {
'repos': {
'docker': {
'items': {
'deb https://download.docker.com/linux/debian {os_release} stable',
},
},
},
'packages': {
'docker-ce': {},
'docker-ce-cli': {},
},
},
}
@metadata_reactor.provides(
'nftables/rules/00-docker-ce',
)
def nftables_nat(metadata):
rules = {
'inet filter forward ct state { related, established } accept',
'inet filter forward iifname docker0 accept',
}
for iface in metadata.get('interfaces'):
rules.add(f'nat postrouting oifname {iface} masquerade')
return {
'nftables': {
'rules': {
'00-docker-ce': sorted(rules),
},
},
}

View file

@ -0,0 +1,39 @@
#!/usr/bin/env python3
from json import loads
from subprocess import check_output
from sys import argv
try:
container_name = argv[1]
docker_ps = check_output([
'docker',
'container',
'ls',
'--all',
'--format',
'json',
'--filter',
f'name={container_name}'
])
containers = loads(f"[{','.join([l for l in docker_ps.decode().splitlines() if l])}]")
if not containers:
print(f'CRITICAL: container {container_name} not found!')
exit(2)
if len(containers) > 1:
print(f'Found more than one container matching {container_name}!')
print(docker_ps)
exit(3)
if containers[0]['State'] != 'running':
print(f'WARNING: container {container_name} not "running"')
exit(2)
print(f"OK: {containers[0]['Status']}")
except Exception as e:
print(repr(e))
exit(2)

View file

@ -0,0 +1,50 @@
#!/bin/bash
[[ -n "$DEBUG" ]] && set -x
ACTION="$1"
set -euo pipefail
if [[ -z "$ACTION" ]]
then
echo "Usage: $0 start|stop"
exit 1
fi
PUID="$(id -u "docker-${name}")"
PGID="$(id -g "docker-${name}")"
if [ "$ACTION" == "start" ]
then
docker run -d \
--name "${name}" \
--env "PUID=$PUID" \
--env "PGID=$PGID" \
--env "TZ=${timezone}" \
% for k, v in sorted(environment.items()):
--env "${k}=${v}" \
% endfor
--network host \
% for host_port, container_port in sorted(ports.items()):
--expose "127.0.0.1:${host_port}:${container_port}" \
% endfor
% for host_path, container_path in sorted(volumes.items()):
--volume "/var/opt/docker-engine/${name}/${host_path}:${container_path}" \
% endfor
--restart unless-stopped \
"${image}"
elif [ "$ACTION" == "stop" ]
then
docker stop "${name}"
docker rm "${name}"
else
echo "Unknown action $ACTION"
exit 1
fi
% if node.has_bundle('nftables'):
systemctl reload nftables
% endif

View file

@ -0,0 +1,14 @@
[Unit]
Description=docker-engine app ${name}
After=network.target
Requires=${' '.join(sorted(requires))}
[Service]
WorkingDirectory=/var/opt/docker-engine/${name}/
ExecStart=/opt/docker-engine/${name} start
ExecStop=/opt/docker-engine/${name} stop
Type=simple
RemainAfterExit=true
[Install]
WantedBy=multi-user.target

View file

@ -0,0 +1,99 @@
from bundlewrap.metadata import metadata_to_json
deps = {
'pkg_apt:docker-ce',
'pkg_apt:docker-ce-cli',
}
directories['/opt/docker-engine'] = {
'purge': True,
}
directories['/var/opt/docker-engine'] = {}
files['/etc/docker/daemon.json'] = {
'content': metadata_to_json(node.metadata.get('docker-engine/config')),
'triggers': {
'svc_systemd:docker:restart',
},
# install config before installing packages to ensure the config is
# applied to the first start as well
'before': deps,
}
svc_systemd['docker'] = {
'needs': deps,
}
files['/usr/local/share/icinga/plugins/check_docker_container'] = {
'mode': '0755',
}
for app, config in node.metadata.get('docker-engine/containers', {}).items():
volumes = config.get('volumes', {})
files[f'/opt/docker-engine/{app}'] = {
'source': 'docker-wrapper',
'content_type': 'mako',
'context': {
'environment': config.get('environment', {}),
'image': config['image'],
'name': app,
'ports': config.get('ports', {}),
'timezone': node.metadata.get('timezone'),
'volumes': volumes,
},
'mode': '0755',
'triggers': {
f'svc_systemd:docker-{app}:restart',
},
}
users[f'docker-{app}'] = {
'home': f'/var/opt/docker-engine/{app}',
'groups': {
'docker',
},
'after': {
# provides docker group
'pkg_apt:docker-ce',
},
}
files[f'/usr/local/lib/systemd/system/docker-{app}.service'] = {
'source': 'docker-wrapper.service',
'content_type': 'mako',
'context': {
'name': app,
'requires': {
*set(config.get('requires', set())),
'docker.service',
}
},
'triggers': {
'action:systemd-reload',
f'svc_systemd:docker-{app}:restart',
},
}
svc_systemd[f'docker-{app}'] = {
'needs': {
*deps,
f'file:/opt/docker-engine/{app}',
f'file:/usr/local/lib/systemd/system/docker-{app}.service',
f'user:docker-{app}',
'svc_systemd:docker',
*set(config.get('needs', set())),
},
}
for volume in volumes:
directories[f'/var/opt/docker-engine/{app}/{volume}'] = {
'owner': f'docker-{app}',
'group': f'docker-{app}',
'needed_by': {
f'svc_systemd:docker-{app}',
},
# don't do anything if the directory exists, docker images
# mangle owners
'unless': f'test -d /var/opt/docker-engine/{app}/{volume}',
}

View file

@ -0,0 +1,83 @@
defaults = {
'apt': {
'packages': {
'docker-ce': {},
'docker-ce-cli': {},
'docker-compose-plugin': {},
},
'repos': {
'docker': {
'items': {
'deb https://download.docker.com/linux/debian {os_release} stable',
},
},
},
},
'backups': {
'paths': {
'/var/opt/docker-engine',
},
},
'hosts': {
'entries': {
'172.17.0.1': {
'host.docker.internal',
},
},
},
'docker-engine': {
'config': {
'iptables': False,
'no-new-privileges': True,
},
},
'zfs': {
'datasets': {
'tank/docker-data': {
'mountpoint': '/var/opt/docker-engine',
},
},
},
}
@metadata_reactor.provides(
'icinga2_api/docker-engine/services',
)
def monitoring(metadata):
services = {
'DOCKER PROCESS': {
'command_on_monitored_host': '/usr/lib/nagios/plugins/check_procs -C dockerd -c 1:',
},
}
for app in metadata.get('docker-engine/containers', {}):
services[f'DOCKER CONTAINER {app}'] = {
'command_on_monitored_host': f'sudo /usr/local/share/icinga/plugins/check_docker_container {app}'
}
return {
'icinga2_api': {
'docker-engine': {
'services': services,
},
},
}
@metadata_reactor.provides(
'zfs/datasets',
)
def zfs(metadata):
datasets = {}
for app in metadata.get('docker-engine/containers', {}):
datasets[f'tank/docker-data/{app}'] = {
'mountpoint': f'/var/opt/docker-engine/{app}'
}
return {
'zfs': {
'datasets': datasets,
},
}

View file

@ -0,0 +1,64 @@
assert node.has_bundle('docker-engine')
assert node.has_bundle('redis')
assert not node.has_bundle('postgresql') # docker container uses that port
defaults = {
'docker-engine': {
'containers': {
'immich': {
'image': 'ghcr.io/imagegenius/immich:latest',
'environment': {
'DB_DATABASE_NAME': 'immich',
'DB_HOSTNAME': 'host.docker.internal',
'DB_PASSWORD': repo.vault.password_for(f'{node.name} postgresql immich'),
'DB_USERNAME': 'immich',
'REDIS_HOSTNAME': 'host.docker.internal',
},
'volumes': {
'config': '/config',
'libraries': '/libraries',
'photos': '/photos',
},
'needs': {
'svc_systemd:docker-postgresql14',
},
'requires': {
'docker-postgresql14.service',
},
},
'postgresql14': {
'image': 'tensorchord/pgvecto-rs:pg14-v0.2.0',
'environment': {
'POSTGRES_PASSWORD': repo.vault.password_for(f'{node.name} postgresql immich'),
'POSTGRES_USER': 'immich',
'POSTGRES_DB': 'immich',
},
'volumes': {
'database': '/var/lib/postgresql/data',
},
},
},
},
'nginx': {
'vhosts': {
'immich': {
'locations': {
'/': {
'target': 'http://127.0.0.1:8080/',
'websockets': True,
'max_body_size': '500m',
},
#'/api/socket.io/': {
# 'target': 'http://127.0.0.1:8081/',
# 'websockets': True,
#},
},
},
},
},
'redis': {
'bind': '0.0.0.0',
},
}

View file

@ -3,3 +3,4 @@ driver = pgsql
default_pass_scheme = MD5-CRYPT default_pass_scheme = MD5-CRYPT
password_query = SELECT username as user, password FROM mailbox WHERE username = '%u' AND active = true password_query = SELECT username as user, password FROM mailbox WHERE username = '%u' AND active = true
user_query = SELECT '/var/mail/vmail/' || maildir as home, 65534 as uid, 65534 as gid FROM mailbox WHERE username = '%u' AND active = true user_query = SELECT '/var/mail/vmail/' || maildir as home, 65534 as uid, 65534 as gid FROM mailbox WHERE username = '%u' AND active = true
iterate_query = SELECT username as user FROM mailbox WHERE active = true

View file

@ -28,19 +28,19 @@ namespace inbox {
mail_location = maildir:/var/mail/vmail/%d/%n mail_location = maildir:/var/mail/vmail/%d/%n
protocols = imap lmtp sieve protocols = imap lmtp sieve
ssl = yes ssl = required
ssl_cert = </var/lib/dehydrated/certs/${node.metadata.get('postfix/myhostname', node.metadata['hostname'])}/fullchain.pem ssl_cert = </var/lib/dehydrated/certs/${node.metadata.get('postfix/myhostname')}/fullchain.pem
ssl_key = </var/lib/dehydrated/certs/${node.metadata.get('postfix/myhostname', node.metadata['hostname'])}/privkey.pem ssl_key = </var/lib/dehydrated/certs/${node.metadata.get('postfix/myhostname')}/privkey.pem
ssl_dh = </etc/dovecot/ssl/dhparam.pem ssl_dh = </etc/ssl/certs/dhparam.pem
ssl_min_protocol = TLSv1.2 ssl_min_protocol = TLSv1.2
ssl_cipher_list = EECDH+AESGCM:EDH+AESGCM ssl_cipher_list = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305
ssl_prefer_server_ciphers = yes ssl_prefer_server_ciphers = no
login_greeting = IMAPd ready login_greeting = IMAPd ready
auth_mechanisms = plain login auth_mechanisms = plain login
first_valid_uid = 65534 first_valid_uid = 65534
disable_plaintext_auth = yes disable_plaintext_auth = yes
mail_plugins = $mail_plugins zlib old_stats mail_plugins = $mail_plugins zlib old_stats fts fts_xapian
plugin { plugin {
zlib_save_level = 6 zlib_save_level = 6
@ -56,6 +56,15 @@ plugin {
old_stats_refresh = 30 secs old_stats_refresh = 30 secs
old_stats_track_cmds = yes old_stats_track_cmds = yes
fts = xapian
fts_xapian = partial=3 full=20
fts_autoindex = yes
fts_enforced = yes
# Index attachements
fts_decoder = decode2text
% if node.has_bundle('rspamd'): % if node.has_bundle('rspamd'):
sieve_before = /var/mail/vmail/sieve/global/spam-global.sieve sieve_before = /var/mail/vmail/sieve/global/spam-global.sieve
@ -86,14 +95,19 @@ service auth {
} }
} }
service lmtp { service decode2text {
unix_listener /var/spool/postfix/private/dovecot-lmtp { executable = script /usr/lib/dovecot/decode2text.sh
group = postfix user = dovecot
mode = 0600 unix_listener decode2text {
user = postfix mode = 0666
} }
} }
service indexer-worker {
vsz_limit = 0
process_limit = 0
}
service imap { service imap {
executable = imap executable = imap
} }
@ -104,6 +118,14 @@ service imap-login {
vsz_limit = 64M vsz_limit = 64M
} }
service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
group = postfix
mode = 0600
user = postfix
}
}
service managesieve-login { service managesieve-login {
inet_listener sieve { inet_listener sieve {
port = 4190 port = 4190

View file

@ -2,10 +2,6 @@
# by this bundle # by this bundle
repo.libs.tools.require_bundle(node, 'postfix') repo.libs.tools.require_bundle(node, 'postfix')
directories = {
'/etc/dovecot/ssl': {},
}
files = { files = {
'/etc/dovecot/dovecot.conf': { '/etc/dovecot/dovecot.conf': {
'content_type': 'mako', 'content_type': 'mako',
@ -49,25 +45,17 @@ files = {
}, },
} }
actions = { symlinks['/usr/lib/dovecot/decode2text.sh'] = {
'dovecot_generate_dhparam': { 'target': '/usr/share/doc/dovecot-core/examples/decode2text.sh',
'command': 'openssl dhparam -out /etc/dovecot/ssl/dhparam.pem 2048', 'before': {
'unless': 'test -f /etc/dovecot/ssl/dhparam.pem', 'svc_systemd:dovecot',
'cascade_skip': False,
'needs': {
'directory:/etc/dovecot/ssl',
'pkg_apt:'
},
'triggers': {
'svc_systemd:dovecot:restart',
},
}, },
} }
svc_systemd = { svc_systemd = {
'dovecot': { 'dovecot': {
'needs': { 'needs': {
'action:dovecot_generate_dhparam', 'action:generate-dhparam',
'file:/etc/dovecot/dovecot.conf', 'file:/etc/dovecot/dovecot.conf',
'file:/etc/dovecot/dovecot-sql.conf', 'file:/etc/dovecot/dovecot-sql.conf',
}, },

View file

@ -3,6 +3,7 @@ from bundlewrap.metadata import atomic
defaults = { defaults = {
'apt': { 'apt': {
'packages': { 'packages': {
'dovecot-fts-xapian': {},
'dovecot-imapd': {}, 'dovecot-imapd': {},
'dovecot-lmtpd': {}, 'dovecot-lmtpd': {},
'dovecot-managesieved': {}, 'dovecot-managesieved': {},
@ -35,6 +36,16 @@ defaults = {
'dovecot', 'dovecot',
}, },
}, },
'systemd-timers': {
'timers': {
'dovecot_fts_optimize': {
'command': [
'/usr/bin/doveadm fts optimize -A',
],
'when': '02:{}:00'.format(node.magic_number % 60),
},
},
},
} }
if node.has_bundle('postfixadmin'): if node.has_bundle('postfixadmin'):
@ -76,19 +87,19 @@ def import_database_settings_from_postfixadmin(metadata):
@metadata_reactor.provides( @metadata_reactor.provides(
'firewall/port_rules/143', 'firewall/port_rules',
'firewall/port_rules/993', 'firewall/port_rules',
'firewall/port_rules/4190', 'firewall/port_rules',
) )
def firewall(metadata): def firewall(metadata):
return { return {
'firewall': { 'firewall': {
'port_rules': { 'port_rules': {
# imap(s) # imap(s)
'143': atomic(metadata.get('dovecot/restrict-to', {'*'})), '143/tcp': atomic(metadata.get('dovecot/restrict-to', {'*'})),
'993': atomic(metadata.get('dovecot/restrict-to', {'*'})), '993/tcp': atomic(metadata.get('dovecot/restrict-to', {'*'})),
# managesieve # managesieve
'4190': atomic(metadata.get('dovecot/restrict-to', {'*'})), '4190/tcp': atomic(metadata.get('dovecot/restrict-to', {'*'})),
}, },
}, },
} }

View file

@ -8,7 +8,7 @@ directories = {
git_deploy = { git_deploy = {
'/opt/element-web': { '/opt/element-web': {
'rev': node.metadata['element-web']['version'], 'rev': node.metadata.get('element-web/version'),
'repo': 'https://github.com/vector-im/element-web.git', 'repo': 'https://github.com/vector-im/element-web.git',
'triggers': { 'triggers': {
'action:element-web_yarn', 'action:element-web_yarn',
@ -18,28 +18,22 @@ git_deploy = {
files = { files = {
'/opt/element-web/webapp/config.json': { '/opt/element-web/webapp/config.json': {
'content': metadata_to_json(node.metadata['element-web']['config']), 'content': metadata_to_json(node.metadata.get('element-web/config')),
'needs': { 'needs': {
'action:element-web_yarn', 'action:element-web_yarn',
}, },
}, },
} }
extra_install_cmds = []
if node.metadata.get('nodejs/version') >= 17:
# TODO verify this is still needed when upgrading to 1.12
extra_install_cmds.append('export NODE_OPTIONS=--openssl-legacy-provider')
actions = { actions = {
'element-web_yarn': { 'element-web_yarn': {
'command': ' && '.join([ 'command': ' && '.join([
*extra_install_cmds,
'cd /opt/element-web', 'cd /opt/element-web',
'yarn install --pure-lockfile --ignore-scripts', 'yarn install --pure-lockfile --ignore-scripts',
'yarn build', 'yarn build',
]), ]),
'needs': { 'needs': {
'action:nodejs_install_yarn', 'action:apt_execute_update_commands',
'pkg_apt:nodejs', 'pkg_apt:nodejs',
}, },
'triggered': True, 'triggered': True,

View file

@ -11,6 +11,26 @@ defaults = {
}, },
} }
@metadata_reactor.provides(
'nodejs/version',
)
def nodejs(metadata):
version = tuple([int(i) for i in metadata.get('element-web/version')[1:].split('.')])
if version >= (1, 11, 71):
return {
'nodejs': {
'version': 20,
},
}
else:
return {
'nodejs': {
'version': 18,
},
}
@metadata_reactor.provides( @metadata_reactor.provides(
'nginx/vhosts/element-web', 'nginx/vhosts/element-web',
) )

View file

@ -1,9 +1,10 @@
APP_NAME = ${app_name} APP_NAME = ${app_name}
RUN_USER = git RUN_USER = git
RUN_MODE = prod RUN_MODE = prod
WORK_PATH = /var/lib/forgejo
[repository] [repository]
ROOT = /home/git/gitea-repositories ROOT = /var/lib/forgejo/repositories
MAX_CREATION_LIMIT = 0 MAX_CREATION_LIMIT = 0
DEFAULT_BRANCH = main DEFAULT_BRANCH = main

View file

@ -5,14 +5,13 @@ After=network.target
Requires=postgresql.service Requires=postgresql.service
[Service] [Service]
RestartSec=2s RestartSec=10
Type=simple Type=simple
User=git User=git
Group=git Group=git
WorkingDirectory=/var/lib/gitea/ WorkingDirectory=/var/lib/forgejo
ExecStart=/usr/local/bin/gitea web -c /etc/gitea/app.ini ExecStart=/usr/local/bin/forgejo web -c /etc/forgejo/app.ini
Restart=always Restart=always
Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/gitea
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target

65
bundles/forgejo/items.py Normal file
View file

@ -0,0 +1,65 @@
users = {
'git': {
'home': '/var/lib/forgejo',
},
}
directories = {
'/var/lib/forgejo/.ssh': {
'mode': '0700',
'owner': 'git',
'group': 'git',
},
'/var/lib/forgejo': {
'owner': 'git',
'mode': '0700',
'triggers': {
'svc_systemd:forgejo:restart',
},
},
}
files = {
'/usr/local/lib/systemd/system/forgejo.service': {
'content_type': 'mako',
'context': node.metadata.get('forgejo'),
'triggers': {
'action:systemd-reload',
'svc_systemd:forgejo:restart',
},
},
'/etc/forgejo/app.ini': {
'content_type': 'mako',
'context': node.metadata.get('forgejo'),
'triggers': {
'svc_systemd:forgejo:restart',
},
},
'/usr/local/bin/forgejo': {
'content_type': 'download',
'source': 'https://codeberg.org/forgejo/forgejo/releases/download/v{0}/forgejo-{0}-linux-amd64'.format(node.metadata.get('forgejo/version')),
'content_hash': node.metadata.get('forgejo/sha1', None),
'mode': '0755',
'triggers': {
'svc_systemd:forgejo:restart',
},
},
}
if node.metadata.get('forgejo/install_ssh_key', False):
files['/var/lib/forgejo/.ssh/id_ed25519'] = {
'content': repo.vault.decrypt_file(f'forgejo/files/ssh-keys/{node.name}.key.vault'),
'mode': '0600',
'owner': 'git',
'group': 'git',
}
svc_systemd = {
'forgejo': {
'needs': {
'file:/etc/forgejo/app.ini',
'file:/usr/local/bin/forgejo',
'file:/usr/local/lib/systemd/system/forgejo.service',
},
},
}

View file

@ -1,33 +1,31 @@
defaults = { defaults = {
'backups': { 'backups': {
'paths': { 'paths': {
'/home/git', '/var/lib/forgejo',
'/var/lib/gitea',
}, },
}, },
'gitea': { 'forgejo': {
'app_name': 'Forgejo', 'app_name': 'Forgejo',
'database': { 'database': {
'username': 'gitea', 'username': 'forgejo',
'password': repo.vault.password_for('{} postgresql gitea'.format(node.name)), 'password': repo.vault.password_for('{} postgresql forgejo'.format(node.name)),
'database': 'gitea', 'database': 'forgejo',
}, },
'disable_registration': True, 'disable_registration': True,
'email_domain_blocklist': set(), 'email_domain_blocklist': set(),
'enable_git_hooks': False, 'enable_git_hooks': False,
'internal_token': repo.vault.password_for('{} gitea internal_token'.format(node.name)), 'internal_token': repo.vault.password_for('{} forgejo internal_token'.format(node.name)),
'lfs_secret_key': repo.vault.password_for('{} gitea lfs_secret_key'.format(node.name)), 'lfs_secret_key': repo.vault.password_for('{} forgejo lfs_secret_key'.format(node.name)),
'oauth_secret_key': repo.vault.password_for('{} gitea oauth_secret_key'.format(node.name)), 'oauth_secret_key': repo.vault.password_for('{} forgejo oauth_secret_key'.format(node.name)),
'security_secret_key': repo.vault.password_for('{} gitea security_secret_key'.format(node.name)), 'security_secret_key': repo.vault.password_for('{} forgejo security_secret_key'.format(node.name)),
}, },
'icinga2_api': { 'icinga2_api': {
'gitea': { 'forgejo': {
'services': { 'services': {
'FORGEJO PROCESS': { 'FORGEJO PROCESS': {
'command_on_monitored_host': '/usr/local/share/icinga/plugins/check_systemd_unit gitea', 'command_on_monitored_host': '/usr/local/share/icinga/plugins/check_systemd_unit forgejo',
}, },
'FORGEJO UPDATE': { 'FORGEJO UPDATE': {
'command_on_monitored_host': '/usr/local/share/icinga/plugins/check_forgejo_for_new_release codeberg.org forgejo/forgejo v$(gitea --version | cut -d" " -f3)',
'vars.notification.mail': True, 'vars.notification.mail': True,
'check_interval': '60m', 'check_interval': '60m',
}, },
@ -41,29 +39,22 @@ defaults = {
}, },
'postgresql': { 'postgresql': {
'roles': { 'roles': {
'gitea': { 'forgejo': {
'password': repo.vault.password_for('{} postgresql gitea'.format(node.name)), 'password': repo.vault.password_for('{} postgresql forgejo'.format(node.name)),
}, },
}, },
'databases': { 'databases': {
'gitea': { 'forgejo': {
'owner': 'gitea', 'owner': 'forgejo',
}, },
}, },
}, },
'zfs': { 'zfs': {
'datasets': { 'datasets': {
'tank/gitea': {}, 'tank/forgejo': {
'tank/gitea/home': { 'mountpoint': '/var/lib/forgejo',
'mountpoint': '/home/git',
'needed_by': { 'needed_by': {
'directory:/home/git', 'directory:/var/lib/forgejo',
},
},
'tank/gitea/var': {
'mountpoint': '/var/lib/gitea',
'needed_by': {
'directory:/var/lib/gitea',
}, },
}, },
}, },
@ -71,6 +62,23 @@ defaults = {
} }
@metadata_reactor.provides(
'icinga2_api/forgejo',
)
def update_monitoring(metadata):
return {
'icinga2_api': {
'forgejo': {
'services': {
'FORGEJO UPDATE': {
'command_on_monitored_host': '/usr/local/share/icinga/plugins/check_forgejo_for_new_release codeberg.org forgejo/forgejo v{}'.format(metadata.get('forgejo/version')),
},
},
},
},
}
@metadata_reactor.provides( @metadata_reactor.provides(
'nginx/vhosts/forgejo', 'nginx/vhosts/forgejo',
) )
@ -82,7 +90,7 @@ def nginx(metadata):
'nginx': { 'nginx': {
'vhosts': { 'vhosts': {
'forgejo': { 'forgejo': {
'domain': metadata.get('gitea/domain'), 'domain': metadata.get('forgejo/domain'),
'locations': { 'locations': {
'/': { '/': {
'target': 'http://127.0.0.1:22000', 'target': 'http://127.0.0.1:22000',
@ -92,16 +100,8 @@ def nginx(metadata):
}, },
}, },
'website_check_path': '/user/login', 'website_check_path': '/user/login',
'website_check_string': 'Sign In', 'website_check_string': 'Sign in',
}, },
}, },
}, },
} }
@metadata_reactor.provides(
'icinga2_api/gitea/services',
)
def icinga_check_for_new_release(metadata):
return {
}

View file

@ -1,33 +0,0 @@
svc_systemd = {}
pkg_apt = {}
for i in {
'gce-disk-expand',
'google-cloud-packages-archive-keyring',
'google-cloud-sdk',
'google-compute-engine',
'google-compute-engine-oslogin',
'google-guest-agent',
'google-osconfig-agent',
}:
pkg_apt[i] = {
'installed': False,
}
for i in {
'google-accounts-daemon.service',
'google-accounts-manager.service',
'google-clock-skew-daemon.service',
'google-clock-sync-manager.service',
'google-guest-agent.service',
'google-osconfig-agent.service',
'google-shutdown-scripts.service',
'google-startup-scripts.service',
'sshguard.service',
'google-oslogin-cache.timer',
}:
svc_systemd[i] = {
'enabled': False,
'running': False,
}

View file

@ -1,68 +0,0 @@
users = {
'git': {},
}
directories = {
'/home/git': {
'mode': '0755',
'owner': 'git',
'group': 'git',
},
'/home/git/.ssh': {
'mode': '0755',
'owner': 'git',
'group': 'git',
},
'/var/lib/gitea': {
'owner': 'git',
'mode': '0700',
'triggers': {
'svc_systemd:gitea:restart',
},
},
}
files = {
'/etc/systemd/system/gitea.service': {
'content_type': 'mako',
'context': node.metadata.get('gitea'),
'triggers': {
'action:systemd-reload',
'svc_systemd:gitea:restart',
},
},
'/etc/gitea/app.ini': {
'content_type': 'mako',
'context': node.metadata.get('gitea'),
'triggers': {
'svc_systemd:gitea:restart',
},
},
'/usr/local/bin/gitea': {
'content_type': 'download',
'source': node.metadata.get('gitea/url'),
'content_hash': node.metadata.get('gitea/sha1', None),
'mode': '0755',
'triggers': {
'svc_systemd:gitea:restart',
},
},
}
if node.metadata['gitea'].get('install_ssh_key', False):
files['/home/git/.ssh/id_ed25519'] = {
'content': repo.vault.decrypt_file(f'gitea/files/ssh-keys/{node.name}.key.vault'),
'mode': '0600',
'owner': 'git',
'group': 'git',
}
svc_systemd = {
'gitea': {
'needs': {
'file:/etc/gitea/app.ini',
'file:/etc/systemd/system/gitea.service',
'file:/usr/local/bin/gitea',
},
},
}

View file

@ -47,7 +47,7 @@ def dashboard_row_smartd(panel_id, node):
'renderer': 'flot', 'renderer': 'flot',
'seriesOverrides': [], 'seriesOverrides': [],
'spaceLength': 10, 'spaceLength': 10,
'span': 8, 'span': 12,
'stack': False, 'stack': False,
'steppedLine': False, 'steppedLine': False,
'targets': [ 'targets': [
@ -114,115 +114,5 @@ def dashboard_row_smartd(panel_id, node):
'alignLevel': None 'alignLevel': None
} }
}, },
{
'aliasColors': {},
'bars': False,
'dashLength': 10,
'dashes': False,
'datasource': None,
'fieldConfig': {
'defaults': {
'displayName': '${__field.labels.device}'
},
'overrides': []
},
'fill': 0,
'fillGradient': 0,
'hiddenSeries': False,
'id': next(panel_id),
'legend': {
'alignAsTable': False,
'avg': False,
'current': False,
'hideEmpty': True,
'hideZero': True,
'max': False,
'min': False,
'rightSide': False,
'show': True,
'total': False,
'values': False
},
'lines': True,
'linewidth': 1,
'NonePointMode': 'None',
'options': {
'alertThreshold': True
},
'percentage': False,
'pluginVersion': '7.5.5',
'pointradius': 2,
'points': False,
'renderer': 'flot',
'seriesOverrides': [],
'spaceLength': 10,
'span': 4,
'stack': False,
'steppedLine': False,
'targets': [
{
'groupBy': [
{'type': 'time', 'params': ['$__interval']},
{'type': 'fill', 'params': ['linear']},
],
'orderByTime': "ASC",
'policy': "default",
'query': f"""from(bucket: "telegraf")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) =>
r["_measurement"] == "smartd_stats" and
r["_field"] == "power_on_hours" and
r["host"] == "{node.name}"
)
|> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)
|> yield(name: "fan")""",
'resultFormat': 'time_series',
'select': [[
{'type': 'field', 'params': ['value']},
{'type': 'mean', 'params': []},
]],
"tags": []
},
],
'thresholds': [],
'timeRegions': [],
'title': 'fans',
'tooltip': {
'shared': True,
'sort': 0,
'value_type': 'individual'
},
'type': 'graph',
'xaxis': {
'buckets': None,
'mode': 'time',
'name': None,
'show': True,
'values': []
},
'yaxes': [
{
'format': 'hours',
'label': None,
'logBase': 1,
'max': None,
'min': None,
'show': True,
'decimals': 0,
},
{
'format': 'short',
'label': None,
'logBase': 1,
'max': None,
'min': None,
'show': False,
}
],
'yaxis': {
'align': False,
'alignLevel': None
}
},
], ],
} }

View file

@ -43,6 +43,7 @@ def nginx(metadata):
'locations': { 'locations': {
'/': { '/': {
'target': 'http://127.0.0.1:21010', 'target': 'http://127.0.0.1:21010',
'websockets': True,
}, },
'/api/ds/query': { '/api/ds/query': {
'target': 'http://127.0.0.1:21010', 'target': 'http://127.0.0.1:21010',

View file

@ -33,7 +33,11 @@ ProtectSystem=strict
ProtectHome=true ProtectHome=true
PrivateTmp=true PrivateTmp=true
SystemCallArchitectures=native SystemCallArchitectures=native
SystemCallFilter=@system-service # FIXME
# causes problems on bookworm
# see https://github.com/hedgedoc/hedgedoc/issues/4686
# cmmented out for now ...
#SystemCallFilter=@system-service
# You may have to adjust these settings # You may have to adjust these settings
User=hedgedoc User=hedgedoc

View file

@ -1,3 +1,5 @@
from semver import compare
repo.libs.tools.require_bundle(node, 'nodejs') repo.libs.tools.require_bundle(node, 'nodejs')
git_deploy = { git_deploy = {
@ -47,16 +49,29 @@ directories = {
}, },
} }
if compare(node.metadata.get('hedgedoc/version'), '1.9.7') <= 0:
command = ' && '.join([
'cd /opt/hedgedoc',
'yarn workspaces focus --production',
'yarn install --ignore-scripts',
'yarn build',
])
elif compare(node.metadata.get('hedgedoc/version'), '1.9.9') >= 0:
command = ' && '.join([
'cd /opt/hedgedoc',
'bin/setup',
'yarn install --immutable',
'yarn build',
])
actions = { actions = {
'hedgedoc_yarn': { 'hedgedoc_yarn': {
'command': ' && '.join([ 'command': ' && '.join([
'cd /opt/hedgedoc', 'cd /opt/hedgedoc',
'yarn install --production=true --pure-lockfile --ignore-scripts', 'yarn install --immutable',
'yarn install --ignore-scripts',
'yarn build', 'yarn build',
]), ]),
'needs': { 'needs': {
'action:nodejs_install_yarn',
'file:/opt/hedgedoc/config.json', 'file:/opt/hedgedoc/config.json',
'git_deploy:/opt/hedgedoc', 'git_deploy:/opt/hedgedoc',
'pkg_apt:nodejs', 'pkg_apt:nodejs',

View file

@ -2,48 +2,42 @@
from sys import exit from sys import exit
import requests from packaging.version import parse
from packaging import version from requests import get
bearer = "${bearer}" API_TOKEN = "${token}"
domain = "${domain}" DOMAIN = "${domain}"
OK = 0
WARN = 1
CRITICAL = 2
UNKNOWN = 3
status = 3
message = "Unknown Update Status"
domain = "hass.home.kunbox.net"
s = requests.Session()
s.headers.update({"Content-Type": "application/json"})
try: try:
stable_version = version.parse( r = get("https://version.home-assistant.io/stable.json")
s.get("https://version.home-assistant.io/stable.json").json()["homeassistant"][ r.raise_for_status()
"generic-x86-64" stable_version = parse(r.json()["homeassistant"]["generic-x86-64"])
]
)
s.headers.update(
{"Authorization": f"Bearer {bearer}", "Content-Type": "application/json"}
)
running_version = version.parse(
s.get(f"https://{domain}/api/config").json()["version"]
)
if running_version == stable_version:
status = 0
message = f"OK - running version {running_version} equals stable version {stable_version}"
elif running_version > stable_version:
status = 1
message = f"WARNING - stable version {stable_version} is lower than running version {running_version}, check if downgrade is necessary."
else:
status = 2
message = f"CRITICAL - update necessary, running version {running_version} is lower than stable version {stable_version}"
except Exception as e: except Exception as e:
message = f"{message}: {repr(e)}" print(f"Could not get stable version information from home-assistant.io: {e!r}")
exit(3)
print(message) try:
exit(status) r = get(
f"https://{DOMAIN}/api/config",
headers={"Authorization": f"Bearer {API_TOKEN}", "Content-Type": "application/json"},
)
r.raise_for_status()
running_version = parse(r.json()["version"])
except Exception as e:
print(f"Could not get running version information from homeassistant: {e!r}")
exit(3)
try:
if stable_version > running_version:
print(
f"There is a newer version available: {stable_version} (currently installed: {running_version})"
)
exit(2)
else:
print(
f"Currently running version {running_version} matches newest release on home-assistant.io"
)
exit(0)
except Exception as e:
print(repr(e))
exit(3)

View file

@ -5,9 +5,13 @@ After=network-online.target
[Service] [Service]
Type=simple Type=simple
User=homeassistant User=homeassistant
Environment="VIRTUAL_ENV=/opt/homeassistant/venv"
Environment="PATH=/opt/homeassistant/venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
WorkingDirectory=/var/opt/homeassistant WorkingDirectory=/var/opt/homeassistant
ExecStart=/opt/homeassistant/venv/bin/hass -c "/var/opt/homeassistant" ExecStart=/opt/homeassistant/venv/bin/hass -c "/var/opt/homeassistant"
RestartForceExitStatus=100 RestartForceExitStatus=100
Restart=on-failure
RestartSec=2
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target

View file

@ -1,6 +1,13 @@
if node.has_bundle('pyenv'):
python_version = sorted(node.metadata.get('pyenv/python_versions'))[-1]
python_path = f'/opt/pyenv/versions/{python_version}/bin/python'
else:
python_path = '/usr/bin/python3'
users = { users = {
'homeassistant': { 'homeassistant': {
'home': '/var/opt/homeassistant', 'home': '/var/opt/homeassistant',
"groups": ["dialout"],
}, },
} }
@ -23,7 +30,7 @@ files = {
'/usr/local/share/icinga/plugins/check_homeassistant_update': { '/usr/local/share/icinga/plugins/check_homeassistant_update': {
'content_type': 'mako', 'content_type': 'mako',
'context': { 'context': {
'bearer': repo.vault.decrypt(node.metadata.get('homeassistant/api_secret')), 'token': node.metadata.get('homeassistant/api_secret'),
'domain': node.metadata.get('homeassistant/domain'), 'domain': node.metadata.get('homeassistant/domain'),
}, },
'mode': '0755', 'mode': '0755',
@ -32,11 +39,18 @@ files = {
actions = { actions = {
'homeassistant_create_virtualenv': { 'homeassistant_create_virtualenv': {
'command': 'sudo -u homeassistant /usr/bin/python3 -m virtualenv -p python3 /opt/homeassistant/venv/', 'command': f'sudo -u homeassistant virtualenv -p {python_path} /opt/homeassistant/venv/',
'unless': 'test -d /opt/homeassistant/venv/', 'unless': 'test -d /opt/homeassistant/venv/',
'needs': { 'needs': {
'directory:/opt/homeassistant', 'directory:/opt/homeassistant',
'user:homeassistant', 'user:homeassistant',
},
},
'homeassistant_install': {
'command': 'sudo -u homeassistant /opt/homeassistant/venv/bin/pip install homeassistant',
'unless': 'test -f /opt/homeassistant/venv/bin/hass',
'needs': {
'action:homeassistant_create_virtualenv',
'pkg_apt:bluez', 'pkg_apt:bluez',
'pkg_apt:libffi-dev', 'pkg_apt:libffi-dev',
'pkg_apt:libssl-dev', 'pkg_apt:libssl-dev',
@ -45,17 +59,10 @@ actions = {
'pkg_apt:autoconf', 'pkg_apt:autoconf',
'pkg_apt:build-essential', 'pkg_apt:build-essential',
'pkg_apt:libopenjp2-7', 'pkg_apt:libopenjp2-7',
'pkg_apt:libtiff5', 'pkg_apt:libtiff6',
'pkg_apt:libturbojpeg0-dev', 'pkg_apt:libturbojpeg0-dev',
'pkg_apt:tzdata', 'pkg_apt:tzdata',
}, },
},
'homeassistant_install': {
'command': 'sudo -u homeassistant /opt/homeassistant/venv/bin/pip install homeassistant',
'unless': 'test -f /opt/homeassistant/venv/bin/hass',
'needs': {
'action:homeassistant_create_virtualenv',
},
'triggers': { 'triggers': {
'svc_systemd:homeassistant:restart', 'svc_systemd:homeassistant:restart',
}, },

View file

@ -4,11 +4,12 @@ defaults = {
'autoconf': {}, 'autoconf': {},
'bluez': {}, 'bluez': {},
'build-essential': {}, 'build-essential': {},
'ffmpeg': {},
'libffi-dev': {}, 'libffi-dev': {},
'libjpeg-dev': {}, 'libjpeg-dev': {},
'libopenjp2-7': {}, 'libopenjp2-7': {},
'libssl-dev': {}, 'libssl-dev': {},
'libtiff5': {}, 'libtiff6': {},
'libturbojpeg0-dev': {}, 'libturbojpeg0-dev': {},
'python3-packaging': {}, 'python3-packaging': {},
'tzdata': {}, 'tzdata': {},
@ -22,6 +23,8 @@ defaults = {
}, },
}, },
} }
@metadata_reactor.provides( @metadata_reactor.provides(
'icinga2_api/homeassistant/services', 'icinga2_api/homeassistant/services',
) )
@ -31,15 +34,17 @@ def icinga_check_for_new_release(metadata):
'homeassistant': { 'homeassistant': {
'services': { 'services': {
'HOMEASSISTANT UPDATE': { 'HOMEASSISTANT UPDATE': {
'check_interval': '60m',
'command_on_monitored_host': '/usr/local/share/icinga/plugins/check_homeassistant_update', 'command_on_monitored_host': '/usr/local/share/icinga/plugins/check_homeassistant_update',
'vars.notification.mail': True, 'vars.notification.mail': True,
'check_interval': '60m', 'vars.sshmon_timeout': 20,
}, },
}, },
}, },
}, },
} }
@metadata_reactor.provides( @metadata_reactor.provides(
'nginx/vhosts/homeassistant', 'nginx/vhosts/homeassistant',
) )

View file

@ -0,0 +1,16 @@
[Unit]
Description=icinga2-statuspage
After=network.target
Requires=postgresql.service
[Service]
User=www-data
Group=www-data
Environment=APP_CONFIG=/opt/icinga2-statuspage/config.json
WorkingDirectory=/opt/icinga2-statuspage/src
ExecStart=/usr/bin/gunicorn statuspage:app --workers 4 --max-requests 1200 --max-requests-jitter 50 --log-level=info --bind=127.0.0.1:22110
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target

View file

@ -0,0 +1,34 @@
directories['/opt/icinga2-statuspage/src'] = {}
git_deploy['/opt/icinga2-statuspage/src'] = {
'repo': 'https://git.franzi.business/kunsi/icinga-dynamic-statuspage.git',
'rev': 'main',
'triggers': {
'svc_systemd:icinga2-statuspage:restart',
},
}
files['/opt/icinga2-statuspage/config.json'] = {
'content': repo.libs.faults.dict_as_json(node.metadata.get('icinga2-statuspage')),
'triggers': {
'svc_systemd:icinga2-statuspage:restart',
},
}
files['/usr/local/lib/systemd/system/icinga2-statuspage.service'] = {
'triggers': {
'action:systemd-reload',
'svc_systemd:icinga2-statuspage:restart',
},
}
svc_systemd['icinga2-statuspage'] = {
'needs': {
'file:/opt/icinga2-statuspage/config.json',
'git_deploy:/opt/icinga2-statuspage/src',
'pkg_apt:gunicorn',
'pkg_apt:python3-flask',
'pkg_apt:python3-psycopg2',
},
}

View file

@ -0,0 +1,47 @@
defaults = {
'apt': {
'packages': {
'gunicorn': {},
'python3-flask': {},
'python3-psycopg2': {},
},
},
}
@metadata_reactor.provides(
'icinga2-statuspage',
)
def import_db_settings_from_icinga(metadata):
return {
'icinga2-statuspage': {
'DB_USER': 'icinga2',
'DB_PASS': metadata.get('postgresql/roles/icinga2/password'),
'DB_NAME': 'icinga2',
},
}
@metadata_reactor.provides(
'nginx/vhosts/icinga2-statuspage',
)
def nginx(metadata):
if not node.has_bundle('nginx'):
raise DoNotRunAgain
return {
'nginx': {
'vhosts': {
'icinga2-statuspage': {
'domain': metadata.get('icinga2-statuspage/DOMAIN'),
'locations': {
'/': {
'target': 'http://127.0.0.1:22110',
},
},
'website_check_path': '/',
'website_check_string': 'status page',
},
},
},
}

View file

@ -0,0 +1,132 @@
#!/usr/bin/env python3
import re
from hashlib import md5
from sys import argv, exit
# Supress SSL certificate warnings for ssl_verify=False
import urllib3
from lxml import html
from requests import Session
USERNAME_FIELD = "g2"
PASSWORD_FIELD = "g3"
CRSF_FIELD = "password"
STATUS_OK = 0
STATUS_WARNING = 1
STATUS_CRITICAL = 2
STATUS_UNKNOWN = 3
class OMMCrawler:
def __init__(self, hostname, username, password):
self.session = Session()
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
self.session.verify = False
self.url = f"https://{hostname}"
self.login_data = {
USERNAME_FIELD: username,
PASSWORD_FIELD: password,
CRSF_FIELD: md5(password.encode()).hexdigest(),
}
self.logged_in = False
def login(self):
# if we have multiple dect masters, find out which one is the current master
current_master_url = self.session.get(self.url, verify=False).url
self.hostname = re.search(r"^(.*[\\\/])", current_master_url).group(0)[:-1]
response = self.session.post(f"{self.url}/login_set.html", data=self.login_data)
response.raise_for_status()
# set cookie
pass_value = re.search(r"(?<=pass=)\d+(?=;)", response.text).group(0)
self.session.cookies.set("pass", pass_value)
self.logged_in = True
def get_station_status(self):
if not self.logged_in:
self.login()
data = {}
response = self.session.get(f"{self.url}/fp_pnp_status.html")
response.raise_for_status()
tree = html.fromstring(response.text)
xpath_results = tree.xpath('//tr[@class="l0" or @class="l1"]')
for result in xpath_results:
bubble_is_in_inactive_cluster = False
bubble_is_connected = False
bubble_is_active = False
bubble_name = result.xpath("td[4]/text()")[0]
try:
bubble_is_connected = result.xpath("td[11]/img/@alt")[0] == "yes"
if bubble_is_connected:
try:
bubble_is_active = result.xpath("td[12]/img/@alt")[0] == "yes"
except IndexError:
# If an IndexError occurs, there is no image in the
# 12th td. This means this bubble is in the not inside
# an active DECT cluster, but is a backup bubble.
# This is probably fine.
bubble_is_active = False
bubble_is_in_inactive_cluster = True
else:
bubble_is_active = False
except:
# There is no Image in the 11th td. This usually means there
# is a warning message in the 10th td. We do not care about
# that, currently.
pass
data[bubble_name] = {
"is_connected": bubble_is_connected,
"is_active": bubble_is_active,
"is_in_inactive_cluster": bubble_is_in_inactive_cluster,
}
return data
def handle_station_data(self):
try:
data = self.get_station_status()
except Exception as e:
print(f"Something went wrong. You should take a look at {self.url}")
print(repr(e))
exit(STATUS_UNKNOWN)
critical = False
for name, status in data.items():
if not status["is_active"] and not status["is_connected"]:
print(
f"Base station {name} is not active or connected! Check manually!"
)
critical = True
elif not status["is_active"] and not status["is_in_inactive_cluster"]:
# Bubble is part of an active DECT cluster, but not active.
# This shouldn't happen.
print(
f"Base station {name} is not active but connected! Check manually!"
)
critical = True
elif not status["is_connected"]:
# This should never happen. Seeing this state means OMM
# itself is broken.
print(
f"Base station {name} is not connected but active! Check manually!"
)
critical = True
if critical:
exit(STATUS_CRITICAL)
else:
print(f"OK - {len(data)} base stations connected")
exit(STATUS_OK)
if __name__ == "__main__":
omm = OMMCrawler(argv[1], argv[2], argv[3])
omm.handle_station_data()

View file

@ -1,16 +1,17 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from json import load
from sys import exit from sys import exit
from requests import get from requests import get
SIPGATE_USER = '${node.metadata['icinga2']['sipgate_user']}' with open('/etc/icinga2/notification_config.json') as f:
SIPGATE_PASS = '${node.metadata['icinga2']['sipgate_pass']}' CONFIG = load(f)
try: try:
r = get( r = get(
'https://api.sipgate.com/v2/balance', 'https://api.sipgate.com/v2/balance',
auth=(SIPGATE_USER, SIPGATE_PASS), auth=(CONFIG['sipgate']['user'], CONFIG['sipgate']['password']),
headers={'Accept': 'application/json'}, headers={'Accept': 'application/json'},
) )

View file

@ -5,30 +5,33 @@ from ipaddress import IPv6Address, ip_address
from subprocess import check_output from subprocess import check_output
from sys import argv, exit from sys import argv, exit
BLOCKLISTS = [ BLOCKLISTS = {
'0spam.fusionzero.com', '0spam.fusionzero.com': set(),
'bl.mailspike.org', 'bl.mailspike.org': set(),
'bl.spamcop.net', 'bl.spamcop.net': set(),
'blackholes.brainerd.net', 'blackholes.brainerd.net': set(),
'dnsbl-1.uceprotect.net', 'dnsbl-1.uceprotect.net': set(),
'dnsbl-2.uceprotect.net', 'l2.spews.dnsbl.sorbs.net': set(),
'l2.spews.dnsbl.sorbs.net', 'list.dsbl.org': set(),
'list.dsbl.org', 'multihop.dsbl.org': set(),
'map.spam-rbl.com', 'ns1.unsubscore.com': set(),
'multihop.dsbl.org', 'opm.blitzed.org': set(),
'ns1.unsubscore.com', 'psbl.surriel.com': set(),
'opm.blitzed.org', 'rbl.efnet.org': set(),
'psbl.surriel.com', 'rbl.schulte.org': set(),
'rbl.efnet.org', 'spamguard.leadmon.net': set(),
'rbl.schulte.org', 'ubl.unsubscore.com': set(),
'spamguard.leadmon.net', 'unconfirmed.dsbl.org': set(),
'ubl.unsubscore.com', 'virbl.dnsbl.bit.nl': set(),
'unconfirmed.dsbl.org', 'zen.spamhaus.org': {
'virbl.dnsbl.bit.nl', # https://www.spamhaus.org/news/article/807/using-our-public-mirrors-check-your-return-codes-now.
'zen.spamhaus.org', '127.255.255.252', # Typing Error
] '127.255.255.254', # public resolver / generic rdns
'127.255.255.255', # rate limited
},
}
def check_list(ip_list, blocklist): def check_list(ip_list, blocklist, warn_ips):
dns_name = '{}.{}'.format( dns_name = '{}.{}'.format(
'.'.join(ip_list), '.'.join(ip_list),
blocklist, blocklist,
@ -41,17 +44,22 @@ def check_list(ip_list, blocklist):
result = check_output([ result = check_output([
'dig', 'dig',
'+tries=2', '+tries=2',
'+time=5', '+time=10',
'+short', '+short',
dns_name dns_name
]).decode().splitlines() ]).decode().splitlines()
for item in result: for item in result:
if item.startswith(';;'):
continue
msgs.append('{} listed in {} as {}'.format( msgs.append('{} listed in {} as {}'.format(
ip, ip,
blocklist, blocklist,
item, item,
)) ))
returncode = 2 if item in warn_ips and returncode < 2:
returncode = 1
else:
returncode = 2
except Exception as e: except Exception as e:
if e.returncode == 9: if e.returncode == 9:
# no reply from server # no reply from server
@ -78,8 +86,8 @@ exitcode = 0
with ThreadPoolExecutor(max_workers=len(BLOCKLISTS)) as executor: with ThreadPoolExecutor(max_workers=len(BLOCKLISTS)) as executor:
futures = set() futures = set()
for blocklist in BLOCKLISTS: for blocklist, warn_ips in BLOCKLISTS.items():
futures.add(executor.submit(check_list, ip_list, blocklist)) futures.add(executor.submit(check_list, ip_list, blocklist, warn_ips))
for future in as_completed(futures): for future in as_completed(futures):
msgs, this_exitcode = future.result() msgs, this_exitcode = future.result()

View file

@ -1,31 +1,18 @@
% for monitored_node in sorted(repo.nodes): % for dt in downtimes:
<% object ScheduledDowntime "${dt['name']}" {
auto_updates_enabled = ( host_name = "${dt['host']}"
monitored_node.has_any_bundle(['apt', 'c3voc-addons'])
or (
monitored_node.has_bundle('pacman')
and monitored_node.metadata.get('pacman/unattended-upgrades/is_enabled', False)
)
) and not monitored_node.metadata.get('icinga_options/exclude_from_monitoring', False)
%>\
% if auto_updates_enabled:
object ScheduledDowntime "unattended_upgrades" {
host_name = "${monitored_node.name}"
author = "unattended-upgrades" author = "${dt['name']}"
comment = "Downtime for upgrade-and-reboot of node ${monitored_node.name}" comment = "${dt['comment']}"
fixed = true fixed = true
ranges = { ranges = {
% if monitored_node.has_bundle('pacman'): % for d,t in dt['times'].items():
"${days[monitored_node.metadata.get('pacman/unattended-upgrades/day')]}" = "${monitored_node.metadata.get('pacman/unattended-upgrades/hour')}:${monitored_node.magic_number%30}-${monitored_node.metadata.get('pacman/unattended-upgrades/hour')}:${(monitored_node.magic_number%30)+30}" "${d}" = "${t}"
% else: % endfor
"${days[monitored_node.metadata.get('apt/unattended-upgrades/day')]}" = "${monitored_node.metadata.get('apt/unattended-upgrades/hour')}:${monitored_node.magic_number%30}-${monitored_node.metadata.get('apt/unattended-upgrades/hour')}:${(monitored_node.magic_number%30)+30}"
% endif
} }
child_options = "DowntimeTriggeredChildren" child_options = "DowntimeTriggeredChildren"
} }
% endif
% endfor % endfor

View file

@ -33,3 +33,11 @@ object ServiceGroup "checks_with_sms" {
assign where service.vars.notification.sms == true assign where service.vars.notification.sms == true
ignore where host.vars.notification.sms == false ignore where host.vars.notification.sms == false
} }
object ServiceGroup "statuspage" {
display_name = "Checks which are show on the public status page"
assign where service.vars.notification.sms == true
ignore where host.vars.notification.sms == false
ignore where host.vars.show_on_statuspage == false
}

View file

@ -14,7 +14,8 @@ object Host "${rnode.name}" {
vars.os = "${rnode.os}" vars.os = "${rnode.os}"
# used for status page # used for status page
vars.pretty_name = "${rnode.metadata.get('icinga_options/pretty_name', rnode.name)}" vars.pretty_name = "${rnode.metadata.get('icinga_options/pretty_name', rnode.metadata.get('hostname'))}"
vars.show_on_statuspage = ${str(rnode.metadata.get('icinga_options/show_on_statuspage', True)).lower()}
vars.period = "${rnode.metadata.get('icinga_options/period', '24x7')}" vars.period = "${rnode.metadata.get('icinga_options/period', '24x7')}"

View file

@ -9,6 +9,11 @@ app = Flask(__name__)
@app.route('/status') @app.route('/status')
def statuspage(): def statuspage():
everything_fine = True everything_fine = True
try:
check_output(['/usr/local/share/icinga/plugins/check_mounts'])
except:
everything_fine = False
try: try:
check_output(['/usr/lib/nagios/plugins/check_procs', '-C', 'icinga2', '-c', '1:']) check_output(['/usr/lib/nagios/plugins/check_procs', '-C', 'icinga2', '-c', '1:'])
except: except:

View file

@ -3,8 +3,6 @@ Description=Icinga2 Statusmonitor
After=network.target After=network.target
[Service] [Service]
User=nagios
Group=nagios
Environment="FLASK_APP=/etc/icinga2/icinga_statusmonitor.py" Environment="FLASK_APP=/etc/icinga2/icinga_statusmonitor.py"
ExecStart=/usr/bin/python3 -m flask run ExecStart=/usr/bin/python3 -m flask run
WorkingDirectory=/tmp WorkingDirectory=/tmp

View file

@ -0,0 +1,5 @@
[settings]
acknowledge_sticky = 1
hostdowntime_all_services = 1
hostdowntime_end_fixed = P1W
servicedowntime_end_fixed = P2D

View file

@ -3,22 +3,14 @@
import email.mime.text import email.mime.text
import smtplib import smtplib
from argparse import ArgumentParser from argparse import ArgumentParser
from json import dumps from json import dumps, load
from subprocess import run from subprocess import run
from sys import argv from sys import argv
from requests import post from requests import post
SIPGATE_USER='${node.metadata['icinga2']['sipgate_user']}' with open('/etc/icinga2/notification_config.json') as f:
SIPGATE_PASS='${node.metadata['icinga2']['sipgate_pass']}' CONFIG = load(f)
STATUS_TO_EMOJI = {
'critical': '🔥',
'down': '🚨🚨🚨',
'ok': '🆗',
'up': '👌',
'warning': '⚡',
}
parser = ArgumentParser( parser = ArgumentParser(
prog='icinga_notification_wrapper', prog='icinga_notification_wrapper',
@ -73,36 +65,31 @@ def notify_per_sms():
output_text = '' output_text = ''
else: else:
output_text = '\n\n{}'.format(args.output) output_text = '\n\n{}'.format(args.output)
if args.state.lower() in STATUS_TO_EMOJI:
message_text = '{emoji} {host}{service} {emoji}{output}'.format( message_text = 'ICINGA: {host}{service} is {state}{output}'.format(
emoji=STATUS_TO_EMOJI[args.state.lower()], host=args.host_name,
host=args.host_name, service=('/'+args.service_name if args.service_name else ''),
service=('/'+args.service_name if args.service_name else ''), state=args.state.upper(),
state=args.state.upper(), output=output_text,
output=output_text, )
)
else:
message_text = 'ICINGA: {host}{service} is {state}{output}'.format(
host=args.host_name,
service=('/'+args.service_name if args.service_name else ''),
state=args.state.upper(),
output=output_text,
)
message = { message = {
'message': message_text, 'message': message_text,
'smsId': 's0', # XXX what does this mean? Documentation is unclear 'smsId': 's0', # XXX what does this mean? Documentation is unclear
'recipient': args.sms 'recipient': args.sms
} }
headers = { headers = {
'Content-type': 'application/json', 'Content-type': 'application/json',
'Accept': 'application/json' 'Accept': 'application/json'
} }
try: try:
r = post( r = post(
'https://api.sipgate.com/v2/sessions/sms', 'https://api.sipgate.com/v2/sessions/sms',
json=message, json=message,
headers=headers, headers=headers,
auth=(SIPGATE_USER, SIPGATE_PASS), auth=(CONFIG['sipgate']['user'], CONFIG['sipgate']['password']),
) )
if r.status_code == 204: if r.status_code == 204:
@ -113,6 +100,42 @@ def notify_per_sms():
log_to_syslog('Sending a SMS to "{}" failed: {}'.format(args.sms, repr(e))) log_to_syslog('Sending a SMS to "{}" failed: {}'.format(args.sms, repr(e)))
def notify_per_ntfy():
message_text = 'ICINGA: {host}{service} is {state}\n\n{output}'.format(
host=args.host_name,
service=('/'+args.service_name if args.service_name else ''),
state=args.state.upper(),
output=args.output,
)
if args.service_name:
subject = '[ICINGA] {}/{}'.format(args.host_name, args.service_name)
else:
subject = '[ICINGA] {}'.format(args.host_name)
if args.notification_type.lower() == 'recovery':
priority = 'default'
else:
priority = 'urgent'
headers = {
'Title': subject,
'Priority': priority,
}
try:
r = post(
CONFIG['ntfy']['url'],
data=message_text,
headers=headers,
auth=(CONFIG['ntfy']['user'], CONFIG['ntfy']['password']),
)
r.raise_for_status()
except Exception as e:
log_to_syslog('Sending a Notification failed: {}'.format(repr(e)))
def notify_per_mail(): def notify_per_mail():
if args.notification_type.lower() == 'recovery': if args.notification_type.lower() == 'recovery':
# Do not send recovery emails. # Do not send recovery emails.
@ -176,4 +199,7 @@ if __name__ == '__main__':
notify_per_mail() notify_per_mail()
if args.sms: if args.sms:
notify_per_sms() if not args.service_name:
notify_per_sms()
if CONFIG['ntfy']['user']:
notify_per_ntfy()

View file

@ -76,8 +76,6 @@ files = {
}, },
'/usr/local/share/icinga/plugins/check_sipgate_account_balance': { '/usr/local/share/icinga/plugins/check_sipgate_account_balance': {
'mode': '0755', 'mode': '0755',
'content_type': 'mako',
'cascade_skip': False, # contains faults
}, },
'/usr/local/share/icinga/plugins/check_freifunk_node': { '/usr/local/share/icinga/plugins/check_freifunk_node': {
'mode': '0755', 'mode': '0755',
@ -114,11 +112,22 @@ files = {
'svc_systemd:icinga2:restart', 'svc_systemd:icinga2:restart',
}, },
}, },
'/etc/icinga2/notification_config.json': {
'content': repo.libs.faults.dict_as_json({
'sipgate': {
'user': node.metadata.get('icinga2/sipgate/user'),
'password': node.metadata.get('icinga2/sipgate/pass'),
},
'ntfy': {
'url': node.metadata.get('icinga2/ntfy/url'),
'user': node.metadata.get('icinga2/ntfy/user'),
'password': node.metadata.get('icinga2/ntfy/pass'),
},
}),
},
'/etc/icinga2/scripts/icinga_notification_wrapper': { '/etc/icinga2/scripts/icinga_notification_wrapper': {
'source': 'scripts/icinga_notification_wrapper', 'source': 'scripts/icinga_notification_wrapper',
'content_type': 'mako',
'mode': '0755', 'mode': '0755',
'cascade_skip': False, # contains faults
}, },
'/etc/icinga2/features-available/ido-pgsql.conf': { '/etc/icinga2/features-available/ido-pgsql.conf': {
'source': 'icinga2/ido-pgsql.conf', 'source': 'icinga2/ido-pgsql.conf',
@ -245,6 +254,11 @@ files = {
'mode': '0660', 'mode': '0660',
'group': 'icingaweb2', 'group': 'icingaweb2',
}, },
'/etc/icingaweb2/modules/monitoring/config.ini': {
'source': 'icingaweb2/monitoring_config.ini',
'mode': '0660',
'group': 'icingaweb2',
},
'/etc/icingaweb2/groups.ini': { '/etc/icingaweb2/groups.ini': {
'source': 'icingaweb2/groups.ini', 'source': 'icingaweb2/groups.ini',
'mode': '0660', 'mode': '0660',
@ -262,13 +276,13 @@ files = {
'group': 'icingaweb2', 'group': 'icingaweb2',
}, },
# Statusmonitor # monitoring
'/etc/icinga2/icinga_statusmonitor.py': { '/etc/icinga2/icinga_statusmonitor.py': {
'triggers': { 'triggers': {
'svc_systemd:icinga_statusmonitor:restart', 'svc_systemd:icinga_statusmonitor:restart',
}, },
}, },
'/etc/systemd/system/icinga_statusmonitor.service': { '/usr/local/lib/systemd/system/icinga_statusmonitor.service': {
'triggers': { 'triggers': {
'action:systemd-reload', 'action:systemd-reload',
'svc_systemd:icinga_statusmonitor:restart', 'svc_systemd:icinga_statusmonitor:restart',
@ -276,8 +290,12 @@ files = {
}, },
} }
pkg_pip = { svc_systemd['icinga_statusmonitor'] = {
'easysnmp': {}, # for check_usv_snmp 'needs': {
'file:/etc/icinga2/icinga_statusmonitor.py',
'file:/usr/local/lib/systemd/system/icinga_statusmonitor.service',
'pkg_apt:python3-flask',
},
} }
actions = { actions = {
@ -319,44 +337,30 @@ for name in files:
for name in symlinks: for name in symlinks:
icinga_run_deps.add(f'symlink:{name}') icinga_run_deps.add(f'symlink:{name}')
svc_systemd = { svc_systemd['icinga2'] = {
'icinga2': { 'needs': icinga_run_deps,
'needs': icinga_run_deps,
},
'icinga_statusmonitor': {
'needs': {
'file:/etc/icinga2/icinga_statusmonitor.py',
'file:/etc/systemd/system/icinga_statusmonitor.service',
'pkg_apt:python3-flask',
},
},
} }
# The actual hosts and services management starts here # The actual hosts and services management starts here
bundles = set() bundles = set()
for rnode in repo.nodes: downtimes = []
for rnode in sorted(repo.nodes):
if rnode.metadata.get('icinga_options/exclude_from_monitoring', False): if rnode.metadata.get('icinga_options/exclude_from_monitoring', False):
continue continue
host_ips = repo.libs.tools.resolve_identifier(repo, rnode.name) host_ips = repo.libs.tools.resolve_identifier(repo, rnode.name, only_physical=True)
icinga_ips = {} icinga_ips = {}
# XXX for the love of god, PLEASE remove this once DNS is no longer for ip_type in ('ipv4', 'ipv6'):
# hosted at GCE for ip in sorted(host_ips[ip_type]):
if rnode.in_group('gce'): if ip.is_private and not ip.is_link_local:
icinga_ips['ipv4'] = rnode.metadata.get('external_ipv4') icinga_ips[ip_type] = str(ip)
else: break
for ip_type in ('ipv4', 'ipv6'): else:
for ip in sorted(host_ips[ip_type]): if host_ips[ip_type]:
if ip.is_private and not ip.is_link_local: icinga_ips[ip_type] = sorted(host_ips[ip_type])[0]
icinga_ips[ip_type] = str(ip)
break
else:
if host_ips[ip_type]:
icinga_ips[ip_type] = sorted(host_ips[ip_type])[0]
if not icinga_ips: if not icinga_ips:
raise ValueError(f'{rnode.name} requests monitoring, but has neither IPv4 nor IPv6 addresses!') raise ValueError(f'{rnode.name} requests monitoring, but has neither IPv4 nor IPv6 addresses!')
@ -379,6 +383,41 @@ for rnode in repo.nodes:
bundles |= set(rnode.metadata.get('icinga2_api', {}).keys()) bundles |= set(rnode.metadata.get('icinga2_api', {}).keys())
if rnode.has_any_bundle(['apt', 'c3voc-addons']):
day = rnode.metadata.get('apt/unattended-upgrades/day')
hour = rnode.metadata.get('apt/unattended-upgrades/hour')
minute = rnode.magic_number%30
spread = rnode.metadata.get('apt/unattended-upgrades/spread_in_group', None)
if spread is not None:
spread_nodes = sorted(repo.nodes_in_group(spread))
day += spread_nodes.index(rnode)
downtimes.append({
'name': 'unattended-upgrades',
'host': rnode.name,
'comment': f'Downtime for upgrade-and-reboot of node {rnode.name}',
'times': {
DAYS_TO_STRING[day%7]: f'{hour}:{minute}-{hour}:{minute+15}',
},
})
elif (
rnode.has_bundle('pacman')
and rnode.metadata.get('pacman/unattended-upgrades/is_enabled', False)
):
day = rnode.metadata.get('pacman/unattended-upgrades/day')
hour = rnode.metadata.get('pacman/unattended-upgrades/hour')
minute = rnode.magic_number%30
downtimes.append({
'name': 'unattended-upgrades',
'host': rnode.name,
'comment': f'Downtime for upgrade-and-reboot of node {rnode.name}',
'times': {
DAYS_TO_STRING[day%7]: f'{hour}:{minute}-{hour}:{minute+15}',
},
})
files['/etc/icinga2/conf.d/groups.conf'] = { files['/etc/icinga2/conf.d/groups.conf'] = {
'source': 'icinga2/groups.conf', 'source': 'icinga2/groups.conf',
'content_type': 'mako', 'content_type': 'mako',
@ -399,7 +438,7 @@ files['/etc/icinga2/conf.d/downtimes.conf'] = {
'source': 'icinga2/downtimes.conf', 'source': 'icinga2/downtimes.conf',
'content_type': 'mako', 'content_type': 'mako',
'context': { 'context': {
'days': DAYS_TO_STRING, 'downtimes': downtimes,
}, },
'owner': 'nagios', 'owner': 'nagios',
'group': 'nagios', 'group': 'nagios',

View file

@ -17,12 +17,9 @@ defaults = {
'icinga2': {}, 'icinga2': {},
'icinga2-ido-pgsql': {}, 'icinga2-ido-pgsql': {},
'icingaweb2': {}, 'icingaweb2': {},
'python3-easysnmp': {},
# apparently no longer needed
#'icingaweb2-module-monitoring': {},
# neeeded for statusmonitor
'python3-flask': {}, 'python3-flask': {},
'snmp': {},
} }
}, },
'icinga2': { 'icinga2': {
@ -43,9 +40,6 @@ defaults = {
'check_interval': '30m', 'check_interval': '30m',
'vars.notification.mail': True, 'vars.notification.mail': True,
}, },
'ICINGA STATUSMONITOR': {
'command_on_monitored_host': '/usr/local/share/icinga/plugins/check_systemd_unit icinga_statusmonitor',
},
'IDO-PGSQL': { 'IDO-PGSQL': {
'check_command': 'ido', 'check_command': 'ido',
'vars.ido_type': 'IdoPgsqlConnection', 'vars.ido_type': 'IdoPgsqlConnection',
@ -59,6 +53,21 @@ defaults = {
'icingaweb2': { 'icingaweb2': {
'setup-token': repo.vault.password_for(f'{node.name} icingaweb2 setup-token'), 'setup-token': repo.vault.password_for(f'{node.name} icingaweb2 setup-token'),
}, },
'php': {
'version': '8.2',
'packages': {
'curl',
'gd',
'intl',
'imagick',
'ldap',
'mysql',
'opcache',
'pgsql',
'readline',
'xml',
},
},
'postgresql': { 'postgresql': {
'roles': { 'roles': {
'icinga2': { 'icinga2': {
@ -105,13 +114,29 @@ def add_users_from_json(metadata):
@metadata_reactor.provides( @metadata_reactor.provides(
'firewall/port_rules/5665', 'nginx/vhosts/icingaweb2',
'nginx/vhosts/icinga_statusmonitor',
) )
def firewall(metadata): def nginx(metadata):
if not node.has_bundle('nginx'):
raise DoNotRunAgain
return { return {
'firewall': { 'nginx': {
'port_rules': { 'vhosts': {
'5665': atomic(metadata.get('icinga2/restrict-to', set())), 'icingaweb2': {
'domain': metadata.get('icinga2/web_domain'),
'webroot': '/usr/share/icingaweb2/public',
'locations': {
'/api/': {
'target': 'https://127.0.0.1:5665/',
},
'/statusmonitor/': {
'target': 'http://127.0.0.1:5000/',
},
},
'extras': True,
},
}, },
}, },
} }

View file

@ -10,7 +10,7 @@ defaults = {
'repos': { 'repos': {
'influxdb': { 'influxdb': {
'items': { 'items': {
'deb https://repos.influxdata.com/{os} {os_release} stable', 'deb https://repos.influxdata.com/{os} stable main',
}, },
}, },
}, },

View file

@ -4,7 +4,8 @@ After=network.target
Requires=infobeamer-cms.service Requires=infobeamer-cms.service
[Service] [Service]
Environment=SETTINGS=/opt/infobeamer-cms/settings.toml
WorkingDirectory=/opt/infobeamer-cms/src
User=infobeamer-cms User=infobeamer-cms
Group=infobeamer-cms Group=infobeamer-cms
WorkingDirectory=/opt/infobeamer-cms ExecStart=/opt/infobeamer-cms/venv/bin/python syncer.py
ExecStart=curl -s -H "Host: ${domain}" http://127.0.0.1:8000/sync

View file

@ -2,7 +2,7 @@
Description=Run infobeamer-cms sync Description=Run infobeamer-cms sync
[Timer] [Timer]
OnCalendar=*:0/5 OnCalendar=minutely
Persistent=true Persistent=true
[Install] [Install]

View file

@ -1,4 +0,0 @@
<%
from tomlkit import dumps as toml_dumps
from bundlewrap.utils.text import toml_clean
%>${toml_clean(toml_dumps(repo.libs.faults.resolve_faults(config), sort_keys=True))}

View file

@ -1,8 +1,4 @@
actions = { actions = {
'infobeamer-cms_set_directory_permissions': {
'triggered': True,
'command': 'chown -R infobeamer-cms:infobeamer-cms /opt/infobeamer-cms/src/static/'
},
'infobeamer-cms_create_virtualenv': { 'infobeamer-cms_create_virtualenv': {
'command': '/usr/bin/python3 -m virtualenv -p python3 /opt/infobeamer-cms/venv/', 'command': '/usr/bin/python3 -m virtualenv -p python3 /opt/infobeamer-cms/venv/',
'unless': 'test -d /opt/infobeamer-cms/venv/', 'unless': 'test -d /opt/infobeamer-cms/venv/',
@ -12,7 +8,11 @@ actions = {
}, },
}, },
'infobeamer-cms_install_requirements': { 'infobeamer-cms_install_requirements': {
'command': 'cd /opt/infobeamer-cms/src && /opt/infobeamer-cms/venv/bin/pip install --upgrade pip gunicorn -r requirements.txt', 'command': ' && '.join([
'cd /opt/infobeamer-cms/src',
'/opt/infobeamer-cms/venv/bin/pip install --upgrade pip gunicorn -r requirements.txt',
'rsync /opt/infobeamer-cms/src/static/* /opt/infobeamer-cms/static/',
]),
'needs': { 'needs': {
'action:infobeamer-cms_create_virtualenv', 'action:infobeamer-cms_create_virtualenv',
}, },
@ -23,13 +23,12 @@ actions = {
git_deploy = { git_deploy = {
'/opt/infobeamer-cms/src': { '/opt/infobeamer-cms/src': {
'rev': 'master', 'rev': 'master',
'repo': 'https://github.com/sophieschi/36c3-cms.git', 'repo': 'https://github.com/voc/infobeamer-cms.git',
'needs': { 'needs': {
'directory:/opt/infobeamer-cms/src', 'directory:/opt/infobeamer-cms/src',
}, },
'triggers': { 'triggers': {
'svc_systemd:infobeamer-cms:restart', 'svc_systemd:infobeamer-cms:restart',
'action:infobeamer-cms_set_directory_permissions',
'action:infobeamer-cms_install_requirements', 'action:infobeamer-cms_install_requirements',
}, },
}, },
@ -37,6 +36,9 @@ git_deploy = {
directories = { directories = {
'/opt/infobeamer-cms/src': {}, '/opt/infobeamer-cms/src': {},
'/opt/infobeamer-cms/static': {
'owner': 'infobeamer-cms',
},
} }
config = node.metadata.get('infobeamer-cms/config', {}) config = node.metadata.get('infobeamer-cms/config', {})
@ -66,10 +68,7 @@ for room, device_id in sorted(node.metadata.get('infobeamer-cms/rooms', {}).item
files = { files = {
'/opt/infobeamer-cms/settings.toml': { '/opt/infobeamer-cms/settings.toml': {
'content_type': 'mako', 'content': repo.libs.faults.dict_as_toml(config),
'context': {
'config': config,
},
'triggers': { 'triggers': {
'svc_systemd:infobeamer-cms:restart', 'svc_systemd:infobeamer-cms:restart',
}, },
@ -97,19 +96,11 @@ files = {
}, },
} }
pkg_pip = {
'github-flask': {
'needed_by': {
'svc_systemd:infobeamer-cms',
},
},
}
svc_systemd = { svc_systemd = {
'infobeamer-cms': { 'infobeamer-cms': {
'needs': { 'needs': {
'action:infobeamer-cms_install_requirements', 'action:infobeamer-cms_install_requirements',
'action:infobeamer-cms_set_directory_permissions', 'directory:/opt/infobeamer-cms/static',
'file:/etc/systemd/system/infobeamer-cms.service', 'file:/etc/systemd/system/infobeamer-cms.service',
'file:/opt/infobeamer-cms/settings.toml', 'file:/opt/infobeamer-cms/settings.toml',
'git_deploy:/opt/infobeamer-cms/src', 'git_deploy:/opt/infobeamer-cms/src',
@ -117,8 +108,12 @@ svc_systemd = {
}, },
'infobeamer-cms-runperiodic.timer': { 'infobeamer-cms-runperiodic.timer': {
'needs': { 'needs': {
'file:/etc/systemd/system/infobeamer-cms-runperiodic.timer', 'action:infobeamer-cms_install_requirements',
'directory:/opt/infobeamer-cms/static',
'file:/etc/systemd/system/infobeamer-cms-runperiodic.service', 'file:/etc/systemd/system/infobeamer-cms-runperiodic.service',
'file:/etc/systemd/system/infobeamer-cms-runperiodic.timer',
'file:/opt/infobeamer-cms/settings.toml',
'git_deploy:/opt/infobeamer-cms/src',
}, },
}, },
} }

View file

@ -6,6 +6,7 @@ defaults = {
'MAX_UPLOADS': 5, 'MAX_UPLOADS': 5,
'PREFERRED_URL_SCHEME': 'https', 'PREFERRED_URL_SCHEME': 'https',
'SESSION_COOKIE_NAME': '__Host-sess', 'SESSION_COOKIE_NAME': '__Host-sess',
'STATIC_PATH': '/opt/infobeamer-cms/static',
'URL_KEY': repo.vault.password_for(f'{node.name} infobeamer-cms url key'), 'URL_KEY': repo.vault.password_for(f'{node.name} infobeamer-cms url key'),
'VERSION': 1, 'VERSION': 1,
}, },
@ -29,15 +30,13 @@ def nginx(metadata):
'/': { '/': {
'target': 'http://127.0.0.1:8000', 'target': 'http://127.0.0.1:8000',
}, },
'/sync': {
'return': 403,
},
'/static': { '/static': {
'alias': '/opt/infobeamer-cms/src/static', 'alias': '/opt/infobeamer-cms/static',
}, },
}, },
'website_check_path': '/', 'website_check_path': '/',
'website_check_string': 'Share your projects', 'website_check_string': 'Share your projects',
'do_not_set_content_security_headers': True,
}, },
}, },
}, },
@ -45,6 +44,7 @@ def nginx(metadata):
@metadata_reactor.provides( @metadata_reactor.provides(
'infobeamer-cms/config/DOMAIN',
'infobeamer-cms/config/TIME_MAX', 'infobeamer-cms/config/TIME_MAX',
'infobeamer-cms/config/TIME_MIN', 'infobeamer-cms/config/TIME_MIN',
) )
@ -57,6 +57,7 @@ def event_times(metadata):
return { return {
'infobeamer-cms': { 'infobeamer-cms': {
'config': { 'config': {
'DOMAIN': metadata.get('infobeamer-cms/domain'),
'TIME_MAX': int(event_end.timestamp()), 'TIME_MAX': int(event_end.timestamp()),
'TIME_MIN': int(event_start.timestamp()), 'TIME_MIN': int(event_start.timestamp()),
}, },

View file

@ -0,0 +1,15 @@
[Unit]
Description=infobeamer-monitor
After=network.target
[Service]
Type=exec
Restart=always
RestartSec=5s
ExecStart=/opt/infobeamer-cms/venv/bin/python monitor.py
User=infobeamer-cms
Group=infobeamer-cms
WorkingDirectory=/opt/infobeamer-monitor/
[Install]
WantedBy=multi-user.target

View file

@ -0,0 +1,227 @@
#!/usr/bin/env python3
import logging
from datetime import datetime
from json import dumps
from time import sleep
from zoneinfo import ZoneInfo
import paho.mqtt.client as mqtt
from requests import RequestException, get
try:
# python 3.11
from tomllib import loads as toml_load
except ImportError:
from rtoml import load as toml_load
with open("config.toml") as f:
CONFIG = toml_load(f.read())
logging.basicConfig(
format="[%(levelname)s %(name)s] %(message)s",
level=logging.INFO,
)
LOG = logging.getLogger("main")
MLOG = logging.getLogger("mqtt")
state = None
client = mqtt.Client()
client.username_pw_set(CONFIG["mqtt"]["user"], CONFIG["mqtt"]["password"])
client.connect(CONFIG["mqtt"]["host"], 1883, 60)
client.loop_start()
def mqtt_out(message, level="INFO", device=None):
key = "infobeamer"
if device:
key += f"/{device['id']}"
message = f"[{device['description']}] {message}"
client.publish(
CONFIG["mqtt"]["topic"],
dumps(
{
"level": level,
"component": key,
"msg": message,
}
),
)
def mqtt_dump_state(device):
if not device["is_online"]:
return
out = []
if device["location"]:
out.append("Location: {}".format(device["location"]))
out.append("Setup: {} ({})".format(device["setup"]["name"], device["setup"]["id"]))
out.append("Resolution: {}".format(device["run"].get("resolution", "unknown")))
mqtt_out(
" - ".join(out),
device=device,
)
mqtt_out("Monitor starting up")
while True:
try:
online_devices = set()
available_credits = None
try:
r = get(
"https://info-beamer.com/api/v1/device/list",
auth=("", CONFIG["api_key"]),
)
r.raise_for_status()
ib_state = r.json()["devices"]
except RequestException as e:
LOG.exception("Could not get data from info-beamer")
mqtt_out(
f"Could not get data from info-beamer: {e!r}",
level="WARN",
)
else:
new_state = {}
for device in ib_state:
did = str(device["id"])
if did in new_state:
mqtt_out("DUPLICATE DETECTED!", level="ERROR", device=device)
continue
new_state[did] = device
must_dump_state = False
if state is not None:
if did not in state:
LOG.info(
"new device found: {} [{}]".format(
did,
device["description"],
)
)
mqtt_out(
"new device found!",
device=device,
)
must_dump_state = True
else:
if device["is_online"] != state[did]["is_online"]:
online_status = (
"online from {}".format(device["run"]["public_addr"])
if device["is_online"]
else "offline"
)
LOG.info("device {} is now {}".format(did, online_status))
mqtt_out(
f"status changed to {online_status}",
level="INFO" if device["is_online"] else "WARN",
device=device,
)
must_dump_state = True
if device["description"] != state[did]["description"]:
LOG.info(
"device {} changed name to {}".format(
did, device["description"]
)
)
must_dump_state = True
if device["is_online"]:
if device["maintenance"]:
mqtt_out(
"maintenance required: {}".format(
" ".join(sorted(device["maintenance"]))
),
level="WARN",
device=device,
)
if (
device["location"] != state[did]["location"]
or device["setup"]["id"] != state[did]["setup"]["id"]
or device["run"].get("resolution")
!= state[did]["run"].get("resolution")
):
must_dump_state = True
if must_dump_state:
mqtt_dump_state(device)
else:
LOG.info("adding device {} to empty state".format(device["id"]))
if device["is_online"]:
online_devices.add(
"{} ({})".format(
device["id"],
device["description"],
)
)
state = new_state
try:
r = get(
"https://info-beamer.com/api/v1/account",
auth=("", CONFIG["api_key"]),
)
r.raise_for_status()
ib_account = r.json()
except RequestException as e:
LOG.exception("Could not get data from info-beamer")
mqtt_out(
f"Could not get data from info-beamer: {e!r}",
level="WARN",
)
else:
available_credits = ib_account["balance"]
if available_credits < 50:
mqtt_out(
f"balance has dropped below 50 credits! (available: {available_credits})",
level="ERROR",
)
elif available_credits < 100:
mqtt_out(
f"balance has dropped below 100 credits! (available: {available_credits})",
level="WARN",
)
for quota_name, quota_config in sorted(ib_account["quotas"].items()):
value = quota_config["count"]["value"]
limit = quota_config["count"]["limit"]
if value > limit * 0.9:
mqtt_out(
f"quota {quota_name} is over 90% (limit {limit}, value {value})",
level="ERROR",
)
elif value > limit * 0.8:
mqtt_out(
f"quota {quota_name} is over 80% (limit {limit}, value {value})",
level="WARN",
)
if datetime.now(ZoneInfo("Europe/Berlin")).strftime("%H%M") == "0900":
if available_credits is not None:
mqtt_out(f"Available Credits: {available_credits}")
if online_devices:
mqtt_out(
"Online Devices: {}".format(", ".join(sorted(online_devices)))
)
sleep(60)
except KeyboardInterrupt:
break
mqtt_out("Monitor exiting")

View file

@ -0,0 +1,30 @@
assert node.has_bundle('infobeamer-cms') # uses same venv
files['/opt/infobeamer-monitor/config.toml'] = {
'content': repo.libs.faults.dict_as_toml(node.metadata.get('infobeamer-monitor')),
'triggers': {
'svc_systemd:infobeamer-monitor:restart',
},
}
files['/opt/infobeamer-monitor/monitor.py'] = {
'mode': '0755',
'triggers': {
'svc_systemd:infobeamer-monitor:restart',
},
}
files['/usr/local/lib/systemd/system/infobeamer-monitor.service'] = {
'triggers': {
'action:systemd-reload',
'svc_systemd:infobeamer-monitor:restart',
},
}
svc_systemd['infobeamer-monitor'] = {
'needs': {
'file:/opt/infobeamer-monitor/config.toml',
'file:/opt/infobeamer-monitor/monitor.py',
'file:/usr/local/lib/systemd/system/infobeamer-monitor.service',
},
}

View file

@ -0,0 +1,7 @@
Cmnd_Alias RESTARTSERVER_SYSTEMD = /usr/bin/systemd-run systemctl restart jellyfin
Cmnd_Alias STARTSERVER_SYSTEMD = /usr/bin/systemd-run systemctl start jellyfin
Cmnd_Alias STOPSERVER_SYSTEMD = /usr/bin/systemd-run systemctl stop jellyfin
jellyfin ALL=(ALL) NOPASSWD: RESTARTSERVER_SYSTEMD
jellyfin ALL=(ALL) NOPASSWD: STARTSERVER_SYSTEMD
jellyfin ALL=(ALL) NOPASSWD: STOPSERVER_SYSTEMD

View file

@ -0,0 +1,5 @@
files['/etc/sudoers.d/jellyfin-sudoers'] = {
'after': {
'pkg_apt:jellyfin',
},
}

View file

@ -0,0 +1,69 @@
from bundlewrap.metadata import atomic
defaults = {
'apt': {
'packages': {
'jellyfin': {},
},
'repos': {
'jellyfin': {
'uris': {
'https://repo.jellyfin.org/{os}'
},
},
},
},
'backups': {
'paths': {
f'/var/lib/jellyfin/{x}' for x in ('data', 'metadata', 'plugins', 'root')
},
},
'icinga2_api': {
'transmission': {
'services': {
'JELLYFIN PROCESS': {
'command_on_monitored_host': '/usr/lib/nagios/plugins/check_procs -C jellyfin -c 1:',
},
},
},
},
}
@metadata_reactor.provides(
'nginx/vhosts/jellyfin',
)
def nginx(metadata):
if not node.has_bundle('nginx'):
raise DoNotRunAgain
if 'jellyfin' not in metadata.get('nginx/vhosts', {}):
return {}
return {
'nginx': {
'vhosts': {
'jellyfin': {
'do_not_add_content_security_headers': True,
'locations': {
'/': {
'target': 'http://127.0.0.1:8096',
'websockets': True,
},
},
},
},
},
}
@metadata_reactor.provides(
'firewall/port_rules',
)
def firewall(metadata):
return {
'firewall': {
'port_rules': {
'8096/tcp': atomic(metadata.get('jellyfin/restrict-to', set())),
},
},
}

15
bundles/jool/items.py Normal file
View file

@ -0,0 +1,15 @@
actions['modprobe_jool'] = {
'command': 'modprobe jool',
'unless': 'lsmod | grep -F jool',
}
actions['jool_add_nat64_instance'] = {
'command': 'jool instance add "nat64" --netfilter --pool6 64:ff9b::/96',
'unless': 'jool instance display --no-headers --csv | grep -E ",nat64,netfilter$"',
'needs': {
'action:modprobe_jool',
'pkg_apt:jool-dkms',
'pkg_apt:jool-tools',
'pkg_apt:linux-headers-amd64',
},
}

14
bundles/jool/metadata.py Normal file
View file

@ -0,0 +1,14 @@
defaults = {
'apt': {
'packages': {
'jool-dkms': {},
'jool-tools': {},
'linux-headers-amd64': {},
},
},
'modules': {
'jool': [
'jool',
],
},
}

View file

@ -0,0 +1,16 @@
[Unit]
Description=jugendhackt_tools web service
After=network.target
Requires=postgresql.service
[Service]
User=jugendhackt_tools
Group=jugendhackt_tools
Environment=CONFIG_PATH=/opt/jugendhackt_tools/config.toml
WorkingDirectory=/opt/jugendhackt_tools/src
ExecStart=/opt/jugendhackt_tools/venv/bin/gunicorn jugendhackt_tools.wsgi --name jugendhackt_tools --workers 4 --max-requests 1200 --max-requests-jitter 50 --log-level=info --bind=127.0.0.1:22090
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target

View file

@ -0,0 +1,75 @@
directories['/opt/jugendhackt_tools/src'] = {}
git_deploy['/opt/jugendhackt_tools/src'] = {
'repo': 'https://github.com/kunsi/jugendhackt_schedule.git',
'rev': 'main',
'triggers': {
'action:jugendhackt_tools_install',
'action:jugendhackt_tools_migrate',
'svc_systemd:jugendhackt_tools:restart',
},
}
actions['jugendhackt_tools_create_virtualenv'] = {
'command': '/usr/bin/python3 -m virtualenv -p python3 /opt/jugendhackt_tools/venv/',
'unless': 'test -d /opt/jugendhackt_tools/venv/',
'needs': {
# actually /opt/jugendhackt_tools, but we don't create that
'directory:/opt/jugendhackt_tools/src',
},
}
actions['jugendhackt_tools_install'] = {
'command': ' && '.join([
'cd /opt/jugendhackt_tools/src',
'/opt/jugendhackt_tools/venv/bin/pip install --upgrade pip wheel gunicorn psycopg2-binary',
'/opt/jugendhackt_tools/venv/bin/pip install --upgrade -r requirements.txt',
]),
'needs': {
'action:jugendhackt_tools_create_virtualenv',
},
'triggered': True,
}
actions['jugendhackt_tools_migrate'] = {
'command': ' && '.join([
'cd /opt/jugendhackt_tools/src',
'CONFIG_PATH=/opt/jugendhackt_tools/config.toml /opt/jugendhackt_tools/venv/bin/python manage.py migrate',
'CONFIG_PATH=/opt/jugendhackt_tools/config.toml /opt/jugendhackt_tools/venv/bin/python manage.py collectstatic --noinput',
]),
'needs': {
'action:jugendhackt_tools_install',
'file:/opt/jugendhackt_tools/config.toml',
'postgres_db:jugendhackt_tools',
'postgres_role:jugendhackt_tools',
},
'triggered': True,
}
files['/opt/jugendhackt_tools/config.toml'] = {
'content': repo.libs.faults.dict_as_toml(node.metadata.get('jugendhackt_tools')),
'triggers': {
'svc_systemd:jugendhackt_tools:restart',
},
}
files['/usr/local/lib/systemd/system/jugendhackt_tools.service'] = {
'triggers': {
'action:systemd-reload',
'svc_systemd:jugendhackt_tools:restart',
},
}
svc_systemd['jugendhackt_tools'] = {
'needs': {
'action:jugendhackt_tools_migrate',
'file:/opt/jugendhackt_tools/config.toml',
'file:/usr/local/lib/systemd/system/jugendhackt_tools.service',
'git_deploy:/opt/jugendhackt_tools/src',
'user:jugendhackt_tools',
},
}
users['jugendhackt_tools'] = {
'home': '/opt/jugendhackt_tools/src',
}

View file

@ -0,0 +1,28 @@
defaults = {
'jugendhackt_tools': {
'django_secret': repo.vault.random_bytes_as_base64_for(f'{node.name} jugendhackt_tools django_secret'),
'django_debug': False,
'static_root': '/opt/jugendhackt_tools/src/static/',
'database': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'jugendhackt_tools',
'USER': 'jugendhackt_tools',
'PASSWORD': repo.vault.password_for(f'{node.name} postgresql jugendhackt_tools'),
'HOST': 'localhost',
'PORT': '5432'
},
},
'postgresql': {
'roles': {
'jugendhackt_tools': {
'password': repo.vault.password_for(f'{node.name} postgresql jugendhackt_tools'),
},
},
'databases': {
'jugendhackt_tools': {
'owner': 'jugendhackt_tools',
},
},
},
}

View file

@ -0,0 +1,37 @@
#!/usr/bin/env python3
from csv import DictReader
from datetime import datetime, timezone
from os import scandir
from os.path import join
def parse():
NOW = datetime.now()
active_leases = {}
for file in scandir("/var/lib/kea/"):
with open(file.path) as f:
for row in DictReader(f):
expires = datetime.fromtimestamp(int(row["expire"]))
if expires >= NOW:
if (
row["address"] not in active_leases
or active_leases[row["address"]]["expires_dt"] < expires
):
row["expires_dt"] = expires
active_leases[row["address"]] = row
return active_leases.values()
def print_table(leases):
print(""" address | MAC | expires | hostname
-----------------+-------------------+---------+----------""")
for lease in sorted(leases, key=lambda r: r["address"]):
print(
f' {lease["address"]:<15} | {lease["hwaddr"].lower()} | {lease["expires_dt"]:%H:%M} | {lease["hostname"]}'
)
if __name__ == "__main__":
print_table(parse())

View file

@ -0,0 +1,56 @@
kea_config = {
'Dhcp4': {
**node.metadata.get('kea-dhcp-server/config'),
'interfaces-config': {
'interfaces': sorted(node.metadata.get('kea-dhcp-server/subnets', {}).keys()),
},
'subnet4': [],
'loggers': [{
'name': 'kea-dhcp4',
'output_options': [{
# -> journal
'output': 'stdout',
}],
'severity': 'WARN',
}],
},
}
for iface, config in sorted(node.metadata.get('kea-dhcp-server/subnets', {}).items()):
kea_config['Dhcp4']['subnet4'].append({
'subnet': config['subnet'],
'pools': [{
'pool': f'{config["lower"]} - {config["higher"]}',
}],
'option-data': [
{
'name': k,
'data': v,
} for k, v in sorted(config.get('options', {}).items())
],
'reservations': [
{
'ip-address': v['ip'],
'hw-address': v['mac'],
'hostname': k,
} for k, v in sorted(node.metadata.get(f'kea-dhcp-server/fixed_allocations/{iface}', {}).items())
]
})
files['/etc/kea/kea-dhcp4.conf'] = {
'content': repo.libs.faults.dict_as_json(kea_config),
'triggers': {
'svc_systemd:kea-dhcp4-server:restart',
},
}
files['/usr/local/bin/kea-lease-list'] = {
'mode': '0500',
}
svc_systemd['kea-dhcp4-server'] = {
'needs': {
'file:/etc/kea/kea-dhcp4.conf',
'pkg_apt:kea-dhcp4-server',
},
}

View file

@ -0,0 +1,83 @@
from ipaddress import ip_address, ip_network
defaults = {
'apt': {
'packages': {
'kea-dhcp4-server': {},
},
},
'kea-dhcp-server': {
'config': {
'authoritative': True,
'rebind-timer': 450,
'renew-timer': 300,
'valid-lifetime': 600,
'expired-leases-processing': {
'max-reclaim-leases': 0,
'max-reclaim-time': 0,
},
'lease-database': {
'lfc-interval': 3600,
'name': '/var/lib/kea/kea-leases4.csv',
'persist': True,
'type': 'memfile',
},
},
},
}
@metadata_reactor.provides(
'kea-dhcp-server/fixed_allocations',
)
def get_static_allocations(metadata):
result = {}
mapping = {}
for iface, config in metadata.get('kea-dhcp-server/subnets', {}).items():
result[iface] = {}
mapping[iface] = ip_network(config['subnet'])
for rnode in repo.nodes:
if (
rnode.metadata.get('location', '') != metadata.get('location', '')
or rnode == node
):
continue
for iface_name, iface_config in rnode.metadata.get('interfaces', {}).items():
if iface_config.get('dhcp', False) and iface_config.get('mac'):
for ip in iface_config.get('ips', set()):
ipaddr = ip_address(ip)
for kea_iface, kea_subnet in mapping.items():
if ipaddr in kea_subnet:
result[kea_iface][f'{rnode.name}_{iface_name}'] = {
'ip': ip,
'mac': iface_config['mac'],
}
break
return {
'kea-dhcp-server': {
'fixed_allocations': result,
}
}
@metadata_reactor.provides(
'nftables/input/10-kea-dhcp-server',
)
def nftables(metadata):
rules = set()
for iface in node.metadata.get('kea-dhcp-server/subnets', {}):
rules.add(f'udp dport {{ 67, 68 }} iifname {iface} accept')
return {
'nftables': {
'input': {
# can't use port_rules here, because we're generating interface based rules.
'10-kea-dhcp-server': sorted(rules),
},
}
}

View file

@ -0,0 +1,8 @@
# This file is managed using bundlewrap
% for identifier, modules in sorted(node.metadata.get('modules', {}).items()):
# ${identifier}
% for module in modules:
${module}
% endfor
% endfor

View file

@ -0,0 +1,3 @@
files['/etc/modules'] = {
'content_type': 'mako',
}

View file

@ -43,15 +43,15 @@ defaults = {
@metadata_reactor.provides( @metadata_reactor.provides(
'firewall/port_rules/8080', 'firewall/port_rules',
'firewall/port_rules/9090', 'firewall/port_rules',
) )
def firewall(metadata): def firewall(metadata):
return { return {
'firewall': { 'firewall': {
'port_rules': { 'port_rules': {
'8080': atomic(metadata.get('kodi/restrict-to', {'*'})), '8080/tcp': atomic(metadata.get('kodi/restrict-to', {'*'})),
'9090': atomic(metadata.get('kodi/restrict-to', {'*'})), '9090/tcp': atomic(metadata.get('kodi/restrict-to', {'*'})),
}, },
}, },
} }

View file

@ -39,6 +39,7 @@ def cron(metadata):
'/usr/bin/dehydrated --cleanup', '/usr/bin/dehydrated --cleanup',
], ],
'when': '04:{}:00'.format(node.magic_number % 60), 'when': '04:{}:00'.format(node.magic_number % 60),
'exclude_from_monitoring': True,
}, },
}, },
}, },

View file

@ -1,28 +1,29 @@
directories = { if node.os != 'routeros':
'/etc/lldpd.d': { directories = {
'purge': True, '/etc/lldpd.d': {
'triggers': { 'purge': True,
'svc_systemd:lldpd:restart', 'triggers': {
'svc_systemd:lldpd:restart',
},
}, },
}, }
}
files = { files = {
'/etc/lldpd.conf': { '/etc/lldpd.conf': {
'delete': True, 'delete': True,
},
'/etc/lldpd.d/bundlewrap.conf': {
'content_type': 'mako',
'triggers': {
'svc_systemd:lldpd:restart',
}, },
}, '/etc/lldpd.d/bundlewrap.conf': {
} 'content_type': 'mako',
'triggers': {
'svc_systemd:lldpd:restart',
},
},
}
svc_systemd = { svc_systemd = {
'lldpd': { 'lldpd': {
'needs': { 'needs': {
'file:/etc/lldpd.d/bundlewrap.conf', 'file:/etc/lldpd.d/bundlewrap.conf',
},
}, },
}, }
}

Some files were not shown because too many files have changed in this diff Show more