From f41ba0b9348d6f34d879bcedb69d2756285dd79b Mon Sep 17 00:00:00 2001 From: mwiegand Date: Tue, 6 Jul 2021 21:26:47 +0200 Subject: [PATCH] wip --- bundles/apt/README.md | 13 -- bundles/apt/items.py | 95 ----------- bundles/apt/metadata.py | 6 - bundles/archive/README.md | 12 -- bundles/archive/files/archive | 29 ---- bundles/archive/files/get_file | 10 -- bundles/archive/files/validate_file | 15 -- bundles/archive/items.py | 43 ----- bundles/archive/metadata.py | 45 ------ bundles/bind/files/db | 23 --- bundles/bind/files/defaults | 2 - bundles/bind/files/named.conf | 6 - bundles/bind/files/named.conf.local | 39 ----- bundles/bind/files/named.conf.options | 10 -- bundles/bind/items.py | 141 ---------------- bundles/bind/metadata.py | 87 ---------- bundles/dovecot/README.md | 9 -- bundles/dovecot/files/decode2text.sh | 105 ------------ bundles/dovecot/files/dovecot-sql.conf | 10 -- bundles/dovecot/files/dovecot.conf | 134 ---------------- bundles/dovecot/files/learn-ham.sieve | 7 - bundles/dovecot/files/learn-spam.sieve | 3 - bundles/dovecot/files/spam-global.sieve | 6 - bundles/dovecot/items.py | 112 ------------- bundles/dovecot/metadata.py | 37 ----- bundles/gcloud/README.md | 12 -- bundles/gcloud/items.py | 43 ----- bundles/gcloud/metadata.py | 14 -- bundles/gitea/files/app.ini | 88 ---------- bundles/gitea/items.py | 45 ------ bundles/gitea/metadata.py | 94 ----------- bundles/gocryptfs-inspect/items.py | 6 - bundles/gocryptfs-inspect/metadata.py | 7 - bundles/gocryptfs/items.py | 43 ----- bundles/gocryptfs/metadata.py | 103 ------------ bundles/grafana/README.md | 14 -- bundles/grafana/items.py | 150 ------------------ bundles/grafana/metadata.py | 107 ------------- bundles/hetzner-cloud/metadata.py | 8 - bundles/influxdb2/README.md | 21 --- bundles/influxdb2/items.py | 77 --------- bundles/influxdb2/metadata.py | 53 ------- bundles/l4d2/files/l4d2.service | 13 -- bundles/l4d2/files/update_addons | 4 - bundles/l4d2/metadata.py | 7 - bundles/letsencrypt/files/config | 5 - bundles/letsencrypt/files/domains.txt | 3 - bundles/letsencrypt/files/hook.sh | 37 ----- .../files/letsencrypt-ensure-some-certificate | 31 ---- bundles/letsencrypt/items.py | 50 ------ bundles/letsencrypt/metadata.py | 16 -- bundles/mailserver/items.py | 79 --------- bundles/mailserver/metadata.py | 66 -------- bundles/mirror/metadata.py | 17 -- bundles/network/metadata.py | 46 ------ bundles/nextcloud/README.md | 38 ----- bundles/nextcloud/files/managed.config.php | 24 --- bundles/nextcloud/items.py | 144 ----------------- bundles/nextcloud/metadata.py | 83 ---------- bundles/nginx/files/fastcgi.conf | 27 ---- bundles/nginx/items.py | 88 ---------- bundles/nginx/metadata.py | 126 --------------- bundles/opendkim/files/key_table | 3 - bundles/opendkim/files/opendkim.conf | 15 -- bundles/opendkim/files/signing_table | 3 - bundles/opendkim/items.py | 86 ---------- bundles/opendkim/metadata.py | 93 ----------- bundles/php/files/php.ini | 102 ------------ bundles/php/items.py | 37 ----- bundles/php/metadata.py | 7 - bundles/postfix/files/main.cf | 53 ------- bundles/postfix/files/master.cf | 55 ------- bundles/postfix/files/virtual_alias_maps.cf | 5 - .../postfix/files/virtual_mailbox_domains.cf | 5 - bundles/postfix/files/virtual_mailbox_maps.cf | 5 - bundles/postfix/items.py | 73 --------- bundles/postfix/metadata.py | 25 --- bundles/postgresql/items.py | 22 --- bundles/postgresql/metadata.py | 52 ------ bundles/redis/metadata.py | 7 - bundles/roundcube/files/config.inc.php | 79 --------- bundles/roundcube/items.py | 34 ---- bundles/roundcube/metadata.py | 66 -------- bundles/rspamd/files/ip_whitelist.map | 3 - .../files/local.d/classifier-bayes.conf | 1 - bundles/rspamd/files/local.d/logging.inc | 2 - .../rspamd/files/local.d/milter_headers.conf | 2 - bundles/rspamd/files/local.d/multimap.conf | 6 - bundles/rspamd/files/local.d/redis.conf | 1 - .../rspamd/files/local.d/worker-normal.inc | 1 - bundles/rspamd/files/local.d/worker-proxy.inc | 7 - .../rspamd/files/override.d/antivirus.conf | 6 - bundles/rspamd/files/worker-controller.inc | 1 - bundles/rspamd/items.py | 66 -------- bundles/rspamd/metadata.py | 15 -- bundles/steam/files/steam-update.service | 15 -- bundles/steam/items.py | 4 - bundles/systemd-networkd/files/resolv.conf | 3 - bundles/systemd-networkd/items.py | 36 ----- bundles/systemd-networkd/metadata.py | 13 -- bundles/systemd-timers/items.py | 21 --- bundles/systemd-timers/metadata.py | 27 ---- bundles/systemd/items.py | 44 ----- bundles/systemd/metadata.py | 5 - bundles/telegraf/README.md | 4 - bundles/telegraf/items.py | 15 -- bundles/telegraf/metadata.py | 79 --------- bundles/wireguard/items.py | 3 - bundles/wireguard/metadata.py | 135 ---------------- bundles/zfs/items.py | 42 ----- bundles/zfs/metadata.py | 80 ---------- bundles/zsh/files/bw.zsh-theme | 31 ---- bundles/zsh/files/zshrc | 6 - bundles/zsh/items.py | 43 ----- bundles/zsh/metadata.py | 7 - data/apt/keys/deb.debian.org.gpg | Bin 8132 -> 0 bytes data/apt/keys/packages.cloud.google.com.gpg | Bin 2537 -> 0 bytes data/apt/keys/packages.grafana.com.asc | 30 ---- data/apt/keys/repos.influxdata.com.asc | 52 ------ data/apt/keys/security.debian.org.gpg | Bin 8141 -> 0 bytes data/dkim/islamicstate.eu.privkey.enc | 1 - data/dkim/islamicstate.eu.pubkey | 1 - data/dkim/mail2.sublimity.de.privkey.enc | 1 - data/dkim/mail2.sublimity.de.pubkey | 1 - data/dkim/mail3.sublimity.de.privkey.enc | 1 - data/dkim/mail3.sublimity.de.pubkey | 1 - .../backup@sublimity-182017.json.enc | 1 - data/grafana/dashboard.py | 37 ----- data/grafana/flux.mako | 15 -- data/grafana/panel.py | 66 -------- data/grafana/rows/cpu.py | 37 ----- data/grafana/rows/disk_io.py | 34 ---- data/grafana/rows/mem.py | 36 ----- data/grafana/rows/net_io.py | 34 ---- data/network.py | 19 --- groups/all.py | 9 +- groups/applications/archive.py | 10 -- groups/applications/backup-server.py | 6 - groups/applications/backup.py | 10 -- groups/applications/dnsserver.py | 5 - groups/applications/gcloud.py | 12 -- groups/applications/mailserver.py | 14 -- groups/applications/monitored.py | 10 -- groups/applications/nextcloud.py | 6 - groups/applications/webserver.py | 6 - groups/hardware/hetzner-cloud.py | 5 - groups/os/debian-10.py | 20 --- groups/os/debian-11.py | 20 --- groups/os/debian.py | 22 --- groups/os/linux.py | 11 -- libs/apt.py | 70 -------- libs/derive_string.py | 71 --------- libs/dns.py | 15 -- libs/grafana.py | 29 ---- libs/ini.py | 24 --- libs/keys.py | 15 -- libs/nextcloud.py | 2 - libs/nginx.py | 27 ---- libs/systemd.py | 27 ---- libs/tools.py | 88 ---------- nodes/home.backups.py | 28 +--- nodes/home.server.py | 78 +-------- nodes/htz.games.py | 7 +- nodes/htz.mails.py | 122 +------------- nodes/netcup.secondary.py | 31 +--- 165 files changed, 12 insertions(+), 5494 deletions(-) delete mode 100644 bundles/apt/README.md delete mode 100644 bundles/apt/items.py delete mode 100644 bundles/apt/metadata.py delete mode 100644 bundles/archive/README.md delete mode 100644 bundles/archive/files/archive delete mode 100644 bundles/archive/files/get_file delete mode 100644 bundles/archive/files/validate_file delete mode 100644 bundles/archive/items.py delete mode 100644 bundles/archive/metadata.py delete mode 100644 bundles/bind/files/db delete mode 100644 bundles/bind/files/defaults delete mode 100644 bundles/bind/files/named.conf delete mode 100644 bundles/bind/files/named.conf.local delete mode 100644 bundles/bind/files/named.conf.options delete mode 100644 bundles/bind/items.py delete mode 100644 bundles/bind/metadata.py delete mode 100644 bundles/dovecot/README.md delete mode 100644 bundles/dovecot/files/decode2text.sh delete mode 100644 bundles/dovecot/files/dovecot-sql.conf delete mode 100644 bundles/dovecot/files/dovecot.conf delete mode 100644 bundles/dovecot/files/learn-ham.sieve delete mode 100644 bundles/dovecot/files/learn-spam.sieve delete mode 100644 bundles/dovecot/files/spam-global.sieve delete mode 100644 bundles/dovecot/items.py delete mode 100644 bundles/dovecot/metadata.py delete mode 100644 bundles/gcloud/README.md delete mode 100644 bundles/gcloud/items.py delete mode 100644 bundles/gcloud/metadata.py delete mode 100644 bundles/gitea/files/app.ini delete mode 100644 bundles/gitea/items.py delete mode 100644 bundles/gitea/metadata.py delete mode 100644 bundles/gocryptfs-inspect/items.py delete mode 100644 bundles/gocryptfs-inspect/metadata.py delete mode 100644 bundles/gocryptfs/items.py delete mode 100644 bundles/gocryptfs/metadata.py delete mode 100644 bundles/grafana/README.md delete mode 100644 bundles/grafana/items.py delete mode 100644 bundles/grafana/metadata.py delete mode 100644 bundles/hetzner-cloud/metadata.py delete mode 100644 bundles/influxdb2/README.md delete mode 100644 bundles/influxdb2/items.py delete mode 100644 bundles/influxdb2/metadata.py delete mode 100644 bundles/l4d2/files/l4d2.service delete mode 100644 bundles/l4d2/files/update_addons delete mode 100644 bundles/l4d2/metadata.py delete mode 100644 bundles/letsencrypt/files/config delete mode 100644 bundles/letsencrypt/files/domains.txt delete mode 100644 bundles/letsencrypt/files/hook.sh delete mode 100644 bundles/letsencrypt/files/letsencrypt-ensure-some-certificate delete mode 100644 bundles/letsencrypt/items.py delete mode 100644 bundles/letsencrypt/metadata.py delete mode 100644 bundles/mailserver/items.py delete mode 100644 bundles/mailserver/metadata.py delete mode 100644 bundles/mirror/metadata.py delete mode 100644 bundles/network/metadata.py delete mode 100644 bundles/nextcloud/README.md delete mode 100644 bundles/nextcloud/files/managed.config.php delete mode 100644 bundles/nextcloud/items.py delete mode 100644 bundles/nextcloud/metadata.py delete mode 100644 bundles/nginx/files/fastcgi.conf delete mode 100644 bundles/nginx/items.py delete mode 100644 bundles/nginx/metadata.py delete mode 100644 bundles/opendkim/files/key_table delete mode 100644 bundles/opendkim/files/opendkim.conf delete mode 100644 bundles/opendkim/files/signing_table delete mode 100644 bundles/opendkim/items.py delete mode 100644 bundles/opendkim/metadata.py delete mode 100644 bundles/php/files/php.ini delete mode 100644 bundles/php/items.py delete mode 100644 bundles/php/metadata.py delete mode 100644 bundles/postfix/files/main.cf delete mode 100644 bundles/postfix/files/master.cf delete mode 100644 bundles/postfix/files/virtual_alias_maps.cf delete mode 100644 bundles/postfix/files/virtual_mailbox_domains.cf delete mode 100644 bundles/postfix/files/virtual_mailbox_maps.cf delete mode 100644 bundles/postfix/items.py delete mode 100644 bundles/postfix/metadata.py delete mode 100644 bundles/postgresql/items.py delete mode 100644 bundles/postgresql/metadata.py delete mode 100644 bundles/redis/metadata.py delete mode 100644 bundles/roundcube/files/config.inc.php delete mode 100644 bundles/roundcube/items.py delete mode 100644 bundles/roundcube/metadata.py delete mode 100644 bundles/rspamd/files/ip_whitelist.map delete mode 100644 bundles/rspamd/files/local.d/classifier-bayes.conf delete mode 100644 bundles/rspamd/files/local.d/logging.inc delete mode 100644 bundles/rspamd/files/local.d/milter_headers.conf delete mode 100644 bundles/rspamd/files/local.d/multimap.conf delete mode 100644 bundles/rspamd/files/local.d/redis.conf delete mode 100644 bundles/rspamd/files/local.d/worker-normal.inc delete mode 100644 bundles/rspamd/files/local.d/worker-proxy.inc delete mode 100644 bundles/rspamd/files/override.d/antivirus.conf delete mode 100644 bundles/rspamd/files/worker-controller.inc delete mode 100644 bundles/rspamd/items.py delete mode 100644 bundles/rspamd/metadata.py delete mode 100644 bundles/steam/files/steam-update.service delete mode 100644 bundles/steam/items.py delete mode 100644 bundles/systemd-networkd/files/resolv.conf delete mode 100644 bundles/systemd-networkd/items.py delete mode 100644 bundles/systemd-networkd/metadata.py delete mode 100644 bundles/systemd-timers/items.py delete mode 100644 bundles/systemd-timers/metadata.py delete mode 100644 bundles/systemd/items.py delete mode 100644 bundles/systemd/metadata.py delete mode 100644 bundles/telegraf/README.md delete mode 100644 bundles/telegraf/items.py delete mode 100644 bundles/telegraf/metadata.py delete mode 100644 bundles/wireguard/items.py delete mode 100644 bundles/wireguard/metadata.py delete mode 100644 bundles/zfs/items.py delete mode 100644 bundles/zfs/metadata.py delete mode 100644 bundles/zsh/files/bw.zsh-theme delete mode 100644 bundles/zsh/files/zshrc delete mode 100644 bundles/zsh/items.py delete mode 100644 bundles/zsh/metadata.py delete mode 100644 data/apt/keys/deb.debian.org.gpg delete mode 100644 data/apt/keys/packages.cloud.google.com.gpg delete mode 100644 data/apt/keys/packages.grafana.com.asc delete mode 100644 data/apt/keys/repos.influxdata.com.asc delete mode 100644 data/apt/keys/security.debian.org.gpg delete mode 100644 data/dkim/islamicstate.eu.privkey.enc delete mode 100644 data/dkim/islamicstate.eu.pubkey delete mode 100644 data/dkim/mail2.sublimity.de.privkey.enc delete mode 100644 data/dkim/mail2.sublimity.de.pubkey delete mode 100644 data/dkim/mail3.sublimity.de.privkey.enc delete mode 100644 data/dkim/mail3.sublimity.de.pubkey delete mode 100644 data/gcloud/service_accounts/backup@sublimity-182017.json.enc delete mode 100644 data/grafana/dashboard.py delete mode 100644 data/grafana/flux.mako delete mode 100644 data/grafana/panel.py delete mode 100644 data/grafana/rows/cpu.py delete mode 100644 data/grafana/rows/disk_io.py delete mode 100644 data/grafana/rows/mem.py delete mode 100644 data/grafana/rows/net_io.py delete mode 100644 data/network.py delete mode 100644 groups/applications/archive.py delete mode 100644 groups/applications/backup-server.py delete mode 100644 groups/applications/backup.py delete mode 100644 groups/applications/dnsserver.py delete mode 100644 groups/applications/gcloud.py delete mode 100644 groups/applications/mailserver.py delete mode 100644 groups/applications/monitored.py delete mode 100644 groups/applications/nextcloud.py delete mode 100644 groups/applications/webserver.py delete mode 100644 groups/hardware/hetzner-cloud.py delete mode 100644 groups/os/debian-10.py delete mode 100644 groups/os/debian-11.py delete mode 100644 groups/os/debian.py delete mode 100644 groups/os/linux.py delete mode 100644 libs/apt.py delete mode 100644 libs/derive_string.py delete mode 100644 libs/dns.py delete mode 100644 libs/grafana.py delete mode 100644 libs/ini.py delete mode 100644 libs/keys.py delete mode 100644 libs/nextcloud.py delete mode 100644 libs/nginx.py delete mode 100644 libs/systemd.py delete mode 100644 libs/tools.py diff --git a/bundles/apt/README.md b/bundles/apt/README.md deleted file mode 100644 index ec66fa1..0000000 --- a/bundles/apt/README.md +++ /dev/null @@ -1,13 +0,0 @@ -```python -{ - 'apt': { - 'packages': { - 'apt-transport-https': {}, - }, - 'sources': [ - # place key under data/apt/keys/packages.cloud.google.com.{asc|gpg} - 'deb https://packages.cloud.google.com/apt cloud-sdk main', - ], - }, -} -``` diff --git a/bundles/apt/items.py b/bundles/apt/items.py deleted file mode 100644 index ed992ef..0000000 --- a/bundles/apt/items.py +++ /dev/null @@ -1,95 +0,0 @@ -from os.path import join -from urllib.parse import urlparse -from glob import glob -from os.path import join, basename - -directories = { - '/etc/apt/sources.list.d': { - 'purge': True, - 'triggers': { - 'action:apt_update', - }, - }, - '/etc/apt/trusted.gpg.d': { - 'purge': True, - 'triggers': { - 'action:apt_update', - }, - }, - '/etc/apt/preferences.d': { - 'purge': True, - 'triggers': { - 'action:apt_update', - }, - }, -} - -files = { - '/etc/apt/sources.list': { - 'content': '# managed' - }, -} - -actions = { - 'apt_update': { - 'command': 'apt-get update', - 'needed_by': { - 'pkg_apt:', - }, - 'triggered': True, - 'cascade_skip': False, - }, -} - -hosts = {} - -for source_string in node.metadata.get('apt/sources'): - source = repo.libs.apt.AptSource(source_string) - hosts\ - .setdefault(source.url.hostname, set())\ - .add(source) - -for host, sources in hosts.items(): - keyfile = basename(glob(join(repo.path, 'data', 'apt', 'keys', f'{host}.*'))[0]) - destination_path = f'/etc/apt/trusted.gpg.d/{keyfile}' - - for source in sources: - source.options['signed-by'] = [destination_path] - - files[f'/etc/apt/sources.list.d/{host}.list'] = { - 'content': '\n'.join( - str(source) for source in sorted(sources) - ).format( - release=node.metadata.get('os_release') - ), - 'triggers': { - 'action:apt_update', - }, - } - - files[destination_path] = { - 'source': join(repo.path, 'data', 'apt', 'keys', keyfile), - 'content_type': 'binary', - 'triggers': { - 'action:apt_update', - }, - } - - -for package, options in node.metadata.get('apt/packages', {}).items(): - pkg_apt[package] = options - - if pkg_apt[package].pop('backports', False): - files[f'/etc/apt/preferences.d/{package}'] = { - 'content': '\n'.join([ - f"Package: {package}", - f"Pin: release a={node.metadata.get('os_release')}-backports", - f"Pin-Priority: 900", - ]), - 'needed_by': [ - f'pkg_apt:{package}', - ], - 'triggers': { - 'action:apt_update', - }, - } diff --git a/bundles/apt/metadata.py b/bundles/apt/metadata.py deleted file mode 100644 index f62c8ac..0000000 --- a/bundles/apt/metadata.py +++ /dev/null @@ -1,6 +0,0 @@ -defaults = { - 'apt': { - 'packages': {}, - 'sources': [], - }, -} diff --git a/bundles/archive/README.md b/bundles/archive/README.md deleted file mode 100644 index 4a23ef0..0000000 --- a/bundles/archive/README.md +++ /dev/null @@ -1,12 +0,0 @@ -``` -defaults = { - 'archive': { - '/var/important': { - 'exclude': [ - '\.cache/', - '\.log$', - ], - }, - }, -} -``` diff --git a/bundles/archive/files/archive b/bundles/archive/files/archive deleted file mode 100644 index fab7b27..0000000 --- a/bundles/archive/files/archive +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash - -if [[ "$1" == 'perform' ]] -then - echo 'NON-DRY RUN' - DRY='' -else - echo 'DRY RUN' - DRY='-n' -fi - -% for path, options in paths.items(): -# ${path} -gsutil ${'\\'} - -m ${'\\'} - -o 'GSUtil:parallel_process_count=${processes}' ${'\\'} - -o 'GSUtil:parallel_thread_count=${threads}' ${'\\'} - rsync ${'\\'} - $DRY ${'\\'} - -r ${'\\'} - -d ${'\\'} - -e ${'\\'} -% if options.get('exclude'): - -x '${'|'.join(options['exclude'])}' ${'\\'} -% endif - '${options['encrypted_path']}' ${'\\'} - 'gs://${bucket}/${node_id}${path}' ${'\\'} - 2>&1 | logger -st gsutil -% endfor diff --git a/bundles/archive/files/get_file b/bundles/archive/files/get_file deleted file mode 100644 index 81f94b7..0000000 --- a/bundles/archive/files/get_file +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -FILENAME=$1 -TMPFILE=$(mktemp /tmp/archive_file.XXXXXXXXXX) -BUCKET=$(cat /etc/gcloud/gcloud.json | jq -r .bucket) -NODE=$(cat /etc/archive/archive.json | jq -r .node_id) -MASTERKEY=$(cat /etc/gocryptfs/masterkey) - -gsutil cat "gs://$BUCKET/$NODE$FILENAME" > "$TMPFILE" -/opt/gocryptfs-inspect/gocryptfs.py --aessiv --config=/etc/gocryptfs/gocryptfs.conf --masterkey="$MASTERKEY" "$TMPFILE" diff --git a/bundles/archive/files/validate_file b/bundles/archive/files/validate_file deleted file mode 100644 index 57da963..0000000 --- a/bundles/archive/files/validate_file +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -FILENAME=$1 - -ARCHIVE=$(/opt/archive/get_file "$FILENAME" | sha256sum) -ORIGINAL=$(cat "$FILENAME" | sha256sum) - -if [[ "$ARCHIVE" == "$ORIGINAL" ]] -then - echo "OK" - exit 0 -else - echo "ERROR" - exit 1 -fi diff --git a/bundles/archive/items.py b/bundles/archive/items.py deleted file mode 100644 index dedf580..0000000 --- a/bundles/archive/items.py +++ /dev/null @@ -1,43 +0,0 @@ -assert node.has_bundle('gcloud') -assert node.has_bundle('gocryptfs') -assert node.has_bundle('gocryptfs-inspect') -assert node.has_bundle('systemd') - -from json import dumps - -directories['/opt/archive'] = {} -directories['/etc/archive'] = {} - -files['/etc/archive/archive.json'] = { - 'content': dumps( - { - 'node_id': node.metadata.get('id'), - **node.metadata.get('archive'), - }, - indent=4, - sort_keys=True - ), -} - -files['/opt/archive/archive'] = { - 'content_type': 'mako', - 'mode': '700', - 'context': { - 'node_id': node.metadata.get('id'), - 'paths': node.metadata.get('archive/paths'), - 'bucket': node.metadata.get('gcloud/bucket'), - 'processes': 4, - 'threads': 4, - }, - 'needs': [ - 'bundle:gcloud', - ], -} - -files['/opt/archive/get_file'] = { - 'mode': '700', -} - -files['/opt/archive/validate_file'] = { - 'mode': '700', -} diff --git a/bundles/archive/metadata.py b/bundles/archive/metadata.py deleted file mode 100644 index 39b9282..0000000 --- a/bundles/archive/metadata.py +++ /dev/null @@ -1,45 +0,0 @@ -defaults = { - 'apt': { - 'packages': { - 'jq': {}, - }, - }, - 'archive': { - 'paths': {}, - }, -} - - -@metadata_reactor.provides( - 'archive/paths', -) -def paths(metadata): - return { - 'archive': { - 'paths': { - path: { - 'encrypted_path': f'/mnt/archive.enc{path}', - 'exclude': [ - '^\..*', - '/\..*', - ], - } for path in metadata.get('archive/paths') - }, - } - } - - -@metadata_reactor.provides( - 'gocryptfs/paths', -) -def gocryptfs(metadata): - return { - 'gocryptfs': { - 'paths': { - path: { - 'mountpoint': options['encrypted_path'], - 'reverse': True, - } for path, options in metadata.get('archive/paths').items() - }, - } - } diff --git a/bundles/bind/files/db b/bundles/bind/files/db deleted file mode 100644 index a5c1703..0000000 --- a/bundles/bind/files/db +++ /dev/null @@ -1,23 +0,0 @@ -<%! -def column_width(column, table): - return max(map(lambda row: len(row[column]), table)) if table else 0 -%>\ -$TTL 600 -@ IN SOA ns.sublimity.de. admin.sublimity.de. ( - 2020080302 ;Serial - 600 ;Refresh - 300 ;Retry - 1209600 ;Expire - 300 ;Negative response caching TTL -) - -% for record in sorted(records, key=lambda r: (r['name'], r['type'], r['value'])): -${(record['name'] or '@').ljust(column_width('name', records))} \ -IN \ -${record['type'].ljust(column_width('type', records))} \ - % if record['type'] == 'TXT': -(${' '.join('"'+record['value'][i:i+255]+'"' for i in range(0, len(record['value']), 255))}) - % else: -${record['value']} - % endif -% endfor diff --git a/bundles/bind/files/defaults b/bundles/bind/files/defaults deleted file mode 100644 index 9819214..0000000 --- a/bundles/bind/files/defaults +++ /dev/null @@ -1,2 +0,0 @@ -RESOLVCONF=no -OPTIONS="-u bind" diff --git a/bundles/bind/files/named.conf b/bundles/bind/files/named.conf deleted file mode 100644 index 568b28d..0000000 --- a/bundles/bind/files/named.conf +++ /dev/null @@ -1,6 +0,0 @@ -statistics-channels { - inet 127.0.0.1 port 8053; -}; - -include "/etc/bind/named.conf.options"; -include "/etc/bind/named.conf.local"; diff --git a/bundles/bind/files/named.conf.local b/bundles/bind/files/named.conf.local deleted file mode 100644 index 749ce14..0000000 --- a/bundles/bind/files/named.conf.local +++ /dev/null @@ -1,39 +0,0 @@ -% for view in views: -acl "${view['name']}" { - ${' '.join(f'{e};' for e in view['acl'])} -}; -% endfor - -% for view in views: -view "${view['name']}" { - match-clients { ${view['name']}; }; - - % if view['is_internal']: - recursion yes; - % else: - recursion no; - rate-limit { - responses-per-second 2; - window 25; - }; - % endif - - forward only; - forwarders { - 1.1.1.1; - 9.9.9.9; - 8.8.8.8; - }; - - % for zone in zones: - zone "${zone}" { - type master; - file "/var/lib/bind/${view['name']}/db.${zone}"; - }; - % endfor - - include "/etc/bind/named.conf.default-zones"; - include "/etc/bind/zones.rfc1918"; -}; - -% endfor diff --git a/bundles/bind/files/named.conf.options b/bundles/bind/files/named.conf.options deleted file mode 100644 index 8a64abc..0000000 --- a/bundles/bind/files/named.conf.options +++ /dev/null @@ -1,10 +0,0 @@ -options { - directory "/var/cache/bind"; - dnssec-validation auto; - - listen-on-v6 { any; }; - allow-query { any; }; - - max-cache-size 30%; - querylog yes; -}; diff --git a/bundles/bind/items.py b/bundles/bind/items.py deleted file mode 100644 index 16714bc..0000000 --- a/bundles/bind/items.py +++ /dev/null @@ -1,141 +0,0 @@ -from ipaddress import ip_address - -directories[f'/var/lib/bind'] = { - 'purge': True, - 'needed_by': [ - 'svc_systemd:bind9', - ], - 'triggers': [ - 'svc_systemd:bind9:restart', - ], -} - -files['/etc/default/bind9'] = { - 'source': 'defaults', - 'needed_by': [ - 'svc_systemd:bind9', - ], - 'triggers': [ - 'svc_systemd:bind9:restart', - ], -} - -files['/etc/bind/named.conf'] = { - 'owner': 'root', - 'group': 'bind', - 'needed_by': [ - 'svc_systemd:bind9', - ], - 'triggers': [ - 'svc_systemd:bind9:restart', - ], -} -files['/etc/bind/named.conf.options'] = { - 'owner': 'root', - 'group': 'bind', - 'needed_by': [ - 'svc_systemd:bind9', - ], - 'triggers': [ - 'svc_systemd:bind9:restart', - ], -} - -views = [ - { - 'name': 'internal', - 'is_internal': True, - 'acl': [ - '127.0.0.1', - '10.0.0.0/8', - '169.254.0.0/16', - '172.16.0.0/12', - '192.168.0.0/16', - ] - }, - { - 'name': 'external', - 'is_internal': False, - 'acl': [ - 'any', - ] - }, -] - -files['/etc/bind/named.conf.local'] = { - 'content_type': 'mako', - 'context': { - 'views': views, - 'zones': sorted(node.metadata.get('bind/zones')), - }, - 'owner': 'root', - 'group': 'bind', - 'needed_by': [ - 'svc_systemd:bind9', - ], - 'triggers': [ - 'svc_systemd:bind9:restart', - ], -} - -def use_record(record, records, view): - if record['type'] in ['A', 'AAAA']: - if view == 'external': - # no internal addresses in external view - if ip_address(record['value']).is_private: - return False - elif view == 'internal': - # external addresses in internal view only, if no internal exists - if ip_address(record['value']).is_global: - for other_record in records: - if ( - record['name'] == other_record['name'] and - record['type'] == other_record['type'] and - ip_address(other_record['value']).is_private - ): - return False - return True - -for view in views: - directories[f"/var/lib/bind/{view['name']}"] = { - 'purge': True, - 'needed_by': [ - 'svc_systemd:bind9', - ], - 'triggers': [ - 'svc_systemd:bind9:restart', - ], - } - - for zone, records in node.metadata.get('bind/zones').items(): - files[f"/var/lib/bind/{view['name']}/db.{zone}"] = { - 'group': 'bind', - 'source': 'db', - 'content_type': 'mako', - 'context': { - 'view': view['name'], - 'records': list(filter( - lambda record: use_record(record, records, view['name']), - records - )), - }, - 'needs': [ - f"directory:/var/lib/bind/{view['name']}", - ], - 'needed_by': [ - 'svc_systemd:bind9', - ], - 'triggers': [ - 'svc_systemd:bind9:restart', - ], - } - -svc_systemd['bind9'] = {} - -actions['named-checkconf'] = { - 'command': 'named-checkconf -z', - 'unless': 'named-checkconf -z', - 'needs': [ - 'svc_systemd:bind9', - ] -} diff --git a/bundles/bind/metadata.py b/bundles/bind/metadata.py deleted file mode 100644 index b772f8a..0000000 --- a/bundles/bind/metadata.py +++ /dev/null @@ -1,87 +0,0 @@ -from ipaddress import ip_interface - - -defaults = { - 'apt': { - 'packages': { - 'bind9': {}, - }, - }, - 'bind': { - 'zones': {}, - }, - 'telegraf': { - 'config': { - 'inputs': { - 'bind': [{ - 'urls': ['http://localhost:8053/xml/v3'], - 'gather_memory_contexts': False, - 'gather_views': True, - }], - }, - }, - }, -} - - -@metadata_reactor.provides( - 'dns', -) -def dns(metadata): - return { - 'dns': { - metadata.get('bind/hostname'): repo.libs.dns.get_a_records(metadata), - } - } - - -@metadata_reactor.provides( - 'bind/zones', -) -def collect_records(metadata): - zones = {} - - for other_node in repo.nodes: - for fqdn, records in other_node.metadata.get('dns').items(): - matching_zones = sorted( - filter( - lambda potential_zone: fqdn.endswith(potential_zone), - metadata.get('bind/zones').keys() - ), - key=len, - ) - if matching_zones: - zone = matching_zones[-1] - else: - continue - - name = fqdn[0:-len(zone) - 1] - - for type, values in records.items(): - for value in values: - zones\ - .setdefault(zone, [])\ - .append( - {'name': name, 'type': type, 'value': value} - ) - - return { - 'bind': { - 'zones': zones, - }, - } - - -@metadata_reactor.provides( - 'bind/zones', -) -def ns_records(metadata): - return { - 'bind': { - 'zones': { - zone: [ - {'name': '@', 'type': 'NS', 'value': f"{metadata.get('bind/hostname')}."}, - ] for zone in metadata.get('bind/zones').keys() - }, - }, - } diff --git a/bundles/dovecot/README.md b/bundles/dovecot/README.md deleted file mode 100644 index b40e7f1..0000000 --- a/bundles/dovecot/README.md +++ /dev/null @@ -1,9 +0,0 @@ -DOVECOT -======= - -rescan index: https://doc.dovecot.org/configuration_manual/fts/#rescan - -``` - sudo -u vmail doveadm fts rescan -u 'test@mail2.sublimity.de' - sudo -u vmail doveadm index -u 'test@mail2.sublimity.de' -q '*' -``` diff --git a/bundles/dovecot/files/decode2text.sh b/bundles/dovecot/files/decode2text.sh deleted file mode 100644 index 151fb7c..0000000 --- a/bundles/dovecot/files/decode2text.sh +++ /dev/null @@ -1,105 +0,0 @@ -#!/bin/sh - -# Example attachment decoder script. The attachment comes from stdin, and -# the script is expected to output UTF-8 data to stdout. (If the output isn't -# UTF-8, everything except valid UTF-8 sequences are dropped from it.) - -# The attachment decoding is enabled by setting: -# -# plugin { -# fts_decoder = decode2text -# } -# service decode2text { -# executable = script /usr/local/libexec/dovecot/decode2text.sh -# user = dovecot -# unix_listener decode2text { -# mode = 0666 -# } -# } - -libexec_dir=`dirname $0` -content_type=$1 - -# The second parameter is the format's filename extension, which is used when -# found from a filename of application/octet-stream. You can also add more -# extensions by giving more parameters. -formats='application/pdf pdf -application/x-pdf pdf -application/msword doc -application/mspowerpoint ppt -application/vnd.ms-powerpoint ppt -application/ms-excel xls -application/x-msexcel xls -application/vnd.ms-excel xls -application/vnd.openxmlformats-officedocument.wordprocessingml.document docx -application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx -application/vnd.openxmlformats-officedocument.presentationml.presentation pptx -application/vnd.oasis.opendocument.text odt -application/vnd.oasis.opendocument.spreadsheet ods -application/vnd.oasis.opendocument.presentation odp -' - -if [ "$content_type" = "" ]; then - echo "$formats" - exit 0 -fi - -fmt=`echo "$formats" | grep -w "^$content_type" | cut -d ' ' -f 2` -if [ "$fmt" = "" ]; then - echo "Content-Type: $content_type not supported" >&2 - exit 1 -fi - -# most decoders can't handle stdin directly, so write the attachment -# to a temp file -path=`mktemp` -trap "rm -f $path" 0 1 2 3 14 15 -cat > $path - -xmlunzip() { - name=$1 - - tempdir=`mktemp -d` - if [ "$tempdir" = "" ]; then - exit 1 - fi - trap "rm -rf $path $tempdir" 0 1 2 3 14 15 - cd $tempdir || exit 1 - unzip -q "$path" 2>/dev/null || exit 0 - find . -name "$name" -print0 | xargs -0 cat | - $libexec_dir/xml2text -} - -wait_timeout() { - childpid=$! - trap "kill -9 $childpid; rm -f $path" 1 2 3 14 15 - wait $childpid -} - -LANG=en_US.UTF-8 -export LANG -if [ $fmt = "pdf" ]; then - /usr/bin/pdftotext $path - 2>/dev/null& - wait_timeout 2>/dev/null -elif [ $fmt = "doc" ]; then - (/usr/bin/catdoc $path; true) 2>/dev/null& - wait_timeout 2>/dev/null -elif [ $fmt = "ppt" ]; then - (/usr/bin/catppt $path; true) 2>/dev/null& - wait_timeout 2>/dev/null -elif [ $fmt = "xls" ]; then - (/usr/bin/xls2csv $path; true) 2>/dev/null& - wait_timeout 2>/dev/null -elif [ $fmt = "odt" -o $fmt = "ods" -o $fmt = "odp" ]; then - xmlunzip "content.xml" -elif [ $fmt = "docx" ]; then - xmlunzip "document.xml" -elif [ $fmt = "xlsx" ]; then - xmlunzip "sharedStrings.xml" -elif [ $fmt = "pptx" ]; then - xmlunzip "slide*.xml" -else - echo "Buggy decoder script: $fmt not handled" >&2 - exit 1 -fi -exit 0 diff --git a/bundles/dovecot/files/dovecot-sql.conf b/bundles/dovecot/files/dovecot-sql.conf deleted file mode 100644 index 12f6707..0000000 --- a/bundles/dovecot/files/dovecot-sql.conf +++ /dev/null @@ -1,10 +0,0 @@ -connect = host=${host} dbname=${name} user=${user} password=${password} -driver = pgsql -default_pass_scheme = PLAIN-MD5 - -password_query = SELECT CONCAT(users.name, '@', domains.name) AS user, password\ - FROM users \ - LEFT JOIN domains ON users.domain_id = domains.id \ - WHERE redirect IS NULL \ - AND users.name = SPLIT_PART('%u', '@', 1) \ - AND domains.name = SPLIT_PART('%u', '@', 2) diff --git a/bundles/dovecot/files/dovecot.conf b/bundles/dovecot/files/dovecot.conf deleted file mode 100644 index 57daf4e..0000000 --- a/bundles/dovecot/files/dovecot.conf +++ /dev/null @@ -1,134 +0,0 @@ -protocols = imap lmtp sieve -auth_mechanisms = plain login -mail_privileged_group = mail -ssl = required -ssl_cert = - -[session] -PROVIDER = file - -[picture] -DISABLE_GRAVATAR = true -ENABLE_FEDERATED_AVATAR = false - -[log] -MODE = console -LEVEL = warn - -[oauth2] -JWT_SECRET = ${oauth_secret_key} - -[other] -SHOW_FOOTER_BRANDING = true -SHOW_FOOTER_TEMPLATE_LOAD_TIME = false diff --git a/bundles/gitea/items.py b/bundles/gitea/items.py deleted file mode 100644 index 3819d77..0000000 --- a/bundles/gitea/items.py +++ /dev/null @@ -1,45 +0,0 @@ -version = version=node.metadata.get('gitea/version') - -downloads['/usr/local/bin/gitea'] = { - 'url': f'https://dl.gitea.io/gitea/{version}/gitea-{version}-linux-amd64', - 'sha256': node.metadata.get('gitea/sha256'), - 'triggers': { - 'svc_systemd:gitea:restart', - }, - 'preceded_by': { - 'action:stop_gitea', - }, -} - -users['git'] = {} - -directories['/var/lib/gitea'] = { - 'owner': 'git', - 'mode': '0700', - 'triggers': { - 'svc_systemd:gitea:restart', - }, -} - -actions = { - 'chmod_gitea': { - 'command': 'chmod a+x /usr/local/bin/gitea', - 'unless': 'test -x /usr/local/bin/gitea', - 'needs': { - 'download:/usr/local/bin/gitea', - }, - }, - 'stop_gitea': { - 'command': 'systemctl stop gitea', - 'triggered': True, - }, -} - -files['/etc/gitea/app.ini'] = { - 'content_type': 'mako', - 'owner': 'git', - 'context': node.metadata['gitea'], - 'triggers': { - 'svc_systemd:gitea:restart', - }, -} diff --git a/bundles/gitea/metadata.py b/bundles/gitea/metadata.py deleted file mode 100644 index 2c98618..0000000 --- a/bundles/gitea/metadata.py +++ /dev/null @@ -1,94 +0,0 @@ -database_password = repo.vault.password_for(f'{node.name} postgresql gitea') - -defaults = { - 'gitea': { - 'database': { - 'host': 'localhost', - 'port': '5432', - 'username': 'gitea', - 'password': database_password, - 'database': 'gitea', - }, - 'app_name': 'Gitea', - 'lfs_secret_key': repo.vault.password_for(f'{node.name} gitea lfs_secret_key', length=43), - 'security_secret_key': repo.vault.password_for(f'{node.name} gitea security_secret_key'), - 'oauth_secret_key': repo.vault.password_for(f'{node.name} gitea oauth_secret_key', length=43), - 'internal_token': repo.vault.password_for(f'{node.name} gitea internal_token'), - }, - 'postgresql': { - 'roles': { - 'gitea': { - 'password': database_password, - }, - }, - 'databases': { - 'gitea': { - 'owner': 'gitea', - }, - }, - }, - 'systemd': { - 'services': { - 'gitea': { - 'content': { - 'Unit': { - 'Description': 'gitea', - 'After': 'syslog.target', - 'After': 'network.target', - 'Requires': 'postgresql.service', - }, - 'Service': { - 'RestartSec': '2s', - 'Type': 'simple', - 'User': 'git', - 'Group': 'git', - 'WorkingDirectory': '/var/lib/gitea/', - 'ExecStart': '/usr/local/bin/gitea web -c /etc/gitea/app.ini', - 'Restart': 'always', - 'Environment': 'USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/gitea', - }, - 'Install': { - 'WantedBy': 'multi-user.target', - }, - }, - 'needs': [ - 'action:chmod_gitea', - 'download:/usr/local/bin/gitea', - 'file:/etc/systemd/system/gitea.service', - 'file:/etc/gitea/app.ini', - ], - }, - }, - }, - 'zfs': { - 'datasets': { - 'tank/gitea': { - 'mountpoint': '/var/lib/gitea', - }, - }, - }, -} - - -@metadata_reactor.provides( - 'nginx/vhosts', -) -def nginx(metadata): - if not node.has_bundle('nginx'): - raise DoNotRunAgain - - return { - 'nginx': { - 'vhosts': { - metadata.get('gitea/domain'): { - 'proxy': { - '/': { - 'target': 'http://127.0.0.1:22000', - }, - }, - 'website_check_path': '/user/login', - 'website_check_string': 'Sign In', - }, - }, - }, - } diff --git a/bundles/gocryptfs-inspect/items.py b/bundles/gocryptfs-inspect/items.py deleted file mode 100644 index 4466343..0000000 --- a/bundles/gocryptfs-inspect/items.py +++ /dev/null @@ -1,6 +0,0 @@ -directories['/opt/gocryptfs-inspect'] = {} - -git_deploy['/opt/gocryptfs-inspect'] = { - 'repo': 'https://github.com/slackner/gocryptfs-inspect.git', - 'rev': 'ecd296c8f014bf18f5889e3cb9cb64807ff6b9c4', -} diff --git a/bundles/gocryptfs-inspect/metadata.py b/bundles/gocryptfs-inspect/metadata.py deleted file mode 100644 index b12c65d..0000000 --- a/bundles/gocryptfs-inspect/metadata.py +++ /dev/null @@ -1,7 +0,0 @@ -defaults = { - 'apt': { - 'packages': { - 'python3-pycryptodome': {}, - }, - }, -} diff --git a/bundles/gocryptfs/items.py b/bundles/gocryptfs/items.py deleted file mode 100644 index 43967b9..0000000 --- a/bundles/gocryptfs/items.py +++ /dev/null @@ -1,43 +0,0 @@ -from json import dumps - -directories['/etc/gocryptfs'] = { - 'purge': True, -} - -files['/etc/gocryptfs/masterkey'] = { - 'content': node.metadata.get('gocryptfs/masterkey'), - 'mode': '500', -} - -files['/etc/gocryptfs/gocryptfs.conf'] = { - 'content': dumps({ - 'Version': 2, - 'Creator': 'gocryptfs 1.6.1', - 'ScryptObject': { - 'Salt': node.metadata.get('gocryptfs/salt'), - 'N': 65536, - 'R': 8, - 'P': 1, - 'KeyLen': 32, - }, - 'FeatureFlags': [ - 'GCMIV128', - 'HKDF', - 'PlaintextNames', - 'AESSIV', - ] - }, indent=4, sort_keys=True) -} - -for path, options in node.metadata.get('gocryptfs/paths').items(): - directories[options['mountpoint']] = { - 'owner': None, - 'group': None, - 'mode': None, - 'preceded_by': [ - f'svc_systemd:gocryptfs-{options["id"]}:stop', - ], - 'needed_by': [ - f'svc_systemd:gocryptfs-{options["id"]}', - ], - } diff --git a/bundles/gocryptfs/metadata.py b/bundles/gocryptfs/metadata.py deleted file mode 100644 index aa51819..0000000 --- a/bundles/gocryptfs/metadata.py +++ /dev/null @@ -1,103 +0,0 @@ -from hashlib import sha3_256 -from base64 import b64decode, b64encode -from binascii import hexlify -from uuid import UUID - -defaults = { - 'apt': { - 'packages': { - 'gocryptfs': {}, - 'fuse': {}, - 'socat': {}, - }, - }, - 'gocryptfs': { - 'paths': {}, - }, -} - - -@metadata_reactor.provides( - 'gocryptfs', -) -def config(metadata): - return { - 'gocryptfs': { - 'masterkey': hexlify(b64decode( - str(repo.vault.random_bytes_as_base64_for(metadata.get('id'), length=32)) - )).decode(), - 'salt': b64encode( - sha3_256(UUID(metadata.get('id')).bytes).digest() - ).decode(), - }, - } - - -@metadata_reactor.provides( - 'gocryptfs', -) -def paths(metadata): - paths = {} - - for path, options in metadata.get('gocryptfs/paths').items(): - paths[path] = { - 'id': hexlify(sha3_256(path.encode()).digest()[:8]).decode(), - } - - return { - 'gocryptfs': { - 'paths': paths, - }, - } - - - -@metadata_reactor.provides( - 'systemd/services', -) -def systemd(metadata): - services = {} - - for path, options in metadata.get('gocryptfs/paths').items(): - services[f'gocryptfs-{options["id"]}'] = { - 'content': { - 'Unit': { - 'Description': f'gocryptfs@{path} ({options["id"]})', - 'After': { - 'filesystem.target', - 'zfs.target', - }, - }, - 'Service': { - 'RuntimeDirectory': 'gocryptfs', - 'Environment': { - 'MASTERKEY': metadata.get('gocryptfs/masterkey'), - 'SOCKET': f'/var/run/gocryptfs/{options["id"]}', - 'PLAIN': path, - 'CIPHER': options["mountpoint"] - }, - 'ExecStart': [ - '/usr/bin/gocryptfs -fg -plaintextnames -reverse -masterkey $MASTERKEY -ctlsock $SOCKET $PLAIN $CIPHER', - ], - 'ExecStopPost': [ - '/usr/bin/umount $CIPHER' - ], - }, - }, - 'needs': [ - 'pkg_apt:gocryptfs', - 'pkg_apt:fuse', - 'pkg_apt:socat', - 'file:/etc/gocryptfs/masterkey', - 'file:/etc/gocryptfs/gocryptfs.conf', - ], - 'triggers': [ - f'svc_systemd:gocryptfs-{options["id"]}:restart', - ], - } - - return { - 'systemd': { - 'services': services, - }, - } diff --git a/bundles/grafana/README.md b/bundles/grafana/README.md deleted file mode 100644 index 61e9ffc..0000000 --- a/bundles/grafana/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# metadata - -```python -{ - 'hostname': 'example.com', - 'influxdb_node': 'htz.influx', -} -``` - -# links - - -https://github.com/grafana/influxdb-flux-datasource/issues/42 -https://community.grafana.com/t/no-alias-by-when-using-flux/15575/6 diff --git a/bundles/grafana/items.py b/bundles/grafana/items.py deleted file mode 100644 index 3f41725..0000000 --- a/bundles/grafana/items.py +++ /dev/null @@ -1,150 +0,0 @@ -assert node.has_bundle('redis') -assert node.has_bundle('postgresql') - -from mako.template import Template -from shlex import quote -from copy import deepcopy -from itertools import count -import yaml -import json - -svc_systemd['grafana-server'] = { - 'needs': [ - 'pkg_apt:grafana', - ], -} - -admin_password = node.metadata.get('grafana/config/security/admin_password') -port = node.metadata.get('grafana/config/server/http_port') -actions['reset_grafana_admin_password'] = { - 'command': f"grafana-cli admin reset-admin-password {quote(admin_password)}", - 'unless': f"curl http://admin:{quote(admin_password)}@localhost:{port}/api/org", - 'needs': [ - 'svc_systemd:grafana-server', - ], -} - -directories = { - '/etc/grafana': { - }, - '/etc/grafana/provisioning': { - }, - '/etc/grafana/provisioning/datasources': { - 'purge': True, - }, - '/etc/grafana/provisioning/dashboards': { - 'purge': True, - }, - '/var/lib/grafana': {}, - '/var/lib/grafana/dashboards': {}, -} - -files = { - '/etc/grafana/grafana.ini': { - 'content': repo.libs.ini.dumps(node.metadata.get('grafana/config')), - 'triggers': [ - 'svc_systemd:grafana-server:restart', - ], - }, - '/etc/grafana/provisioning/datasources/managed.yaml': { - 'content': yaml.dump({ - 'apiVersion': 1, - 'datasources': list(node.metadata.get('grafana/datasources').values()), - }), - 'triggers': [ - 'svc_systemd:grafana-server:restart', - ], - }, - '/etc/grafana/provisioning/dashboards/managed.yaml': { - 'content': yaml.dump({ - 'apiVersion': 1, - 'providers': [{ - 'name': 'Default', - 'folder': 'Generated', - 'type': 'file', - 'options': { - 'path': '/var/lib/grafana/dashboards', - }, - }], - }), - 'triggers': [ - 'svc_systemd:grafana-server:restart', - ], - }, -} - -# DASHBOARDS - -with open(repo.path.join([f'data/grafana/dashboard.py'])) as file: - dashboard_template = eval(file.read()) -with open(repo.path.join([f'data/grafana/panel.py'])) as file: - panel_template = eval(file.read()) -with open(repo.path.join([f'data/grafana/flux.mako'])) as file: - flux_template = Template(file.read()) - -bucket = repo.get_node(node.metadata.get('grafana/influxdb_node')).metadata.get('influxdb/bucket') - -monitored_nodes = [ - other_node - for other_node in repo.nodes - if other_node.metadata.get('telegraf/influxdb_node', None) == node.metadata.get('grafana/influxdb_node') -] - -for dashboard_id, monitored_node in enumerate(monitored_nodes, start=1): - dashboard = deepcopy(dashboard_template) - dashboard['id'] = dashboard_id - dashboard['title'] = monitored_node.name - dashboard['uid'] = monitored_node.metadata.get('id') - panel_id = count(start=1) - - for row_id, row_name in enumerate(sorted(monitored_node.metadata.get('grafana_rows')), start=1): - with open(repo.path.join([f'data/grafana/rows/{row_name}.py'])) as file: - row = eval(file.read()) - - for panel_in_row, (panel_name, panel_config) in enumerate(row.items()): - panel = deepcopy(panel_template) - panel['id'] = next(panel_id) - panel['title'] = f'{row_name} {panel_name}' - panel['gridPos']['w'] = 24 // len(row) - panel['gridPos']['x'] = (24 // len(row)) * panel_in_row - panel['gridPos']['y'] = (row_id - 1) * panel['gridPos']['h'] - - if 'display_name' in panel_config: - panel['fieldConfig']['defaults']['displayName'] = '${'+panel_config['display_name']+'}' - - if panel_config.get('stacked'): - panel['fieldConfig']['defaults']['custom']['stacking']['mode'] = 'normal' - - if 'unit' in panel_config: - panel['fieldConfig']['defaults']['unit'] = panel_config['unit'] - - if 'min' in panel_config: - panel['fieldConfig']['defaults']['min'] = panel_config['min'] - if 'max' in panel_config: - panel['fieldConfig']['defaults']['max'] = panel_config['max'] - - - for query_name, query_config in panel_config['queries'].items(): - panel['targets'].append({ - 'refId': query_name, - 'query': flux_template.render( - bucket=bucket, - host=monitored_node.name, - negative=query_config.get('negative', False), - filters={ - 'host': monitored_node.name, - **query_config['filters'], - }, - function=query_config.get('function', None), - ).strip() - }) - - dashboard['panels'].append(panel) - - files[f'/var/lib/grafana/dashboards/{monitored_node.name}.json'] = { - 'content': json.dumps(dashboard, indent=4), - 'triggers': [ - 'svc_systemd:grafana-server:restart', - ] - } - diff --git a/bundles/grafana/metadata.py b/bundles/grafana/metadata.py deleted file mode 100644 index 6e3cd28..0000000 --- a/bundles/grafana/metadata.py +++ /dev/null @@ -1,107 +0,0 @@ -from mako.template import Template - -postgres_password = repo.vault.password_for(f'{node.name} postgres role grafana') - -defaults = { - 'apt': { - 'packages': { - 'grafana': {}, - }, - 'sources': [ - 'deb https://packages.grafana.com/oss/deb stable main', - ], - }, - 'grafana': { - 'config': { - 'server': { - 'http_port': 8300, - }, - 'database': { - 'url': f'postgres://grafana:{postgres_password}@localhost:5432/grafana', - }, - 'remote_cache': { - 'type': 'redis', - 'connstr': 'addr=127.0.0.1:6379', - }, - 'security': { - 'admin_user': 'admin', - 'admin_password': str(repo.vault.password_for(f'{node.name} grafana admin')), - }, - 'users': { - 'allow_signup': False, - }, - }, - 'datasources': {}, - }, - 'postgresql': { - 'databases': { - 'grafana': { - 'owner': 'grafana', - }, - }, - 'roles': { - 'grafana': { - 'password': postgres_password, - }, - }, - }, - 'zfs': { - 'datasets': { - 'tank/grafana': { - 'mountpoint': '/var/lib/grafana' - }, - }, - }, -} - - -@metadata_reactor.provides( - 'grafana/datasources', -) -def influxdb2(metadata): - influxdb_metadata = repo.get_node(metadata.get('grafana/influxdb_node')).metadata.get('influxdb') - - return { - 'grafana': { - 'datasources': { - f"influxdb@{influxdb_metadata['hostname']}": { - 'type': 'influxdb', - 'url': f"http://{influxdb_metadata['hostname']}:{influxdb_metadata['port']}", - 'jsonData': { - 'version': 'Flux', - 'organization': influxdb_metadata['org'], - 'defaultBucket': influxdb_metadata['bucket'], - }, - 'secureJsonData': { - 'token': str(influxdb_metadata['readonly_token']), - }, - 'editable': False, - 'isDefault': True, - }, - }, - }, - } - - -@metadata_reactor.provides( - 'grafana/datasources', -) -def datasource_key_to_name(metadata): - return { - 'grafana': { - 'datasources': { - name: {'name': name} for name in metadata.get('grafana/datasources').keys() - }, - }, - } - - -@metadata_reactor.provides( - 'dns', -) -def dns(metadata): - return { - 'dns': { - metadata.get('grafana/hostname'): repo.libs.dns.get_a_records(metadata), - } - } diff --git a/bundles/hetzner-cloud/metadata.py b/bundles/hetzner-cloud/metadata.py deleted file mode 100644 index e73592c..0000000 --- a/bundles/hetzner-cloud/metadata.py +++ /dev/null @@ -1,8 +0,0 @@ -# defaults = { -# 'network': { -# 'external': { -# 'gateway4': '172.31.1.1', -# 'gateway6': 'fe80::1', -# }, -# }, -# } diff --git a/bundles/influxdb2/README.md b/bundles/influxdb2/README.md deleted file mode 100644 index ac2b112..0000000 --- a/bundles/influxdb2/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# setup - -1. apply influxdb to server -2. write `admin`, `readonly` and `writeonly` token into influxdb metadata: - `influx auth list --json | jq -r '.[] | select (.description == "NAME") | .token'` -3. apply clients - -# metadata - -```python -{ - 'hostname': 'example.com', - 'admin_token': 'Wawbd5n...HJS76ez', - 'readonly_token': '5v235b3...6wbnuzz', - 'writeonly_token': '8w4cnos...fn849zg', -} -``` - -# reset password - -Opening /var/lib/influxdb/influxd.bolt with https://github.com/br0xen/boltbrowser might help diff --git a/bundles/influxdb2/items.py b/bundles/influxdb2/items.py deleted file mode 100644 index 525a67c..0000000 --- a/bundles/influxdb2/items.py +++ /dev/null @@ -1,77 +0,0 @@ -from tomlkit import dumps -from shlex import quote - -directories['/var/lib/influxdb'] = { - 'owner': 'influxdb', - 'group': 'influxdb', - 'needs': [ - 'zfs_dataset:tank/influxdb', - ], -} - -directories['/etc/influxdb'] = { - 'purge': True, -} -files['/etc/influxdb/config.toml'] = { - 'content': dumps(node.metadata.get('influxdb/config')), - 'triggers': [ - 'svc_systemd:influxdb:restart', - ] -} - -svc_systemd['influxdb'] = { - 'needs': [ - 'directory:/var/lib/influxdb', - 'file:/etc/influxdb/config.toml', - 'pkg_apt:influxdb2', - ] -} - -actions['wait_for_influxdb_start'] = { - 'command': 'sleep 15', - 'triggered': True, - 'triggered_by': [ - 'svc_systemd:influxdb', - 'svc_systemd:influxdb:restart', - ] -} - -actions['setup_influxdb'] = { - 'command': 'influx setup --username={username} --password={password} --org={org} --bucket={bucket} --token={token} --retention=0 --force'.format( - username=node.metadata.get('influxdb/username'), - password=quote(str(node.metadata.get('influxdb/password'))), - org=node.metadata.get('influxdb/org'), - bucket=node.metadata.get('influxdb/bucket'), - token=str(node.metadata.get('influxdb/admin_token')), - ), - 'unless': 'influx bucket list', - 'needs': [ - 'action:wait_for_influxdb_start', - ], -} - -files['/root/.influxdbv2/configs'] = { - 'content': dumps({ - node.metadata.get('influxdb/bucket'): { - 'url': f"http://localhost:{node.metadata.get('influxdb/port')}", - 'token': str(node.metadata.get('influxdb/admin_token')), - 'org': node.metadata.get('influxdb/org'), - 'active': True, - }, - }), - 'needs': [ - 'action:setup_influxdb', - ], -} - -for description, permissions in { - 'readonly': '--read-buckets', - 'writeonly': '--write-buckets --read-telegrafs', -}.items(): - actions[f'influxdb_{description}_token'] = { - 'command': f'influx auth create --description {description} {permissions}', - 'unless': f'''influx auth list --json | jq -r '.[] | select (.description == "{description}") | .token' | wc -l | grep -q ^1$''', - 'needs': [ - 'file:/root/.influxdbv2/configs', - ], - } diff --git a/bundles/influxdb2/metadata.py b/bundles/influxdb2/metadata.py deleted file mode 100644 index be179e0..0000000 --- a/bundles/influxdb2/metadata.py +++ /dev/null @@ -1,53 +0,0 @@ -from ipaddress import ip_interface - -defaults = { - 'apt': { - 'packages': { - 'influxdb2': {}, - }, - 'sources': [ - 'deb https://repos.influxdata.com/debian {release} stable', - ], - }, - 'influxdb': { - 'port': '8200', - 'username': 'admin', - 'org': 'default', - 'bucket': 'default', - 'config': { - 'bolt-path': '/var/lib/influxdb/influxd.bolt', - 'engine-path': '/var/lib/influxdb/engine', - 'reporting-disabled': True, - 'http-bind-address': ':8200', - }, - }, - 'zfs': { - 'datasets': { - 'tank/influxdb': { - 'mountpoint': '/var/lib/influxdb' - }, - }, - }, -} - -@metadata_reactor.provides( - 'influxdb/password', -) -def admin_password(metadata): - return { - 'influxdb': { - 'password': repo.vault.password_for(f"{metadata.get('id')} influxdb admin"), - 'admin_token': repo.vault.random_bytes_as_base64_for(f"{metadata.get('id')} influxdb default token", length=64), - }, - } - - -@metadata_reactor.provides( - 'dns', -) -def dns(metadata): - return { - 'dns': { - metadata.get('influxdb/hostname'): repo.libs.dns.get_a_records(metadata), - } - } diff --git a/bundles/l4d2/files/l4d2.service b/bundles/l4d2/files/l4d2.service deleted file mode 100644 index 06cc1fd..0000000 --- a/bundles/l4d2/files/l4d2.service +++ /dev/null @@ -1,13 +0,0 @@ -GNU nano 4.8 /etc/systemd/system/l4d2-server-a.service -[Unit] -Description=l4d2 Server A -After=network.target steam-update.service - -[Service] -User=steam -WorkingDirectory=/home/steam/steam/l4d2 -ExecStart=/home/steam/steam/l4d2/srcds_run -port 27001 -secure +exec server_a.cfg -Restart=on-failure - -[Install] -WantedBy=multi-user.target diff --git a/bundles/l4d2/files/update_addons b/bundles/l4d2/files/update_addons deleted file mode 100644 index 6025c5b..0000000 --- a/bundles/l4d2/files/update_addons +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -/home/steam/steam_workshop_downloader/workshop.py -o /home/steam/steam/l4d2/left4dead2/addons 2283884609 -chown -R steam:steam /home/steam/steam/l4d2/left4dead2/addons diff --git a/bundles/l4d2/metadata.py b/bundles/l4d2/metadata.py deleted file mode 100644 index c3b4514..0000000 --- a/bundles/l4d2/metadata.py +++ /dev/null @@ -1,7 +0,0 @@ -@metadata_reactor.provides() -def steam(metadata): - return { - 'steam': { - '222860': 'l4d2', - }, - } diff --git a/bundles/letsencrypt/files/config b/bundles/letsencrypt/files/config deleted file mode 100644 index 2d4b2b6..0000000 --- a/bundles/letsencrypt/files/config +++ /dev/null @@ -1,5 +0,0 @@ -CONFIG_D=/etc/dehydrated/conf.d -BASEDIR=/var/lib/dehydrated -WELLKNOWN="${BASEDIR}/acme-challenges" -DOMAINS_TXT="/etc/dehydrated/domains.txt" -HOOK="/etc/dehydrated/hook.sh" diff --git a/bundles/letsencrypt/files/domains.txt b/bundles/letsencrypt/files/domains.txt deleted file mode 100644 index ea7e427..0000000 --- a/bundles/letsencrypt/files/domains.txt +++ /dev/null @@ -1,3 +0,0 @@ -% for domain, aliases in sorted(node.metadata.get('letsencrypt/domains', {}).items()): -${domain} ${' '.join(sorted(aliases))} -% endfor diff --git a/bundles/letsencrypt/files/hook.sh b/bundles/letsencrypt/files/hook.sh deleted file mode 100644 index 4cdf79d..0000000 --- a/bundles/letsencrypt/files/hook.sh +++ /dev/null @@ -1,37 +0,0 @@ -deploy_cert() {<%text> - local DOMAIN="${1}" KEYFILE="${2}" CERTFILE="${3}" FULLCHAINFILE="${4}" CHAINFILE="${5}" TIMESTAMP="${6}" -% for service, config in node.metadata.get('letsencrypt/concat_and_deploy', {}).items(): - - # concat_and_deploy ${service} - if [ "$DOMAIN" = "${config['match_domain']}" ]; then - cat $KEYFILE > ${config['target']} - cat $FULLCHAINFILE >> ${config['target']} -% if 'chown' in config: - chown ${config['chown']} ${config['target']} -% endif -% if 'chmod' in config: - chmod ${config['chmod']} ${config['target']} -% endif -% if 'commands' in config: -% for command in config['commands']: - ${command} -% endfor -% endif - fi -% endfor -} - - -exit_hook() {<%text> - local ERROR="${1:-}" - -% for service in sorted(node.metadata.get('letsencrypt/reload_after', set())): - systemctl reload-or-restart ${service} -% endfor -} - -<%text> -HANDLER="$1"; shift -if [[ "${HANDLER}" =~ ^(deploy_cert|exit_hook)$ ]]; then - "$HANDLER" "$@" -fi diff --git a/bundles/letsencrypt/files/letsencrypt-ensure-some-certificate b/bundles/letsencrypt/files/letsencrypt-ensure-some-certificate deleted file mode 100644 index e0248cb..0000000 --- a/bundles/letsencrypt/files/letsencrypt-ensure-some-certificate +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/sh - -domain=$1 -just_check=$2 - -cert_path="/var/lib/dehydrated/certs/$domain" - -already_exists=false -if [ -f "$cert_path/privkey.pem" -a -f "$cert_path/fullchain.pem" -a -f "$cert_path/chain.pem" ] -then - already_exists=true -fi - -if [ "$just_check" = true ] -then - if [ "$already_exists" = true ] - then - exit 0 - else - exit 1 - fi -fi - -if [ "$already_exists" != true ] -then - rm -r "$cert_path" - mkdir -p "$cert_path" - openssl req -x509 -newkey rsa:4096 -nodes -days 3650 -subj "/CN=$domain" -keyout "$cert_path/privkey.pem" -out "$cert_path/fullchain.pem" - chmod 0600 "$cert_path/privkey.pem" - cp "$cert_path/fullchain.pem" "$cert_path/chain.pem" -fi diff --git a/bundles/letsencrypt/items.py b/bundles/letsencrypt/items.py deleted file mode 100644 index 9b86c36..0000000 --- a/bundles/letsencrypt/items.py +++ /dev/null @@ -1,50 +0,0 @@ -assert node.has_bundle('nginx') - -directories = { - '/etc/dehydrated/conf.d': {}, - '/var/lib/dehydrated/acme-challenges': {}, -} - -files = { - '/etc/dehydrated/domains.txt': { - 'content_type': 'mako', - 'triggers': { - 'action:letsencrypt_update_certificates', - }, - }, - '/etc/dehydrated/config': { - 'triggers': { - 'action:letsencrypt_update_certificates', - }, - }, - '/etc/dehydrated/hook.sh': { - 'content_type': 'mako', - 'mode': '0755', - }, - '/etc/dehydrated/letsencrypt-ensure-some-certificate': { - 'mode': '0755', - }, -} - -actions['letsencrypt_update_certificates'] = { - 'command': 'dehydrated --cron --accept-terms --challenge http-01', - 'triggered': True, - 'needs': { - 'svc_systemd:nginx', - }, -} - -for domain, _ in node.metadata.get('letsencrypt/domains').items(): - actions['letsencrypt_ensure-some-certificate_{}'.format(domain)] = { - 'command': '/etc/dehydrated/letsencrypt-ensure-some-certificate {}'.format(domain), - 'unless': '/etc/dehydrated/letsencrypt-ensure-some-certificate {} true'.format(domain), - 'needs': { - 'file:/etc/dehydrated/letsencrypt-ensure-some-certificate', - }, - 'needed_by': { - 'svc_systemd:nginx', - }, - 'triggers': { - 'action:letsencrypt_update_certificates', - }, - } diff --git a/bundles/letsencrypt/metadata.py b/bundles/letsencrypt/metadata.py deleted file mode 100644 index d735ccb..0000000 --- a/bundles/letsencrypt/metadata.py +++ /dev/null @@ -1,16 +0,0 @@ -defaults = { - 'apt': { - 'packages': { - 'dehydrated': {}, - }, - }, - 'cron': { - 'letsencrypt_renew': '{} 4 * * * root /usr/bin/dehydrated --cron --accept-terms --challenge http-01 > /dev/null'.format((node.magic_number % 60)), - 'letsencrypt_cleanup': '{} 4 * * 0 root /usr/bin/dehydrated --cleanup > /dev/null'.format((node.magic_number % 60)), - }, - 'pacman': { - 'packages': { - 'dehydrated': {}, - }, - }, -} diff --git a/bundles/mailserver/items.py b/bundles/mailserver/items.py deleted file mode 100644 index 14527b7..0000000 --- a/bundles/mailserver/items.py +++ /dev/null @@ -1,79 +0,0 @@ -assert node.has_bundle('postfix') -assert node.has_bundle('opendkim') -assert node.has_bundle('dovecot') -assert node.has_bundle('letsencrypt') -assert node.has_bundle('roundcube') -assert node.has_bundle('rspamd') -assert node.has_bundle('redis') - -from hashlib import md5 -from shlex import quote - -db_data = node.metadata.get('mailserver/database') -test_password = str(node.metadata.get('mailserver/test_password')) -setup = f""" - CREATE TABLE domains ( - "id" BIGSERIAL PRIMARY KEY, - "name" varchar(255) UNIQUE NOT NULL - ); - CREATE INDEX ON domains ("name"); - - CREATE TABLE users ( - "id" BIGSERIAL PRIMARY KEY, - "name" varchar(255) NOT NULL, - "domain_id" BIGSERIAL REFERENCES domains(id), - "password" varchar(255) NULL, - "redirect" varchar(255) DEFAULT NULL - ); - CREATE UNIQUE INDEX ON users ("name", "domain_id") WHERE "redirect" IS NULL; - - -- OWNERSHIPS - - ALTER TABLE domains OWNER TO {db_data['user']}; - ALTER TABLE users OWNER TO {db_data['user']}; - - -- TEST DATA - - INSERT INTO domains (name) VALUES ('example.com'); - - INSERT INTO users (name, domain_id, password) - SELECT 'bw_test_user', domains.id, MD5('{test_password}') - FROM domains - WHERE domains.name = 'example.com'; - - INSERT INTO users (name, domain_id, redirect) - SELECT 'bw_test_alias', domains.id, 'somewhere@example.com' - FROM domains - WHERE domains.name = 'example.com'; -""" - -actions['initialize_mailserver_db'] = { - 'command': f"psql -d {db_data['name']} -c {quote(setup)}", - 'unless': f"psql -At -d {db_data['name']} -c \"SELECT to_regclass(\'public.users\')\" | grep -q '^users$'", - 'needs': [ - 'postgres_db:mailserver', - ], -} - -# testuser - -test_password_md5 = md5(str(test_password).encode()).hexdigest() -check_query = """ - SELECT password - FROM users - WHERE name = 'bw_test_user' - AND domain_id = (SELECT id FROM domains WHERE name = 'example.com') -""" -update_query = f""" - UPDATE users - SET password = MD5('{test_password}') - WHERE name = 'bw_test_user' - AND domain_id = (SELECT id FROM domains WHERE name = 'example.com') -""" -actions['mailserver_update_test_pw'] = { - 'command': f"psql -d {db_data['name']} -c {quote(update_query)}", - 'unless': f"psql -At -d {db_data['name']} -c {quote(check_query)} | grep -q '^{test_password_md5}$\'", - 'needs': [ - 'action:initialize_mailserver_db', - ], -} diff --git a/bundles/mailserver/metadata.py b/bundles/mailserver/metadata.py deleted file mode 100644 index 99c539b..0000000 --- a/bundles/mailserver/metadata.py +++ /dev/null @@ -1,66 +0,0 @@ -from ipaddress import ip_interface - -database_password = repo.vault.password_for(f'{node.name} db mailserver') - -defaults = { - 'mailserver': { - 'maildir': '/var/vmail', - 'database': { - 'host': '127.0.0.1', # dont use localhost - 'name': 'mailserver', - 'user': 'mailserver', - 'password': database_password, - }, - 'test_password': repo.vault.password_for(f'{node.name} test_pw mailserver'), - 'domains': [], - }, - 'postgresql': { - 'roles': { - 'mailserver': { - 'password': database_password, - }, - }, - 'databases': { - 'mailserver': { - 'owner': 'mailserver', - }, - }, - }, - 'zfs': { - 'datasets': { - 'tank/vmail': { - 'mountpoint': '/var/vmail', - 'compression': 'on', - }, - }, - }, -} - - -@metadata_reactor.provides( - 'dns', -) -def dns(metadata): - dns = {} - - for domain in metadata.get('mailserver/domains'): - dns[domain] = { - 'MX': [f'5 {domain}.'], - 'TXT': ['v=spf1 a mx -all'], - } - - return { - 'dns': dns, - } - -@metadata_reactor.provides( - 'letsencrypt/domains', -) -def letsencrypt(metadata): - return { - 'letsencrypt': { - 'domains': { - metadata.get('mailserver/hostname'): set(), - }, - }, - } diff --git a/bundles/mirror/metadata.py b/bundles/mirror/metadata.py deleted file mode 100644 index 8f444ca..0000000 --- a/bundles/mirror/metadata.py +++ /dev/null @@ -1,17 +0,0 @@ -defaults = { - 'mirror': {}, -} - - -@metadata_reactor.provides( - 'systemd-timers', -) -def timers(metadata): - return { - 'systemd-timers': { - f'mirror-{name}': { - 'command': f"/usr/bin/scp -r -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null '{config['from']}' '{config['to']}'", - 'when': 'hourly', - } for name, config in metadata.get('mirror').items() - } - } diff --git a/bundles/network/metadata.py b/bundles/network/metadata.py deleted file mode 100644 index bd97df3..0000000 --- a/bundles/network/metadata.py +++ /dev/null @@ -1,46 +0,0 @@ -from ipaddress import ip_interface - -defaults = { - 'network': { - } -} - - -@metadata_reactor.provides( - 'systemd-networkd/networks', -) -def systemd_networkd(metadata): - units = {} - - for type, network in metadata.get('network').items(): - units[type] = { - 'Match': { - 'Name': network['interface'], - }, - 'Network': { - 'DHCP': 'no', - 'IPv6AcceptRA': 'no', - } - } - - for i in [4, 6]: - if network.get(f'ipv{i}', None): - units[type].update({ - f'Address#ipv{i}': { - 'Address': network[f'ipv{i}'], - }, - }) - if f'gateway{i}' in network: - units[type].update({ - f'Route#ipv{i}': { - 'Gateway': network[f'gateway{i}'], - 'GatewayOnlink': 'yes', - } - }) - - - return { - 'systemd-networkd': { - 'networks': units, - } - } diff --git a/bundles/nextcloud/README.md b/bundles/nextcloud/README.md deleted file mode 100644 index 4d51f9c..0000000 --- a/bundles/nextcloud/README.md +++ /dev/null @@ -1,38 +0,0 @@ -# downloads[f'/tmp/nextcloud-{version}.tar.bz2'] = { -# 'url': f'https://download.nextcloud.com/server/releases/nextcloud-{version}.tar.bz2', -# 'sha256_url': '{url}.sha256', -# 'triggered': True, -# } -# actions['delete_nextcloud'] = { -# 'command': 'rm -rf /opt/nextcloud/*', -# 'triggered': True, -# } -# actions['extract_nextcloud'] = { -# 'command': f'tar xfvj /tmp/nextcloud-{version}.tar.bz2 --strip 1 -C /opt/nextcloud nextcloud', -# 'unless': f"""php -r 'include "/opt/nextcloud/version.php"; echo "$OC_VersionString";' | grep -q '^{version}$'""", -# 'preceded_by': [ -# 'action:delete_nextcloud', -# f'download:/tmp/nextcloud-{version}.tar.bz2', -# ], -# 'needs': [ -# 'directory:/opt/nextcloud', -# ], -# } - - -# git_deploy = { -# '/opt/nextcloud': { -# 'repo': 'git://github.com/nextcloud/server.git', -# 'rev': f"v{node.metadata.get('nextcloud/version')}", -# 'needs': { -# 'directory:/opt/nextcloud', -# }, -# }, -# '/opt/nextcloud/3rdparty': { -# 'repo': 'git://github.com/nextcloud/3rdparty.git', -# 'rev': f"v{node.metadata.get('nextcloud/version')}", -# 'needs': { -# 'git_deploy:/opt/nextcloud', -# }, -# }, -# } diff --git a/bundles/nextcloud/files/managed.config.php b/bundles/nextcloud/files/managed.config.php deleted file mode 100644 index e186d1b..0000000 --- a/bundles/nextcloud/files/managed.config.php +++ /dev/null @@ -1,24 +0,0 @@ - "nextcloud", - "dbpassword" => "${db_password}", - "dbname" => "nextcloud", - "dbhost" => "localhost", - "dbtype" => "pgsql", - "datadirectory" => "/var/lib/nextcloud", - "dbport" => "5432", - "apps_paths" => [ - [ - "path" => "/opt/nextcloud/apps", - "url" => "/apps", - "writable" => false, - ], - [ - "path" => "/var/lib/nextcloud/.userapps", - "url" => "/userapps", - "writable" => true, - ], - ], - "cache_path" => "/var/lib/nextcloud/.cache", -); diff --git a/bundles/nextcloud/items.py b/bundles/nextcloud/items.py deleted file mode 100644 index 38fcb0c..0000000 --- a/bundles/nextcloud/items.py +++ /dev/null @@ -1,144 +0,0 @@ -assert node.has_bundle('php') - -from shlex import quote -from os.path import join -from mako.template import Template - -version = node.metadata.get('nextcloud/version') - -directories = { - '/opt/nextcloud': {}, - '/etc/nextcloud': { - 'owner': 'www-data', - 'group': 'www-data', - }, - '/var/lib/nextcloud': { - 'owner': 'www-data', - 'group': 'www-data', - 'mode': '770', - }, - '/var/lib/nextcloud/.userapps': { - 'owner': 'www-data', - 'group': 'www-data', - }, - '/var/lib/nextcloud/.cache': { - 'owner': 'www-data', - 'group': 'www-data', - }, -} - -downloads[f'/tmp/nextcloud-{version}.tar.bz2'] = { - 'url': f'https://download.nextcloud.com/server/releases/nextcloud-{version}.tar.bz2', - 'sha256_url': '{url}.sha256', - 'triggered': True, -} -actions['delete_nextcloud'] = { - 'command': 'rm -rf /opt/nextcloud/*', - 'triggered': True, -} -actions['extract_nextcloud'] = { - 'command': f'tar xfvj /tmp/nextcloud-{version}.tar.bz2 --strip 1 -C /opt/nextcloud nextcloud', - 'unless': f"""php -r 'include "/opt/nextcloud/version.php"; echo "$OC_VersionString";' | grep -q '^{version}$'""", - 'preceded_by': [ - 'action:delete_nextcloud', - f'download:/tmp/nextcloud-{version}.tar.bz2', - ], - 'needs': [ - 'directory:/opt/nextcloud', - ], -} - -symlinks = { - '/opt/nextcloud/config': { - 'target': '/etc/nextcloud', - 'owner': 'www-data', - 'group': 'www-data', - 'needs': [ - 'action:extract_nextcloud', - ], - }, - '/opt/nextcloud/userapps': { - 'target': '/var/lib/nextcloud/.userapps', - 'owner': 'www-data', - 'group': 'www-data', - 'needs': [ - 'action:extract_nextcloud', - ], - }, -} - -files = { - '/etc/nextcloud/CAN_INSTALL': { - 'content': '', - 'owner': 'www-data', - 'group': 'www-data', - 'mode': '640', - 'needs': [ - 'directory:/etc/nextcloud', - ], - }, - '/etc/nextcloud/managed.config.php': { - 'content_type': 'mako', - 'owner': 'www-data', - 'group': 'www-data', - 'mode': '640', - 'context': { - 'db_password': node.metadata.get('postgresql/roles/nextcloud/password'), - }, - 'needs': [ - 'directory:/etc/nextcloud', - ], - }, -} - -# SETUP - -actions['install_nextcloud'] = { - 'command': repo.libs.nextcloud.occ( - 'maintenance:install', - no_interaction=None, - database='pgsql', - database_name='nextcloud', - database_host='localhost', - database_user='nextcloud', - database_pass=node.metadata.get('postgresql/roles/nextcloud/password'), - admin_user='admin', - admin_pass=node.metadata.get('nextcloud/admin_pass'), - data_dir='/var/lib/nextcloud', - ), - 'unless': repo.libs.nextcloud.occ('status') + ' | grep -q "installed: true"', - 'needs': [ - 'directory:/etc/nextcloud', - 'directory:/opt/nextcloud', - 'directory:/var/lib/nextcloud', - 'directory:/var/lib/nextcloud/.userapps', - 'directory:/var/lib/nextcloud/.cache', - 'symlink:/opt/nextcloud/config', - 'symlink:/opt/nextcloud/userapps', - 'action:extract_nextcloud', - 'file:/etc/nextcloud/CAN_INSTALL', - 'file:/etc/nextcloud/managed.config.php', - 'postgres_db:nextcloud', - ], -} - -# UPGRADE - -actions['upgrade_nextcloud'] = { - 'command': repo.libs.nextcloud.occ('upgrade'), - 'unless': "! " + repo.libs.nextcloud.occ('status') + ' | grep -q "Nextcloud or one of the apps require upgrade"', - 'needs': [ - 'action:install_nextcloud', - ], -} - -actions['nextcloud_add_missing_inidces'] = { - 'command': repo.libs.nextcloud.occ('db:add-missing-indices'), - 'needs': [ - 'action:upgrade_nextcloud', - ], - 'triggered': True, - 'triggered_by': [ - f'action:extract_nextcloud', - ], -} diff --git a/bundles/nextcloud/metadata.py b/bundles/nextcloud/metadata.py deleted file mode 100644 index d4bfe11..0000000 --- a/bundles/nextcloud/metadata.py +++ /dev/null @@ -1,83 +0,0 @@ -import string -from uuid import UUID - -defaults = { - 'apt': { - 'packages': { - 'php': {}, - 'php-curl': {}, - 'php-gd': {}, - 'php-json': {}, - 'php-xml': {}, - 'php-mbstring': {}, - 'php-cli': {}, - 'php-cgi': {}, - 'php-zip': {}, - 'php-pgsql': {}, - }, - }, - 'archive': { - 'paths': { - '/var/lib/nextcloud': { - 'exclude': [ - '^appdata_', - '^updater-', - '^nextcloud\.log', - '^updater\.log', - '^[^/]+/cache', - '^[^/]+/files_versions', - '^[^/]+/files_trashbin', - ], - }, - }, - }, - 'backup': { - 'paths': [ - '/etc/nextcloud/config.php', - ], - }, - 'nextcloud': { - 'admin_user': 'admin', - 'admin_pass': repo.vault.password_for(f'{node.name} nextcloud admin pw'), - }, - 'postgresql': { - 'roles': { - 'nextcloud': { - 'password': repo.vault.password_for(f'{node.name} nextcloud db pw'), - }, - }, - 'databases': { - 'nextcloud': { - 'owner': 'nextcloud', - }, - }, - }, - 'zfs': { - 'datasets': { - 'tank/nextcloud': { - 'mountpoint': '/var/lib/nextcloud', - 'needed_by': [ - 'bundle:nextcloud', - ], - }, - }, - }, -} - - -@metadata_reactor.provides( - 'nginx/vhosts' -) -def vhost(metadata): - return { - 'nginx': { - 'vhosts': { - metadata.get('nextcloud/hostname'): { - 'root': '/opt/nextcloud', - 'include': [ - 'php.conf', - ], - }, - }, - }, - } diff --git a/bundles/nginx/files/fastcgi.conf b/bundles/nginx/files/fastcgi.conf deleted file mode 100644 index bd151a6..0000000 --- a/bundles/nginx/files/fastcgi.conf +++ /dev/null @@ -1,27 +0,0 @@ -fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; -fastcgi_param QUERY_STRING $query_string; -fastcgi_param REQUEST_METHOD $request_method; -fastcgi_param CONTENT_TYPE $content_type; -fastcgi_param CONTENT_LENGTH $content_length; - -fastcgi_param SCRIPT_NAME $fastcgi_script_name; -fastcgi_param REQUEST_URI $request_uri; -fastcgi_param DOCUMENT_URI $document_uri; -fastcgi_param DOCUMENT_ROOT $document_root; -fastcgi_param SERVER_PROTOCOL $server_protocol; -fastcgi_param REQUEST_SCHEME $scheme; -fastcgi_param HTTPS $https if_not_empty; - -fastcgi_param GATEWAY_INTERFACE CGI/1.1; -fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; - -fastcgi_param REMOTE_ADDR $remote_addr; -fastcgi_param REMOTE_PORT $remote_port; -fastcgi_param SERVER_ADDR $server_addr; -fastcgi_param SERVER_PORT $server_port; -fastcgi_param SERVER_NAME $server_name; - -fastcgi_param REDIRECT_STATUS 200; - -# This is the only thing that's different to the debian default. -fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; diff --git a/bundles/nginx/items.py b/bundles/nginx/items.py deleted file mode 100644 index b8cc63c..0000000 --- a/bundles/nginx/items.py +++ /dev/null @@ -1,88 +0,0 @@ -from datetime import datetime, timedelta - -directories = { - '/etc/nginx/sites': { - 'purge': True, - 'triggers': { - 'svc_systemd:nginx:restart', - }, - }, - '/etc/nginx/ssl': { - 'purge': True, - 'triggers': { - 'svc_systemd:nginx:restart', - }, - }, - '/var/www': {}, -} - -files = { - '/etc/nginx/nginx.conf': { - 'content': repo.libs.nginx.render_config(node.metadata.get('nginx/config')), - 'triggers': { - 'svc_systemd:nginx:restart', - }, - }, - '/etc/nginx/fastcgi.conf': { - 'triggers': { - 'svc_systemd:nginx:restart', - }, - }, - '/etc/nginx/sites-available': { - 'delete': True, - }, - '/etc/nginx/sites-enabled': { - 'delete': True, - }, -} - -actions = { - 'nginx-generate-dhparam': { - 'command': 'openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048', - 'unless': 'test -f /etc/ssl/certs/dhparam.pem', - }, -} - -svc_systemd = { - 'nginx': { - 'needs': { - 'action:nginx-generate-dhparam', - 'pkg_apt:nginx', - }, - }, -} - -for name, config in node.metadata.get('nginx/includes').items(): - files[f'/etc/nginx/{name}.conf'] = { - 'content': repo.libs.nginx.render_config(config), - 'needed_by': { - 'svc_systemd:nginx', - 'svc_systemd:nginx:restart', - }, - 'triggers': { - 'svc_systemd:nginx:restart', - }, - } - -for name, config in { - **node.metadata.get('nginx/default_vhosts'), - **node.metadata.get('nginx/vhosts'), -}.items(): - files[f'/etc/nginx/sites/{name}'] = { - 'content': repo.libs.nginx.render_config({ - 'server': config, - }), - 'needs': [], - 'needed_by': { - 'svc_systemd:nginx', - 'svc_systemd:nginx:restart', - }, - 'triggers': { - 'svc_systemd:nginx:restart', - }, - } - - if name in node.metadata.get('letsencrypt/domains'): - files[f'/etc/nginx/sites/{name}']['needs'].append( - f'action:letsencrypt_ensure-some-certificate_{name}', - ) diff --git a/bundles/nginx/metadata.py b/bundles/nginx/metadata.py deleted file mode 100644 index 3f1030c..0000000 --- a/bundles/nginx/metadata.py +++ /dev/null @@ -1,126 +0,0 @@ -from ipaddress import ip_interface - -defaults = { - 'apt': { - 'packages': { - 'nginx': {}, - }, - }, - 'nginx': { - 'config': { - 'user': 'www-data', - 'worker_processes': 10, - 'pid': '/var/run/nginx.pid', - 'events': { - 'worker_connections': 768, - }, - 'http': { - 'include': [ - '/etc/nginx/mime.types', - '/etc/nginx/sites/*', - ], - 'default_type': 'application/octet-stream', - 'sendfile': 'on', - 'tcp_nopush': 'on', - 'server_names_hash_bucket_size': 128, - 'access_log': '/var/log/nginx/access.log', - 'error_log': '/var/log/nginx/error.log', - }, - }, - 'default_vhosts': { - '80': { - 'listen': [ - '80', - '[::]:80', - ], - 'location /.well-known/acme-challenge/': { - 'alias': '/var/lib/dehydrated/acme-challenges/', - }, - 'location /': { - 'return': '301 https://$host$request_uri', - }, - }, - 'stub_status': { - 'listen': '127.0.0.1:22999 default_server', - 'server_name': '_', - 'stub_status': '', - }, - }, - 'vhosts': {}, - 'includes': {}, - }, -} - -@metadata_reactor.provides( - 'nginx/includes/php', -) -def php(metadata): - return { - 'nginx': { - 'includes': { - 'php': { - 'location ~ \.php$': { - 'include': 'fastcgi.conf', - 'fastcgi_split_path_info': '^(.+\.php)(/.+)$', - 'fastcgi_pass': f"unix:/run/php/php{metadata.get('php/version')}-fpm.sock", - }, - }, - }, - }, - } - - -@metadata_reactor.provides( - 'nginx/vhosts', -) -def vhosts(metadata): - vhosts = {} - - for name, config in metadata.get('nginx/vhosts').items(): - vhosts[name] = { - 'server_name': name, - 'listen': [ - '443 ssl http2', - '[::]:443 ssl http2', - ], - 'ssl_certificate': f'/var/lib/dehydrated/certs/{name}/fullchain.pem', - 'ssl_certificate_key': f'/var/lib/dehydrated/certs/{name}/privkey.pem', - 'location /.well-known/acme-challenge/': { - 'alias': '/var/lib/dehydrated/acme-challenges/', - }, - } - - return { - 'nginx': { - 'vhosts': vhosts, - } - } - - -@metadata_reactor.provides( - 'dns', -) -def dns(metadata): - return { - 'dns': { - domain: repo.libs.dns.get_a_records(metadata) - for domain in metadata.get('nginx/vhosts') - }, - } - - -@metadata_reactor.provides( - 'letsencrypt/domains', - 'letsencrypt/reload_after', -) -def letsencrypt(metadata): - return { - 'letsencrypt': { - 'domains': { - domain: {} for domain in metadata.get('nginx/vhosts') - }, - 'reload_after': { - 'nginx', - }, - }, - } diff --git a/bundles/opendkim/files/key_table b/bundles/opendkim/files/key_table deleted file mode 100644 index d669afe..0000000 --- a/bundles/opendkim/files/key_table +++ /dev/null @@ -1,3 +0,0 @@ -% for domain in domains: -mail._domainkey.${domain} ${domain}:mail:/etc/opendkim/keys/${domain}/mail.private -% endfor diff --git a/bundles/opendkim/files/opendkim.conf b/bundles/opendkim/files/opendkim.conf deleted file mode 100644 index 6f2ef79..0000000 --- a/bundles/opendkim/files/opendkim.conf +++ /dev/null @@ -1,15 +0,0 @@ -Mode sv -SignatureAlgorithm rsa-sha256 -Canonicalization relaxed/simple -KeyTable refile:/etc/opendkim/key_table -SigningTable refile:/etc/opendkim/signing_table - -UMask 007 -UserID opendkim:opendkim -PidFile /run/opendkim/opendkim.pid -Socket inet:8891@localhost - -Syslog yes -SyslogSuccess Yes -SyslogFacility mail -LogWhy Yes diff --git a/bundles/opendkim/files/signing_table b/bundles/opendkim/files/signing_table deleted file mode 100644 index 90bf076..0000000 --- a/bundles/opendkim/files/signing_table +++ /dev/null @@ -1,3 +0,0 @@ -% for domain in domains: -*@${domain} mail._domainkey.${domain} -% endfor diff --git a/bundles/opendkim/items.py b/bundles/opendkim/items.py deleted file mode 100644 index 5d10151..0000000 --- a/bundles/opendkim/items.py +++ /dev/null @@ -1,86 +0,0 @@ -file_attributes = { - 'owner': 'opendkim', - 'group': 'opendkim', - 'mode': '700', - 'triggers': [ - 'svc_systemd:opendkim:restart', - ], -} - -groups['opendkim'] = {} -users['opendkim'] = {} - -directories = { - '/etc/opendkim': { - **file_attributes, - 'purge' : True, - }, - '/etc/opendkim/keys': { - **file_attributes, - 'purge' : True, - }, -} - -files = { - '/etc/opendkim.conf': { - **file_attributes, - }, - '/etc/defaults/opendkim': { - # https://metadata.ftp-master.debian.org/changelogs//main/o/opendkim/testing_opendkim.NEWS - 'delete': True, - }, - '/etc/opendkim/key_table': { - 'content_type': 'mako', - 'context': { - 'domains': node.metadata.get('mailserver/domains'), - }, - **file_attributes, - }, - '/etc/opendkim/signing_table': { - 'content_type': 'mako', - 'context': { - 'domains': node.metadata.get('mailserver/domains'), - }, - **file_attributes, - }, -} - -for domain in node.metadata.get('mailserver/domains'): - directories[f'/etc/opendkim/keys/{domain}'] = { - **file_attributes, - 'purge': True, - } - files[f'/etc/opendkim/keys/{domain}/mail.private'] = { - **file_attributes, - 'content': node.metadata.get(f'opendkim/keys/{domain}/private'), - } - # files[f'/etc/opendkim/keys/{domain}/mail.txt'] = { - # **file_attributes, - # 'content_type': 'any', - # } - # actions[f'generate_{domain}_dkim_key'] = { - # 'command': ( - # f'sudo --user opendkim' - # f' opendkim-genkey' - # f' --selector=mail' - # f' --directory=/etc/opendkim/keys/{domain}' - # f' --domain={domain}' - # ), - # 'unless': f'test -f /etc/opendkim/keys/{domain}/mail.private', - # 'needs': [ - # 'svc_systemd:opendkim', - # f'directory:/etc/opendkim/keys/{domain}', - # ], - # 'triggers': [ - # 'svc_systemd:opendkim:restart', - # ], - # } - -svc_systemd['opendkim'] = { - 'needs': [ - 'pkg_apt:opendkim', - 'file:/etc/opendkim.conf', - 'file:/etc/opendkim/key_table', - 'file:/etc/opendkim/signing_table', - ], -} diff --git a/bundles/opendkim/metadata.py b/bundles/opendkim/metadata.py deleted file mode 100644 index 2f4bb9e..0000000 --- a/bundles/opendkim/metadata.py +++ /dev/null @@ -1,93 +0,0 @@ -from os.path import join, exists -from re import sub -from cryptography.hazmat.primitives import serialization as crypto_serialization -from cryptography.hazmat.primitives.asymmetric import rsa -from cryptography.hazmat.backends import default_backend as crypto_default_backend - - -defaults = { - 'apt': { - 'packages': { - 'opendkim': {}, - 'opendkim-tools': {}, - }, - }, - 'opendkim': { - 'keys': {}, - }, - 'dns': { - 'mail._domainkey.mail2.sublimity.de': { - 'TXT': [ - - ] - } - } -} - - -@metadata_reactor.provides( - 'opendkim/keys', -) -def keys(metadata): - keys = {} - - for domain in metadata.get('mailserver/domains'): - if domain in metadata.get(f'opendkim/keys'): - continue - - pubkey_path = join(repo.path, 'data', 'dkim', f'{domain}.pubkey') - privkey_path = join(repo.path, 'data', 'dkim', f'{domain}.privkey.enc') - - if not exists(pubkey_path) or not exists(privkey_path): - key = rsa.generate_private_key( - backend=crypto_default_backend(), - public_exponent=65537, - key_size=2048 - ) - with open(pubkey_path, 'w') as file: - file.write( - key.public_key().public_bytes( - crypto_serialization.Encoding.OpenSSH, - crypto_serialization.PublicFormat.OpenSSH - ).decode() - ) - with open(privkey_path, 'w') as file: - file.write( - repo.vault.encrypt( - key.private_bytes( - crypto_serialization.Encoding.PEM, - crypto_serialization.PrivateFormat.PKCS8, - crypto_serialization.NoEncryption() - ).decode(), - ) - ) - - with open(pubkey_path, 'r') as pubkey: - with open(privkey_path, 'r') as privkey: - keys[domain] = { - 'public': pubkey.read(), - 'private': repo.vault.decrypt(privkey.read()), - } - - return { - 'opendkim': { - 'keys': keys, - } - } - - -@metadata_reactor.provides( - 'dns', -) -def dns(metadata): - dns = {} - - for domain, keys in metadata.get('opendkim/keys').items(): - raw_key = sub('^ssh-rsa ', '', keys['public']) - dns[f'mail._domainkey.{domain}'] = { - 'TXT': [f'v=DKIM1; k=rsa; p={raw_key}'], - } - - return { - 'dns': dns, - } diff --git a/bundles/php/files/php.ini b/bundles/php/files/php.ini deleted file mode 100644 index d06e97f..0000000 --- a/bundles/php/files/php.ini +++ /dev/null @@ -1,102 +0,0 @@ -[PHP] -; Only needed for libapache2-mod-php? -engine = On -short_open_tag = Off -precision = 14 -output_buffering = 4096 -zlib.output_compression = Off -implicit_flush = Off -serialize_precision = -1 -disable_functions = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals -ignore_user_abort = Off -zend.enable_gc = On -expose_php = Off - -max_execution_time = 30 -max_input_time = 60 -memory_limit = 256M - -error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT -display_startup_errors = Off -log_errors = On -log_errors_max_len = 1024 -ignore_repeated_errors = Off -ignore_repeated_source = Off -report_memleaks = On -html_errors = On -error_log = syslog -syslog.ident = php7.4 -syslog.filter = ascii - -arg_separator.output = "&" -variables_order = "GPCS" -request_order = "GP" -register_argc_argv = Off -auto_globals_jit = On -post_max_size = ${post_max_size}M -default_mimetype = "text/html" -default_charset = "UTF-8" - -enable_dl = Off -file_uploads = On -upload_max_filesize = ${post_max_size}M -max_file_uploads = 20 - -allow_url_fopen = On -allow_url_include = Off -default_socket_timeout = 10 - -[CLI Server] -cli_server.color = On - -[mail function] -mail.add_x_header = Off - -[ODBC] -odbc.allow_persistent = On -odbc.check_persistent = On -odbc.max_persistent = -1 -odbc.max_links = -1 -odbc.defaultlrl = 4096 -odbc.defaultbinmode = 1 - -[PostgreSQL] -pgsql.allow_persistent = On -pgsql.auto_reset_persistent = Off -pgsql.max_persistent = -1 -pgsql.max_links = -1 -pgsql.ignore_notice = 0 -pgsql.log_notice = 0 - -[bcmath] -bcmath.scale = 0 - -[Session] -session.save_handler = files -session.use_strict_mode = 0 -session.use_cookies = 1 -session.use_only_cookies = 1 -session.name = PHPSESSID -session.auto_start = 0 -session.cookie_lifetime = 0 -session.cookie_path = / -session.cookie_domain = -session.cookie_httponly = -session.cookie_samesite = -session.serialize_handler = php -session.gc_probability = 1 -session.gc_divisor = 1000 -session.gc_maxlifetime = 1440 -session.referer_check = -session.cache_limiter = nocache -session.cache_expire = 180 -session.use_trans_sid = 0 -session.sid_length = 32 -session.trans_sid_tags = "a=href,area=href,frame=src,form=" -session.sid_bits_per_character = 6 - -[Assertion] -zend.assertions = -1 - -[Date] -date.timezone = Europe/London diff --git a/bundles/php/items.py b/bundles/php/items.py deleted file mode 100644 index 9d36098..0000000 --- a/bundles/php/items.py +++ /dev/null @@ -1,37 +0,0 @@ -version = node.metadata.get('php/version') - -php_ini_context = { - 'num_cpus': node.metadata.get('vm/cores'), - 'post_max_size': node.metadata.get('php/post_max_size', 10), -} - -files = { - f'/etc/php/{version}/fpm/php.ini': { - 'content_type': 'mako', - 'context': php_ini_context, - 'needs': { - # "all php packages" - 'pkg_apt:' - }, - 'triggers': { - f'svc_systemd:php{version}-fpm:restart', - }, - }, - f'/etc/php/{version}/cli/php.ini': { - 'content_type': 'mako', - 'context': php_ini_context, - 'needs': { - # "all php packages" - 'pkg_apt:' - }, - }, -} - -svc_systemd = { - f'php{version}-fpm': { - 'needs': { - 'pkg_apt:', - f'file:/etc/php/{version}/fpm/php.ini', - }, - }, -} diff --git a/bundles/php/metadata.py b/bundles/php/metadata.py deleted file mode 100644 index f658c87..0000000 --- a/bundles/php/metadata.py +++ /dev/null @@ -1,7 +0,0 @@ -defaults = { - 'apt': { - 'packages': { - 'php': {}, - }, - }, -} diff --git a/bundles/postfix/files/main.cf b/bundles/postfix/files/main.cf deleted file mode 100644 index fb307a0..0000000 --- a/bundles/postfix/files/main.cf +++ /dev/null @@ -1,53 +0,0 @@ -smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU) -biff = no -append_dot_mydomain = no -readme_directory = no -compatibility_level = 2 -smtpd_use_tls=yes -<%text> -smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache -smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache - -smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination -myhostname = debian-2gb-nbg1-1 -alias_maps = hash:/etc/aliases -alias_database = hash:/etc/aliases -myorigin = /etc/mailname -mydestination = $myhostname, debian-2gb-nbg1-1, localhost.localdomain, localhost -relayhost = -mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 -mailbox_size_limit = 0 -recipient_delimiter = + -inet_interfaces = all -inet_protocols = all - -virtual_mailbox_domains = pgsql:/etc/postfix/virtual_mailbox_domains.cf -virtual_mailbox_maps = pgsql:/etc/postfix/virtual_mailbox_maps.cf -virtual_alias_maps = pgsql:/etc/postfix/virtual_alias_maps.cf,pgsql:/etc/postfix/virtual_mailbox_maps.cf -smtpd_sender_login_maps = pgsql:/etc/postfix/virtual_alias_maps.cf -virtual_transport = lmtp:unix:private/dovecot-lmtp - -smtpd_sasl_type = dovecot -smtpd_sasl_path = private/auth -smtpd_sasl_auth_enable = yes - -smtpd_tls_security_level = may -smtpd_tls_auth_only = yes -smtpd_tls_cert_file = /var/lib/dehydrated/certs/${node.metadata.get('mailserver/hostname')}/fullchain.pem -smtpd_tls_key_file = /var/lib/dehydrated/certs/${node.metadata.get('mailserver/hostname')}/privkey.pem -smtp_tls_security_level = may - -smtpd_restriction_classes = mua_sender_restrictions, mua_client_restrictions, mua_helo_restrictions -mua_client_restrictions = permit_sasl_authenticated, reject -mua_sender_restrictions = permit_sasl_authenticated, reject -mua_helo_restrictions = permit_mynetworks, reject_non_fqdn_hostname, reject_invalid_hostname, permit - -smtpd_milters = inet:localhost:8891 inet:127.0.0.1:11332 -non_smtpd_milters = inet:localhost:8891 inet:127.0.0.1:11332 - -# opendkim -milter_protocol = 6 -milter_default_action = accept - -# rspamd -milter_mail_macros = "i {mail_addr} {client_addr} {client_name} {auth_authen}" diff --git a/bundles/postfix/files/master.cf b/bundles/postfix/files/master.cf deleted file mode 100644 index f9d8b21..0000000 --- a/bundles/postfix/files/master.cf +++ /dev/null @@ -1,55 +0,0 @@ -# ========================================================================== -# service type private unpriv chroot wakeup maxproc command + args -# (yes) (yes) (no) (never) (100) -# ========================================================================== -smtp inet n - y - - smtpd -pickup unix n - y 60 1 pickup -cleanup unix n - y - 0 cleanup -qmgr unix n - n 300 1 qmgr -tlsmgr unix - - y 1000? 1 tlsmgr -rewrite unix - - y - - trivial-rewrite -bounce unix - - y - 0 bounce -defer unix - - y - 0 bounce -trace unix - - y - 0 bounce -verify unix - - y - 1 verify -flush unix n - y 1000? 0 flush -proxymap unix - - n - - proxymap -proxywrite unix - - n - 1 proxymap -smtp unix - - y - - smtp -relay unix - - y - - smtp - -o syslog_name=postfix/$service_name -showq unix n - y - - showq -error unix - - y - - error -retry unix - - y - - error -discard unix - - y - - discard -local unix - n n - - local -virtual unix - n n - - virtual -lmtp unix - - y - - lmtp -anvil unix - - y - 1 anvil -scache unix - - y - 1 scache -postlog unix-dgram n - n - 1 postlogd -maildrop unix - n n - - pipe - flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient} -uucp unix - n n - - pipe - flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient) -ifmail unix - n n - - pipe - flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient) -bsmtp unix - n n - - pipe - flags=Fq. user=bsmtp argv=/usr/lib/bsmtp/bsmtp -t$nexthop -f$sender $recipient -scalemail-backend unix - n n - 2 pipe - flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store ${nexthop} ${user} ${extension} -mailman unix - n n - - pipe - flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py - ${nexthop} ${user} -submission inet n - y - - smtpd - -o syslog_name=postfix/submission - -o smtpd_tls_security_level=encrypt - -o smtpd_sasl_auth_enable=yes - -o smtpd_tls_auth_only=yes - -o smtpd_reject_unlisted_recipient=no - -o smtpd_client_restrictions=$mua_client_restrictions - -o smtpd_helo_restrictions=$mua_helo_restrictions - -o smtpd_sender_restrictions=$mua_sender_restrictions - -o smtpd_recipient_restrictions= - -o smtpd_relay_restrictions=permit_sasl_authenticated,reject - -o milter_macro_daemon_name=ORIGINATING diff --git a/bundles/postfix/files/virtual_alias_maps.cf b/bundles/postfix/files/virtual_alias_maps.cf deleted file mode 100644 index fe427cd..0000000 --- a/bundles/postfix/files/virtual_alias_maps.cf +++ /dev/null @@ -1,5 +0,0 @@ -hosts = ${host} -dbname = ${name} -user = ${user} -password = ${password} -query = SELECT redirect FROM users LEFT JOIN domains ON users.domain_id = domains.id WHERE redirect IS NOT NULL AND users.name = '%u' AND domains.name = '%d' diff --git a/bundles/postfix/files/virtual_mailbox_domains.cf b/bundles/postfix/files/virtual_mailbox_domains.cf deleted file mode 100644 index 3741a2b..0000000 --- a/bundles/postfix/files/virtual_mailbox_domains.cf +++ /dev/null @@ -1,5 +0,0 @@ -hosts = ${host} -dbname = ${name} -user = ${user} -password = ${password} -query = SELECT name FROM domains WHERE name='%s' diff --git a/bundles/postfix/files/virtual_mailbox_maps.cf b/bundles/postfix/files/virtual_mailbox_maps.cf deleted file mode 100644 index 32c21eb..0000000 --- a/bundles/postfix/files/virtual_mailbox_maps.cf +++ /dev/null @@ -1,5 +0,0 @@ -hosts = ${host} -dbname = ${name} -user = ${user} -password = ${password} -query = SELECT CONCAT(users.name, '@', domains.name) AS email FROM users LEFT JOIN domains ON users.domain_id = domains.id WHERE redirect IS NULL AND users.name = '%u' AND domains.name = '%d' diff --git a/bundles/postfix/items.py b/bundles/postfix/items.py deleted file mode 100644 index 723bb37..0000000 --- a/bundles/postfix/items.py +++ /dev/null @@ -1,73 +0,0 @@ -assert node.has_bundle('mailserver') - -file_options = { - 'triggers': [ - 'svc_systemd:postfix:restart', - ], - 'needed_by': [ - 'svc_systemd:postfix', - ], -} - -files = { - '/etc/postfix/main.cf': { - 'content_type': 'mako', - **file_options, - }, - '/etc/postfix/master.cf': { - **file_options, - }, - '/etc/postfix/virtual_mailbox_domains.cf': { - 'content_type': 'mako', - 'context': node.metadata.get('mailserver/database'), - **file_options, - }, - '/etc/postfix/virtual_mailbox_maps.cf': { - 'content_type': 'mako', - 'context': node.metadata.get('mailserver/database'), - **file_options, - }, - '/etc/postfix/virtual_alias_maps.cf': { - 'content_type': 'mako', - 'context': node.metadata.get('mailserver/database'), - **file_options, - }, -} - -svc_systemd['postfix'] = { - 'needs': [ - 'postgres_db:mailserver', - ], -} - -actions['test_postfix_config'] = { - 'command': 'false', - 'unless': "postconf check | grep -v 'symlink leaves directory' | wc -l | grep -q '^0$'", - 'needs': [ - 'svc_systemd:postfix', - ], -} -actions['test_virtual_mailbox_domains'] = { - 'command': 'false', - 'unless': "postmap -q example.com pgsql:/etc/postfix/virtual_mailbox_domains.cf | grep -q '^example.com$'", - 'needs': [ - 'svc_systemd:postfix', - 'action:mailserver_update_test_pw', - ], -} -actions['test_virtual_mailbox_maps'] = { - 'command': 'false', - 'unless': "postmap -q bw_test_user@example.com pgsql:/etc/postfix/virtual_mailbox_maps.cf | grep -q '^bw_test_user@example.com$'", - 'needs': [ - 'svc_systemd:postfix', - 'action:mailserver_update_test_pw', - ], -} -actions['test_virtual_alias_maps'] = { - 'command': 'false', - 'unless': "postmap -q bw_test_alias@example.com pgsql:/etc/postfix/virtual_alias_maps.cf | grep -q '^somewhere@example.com$'", - 'needs': [ - 'svc_systemd:postfix', - 'action:mailserver_update_test_pw', - ], -} diff --git a/bundles/postfix/metadata.py b/bundles/postfix/metadata.py deleted file mode 100644 index 5f3e8df..0000000 --- a/bundles/postfix/metadata.py +++ /dev/null @@ -1,25 +0,0 @@ -defaults = { - 'apt': { - 'packages': { - 'postfix': {}, - 'postfix-pgsql': {}, - } - }, - 'backup': { - 'paths': [ - '/var/vmail', - ], - }, - 'letsencrypt': { - 'reload_after': { - 'postfix', - }, - }, - 'telegraf': { - 'config': { - 'inputs': { - 'postfix': [{}], - }, - }, - }, -} diff --git a/bundles/postgresql/items.py b/bundles/postgresql/items.py deleted file mode 100644 index 3589587..0000000 --- a/bundles/postgresql/items.py +++ /dev/null @@ -1,22 +0,0 @@ -from bundlewrap.utils.dicts import merge_dict - - -svc_systemd['postgresql'] = { - 'needs': [ - 'pkg_apt:postgresql', - ], -} - -for user, config in node.metadata.get('postgresql/roles').items(): - postgres_roles[user] = merge_dict(config, { - 'needs': [ - 'svc_systemd:postgresql', - ], - }) - -for database, config in node.metadata.get('postgresql/databases').items(): - postgres_dbs[database] = merge_dict(config, { - 'needs': [ - 'svc_systemd:postgresql', - ], - }) diff --git a/bundles/postgresql/metadata.py b/bundles/postgresql/metadata.py deleted file mode 100644 index d41513a..0000000 --- a/bundles/postgresql/metadata.py +++ /dev/null @@ -1,52 +0,0 @@ -root_password = repo.vault.password_for(f'{node.name} postgresql root') - -defaults = { - 'apt': { - 'packages': { - 'postgresql': {}, - }, - }, - 'backup': { - 'paths': [ - '/var/lib/postgresql', - ], - }, - 'postgresql': { - 'roles': { - 'root': { - 'password': root_password, - 'superuser': True, - }, - }, - 'databases': {}, - }, - 'grafana_rows': [], -} - -if node.has_bundle('zfs'): - defaults['zfs'] = { - 'datasets': { - 'tank/postgresql': { - 'mountpoint': '/var/lib/postgresql', -# 'recordsize': '16384', - }, - }, - } - - -@metadata_reactor.provides( - 'telegraf/config/inputs/postgresql', -) -def telegraf(metadata): - return { - 'telegraf': { - 'config': { - 'inputs': { - 'postgresql': [{ - 'address': f'postgres://root:{root_password}@localhost:5432/postgres', - 'databases': sorted(list(node.metadata.get('postgresql/databases').keys())), - }], - }, - }, - }, - } diff --git a/bundles/redis/metadata.py b/bundles/redis/metadata.py deleted file mode 100644 index ad287c2..0000000 --- a/bundles/redis/metadata.py +++ /dev/null @@ -1,7 +0,0 @@ -defaults = { - 'apt': { - 'packages': { - 'redis-server': {}, - }, - }, -} diff --git a/bundles/roundcube/files/config.inc.php b/bundles/roundcube/files/config.inc.php deleted file mode 100644 index bcaef07..0000000 --- a/bundles/roundcube/files/config.inc.php +++ /dev/null @@ -1,79 +0,0 @@ -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 R`!gQAys!_>qtHC>e*ta^ayI|~ diff --git a/data/apt/keys/packages.cloud.google.com.gpg b/data/apt/keys/packages.cloud.google.com.gpg deleted file mode 100644 index 3f0b5a850ba73c4b6d7fe5b206030ee9d0b4da46..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2537 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 aPy2fjM|%0RB7(z@>?-c(X_@*Q=YIhorh*dy diff --git a/data/dkim/islamicstate.eu.privkey.enc b/data/dkim/islamicstate.eu.privkey.enc deleted file mode 100644 index 4de106a..0000000 --- a/data/dkim/islamicstate.eu.privkey.enc +++ /dev/null @@ -1 +0,0 @@ -encrypt$gAAAAABg1uKdl_1A48p7K8tAxh-3QrP8XEplOoQ0VPf4ioO5MN7EF-cJr6QaYEE8zGyJ1luIcqIs8gOICYnMBM6_PsHLkTRq4cvdoEy3989F26fLrc8n2VaXe1eXhe6f87slT4ZR64NJL9UKhaZpkWKXTzDxJd621-wb8MUXJdTg_aJFDh0YK2Qh2waayiQeGa4IY6IOp68un0DIw_XrawxJgZZn9lae1oWdkg_hZeeuZS09kGBVYdwkJDC_mmebwJzYPxek96bn5vdxm2-YTVoeB8PyGA5q8gRJSKyuxtqBQAJJhXJtBdQX--mh0lA3PzCmhA_qwIEhqmJjiE6InnFkFADibofpJsT2MLuS-1PyeD54lhuMZlY9J6HU2fDWdlCVF9K-vy04mjBpWdUU_CUdURkRdOwVrdzt5P2CgilXSaM2nmK_uEWMLsh0SoOJoqyKZaCJ_5TO7ztM_4_vLyNN379F3wVw2iLF_R-cBtZbgERTkvfUw5ppUGYDSyq125cwXJtGTBWK35SU7_5PEID_JjijYcGEe7o4uOj3zqqK3V2JVVBplc45cJi_BIbb77alC1IDKI6MR608qNmutlcKNyRD1JvhwmAP4BDr-gnA4R5NtMRS0s-ZVqxfE8d2yrZJx3EgNxJ3wujlE9QaNxory_utU6i3fnPWNgyXO7UwtVhF_CFEmcB43nDs7Hw5Uzo4Sq-wvgM_Lepj7kLrznqL1PUWucy5ETa9wWZoEf9_1w6T3kJ5Df1nft8N9JI66WUcOiCk4tc5x1qcn1EGVxM_4Pw37kbAUL3tQW-DuUxa1lnKzmLGwgpyV72a1Ivzr46yuIgVOGF5sCFa5yUTS5Uvny8qZ0jBOf9hVJE0ewdrYh9bap8xSo4qC4EZC8YXhZg5_0-WsS7myccSScYEzCUlTdafOrHoO1f4_NBUivUBlO5cRBGoy6O7m-C5MeXaPkglijYhX5iBg_nYKFOgIldF2v0JC1VCsnXCiiC3r6vpNAYl06vAXPJoESx8B9qHdQvU8iJ9ZVTQxMYXTVMRzni6ZA8xunfeHd60vouS67E1yjEMQ56eTqaDDeTYTbMRV6AgZYE-JJQPQkJCqjB3j_bIEpyFEKRnCKUU3eu5-hnLIsia2XMlXgmCwVJm3is_LKQ5ETeehUYLfInccH-nUI7t6qe1v8qQ0JsLERO9Qcfr19_W8ESR5z0ludb2FgjcTUFQiZVXcXGMyinUZsQY6RIOOZ1r-89XjsW5PSmdbM7edxuL_8pWhCMGvZMgU3XHehqYfeWXSVchJbGXSPpCPNfhEmzINWk8BwWyl9YQjWt35_nK0smOzTnPLrfhBVU8uw05KXe6rd0FSdUrj2VCW0y4ii4TMsyFYC_ZTw7x-VkVqdphWzaT28N_wqQZlxFrHWMN02iocbivxEr1UE_VeI6DQQ9ueDPxJoiH6IkTa9Ct_sTKoMD19O_TGg7DrLWZ97tohJQtc4oolFYJ57COu53sR3xbIHfJMYzjRyrZpVPlTkhKH9qMVXxy8e1WNyjOc8-S9Diuv7AFegAYXcye9_b-4facFkEVc4HZws6fht0iQHfUMnk4qmGCxSEuZxo1c0htkWG0eZ5VTq01PHt9EOBkj4A6zM6PPqrqL_NyeF4nvH5_hLmFeSQBfN4iTIlVL9ANexUXQ8u2o2gbmkpsoNP375uClDEWYuElHTiemuIw-cp9KfPyafrOyv3zAZHQ6Eh-Z71-FN-mIqAHpe2DjhG688VNkQnnyXYS4SjXCmN0qdvFzBSzYG-kxV02VTEVoa7jynYWpUqSjkURZZspTVLHA3Iw7m2kdENVBbK0vHkFmhIm0MfXIyJ4pnE1kdeDzB9QycUHK1WSuqiqotsg698BscQ94Z0fUQNt1WJdQZrV0IMS9EXgM29IBjaVWc7yJhqIMLDVio2_7QrfRdqzBoteRSE8Pfq2gLAHL6n0W3IAqV0H5CL1VrKnia83U1y7Gq_yrQh9_E2YoE3YNOI2zNwbUtA5WRNNxNbyjFgupfnx8XvINljNaaRrK8XkPnhaJw1yfTP__LbnL1UruKdHfRMeJYj_W9Kp3TatbllGTq5zN88O22cJWMYKGIBioIB8eZMyLPc8bgA-MGwVscrvFtxspOHASCJ5b1VVtASczIncFldiju9lS_3fNi6UgCDSGw236DLsXZzR_pjjlQkubTwffJscwKmo5hqzx9fYhxiipkL-VGINyF1qClc5ydIWpMzhMPsS-sbvSKau8M9fBlKmlxYDp_uVdy4n-NmYJho1uMUyTnREd5qF0_v8an4oMNldUGy7k0cnbDD7_av7BICX_MIizcgzoAckHSG6RHK-wyx4xqmAb4I= \ No newline at end of file diff --git a/data/dkim/islamicstate.eu.pubkey b/data/dkim/islamicstate.eu.pubkey deleted file mode 100644 index 4be1464..0000000 --- a/data/dkim/islamicstate.eu.pubkey +++ /dev/null @@ -1 +0,0 @@ -ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDHb5hZmUHCe1Rc0OKbnqD20YkhUI2/PaQCEMORZHfOWUSSlLmZcye9kYBTcXNPE4uDW7dCqo2Ng+rXzl3AOcjx12JrFPNi2HN3sHj+bbcsr05ZLYIHvAeWJuV39/A1Xf8yyZ9fzlpAK+fBqKIo+UEnv1ViEBDrdL5LIC90cBmayBcHyvtLBJqoutIOqwNkyXyw7ATPRwTzfevS1iObEmhpkdY2eWfbFQg1TDjcrGALOc0u4BDH9cyit2smAsh4HNpaPhZLJ6X1O0IpfMArv2xyyMkkJI6iRzgOf1Rk68nMKuV8HhvEdI934o9bRcqT9u0LUCWdKhG/OSAcSkUFCBZ9 \ No newline at end of file diff --git a/data/dkim/mail2.sublimity.de.privkey.enc b/data/dkim/mail2.sublimity.de.privkey.enc deleted file mode 100644 index 6fcba4e..0000000 --- a/data/dkim/mail2.sublimity.de.privkey.enc +++ /dev/null @@ -1 +0,0 @@ -encrypt$gAAAAABgynxWv-6xPH0S-lO2UHzvMcGIDMRk0VZxxVP3mLbGstiy7GxdAMUJ9YKg8gssWhLaqPaUNY9XApmiGU4rT7L3C1NfYqri4hHJlhmXS97S_KzQ42gvKRKPSl86yx4jACz1gWHvFJQEq-Xnyave7Yj-SA63kLLxeoOlIfym8GErWaV3GQSVbFoFcZVMs_sVic_J9QQs3Cvq8Gcy5pEGtFr1Cx9_X7zNucsEgqWoAG0GQFEzxFXWyKXpCA3I49KDAbdyYB8PDgUlTMKc2_0QStYv7wjYHhWOskQ8r7Emm0TuvVaRu93kt73KIycwW4ZY6M8FCidZGrjz3s58k26yZ7E-IvPuZnF75QUhtV-jQPtlKqiMazXylq_gT0VNgu5ajUKgRNODC32qLUACE1Z7Zb1RczBY0OYlk-G4Wcr9lPhefgHo0T-Ik3nsTaAi-xV5wt_pun9dieXYHERdi9_95FvfezvbfHjdQt84i8rDvetlpEctXVUKAPXaWYdGjUYDO0GgIkszSb-rC1jjRxTtuW26DA8ylFPl9Nt0exRf94nBCAuW-U6NknLNlMzzcA-0IuS0mXIRRrkeNp4eRNtabnu-GPYU5X_TCjv0weamPtg6CK-oQyiE9Z7NapGwcIcPH_ZXe7k1wqmZMFDemNrcvWUKBOnnunbz8l_Q4Eqx_gVfbcTGGAzWsZytom0Z6GNLJZZf0WIkvEbsUw8VRWWQnIiVC6AZG2c0kS0xwJCFRyC079ZQKcsp6YUTnGj9fsPoNCzuLgeOJk2CkW-Fi8Z6YApVhjWxQvunLSv_PlDFqn5mGFfUWkwe9-sZgr4F8bkMxqV6Mn5KiRPEpHj0wxYf3BmiFROWKYEvCc1axBMyBTEZopM9E-bMzcN26mfbOmyEMnia3MkZKPgEC14rDT5PWQqNhUMZsOT5MliLvmJgBm5l9wigUYgH8xQekMVjc5AeGRZ1GQ9XELgqzuxHHO1cKjUT8wGr8DCwpEolj_a5SfQ20XVuwEck3evAdcsW-q6k8TlANY7Uqznh1UyINuskWEpFIIN7SCAw7EK8Fs5t6RMFAwC9LjkIwUch5JIUUDevh7PD1nKoZvAT651YdJg8LMyMtLn8PpJTZjpY5TbH3605US6HpI-eKY7j_cIJBA3QyhgZSbP2ZtsumVI9IY9bFib8LHJFqJWJkjTe0-qgErpuxLgcCeHW-ERh3yIjvxQjYCWNTzECHQiE6ouNz10LX82Szqs_M6wzYATlPkmwAn8Cg_OCpfMhFNamvWCizeMbHaekIDIIltCCyqqjTlFNCCYSjXWrBoA9qSeCLsPTbpGn_oykHmIbBNvfp7Yzo2pmdzeUGCafajwmn3PpHFOWoFdkxVwW8qmzINcgrbX30vlWe_qQjZ9GrOCs1lR3WbR8au2O8YPZzk_rezWShWPTQqPZe1GmcnTY01rVAc8YZxcwjLYz4WZ98LU-p689BK5bZPOeQ0r7g4hn2RQdr3EnBxiFHhOl6sfS_ZoDKJdtwKvQIlqOadDGmXei5y3IHr3w8FGvqPidIsByC81dmbVfgFfB05a_D6rljseMh62wcOirvh8cDccrwp7NCorVEh-Pi44H5_YagfggcLMdKOgwk8fOKqidYYr4fj-JTG0bgc1Yn1lisdPsXUmEmBx9GPx_M9dEbOIIk4CAUMYVWrpa2A6tww5tFZUnbe89YR95iWWa705YCMUe40RLmU5jy3w2JrkrKFqY9mm26H1OepUlQAyPS9KFZV7vNTsuo_0s4wSFpb3orlGlbQavqW8s_56leAIy4nPaKr7c71noFsbus2oSNb9ygslwmtmysRs2goQYEmde2v5PPxfEE-GOiDRWXxY_shMBSsGguARcO1QgyiuxHWrCd5we0oYrlvy-UxaV_bXH8lbpIrup-nYbD1ZFti3mQoCYxysYae_MLvV7-vFwZsxP1pjAP4muG9fQMBaS7fIMXJ5HRlmmsu4GGhEkUdZTIKTWCzcDSTgpUcaV-M5UC2f0eBTiS5R-Bq54jYcQUBXr3V4YJOxuA2L6_KKD5rK9mqvJ9kGkyZP8zBmrQZes2dvrn-DWtbdw6ydD8sOfkq99uK_XMZvq8fzsuKcy3eOgyhdCwK7CBeArvQ7WH4xRI0u6J2eMzPcGiD-zF1nFcClyE2QryQhfhpUWWj3GOd5rqt4ExATrbxIsIE7r_MkuHshZBpHV42AyDhX0KXzeDAY4DcM2lZ8F1ePfp4MJRJeT8Bg43hBKlkLJgPNJNzKq3g_cTXCVwNcGhqEjg2a64BZLTmp1u43vA3oePkG-zwWoUaOxBfrXAz1RXf_8JpARh1iCwP1FPRvIbioatGjwQOviJ9s= \ No newline at end of file diff --git a/data/dkim/mail2.sublimity.de.pubkey b/data/dkim/mail2.sublimity.de.pubkey deleted file mode 100644 index 8781c0f..0000000 --- a/data/dkim/mail2.sublimity.de.pubkey +++ /dev/null @@ -1 +0,0 @@ -ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC1rIcD4+VFztPE3MUuLiXcejhQFkpNZzn8+1R6Zb/oxNb8hMcBmpAT0evvSaLyJtoLbbdoAS8Ug3JZiIrBXnimTeALWyizZC87mzC/xAaCONbslxqFx9K2zu+4HmGDaezfOTWQJul2QttSNzc2SkHZxf6bUvTtAaEQk9Qx25CTzncNoWwDh388hdZ/BX4zv6KSNH6obE+ny1SXD6yG/tP4SlvpIXnWbimLoEaFWNIRgV9gp95clAnohdwlzhZRMwliQP2EdFMW2l3UOVPbb1XU1Vop78yWDFQKlI2ZkHtvzrayLkkAChlVJPtLQIbLtoh1ZqF5FabGZXQhFlMJif4N \ No newline at end of file diff --git a/data/dkim/mail3.sublimity.de.privkey.enc b/data/dkim/mail3.sublimity.de.privkey.enc deleted file mode 100644 index ada3ca8..0000000 --- a/data/dkim/mail3.sublimity.de.privkey.enc +++ /dev/null @@ -1 +0,0 @@ -encrypt$gAAAAABg1uyiaIUW_xg6bDDltvSBvSx2D2A4ZPdJTNAkgkKNCwT6ByS-QAUEHd8_DPUGL4KX2bJWoZCCDbQOhGOt7-uZvEYyMRweoMHLuSdNe65ryuQWa4EoLnnB1ek-hzdoRDIya5oaF7J3p0xse5Wy_PvS-tQRNrJ5m7f40KUGOYu6XEAMOAE07F9cG6iDbFp3WFH8SdfBsjVH_LzMb4F5HPCkPh7RshcJ0CMs_RAmxE9T07jzi0zfYWbG_R_DuPaSOXNNbD1euGaVkQfaZKWpHQQSM45YISsdW64CLVSGZlsLZOeUoGbq0PFE6Y-WUZ3g7PKBtlCvBYzqhRBqNyY4dTD_PmcykETUEtp_QoQNJBhmy9HgyHPyl0fwJwdo9YqRtqIYXgXsQ1zs2okvupBKSV_vh-28fHRknOEZfxM04ALCZWTdGpswY3RQrVbMToz58ZwhH1dwtFoFccYrKgZpzLQtkmg3AwuabPn6VtO1pSxAFPXspGc3o1lwkapTETn0j42IfVaanYghIOa2PV8szMEnKJcZ5Rf99i8lQk3F9t8PgRXbXBKPrzKFbrzu4W335V7LeZxLUZEW39-FWz6WUMJ8IfpXLGKNuKsU67dO4pempf5RSA1USCF4el3qmvdfMm1hxgWc88kBfr1_MFFPtJqBQCPO6MjXZJ4dV4CudT-vf1GVZQhczoK7fyUN-OSzJ0EtsDKbvxS4lVySrBI1PMPVI7Ah1eRJ2KJHsNe2uKcVZvKqpCYZJdi5g9vqr2eofCAgyNBa9tNWR4tMuoQ3vht7OSR1S4LW_Zky1x3jo65oXiU-9wQE0VpQccjHX5N0jYVUhexk9Q1xO3oj0qMMw4JcL77H4_CmdUgKCPoWO3VHSlSh4JD4iSTLKyWl6frx2aPMHbiDOK9TMiLY9cEOCIkawCSJ4IeFMd0QTRG_Ly-ngeIuKINZYcH5IuwpIZKwBIQ8vweJdX5pO58rwVOOnDWCvYdTwzqC7NsRNSXwW3567gE8orH8EUZ3HWGr4HcJeTuJ4ewM-MH2aPWLNjCzhd-jgWtanHVGHsC4qdwpOZAjr_zbMUvegxA1ZWqeSUkvdscJgBivJKOZIC-fNi8t6vVBu1aUMr-Cb_HV3LV94GdPZz765tr-bJ4JpJswnoWFnF4njP0EnoCN2WmoLpC6ivjhgaulaWlF1MrqpnjhgkkbUPHJVL8dCDThmNihJeAGcUCNKD-5pQrsHEmZsLWphcK6XzfYxXIWBZe_7WlZ49T62lhpoelxNXhgDEncr6Z4Z0Gqx4sjRBBz-UcCh4uR3hMC-bZUyTdzCZhhxbqt0w5DCq0tAK1XHszkZlkc5ceckbSZSlc_mE4aPhv1w3sUs4duSHBqxfbrr9fAfay2k1Etc0nDiH3n19txDKAUyZUpb_0NoXbczG0x51MjdR5w5rSoU4jcQ6FHlMHVYse5Qg-EYEnH5o1MP2RrWB4-q9i6wEeDzdKgbVWgO1MBr3uK82NsFiZD6oPa_Yb_Sw-Y5-UzJ_tjG4DysXimcGney8CuXsHVBuYsJKPjrEGnKpbmWuopZ83f7FPzFEjZVWOPPRE2Nef9tNz2p5bF0rt5iv_vOS8UUMdEY7n4fWYpcGQPOZ1DhMXAvIz_yQx3mZYWGnaU3zDwIm_ryeVElYpV06Yk6dRCq6p4mTMFM7LrK_kv47BguMRx2mRfr_WtfSr1mxBSV8-0OaXVpDMeutzoBnYL3-RrfVklri36l0wtC2kft6taOHYH0e883APweTIz-_1VUVYIB9zdM6QvMx6-U9Jd1rC7Fdg24F-2SAAeUKclM7SNK7OiMD4opk7EUncnwSdDYlFFMqTNmliVuUPW_4YWsNHpHUajyuKfanCiVltw5Bx4xWwyHFYc5rIK4c5nkT3Hc7-SQas1Rxxfrny148QFxF-4ZdPQdF9r81Qfk7VcotCgBTfplupSqYVGNMboPwNLOwsOG7D7fCVx8915L7tVuYWLLi6HT5iC2ML393QYAm_YfypFCS7BzvTCw_sr0K03zgnk63y8XKJltPBRZuouB94WgkfSCMoB3R_66Dtnl8icLJDV0QpHwtFSLcjUYKPlyaN0a3SffHr1ExJtzsw9Bvqrp85S1ii1Uj-TVu4SU8rtTKme5GQ6-WS9jt2Dw_3Me7c6Ms5L3B-t9G2ZhI-O5Q2lzkXNdN2KN70wT-GjOXPuolwFkcDGDYM6QueB_nAQErsTtuMeiyQVO7j97dkNVMhUn-ZRUBUNs_nP7CPMw8uki903gPLmC3kJFKZ73u0wzv0SkWMSj4A_0b6o1J-2ixD97pIWPwnbOIEU_8u0fY3GMXsjK8t-usdzkTgD427zh23t3Uk= \ No newline at end of file diff --git a/data/dkim/mail3.sublimity.de.pubkey b/data/dkim/mail3.sublimity.de.pubkey deleted file mode 100644 index 705f49c..0000000 --- a/data/dkim/mail3.sublimity.de.pubkey +++ /dev/null @@ -1 +0,0 @@ -ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCbsx9bRuzwTsAiFeuYq00Xtxlqqu+aNLBDGFIVSAVETojhqmNlBBaZ0R3mxT/YVkGPYQC5IOF4lZRtCjcRs3QKSJCHxEs3dHba84wP1wg0y1X9WK8pkXiZo9BgbUbxkJz6EWg5FUM/LYWly2lTg4VY/YvoMEKUEicr2fAJuDYiUnK6WXcYIfgHe3Jfjw2IE/oNuk8p1XoazCPcLLw7xT6TleVE/t3pZT0AYFOepm1HQ9xTDS475E4Rn11OkGC7Wd+Roqguer/zAT0353iKIQNj1H3pxHiKY84TFs36p7m3CbeEFDDfdi3bbBFy3Rm9774/mVXyLVE5ZGoKfU8rS0TT \ No newline at end of file diff --git a/data/gcloud/service_accounts/backup@sublimity-182017.json.enc b/data/gcloud/service_accounts/backup@sublimity-182017.json.enc deleted file mode 100644 index 8d064c2..0000000 --- a/data/gcloud/service_accounts/backup@sublimity-182017.json.enc +++ /dev/null @@ -1 +0,0 @@ -encrypt$gAAAAABgzbX64G_2XFuGX4gcdRqms9eiov9FS_p2gwhkJGLTRd8uR8QfxzcUg_RJDuSOhE3lE5mQPjfgjYJ0Bluv87MT8y-Cn16smz0ONWaMusjNR23CJQc9MHfyyxAV6pUiwrqExacY7dS-VDvV_QzpZTbM2WqKHIpxqrzyDSQfFW9LnSZYSEERAmJe4k87vjlOWsbXo2zfo1GJe2eTJO2wUkdzBR0M1EUvG769e0a1NoT_yeRJdid3YAiQi7Zzvmaf_p5SuXQ8IJrDJWL0_citS6XW-mh2blJVjGB1BHGypeAnSRhXbdNouqCYKj6p3bxmpyX2Ao076cnkOyaieXnydaGjxp6ZFlrDOmR07nUGP2e5pbRJavU56RlNVSTAkkV4sZVX_hYs7gzTjZLl2vIg_weRTmf5X881l07qVXhyaGydP4qNYijPdoYcxGlG-tt6dLMmbrTfjdRzpwZcyLveJQPVQD1dZoJxZkT0GPoQ8xAHHm4sZl7jdABxtgoRhF1nFcR1nnvarHgSBlp0eY3NL0fAAtiqqGganvd1x_hQZIpZJP2VY6IuMUXswzL8Rro_6fZVF06GsftQiOyPBpmS4kJph2nr9TNsTajTxbmtEILAP4pmaKwxZtcrZRtm-KHolNn3sTJPku43APTLNGSlth9wJYkOGb__2tH63mAIAGB9JtQr8mbqKUOas5WbEAtlYFuKVcbtdyw1P7gxGZIdt4-_apK_QpfHs9mwj3Fda_POEa9ff2tOGaE6njJXL8xxVgiThkf0YJ4HjewYp72YHKAsQJA0BAlf3oGSggTasQpszcykgH6i4ExwbXH5bc5qvhP-RHzfINj3trd22H9EIhMb1qqc-XlKONCaDG3iOqogUTJgpEe7RXgp-Kl4bPhZENgOTxA5PvIF0zuYjN-HwTX449NmaTP_mGrIftpLUcZQpRiRFBXQAVIbDlxtDUAkecJWSMz3nRJI6pPy1jCJPuvqa_DnkwBmbKiqGXCiz29r-YDb7lRKZ4wEzyMSwZoiToeOGjdC9os2KutwMelzP_O3pWRsp6hIxYtwM2dcUqrdCzt4PKinkUI_2UOC7G7fMIfJVJ-5GYu3ho50kxS0moWbLHcSL4xg5pjgYB4UYpt0_Bke9WjIbvxUMKFXzdsCnhPs8GsdGMxgUijlizJNAWj0mdf6Z29GdjdZ2IR2qSoN22XN6hSAg2gTXXeUBp5uOQn9kSame8cstvn-gKh4F1M_TzF2hHtEzFxfR_vh62ZTcjIq_gsFyXAftbJtmVqJXB16IDXhKUb_sN2dy-HKOuPFd226fzrw9qOaz2NHAs8dEC5f3Gh48y54vWBbNi9WfEacst1ChpqXRwBq4BBhH7okUbXCubdXsk9aD6tSLE0vBLoOytuCVN2Qs6R-SsYCSiEGwjK9WdlQDmiKbYUhtfCX4-Zcm8O4h6w4pWUpJ54aG15jdaenKSRCYI0suRplAjxJxyZSRRo-VJCY_6YRrwD9ydChj9eyBiT8SRb-Focj8JOm9Mk22UOCUqgreyOs_oWf1v-UFRotssuP_Bh9D5xrTnkoLhxIzo0gvVDkFsH66atKHHWObejuHd6o6EUqG68Vi5Bykk5ZlpEZzRTOdZJ-N9cPQ6nXWC2-j_HtVk4qx0MOh3GQwcjws0p2wRV1PlbHCum49VTnMoeFAlZthBDb5TiyhgkEzTpxAGAp1Vg6_ge1-RjAgsaQXHS2X0iKfd1A-9zgAFK6bVjgdnmOj3BlbzJpetEQRs23JY0-rN6d39Wt1Fd3jsbMWB5hTaOqDNC-WbNUJPOCqoG72LueD73I6_ywA-jg9Nv4cKq6IJPnY_QMM0rQtbVyXPDqLXmcPVh5NdTNC5g1zLEGfjCmfTh-0fe-G1VbBvfPtzl33000BtDvVhpedD-pZg5mVa9r0TN_JhktHCa1yMmu-XiCRXY8DeUH3v9RDi4yZ7_ZwqcfrMB75uT5stUD7Y4WVN1iWHRsLjKDLkhTUku5bIZs48GY5DXEvP1zFzmRYFLLhIOP3L8Uh92cjp4rwteVj3-6JDyM_mmB5iXRK71PURc6_Ll-nEFoI6zH9HWCO1woe7O5UJF5OvQ_5ryRRgu_J7EAC9lHhPjOhWRM-d0PAMpsqFi5o7HClfIqY3fOOsMzralakL8uXszhuHW9corxuj9FW_9wiXW1Cue317_anVemJZEl-I_uJ1R0w7izoegjAlewVngZSO9V0HBX6bqKkm_xvAdenyalsKs_M5nzlKNuD3LyfjZ04hYjtcqdTFZB8c76QkSBLj30dDHSpV0ZqIUliXz-u0Uu2Ah3xloLwHieYYkRpXgMK1xTyKpwkW-s7rFRnqdX9qBopNAUOy6a5IGk9gimJh6ZdzOMUSAth9xIEA3LUvujV3JQMYsHzv1u65LDN0IRySwErX2L_oxlFJXMVQROTuMVae70MxyIRHQ8gSbhkyaLx4q9hiDwvOH-nWVf97vF44Z_LjZ5j-lWCaTAaoSZY3z_D5tR3m8KZGy5GIQb2vW9ldtWw8j80dROIVMuqpvVHWbty-jybq1h-SHoyDe0qut8l592XtKQrpjtCK_zLLpBsye6Y0XCvYOOAP260xvwDeWNisoWEmUYpE2O3ZDGLbNAi2l5c2rgQL17Iv_lkPAHv8d5tDTA0nhAkCuoegBRGaoQcYzdfsihFHjTCPYJIShFvqWRKmPPPaOyz-6pGssn1RpzyQFMqq0RxWqsckZG_pKFr-nYPjA-zOTlXjV6D98NjeQLm-tSthey-thHqovrd1oWYbuphR2Hf9h9hLFQFaeFRDtpO--Vqn1rjlOeZvkovNHSvs024PaY_fdu3wjnY_Pik5RNPauFB8eE72avpLhVjkADavqmhXBVN-D-k0fkB56iPmHosifQUUQko4XSDuMYd-Rw7ZRfRdW1PNmti510OlQWKk0hLhy1zmPThjKH7Jaj4mkgvKl61fcZ0BqgzV8UKG3zprZCsGRuXfBEmGEw4R7Jjft-s8lsXher-VceQuf-dbcnzIzZ0EpUf1BIvevy1wvICW1aCD7H-_FhhBHtepNgj-f9JBzimO2mxAcgfNipMR2PaU96fwziOhIoD76QdHDvZ4soc5TQI010HYUnZdxL5KZY5ZjIJs4tTtVUxiKzJ0GR0QqrxBwNi8YImg== diff --git a/data/grafana/dashboard.py b/data/grafana/dashboard.py deleted file mode 100644 index 7dde561..0000000 --- a/data/grafana/dashboard.py +++ /dev/null @@ -1,37 +0,0 @@ -{ -# "id": 1, -# "title": "some dashboard", -# "uid": "IBPgYBznk", - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": True, - "hide": True, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] - }, - "editable": True, - "gnetId": None, - "graphTooltip": 0, - "links": [], - "panels": [], - "refresh": False, - "schemaVersion": 30, - "style": "dark", - "tags": [], - "templating": { - "list": [], - }, - "time": { - "from": "now-6h", - "to": "now" - }, - "timepicker": {}, - "timezone": "", - "version": 15 -} diff --git a/data/grafana/flux.mako b/data/grafana/flux.mako deleted file mode 100644 index d8ffa5c..0000000 --- a/data/grafana/flux.mako +++ /dev/null @@ -1,15 +0,0 @@ -from(bucket: "${bucket}") - |> range(start: v.timeRangeStart, stop: v.timeRangeStop) -% for key, values in filters.items(): -<% values = values if isinstance(values, list) else [values] %>\ - |> filter(fn: (r) => ${' or '.join(f'r["{key}"] == "{value}"' for value in values)}) -% endfor -% if function == 'derivative': - |> derivative() -% else: - |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false) -% endif -% if negative: - |> map(fn: (r) => ({r with _value: r._value * - 1.0})) -% endif - |> yield(name: "mean") diff --git a/data/grafana/panel.py b/data/grafana/panel.py deleted file mode 100644 index 4c652bd..0000000 --- a/data/grafana/panel.py +++ /dev/null @@ -1,66 +0,0 @@ -{ -# 'id': 1, -# 'title': 'TBD', - "gridPos": { -# "x": 0, -# "y": 0, - "h": 8, -# "w": 24 - }, - 'type': 'timeseries', - 'transformations': [], - 'description': '', - 'fieldConfig': { - 'defaults': { - 'custom': { - 'drawStyle': 'line', - 'lineInterpolation': 'smooth', - 'barAlignment': 0, - 'lineWidth': 1, - 'fillOpacity': 40, - 'gradientMode': 'opacity', - 'spanNulls': False, - 'showPoints': 'never', - 'pointSize': 5, - 'stacking': { - 'mode': 'none', - 'group': 'A' - }, - 'axisLabel': '', - 'scaleDistribution': { - 'type': 'linear' - }, - 'hideFrom': { - 'tooltip': False, - 'viz': False, - 'legend': False - }, - 'thresholdsStyle': { - 'mode': 'off', - }, - 'lineStyle': { - 'fill': 'solid', - }, - }, - 'color': { - 'mode': 'palette-classic', - }, - 'mappings': [], - 'displayName': '${__field.name}', - }, - 'overrides': [], - }, - 'options': { - 'tooltip': { - 'mode': 'single', - }, - 'legend': { - 'displayMode': 'list', - 'placement': 'bottom', - 'calcs': [], - }, - }, - 'targets': [], - 'transparent': True, - 'datasource': None, -} diff --git a/data/grafana/rows/cpu.py b/data/grafana/rows/cpu.py deleted file mode 100644 index ba3e44e..0000000 --- a/data/grafana/rows/cpu.py +++ /dev/null @@ -1,37 +0,0 @@ -{ - 'usage': { - 'stacked': False, - 'queries': { - 'usage': { - 'filters': { - '_measurement': 'cpu', - 'cpu': 'cpu-total', - '_field': [ - 'usage_iowait', - 'usage_system', - 'usage_user', - ], - }, - 'function': 'mean', - }, - }, - 'min': 0, - 'max': 100, - }, - 'load': { - 'stacked': False, - 'queries': { - 'load': { - 'filters': { - '_measurement': 'system', - '_field': [ - 'load1', - 'load5', - 'load15', - ], - }, - 'function': 'mean', - }, - }, - }, -} diff --git a/data/grafana/rows/disk_io.py b/data/grafana/rows/disk_io.py deleted file mode 100644 index deca33d..0000000 --- a/data/grafana/rows/disk_io.py +++ /dev/null @@ -1,34 +0,0 @@ -{ - 'read': { - 'stacked': True, - 'queries': { - 'usage': { - 'filters': { - '_measurement': 'diskio', - '_field': [ - 'read_bytes', - ], - }, - 'function': 'derivative', - }, - }, - 'unit': 'decbytes', - 'display_name': '__field.labels.name' - }, - 'write': { - 'stacked': True, - 'queries': { - 'load': { - 'filters': { - '_measurement': 'diskio', - '_field': [ - 'write_bytes', - ], - }, - 'function': 'derivative', - }, - }, - 'unit': 'decbytes', - 'display_name': '__field.labels.name' - }, -} diff --git a/data/grafana/rows/mem.py b/data/grafana/rows/mem.py deleted file mode 100644 index 1fcaf57..0000000 --- a/data/grafana/rows/mem.py +++ /dev/null @@ -1,36 +0,0 @@ -{ - 'memory': { - 'stacked': True, - 'queries': { - 'memory': { - 'filters': { - '_measurement': 'mem', - '_field': [ - 'used', - 'cached', - 'buffered', - 'free', - ], - }, - 'function': 'mean', - }, - }, - 'unit': 'decbytes', - }, - 'swp': { - 'stacked': True, - 'queries': { - 'memory': { - 'filters': { - '_measurement': 'mem', - '_field': [ - 'swap_cached', - 'swap_free', - ], - }, - 'function': 'mean', - }, - }, - 'unit': 'decbytes', - }, -} diff --git a/data/grafana/rows/net_io.py b/data/grafana/rows/net_io.py deleted file mode 100644 index cb8fc63..0000000 --- a/data/grafana/rows/net_io.py +++ /dev/null @@ -1,34 +0,0 @@ -{ - 'in': { - 'stacked': True, - 'queries': { - 'in': { - 'filters': { - '_measurement': 'net', - '_field': [ - 'bytes_recv', - ], - }, - 'function': 'derivative', - }, - }, - 'unit': 'decbytes', - 'display_name': '__field.labels.interface' - }, - 'out': { - 'stacked': True, - 'queries': { - 'out': { - 'filters': { - '_measurement': 'net', - '_field': [ - 'bytes_sent', - ], - }, - 'function': 'derivative', - }, - }, - 'unit': 'decbytes', - 'display_name': '__field.labels.interface' - }, -} diff --git a/data/network.py b/data/network.py deleted file mode 100644 index 2e3a6e8..0000000 --- a/data/network.py +++ /dev/null @@ -1,19 +0,0 @@ -{ - 'networks': [ - '10.0.0.0/24', - '10.0.2.0/24', - '10.0.9.0/24', - '10.0.10.0/24', - ], - 'routers': { - '10.0.0.1': { - '10.0.0.0/24': None, - '10.0.0.2/24': None, - '10.0.0.9/24': None, - }, - '10.0.0.2': { - '10.0.0.0/24': 'internal', - '10.0.10.0/24': 'wg0', - }, - }, -} diff --git a/groups/all.py b/groups/all.py index 294c47c..679d8db 100644 --- a/groups/all.py +++ b/groups/all.py @@ -1,13 +1,12 @@ { 'bundles': [ 'users', - 'zsh', + 'backup', ], 'metadata': { - 'dns': {}, - 'nameservers': [ - '10.0.10.2', - ], + 'backup': { + 'server': 'home.backups', + }, 'users': { 'root': { 'shell': '/usr/bin/zsh', diff --git a/groups/applications/archive.py b/groups/applications/archive.py deleted file mode 100644 index 237d004..0000000 --- a/groups/applications/archive.py +++ /dev/null @@ -1,10 +0,0 @@ -{ - 'supergroups': [ - 'gcloud', - ], - 'bundles': [ - 'archive', - 'gocryptfs', - 'gocryptfs-inspect', - ], -} diff --git a/groups/applications/backup-server.py b/groups/applications/backup-server.py deleted file mode 100644 index 1dd9a2f..0000000 --- a/groups/applications/backup-server.py +++ /dev/null @@ -1,6 +0,0 @@ -{ - 'bundles': [ - 'backup-server', - 'zfs', - ], -} diff --git a/groups/applications/backup.py b/groups/applications/backup.py deleted file mode 100644 index 369925e..0000000 --- a/groups/applications/backup.py +++ /dev/null @@ -1,10 +0,0 @@ -{ - 'bundles': [ - 'backup', - ], - 'metadata': { - 'backup': { - 'server': 'home.backups', - }, - } -} diff --git a/groups/applications/dnsserver.py b/groups/applications/dnsserver.py deleted file mode 100644 index 68c889c..0000000 --- a/groups/applications/dnsserver.py +++ /dev/null @@ -1,5 +0,0 @@ -{ - 'bundles': [ - 'bind', - ], -} diff --git a/groups/applications/gcloud.py b/groups/applications/gcloud.py deleted file mode 100644 index 33f29af..0000000 --- a/groups/applications/gcloud.py +++ /dev/null @@ -1,12 +0,0 @@ -{ - 'bundles': [ - 'gcloud', - ], - 'metadata': { - 'gcloud': { - 'service_account': 'backup', - 'bucket': 'sublimity-backup', - 'project': 'sublimity-182017', - }, - }, -} diff --git a/groups/applications/mailserver.py b/groups/applications/mailserver.py deleted file mode 100644 index c154897..0000000 --- a/groups/applications/mailserver.py +++ /dev/null @@ -1,14 +0,0 @@ -{ - 'bundles': [ - 'opendkim', - 'dovecot', - 'letsencrypt', - 'mailserver', - 'php', - 'postfix', - 'postgresql', - 'redis', - 'roundcube', - 'rspamd', - ], -} diff --git a/groups/applications/monitored.py b/groups/applications/monitored.py deleted file mode 100644 index ccf4ee8..0000000 --- a/groups/applications/monitored.py +++ /dev/null @@ -1,10 +0,0 @@ -{ - 'bundles': [ - 'telegraf', - ], - 'metadata': { - 'telegraf': { - 'influxdb_node': 'home.server', - }, - }, -} diff --git a/groups/applications/nextcloud.py b/groups/applications/nextcloud.py deleted file mode 100644 index 626a331..0000000 --- a/groups/applications/nextcloud.py +++ /dev/null @@ -1,6 +0,0 @@ -{ - 'bundles': [ - 'nextcloud', - 'php', - ], -} diff --git a/groups/applications/webserver.py b/groups/applications/webserver.py deleted file mode 100644 index 70fb0e8..0000000 --- a/groups/applications/webserver.py +++ /dev/null @@ -1,6 +0,0 @@ -{ - 'bundles': [ - 'nginx', - 'letsencrypt', - ], -} diff --git a/groups/hardware/hetzner-cloud.py b/groups/hardware/hetzner-cloud.py deleted file mode 100644 index eb1d2a4..0000000 --- a/groups/hardware/hetzner-cloud.py +++ /dev/null @@ -1,5 +0,0 @@ -{ - 'bundles': [ - 'hetzner-cloud', - ], -} diff --git a/groups/os/debian-10.py b/groups/os/debian-10.py deleted file mode 100644 index 6f72004..0000000 --- a/groups/os/debian-10.py +++ /dev/null @@ -1,20 +0,0 @@ -{ - 'supergroups': [ - 'debian', - ], - 'metadata': { - 'apt': { - 'sources': [ - 'deb http://security.debian.org/debian-security {release}/updates main contrib non-free', - ], - }, - 'php': { - 'version': '7.3', - }, - 'postgresql': { - 'version': '11', - }, - 'os_release': 'buster', - }, - 'os_version': (10,), -} diff --git a/groups/os/debian-11.py b/groups/os/debian-11.py deleted file mode 100644 index 731b69c..0000000 --- a/groups/os/debian-11.py +++ /dev/null @@ -1,20 +0,0 @@ -{ - 'supergroups': [ - 'debian', - ], - 'metadata': { - 'apt': { - 'sources': [ - 'deb http://security.debian.org/ {release}-security main contrib non-free', - ], - }, - 'php': { - 'version': '7.4', - }, - 'postgresql': { - 'version': '13', - }, - 'os_release': 'bullseye', - }, - 'os_version': (11,), -} diff --git a/groups/os/debian.py b/groups/os/debian.py deleted file mode 100644 index 7f80d9f..0000000 --- a/groups/os/debian.py +++ /dev/null @@ -1,22 +0,0 @@ -{ - 'supergroups': [ - 'linux', - ], - 'bundles': [ - 'apt', - ], - 'metadata': { - 'apt': { - 'sources': [ - 'deb http://deb.debian.org/debian {release} main non-free contrib', - 'deb http://deb.debian.org/debian {release}-updates main contrib non-free', - 'deb http://deb.debian.org/debian {release}-backports main contrib non-free', - ], - 'packages': { - 'mtr-tiny': {}, - }, - }, - }, - 'os': 'debian', - 'pip_command': 'pip3', -} diff --git a/groups/os/linux.py b/groups/os/linux.py deleted file mode 100644 index b632300..0000000 --- a/groups/os/linux.py +++ /dev/null @@ -1,11 +0,0 @@ -{ - 'supergroups': [ - 'all', - ], - 'bundles': [ - 'network', - 'systemd', - 'systemd-networkd', - 'systemd-timers', - ], -} diff --git a/libs/apt.py b/libs/apt.py deleted file mode 100644 index 0798c41..0000000 --- a/libs/apt.py +++ /dev/null @@ -1,70 +0,0 @@ -# https://manpages.debian.org/jessie/apt/sources.list.5.de.html -from urllib.parse import urlparse -from re import search, sub -from functools import total_ordering - - -@total_ordering -class AptSource(): - def __init__(self, string): - if search(r'\[.*\]', string): - self.options = { - k:v.split(',') for k,v in ( - e.split('=') for e in search(r'\[(.*)\]', string)[1].split() - ) - } - else: - self.options = {} - - parts = sub(r'\[.*\]', '', string).split() - self.type = parts[0] - self.url = urlparse(parts[1]) - self.suite = parts[2] - self.components = parts[3:] - - def __str__(self): - parts = [ - self.type, - self.url.geturl(), - self.suite, - ' '.join(self.components), - ] - - if self.options: - parts.insert( - 1, - "[{}]".format( - ' '.join( - '{}={}'.format( - k, - ','.join(v) - ) for k,v in self.options.items() - ) - ) - ) - - return ' '.join(parts) - - - def __eq__(self, other): - return str(self) == str(other) - - def __lt__(self, other): - return str(self) < str(other) - - def __hash__(self): - return hash(str(self)) - - def __repr__(self): - return f"{type(self).__name__}('{str(self)}')" - - -# source = AptSource('deb [arch=amd64 trusted=true] http://deb.debian.org/debian buster-backports main contrib non-free') -# print(repr(source)) -# print(source.type) -# print(source.options) -# source.options['test'] = ['was', 'ist', 'das'] -# print(source.url) -# print(source.suite) -# print(source.components) -# print(str(source)) diff --git a/libs/derive_string.py b/libs/derive_string.py deleted file mode 100644 index 828103c..0000000 --- a/libs/derive_string.py +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env python - -from hashlib import sha3_256 -from itertools import count, islice -from Crypto.Cipher import ChaCha20 -from math import floor, ceil -from time import sleep -from os import environ -from sys import stderr - -def debug(*args): - if 'DEBUG' in environ: - print(*args, file=stderr) - -def chacha_bits(input, bit_count): - zerobyte = (0).to_bytes(length=1, byteorder='big') - cipher = ChaCha20.new(key=sha3_256(input).digest(), nonce=zerobyte*8) - i = 0 - - while True: - debug(f'--- BITS {i} ---') - start_bit = bit_count * i - start_byte = start_bit // 8 - start_padding = start_bit % 8 - debug('start_bit', start_bit) - debug('start_byte', start_byte) - debug('start_padding', start_padding) - - end_bit = bit_count * i + bit_count - end_byte = end_bit // 8 - end_padding = 8 - (end_bit % 8) - debug('end_bit', end_bit) - debug('end_byte', end_byte) - debug('end_padding', end_padding) - - byte_count = (end_byte - start_byte) + 1 - debug('byte_count', byte_count) - - cipher.seek(start_byte) - cipherint = int.from_bytes(cipher.encrypt(zerobyte*byte_count), byteorder='big') - debug('ciphertext', bin(cipherint)) - shifted_cipherint = cipherint >> end_padding - debug('shifted_ciphertext', bin(shifted_cipherint)) - - bit_mask = int('1'*bit_count, 2) - debug('bit_mask', bin(bit_mask)) - masked_cipherint = shifted_cipherint & bit_mask - debug('masked_ciphertext', bin(masked_cipherint)) - - debug('') - yield masked_cipherint - i += 1 - - -def chacha_chracter(input, choices): - get_bits = chacha_bits(input, len(choices).bit_length()) - - while True: - key = next(get_bits) - if key < len(choices): - yield choices[key] - - -def derive_string(input, length, choices): - sorted_choices = bytes(sorted(choices)) - get_character = chacha_chracter(input, sorted_choices) - return bytes(islice(get_character, length)) - -# print( -# derive_string(b'12344', length=100, choices=b'abcdefghijklmnopqrstuvwxyz0123456789') -# ) diff --git a/libs/dns.py b/libs/dns.py deleted file mode 100644 index 7af9cf3..0000000 --- a/libs/dns.py +++ /dev/null @@ -1,15 +0,0 @@ -from ipaddress import ip_interface - -def get_a_records(metadata): - return { - 'A': [ - str(ip_interface(network['ipv4']).ip) - for network in metadata.get('network').values() - if 'ipv4' in network - ], - 'AAAA': [ - str(ip_interface(network['ipv6']).ip) - for network in metadata.get('network').values() - if 'ipv6' in network - ], - } diff --git a/libs/grafana.py b/libs/grafana.py deleted file mode 100644 index 73dc1ec..0000000 --- a/libs/grafana.py +++ /dev/null @@ -1,29 +0,0 @@ -from mako.template import Template -from copy import deepcopy - - -def generate_flux(bucket, host, field, data): - return Template(flux_template).render( - bucket=bucket, - host=host, - field=field, - data=data - ).strip() - - -def generate_panel(bucket, host, title, targets, min=None, max=None): - panel = deepcopy(panel_template) - panel['title'] = title - - if min: - panel['fieldConfig']['defaults']['min'] = min - if max: - panel['fieldConfig']['defaults']['max'] = max - - panel['targets'] = [ - { - 'hide': False, - 'refId': field, - 'query': generate_flux(bucket, host, field, data), - } for field, data in targets.items() - ] diff --git a/libs/ini.py b/libs/ini.py deleted file mode 100644 index 792e52b..0000000 --- a/libs/ini.py +++ /dev/null @@ -1,24 +0,0 @@ -from configparser import ConfigParser - -def parse(text): - config = ConfigParser() - config.read_string(text) - - return { - section: dict(config.items(section)) - for section in config.sections() - } - -class Writable(): - data = '' - - def write(self, line): - self.data += line - -def dumps(dict): - config = ConfigParser() - config.read_dict(dict) - writable = Writable() - config.write(writable) - - return writable.data diff --git a/libs/keys.py b/libs/keys.py deleted file mode 100644 index 427a85f..0000000 --- a/libs/keys.py +++ /dev/null @@ -1,15 +0,0 @@ -import base64 -from nacl.public import PrivateKey -from nacl.encoding import Base64Encoder -from bundlewrap.utils import Fault - -def gen_privkey(repo, identifier): - return repo.vault.random_bytes_as_base64_for(identifier) - -def get_pubkey_from_privkey(identifier, privkey): - # FIXME this assumes the privkey is always a base64 encoded string - def derive_pubkey(): - pub_key = PrivateKey(base64.b64decode(str(privkey))).public_key - return pub_key.encode(encoder=Base64Encoder).decode('ascii') - - return Fault(f'pubkey from privkey {identifier}', derive_pubkey) diff --git a/libs/nextcloud.py b/libs/nextcloud.py deleted file mode 100644 index 78e4086..0000000 --- a/libs/nextcloud.py +++ /dev/null @@ -1,2 +0,0 @@ -def occ(command, *args, **kwargs): - return f"""sudo -u www-data php /opt/nextcloud/occ {command} {' '.join(args)} {' '.join(f'--{name.replace("_", "-")}' + (f'={value}' if value else '') for name, value in kwargs.items())}""" diff --git a/libs/nginx.py b/libs/nginx.py deleted file mode 100644 index dc83e25..0000000 --- a/libs/nginx.py +++ /dev/null @@ -1,27 +0,0 @@ -def render_config(config): - return '\n'.join(render_lines(config)) - -def render_lines(config, indent=0): - lines = [] - blocks = [] - - for key, value in sorted(config.items()): - if isinstance(value, dict): - blocks.extend([ - '', - key+' {', - *render_lines(value, indent=4), - '}', - ]) - elif isinstance(value, list): - lines.extend([ - f'{key} {_value};' for _value in value - ]) - else: - lines.append( - f'{key} {value};' - ) - - return [ - f"{' '*indent}{line}" for line in lines+blocks - ] diff --git a/libs/systemd.py b/libs/systemd.py deleted file mode 100644 index b52bb88..0000000 --- a/libs/systemd.py +++ /dev/null @@ -1,27 +0,0 @@ -from mako.template import Template - -template = ''' -% for segment, options in data.items(): - -% if '#' in segment: -# ${segment.split('#', 2)[1]} -% endif -[${segment.split('#')[0]}] -% for option, value in options.items(): -% if isinstance(value, dict): -% for k, v in value.items(): -${option}=${k}=${v} -% endfor -% elif isinstance(value, (list, set, tuple)): -% for item in sorted(value): -${option}=${item} -% endfor -% else: -${option}=${str(value)} -% endif -% endfor -% endfor -''' - -def generate_unitfile(data): - return Template(template).render(data=data).lstrip() diff --git a/libs/tools.py b/libs/tools.py deleted file mode 100644 index d96feec..0000000 --- a/libs/tools.py +++ /dev/null @@ -1,88 +0,0 @@ -from ipaddress import ip_address, ip_network, IPv4Address, IPv4Network - -from bundlewrap.exceptions import NoSuchGroup, NoSuchNode, BundleError -from bundlewrap.utils.text import bold, red -from bundlewrap.utils.ui import io - -def resolve_identifier(repo, identifier): - """ - Try to resolve an identifier (group or node). Return a set of ip - addresses valid for this identifier. - """ - try: - nodes = {repo.get_node(identifier)} - except NoSuchNode: - try: - nodes = repo.nodes_in_group(identifier) - except NoSuchGroup: - try: - ip = ip_network(identifier) - - if isinstance(ip, IPv4Network): - return {'ipv4': {ip}, 'ipv6': set()} - else: - return {'ipv4': set(), 'ipv6': {ip}} - except Exception as e: - io.stderr('{x} {t} Exception while resolving "{i}": {e}'.format( - x=red('✘'), - t=bold('libs.tools.resolve_identifier'), - i=identifier, - e=str(e), - )) - raise - - found_ips = set() - for node in nodes: - for interface, config in node.metadata.get('interfaces', {}).items(): - for ip in config.get('ips', set()): - if '/' in ip: - found_ips.add(ip_address(ip.split('/')[0])) - else: - found_ips.add(ip_address(ip)) - - if node.metadata.get('external_ipv4', None): - found_ips.add(ip_address(node.metadata.get('external_ipv4'))) - - ip_dict = { - 'ipv4': set(), - 'ipv6': set(), - } - - for ip in found_ips: - if isinstance(ip, IPv4Address): - ip_dict['ipv4'].add(ip) - else: - ip_dict['ipv6'].add(ip) - - return ip_dict - - -def remove_more_specific_subnets(input_subnets) -> list: - final_subnets = [] - - for subnet in sorted(input_subnets): - source = ip_network(subnet) - - if not source in final_subnets: - subnet_found = False - - for dest_subnet in final_subnets: - if source.subnet_of(dest_subnet): - subnet_found = True - - if not subnet_found: - final_subnets.append(source) - - out = [] - for net in final_subnets: - out.append(str(net)) - - return out - - -def require_bundle(node, bundle, hint=''): - # It's considered bad style to use assert statements outside of tests. - # That's why this little helper function exists, so we have an easy - # way of defining bundle requirements in other bundles. - if not node.has_bundle(bundle): - raise BundleError(f'{node.name} requires bundle {bundle}, but wasn\'t found! {hint}') diff --git a/nodes/home.backups.py b/nodes/home.backups.py index 3e5c9df..889e250 100644 --- a/nodes/home.backups.py +++ b/nodes/home.backups.py @@ -1,35 +1,15 @@ { 'hostname': '10.0.0.5', - 'groups': [ - 'debian-10', - 'backup-server', - 'monitored', - ], 'bundles': [ - 'zfs', + 'backup-server', + ], + 'groups': [ + 'all', ], 'metadata': { 'id': '9cf52515-63a1-4659-a8ec-6c3c881727e5', 'backup-server': { 'hostname': 'backups.sublimity.de', }, - 'network': { - 'internal': { - 'interface': 'enp1s0', - 'ipv4': '10.0.0.5/24', - 'gateway4': '10.0.0.1', - }, - }, - 'zfs': { - 'pools': { - 'tank': { - 'raidz': [ - '/dev/disk/by-id/ata-HGST_HDN726040ALE614_K3GV6TPL', - '/dev/disk/by-id/ata-HGST_HDN726040ALE614_K4KAJXEB', - '/dev/disk/by-id/ata-TOSHIBA_HDWQ140_19VZK0EMFAYG', - ], - }, - }, - }, }, } diff --git a/nodes/home.server.py b/nodes/home.server.py index 375ad72..03dd064 100644 --- a/nodes/home.server.py +++ b/nodes/home.server.py @@ -1,85 +1,9 @@ { 'hostname': '10.0.0.2', 'groups': [ - 'archive', - 'backup', - 'debian-10', -# 'nextcloud', - 'monitored', - ], - 'bundles': [ - 'gitea', - 'grafana', - 'influxdb2', - 'mirror', - 'postgresql', - 'redis', - 'wireguard', - 'zfs', + 'all', ], 'metadata': { 'id': 'af96709e-b13f-4965-a588-ef2cd476437a', - 'mirror': { - 'certs': { - 'from': '10.0.10.2:/var/lib/dehydrated/certs', - 'to': '/var/lib/dehydrated/certs', - }, - }, - 'network': { - 'internal': { - 'interface': 'enp1s0f0', - 'ipv4': '10.0.0.2/24', - 'gateway4': '10.0.0.1', - }, - }, - 'gitea': { - 'version': '1.14.2', - 'sha256': '0d11d87ce60d5d98e22fc52f2c8c6ba2b54b14f9c26c767a46bf102c381ad128', - 'domain': 'git.sublimity.de', - }, - 'grafana': { - 'hostname': 'grafana.sublimity.de', - 'influxdb_node': 'home.server', - }, - 'influxdb': { - 'hostname': 'influxdb.sublimity.de', - 'admin_token': '!decrypt:encrypt$gAAAAABg3z5PcaLYmUpcElJ07s_G-iYwnS8d532TcR8xUYbZfttT-B736zgR6J726mzKAFNYlIfJ7amNLIzi2ETDH5TAXWsOiAKpX8WC_dPBAvG3uXGtcPYENjdeuvllSagZzPt0hCIZQZXg--Z_YvzaX9VzNrVAgGD-sXQnghN5_Vhf9gVxxwP---VB_6iNlsf61Nc4axoS', - 'readonly_token': '!decrypt:encrypt$gAAAAABg3z1-0hnUdzsfivocxhJm58YnPLn96OUvnHiPaehdRhKd6TZBgEPc5YyR07t2-GEUfOvEwoie-O6QsVhWYxrwxNTBXux_iUSx7W6e-fLQA_3MgWf5G97q_3kx_wCgQ6V0iKRyxH988TpNSMACfS4WhCXdSes1CaMpic4VV3S3ox_gCrSHxO7yVXQkJDnOW0MixY5T', - 'writeonly_token': '!decrypt:encrypt$gAAAAABg3z6fGrOy2tNdo03RoYAXmpJoJYkfhBfpblPh_wxYfqmdjtABaD7XyV9mSh9xl8oWQlTAtCk9KndVCDQy7BJ-ju7S3HCKJ0k244Y5YKxUnQtqt9fc9nnm8XD-NOJqLKyfy0QhL_I8dFT02pygoJeCUR5NkZcTKf6julb-iGXI6vWcQgolJTYrW643pHObd-Z-vIEl', - }, - 'nextcloud': { - 'hostname': 'cloud.sublimity.de', - 'version': '21.0.1', - }, - 'users': { - 'root': { - 'shell': '/usr/bin/zsh', - }, - }, - 'vm': { - 'cores': 2, - 'ram': 16192, - }, - 'wireguard': { - 'my_ip': '172.30.0.2/24', - 'peers': { - 'htz.mails': { - 'route': [ - '10.0.10.0/24', - '10.0.11.0/24', - ], - }, - }, - }, - 'zfs': { - 'pools': { - 'tank': { - 'mirrors': [ - '/dev/disk/by-partlabel/zfs-data-1', - '/dev/disk/by-partlabel/zfs-data-2', - ], - }, - }, - }, }, } diff --git a/nodes/htz.games.py b/nodes/htz.games.py index ad7c720..729d94a 100644 --- a/nodes/htz.games.py +++ b/nodes/htz.games.py @@ -1,12 +1,7 @@ { 'dummy': True, 'groups': [ - 'backup', - 'debian-10', - ], - 'bundles': [ - 'steam', - 'l4d2', + 'all', ], 'metadata': { 'id': '353bb086-f3ce-4f36-8533-e91786c91ed9', diff --git a/nodes/htz.mails.py b/nodes/htz.mails.py index e6ab74f..edf1d73 100644 --- a/nodes/htz.mails.py +++ b/nodes/htz.mails.py @@ -1,129 +1,9 @@ { 'hostname': '162.55.188.157', 'groups': [ - 'archive', - 'backup', - 'hetzner-cloud', - 'debian-10', - 'mailserver', - 'monitored', - 'webserver', - 'dnsserver', - ], - 'bundles': [ - 'nextcloud', - 'wireguard', - 'zfs', + 'all', ], 'metadata': { - 'systemd-timers': { - 'test1': { - 'when': 'weekly', - 'command': '/bin/ls', - }, - }, - 'nextcloud': { - 'hostname': 'cloud.sublimity.de', - 'version': '21.0.0', - }, 'id': 'ea29bdf0-0b47-4bf4-8346-67d60c9dc4ae', - 'bind': { - 'hostname': 'ns.sublimity.de', - 'zones': { - 'sublimity.de': [], - 'freibrief.net': [], - 'nadenau.net': [], - 'naeder.net': [], - 'rolfwerner.eu': [], - 'wettengl.net': [], - 'wingl.de': [], - 'woodpipe.de': [], - 'ckn.li': [], - 'islamicstate.eu': [], - }, - }, - 'dns': { - 'islamicstate.eu': { - 'A': ['1.2.3.4'], - }, - 'test.islamicstate.eu': { - 'AAAA': ['::1337'], - }, - }, - 'network': { - 'internal': { - 'interface': 'ens10', - 'ipv4': '10.0.10.2/24', - }, - 'external': { - 'interface': 'eth0', - 'ipv4': '162.55.188.157/32', - 'ipv6': '2a01:4f8:1c1c:4121::2/64', - 'gateway4': '172.31.1.1', - 'gateway6': 'fe80::1', - } - }, - 'mailserver': { - 'hostname': 'mail.sublimity.de', - 'admin_email': 'postmaster@sublimity.de', - 'domains': [ - 'mail3.sublimity.de', - 'islamicstate.eu', - # 'sublimity.de', - # 'freibrief.net', - # 'nadenau.net', - # 'naeder.net', - # 'rolfwerner.eu', - # 'wettengl.net', - # 'wingl.de', - # 'woodpipe.de', - ], - }, - 'roundcube': { - 'product_name': 'Sublimity Mail', - 'version': '1.4.11', - 'installer': True, - }, - 'users': { - 'root': { - 'authorized_users': [ - 'root@home.server', - ], - }, - }, - 'vm': { - 'cores': 2, - 'ram': 8096, - }, - 'wireguard': { - # ip r add 10.0.0.0/24 via 172.19.136.2 dev wg0 - 'my_ip': '172.30.0.1/24', - 'peers': { - 'home.server': { - 'route': [ - '10.0.0.0/24', - '10.0.2.0/24', - '10.0.9.0/24', - ], - }, - 'netcup.secondary': { - 'route': [ - '10.0.11.0/24', - ], - }, - }, - }, - 'zfs': { - 'pools': { - 'tank': { - 'device': '/dev/disk/by-id/scsi-0HC_Volume_11764264', - }, - }, - }, - 'archive': { - 'paths': { - '/var/test': {}, - }, - }, }, } diff --git a/nodes/netcup.secondary.py b/nodes/netcup.secondary.py index ff520e6..c0141c4 100644 --- a/nodes/netcup.secondary.py +++ b/nodes/netcup.secondary.py @@ -1,38 +1,9 @@ { 'hostname': '46.38.240.85', 'groups': [ - 'debian-10', - ], - 'bundles': [ - 'wireguard', + 'all', ], 'metadata': { 'id': '890848b2-a900-4f74-ad5b-b811fbb4f0bc', - 'network': { - 'external': { - 'interface': 'eth0', - 'ipv4': '46.38.240.85/22', - 'gateway4': '46.38.240.1', - 'ipv6': '2a03:4000:7:534::2/64', - 'gateway6': 'fe80::1', - }, - 'internal': { - 'interface': 'eth1', - 'ipv4': '10.0.11.2', - }, - }, - 'wireguard': { - 'my_ip': '172.30.0.3/24', - 'peers': { - 'htz.mails': { - 'route': [ - '10.0.0.0/24', - '10.0.2.0/24', - '10.0.9.0/24', - '10.0.10.0/24', - ], - }, - }, - }, }, }