Compare commits

..

No commits in common. "main" and "sophiesheomenetwork" have entirely different histories.

147 changed files with 1697 additions and 2736 deletions

View file

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

View file

@ -7,6 +7,9 @@ supported_os = {
12: 'bookworm', 12: 'bookworm',
99: 'unstable', 99: 'unstable',
}, },
'raspbian': {
10: 'buster',
},
} }
try: try:
@ -24,10 +27,6 @@ actions = {
'triggered': True, 'triggered': True,
'cascade_skip': False, 'cascade_skip': False,
}, },
'apt_execute_update_commands': {
'command': ' && '.join(sorted(node.metadata.get('apt/additional_update_commands', {'true'}))),
'triggered': True,
},
} }
files = { files = {

View file

@ -21,9 +21,6 @@ defaults = {
'cron/jobs/upgrade-and-reboot' 'cron/jobs/upgrade-and-reboot'
) )
def patchday(metadata): def patchday(metadata):
if not node.metadata.get('apt/unattended-upgrades/enabled', True):
return {}
day = metadata.get('apt/unattended-upgrades/day') day = metadata.get('apt/unattended-upgrades/day')
hour = metadata.get('apt/unattended-upgrades/hour') hour = metadata.get('apt/unattended-upgrades/hour')

View file

@ -33,7 +33,7 @@ defaults = {
# networking # networking
'avahi': {}, 'avahi': {},
'netctl': {}, 'netctl': {},
'util-linux': {}, # provides rfkill 'rfkill': {},
'wpa_supplicant': {}, 'wpa_supplicant': {},
'wpa_actiond': {}, 'wpa_actiond': {},

View file

@ -1,22 +0,0 @@
[server]
host-name=${node.name.split('.')[-1]}
use-ipv4=yes
use-ipv6=yes
allow-interfaces=${','.join(sorted(node.metadata.get('interfaces', {}).keys()))}
ratelimit-interval-usec=1000000
ratelimit-burst=1000
[wide-area]
enable-wide-area=yes
[publish]
disable-publishing=no
disable-user-service-publishing=no
publish-hinfo=yes
publish-workstation=no
publish-aaaa-on-ipv4=yes
publish-a-on-ipv6=no
[reflector]
[rlimits]

View file

@ -1,18 +0,0 @@
directories['/etc/avahi/services'] = {
'purge': True,
}
files['/etc/avahi/avahi-daemon.conf'] = {
'content_type': 'mako',
'triggers': {
'svc_systemd:avahi-daemon:restart',
},
}
svc_systemd['avahi-daemon'] = {
'needs': {
'file:/etc/avahi/avahi-daemon.conf',
'pkg_apt:avahi-daemon',
'pkg_apt:libnss-mdns',
},
}

View file

@ -1,8 +0,0 @@
defaults = {
'apt': {
'packages': {
'avahi-daemon': {},
'libnss-mdns': {},
},
},
}

View file

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

View file

@ -160,7 +160,7 @@ def monitoring(metadata):
client, client,
config['one_backup_every_hours'], config['one_backup_every_hours'],
), ),
'vars.sshmon_timeout': 40, 'vars.sshmon_timeout': 20,
} }
return { return {

View file

@ -7,6 +7,9 @@ supported_os = {
12: 'bookworm', 12: 'bookworm',
99: 'unstable', 99: 'unstable',
}, },
'raspbian': {
10: 'buster',
},
} }
try: try:
@ -79,10 +82,6 @@ actions = {
'triggered': True, 'triggered': True,
'cascade_skip': False, 'cascade_skip': False,
}, },
'apt_execute_update_commands': {
'command': ' && '.join(sorted(node.metadata.get('apt/additional_update_commands', {'true'}))),
'triggered': True,
},
} }
directories = { directories = {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -29,8 +29,8 @@ mail_location = maildir:/var/mail/vmail/%d/%n
protocols = imap lmtp sieve protocols = imap lmtp sieve
ssl = required ssl = required
ssl_cert = </var/lib/dehydrated/certs/${node.metadata.get('postfix/myhostname')}/fullchain.pem ssl_cert = </var/lib/dehydrated/certs/${node.metadata.get('postfix/myhostname', node.metadata['hostname'])}/fullchain.pem
ssl_key = </var/lib/dehydrated/certs/${node.metadata.get('postfix/myhostname')}/privkey.pem ssl_key = </var/lib/dehydrated/certs/${node.metadata.get('postfix/myhostname', node.metadata['hostname'])}/privkey.pem
ssl_dh = </etc/ssl/certs/dhparam.pem ssl_dh = </etc/ssl/certs/dhparam.pem
ssl_min_protocol = TLSv1.2 ssl_min_protocol = TLSv1.2
ssl_cipher_list = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305 ssl_cipher_list = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305

View file

@ -33,7 +33,7 @@ actions = {
'yarn build', 'yarn build',
]), ]),
'needs': { 'needs': {
'action:apt_execute_update_commands', 'action:nodejs_install_yarn',
'pkg_apt:nodejs', 'pkg_apt:nodejs',
}, },
'triggered': True, 'triggered': True,

View file

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

View file

@ -100,7 +100,7 @@ def nginx(metadata):
}, },
}, },
'website_check_path': '/user/login', 'website_check_path': '/user/login',
'website_check_string': 'Sign in', 'website_check_string': 'Sign In',
}, },
}, },
}, },

View file

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

View file

@ -72,6 +72,7 @@ actions = {
'yarn build', 'yarn build',
]), ]),
'needs': { 'needs': {
'action:nodejs_install_yarn',
'file:/opt/hedgedoc/config.json', 'file:/opt/hedgedoc/config.json',
'git_deploy:/opt/hedgedoc', 'git_deploy:/opt/hedgedoc',
'pkg_apt:nodejs', 'pkg_apt:nodejs',

View file

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

View file

@ -5,8 +5,6 @@ After=network-online.target
[Service] [Service]
Type=simple Type=simple
User=homeassistant User=homeassistant
Environment="VIRTUAL_ENV=/opt/homeassistant/venv"
Environment="PATH=/opt/homeassistant/venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
WorkingDirectory=/var/opt/homeassistant WorkingDirectory=/var/opt/homeassistant
ExecStart=/opt/homeassistant/venv/bin/hass -c "/var/opt/homeassistant" ExecStart=/opt/homeassistant/venv/bin/hass -c "/var/opt/homeassistant"
RestartForceExitStatus=100 RestartForceExitStatus=100

View file

@ -30,7 +30,7 @@ files = {
'/usr/local/share/icinga/plugins/check_homeassistant_update': { '/usr/local/share/icinga/plugins/check_homeassistant_update': {
'content_type': 'mako', 'content_type': 'mako',
'context': { 'context': {
'token': node.metadata.get('homeassistant/api_secret'), 'bearer': repo.vault.decrypt(node.metadata.get('homeassistant/api_secret')),
'domain': node.metadata.get('homeassistant/domain'), 'domain': node.metadata.get('homeassistant/domain'),
}, },
'mode': '0755', 'mode': '0755',

View file

@ -50,13 +50,17 @@ def check_list(ip_list, blocklist, warn_ips):
]).decode().splitlines() ]).decode().splitlines()
for item in result: for item in result:
if item.startswith(';;'): if item.startswith(';;'):
continue msgs.append('{} - {}'.format(
msgs.append('{} listed in {} as {}'.format( blocklist,
ip, item,
blocklist, ))
item, else:
)) msgs.append('{} listed in {} as {}'.format(
if item in warn_ips and returncode < 2: ip,
blocklist,
item,
))
if (item in warn_ips or item.startswith(';;')) and returncode < 2:
returncode = 1 returncode = 1
else: else:
returncode = 2 returncode = 2

View file

@ -129,14 +129,11 @@ def notify_per_ntfy():
data=message_text, data=message_text,
headers=headers, headers=headers,
auth=(CONFIG['ntfy']['user'], CONFIG['ntfy']['password']), auth=(CONFIG['ntfy']['user'], CONFIG['ntfy']['password']),
timeout=10,
) )
r.raise_for_status() r.raise_for_status()
except Exception as e: except Exception as e:
log_to_syslog('Sending a Notification failed: {}'.format(repr(e))) log_to_syslog('Sending a Notification failed: {}'.format(repr(e)))
return False
return True
def notify_per_mail(): def notify_per_mail():
@ -202,8 +199,7 @@ if __name__ == '__main__':
notify_per_mail() notify_per_mail()
if args.sms: if args.sms:
ntfy_worked = False if args.service_name:
if CONFIG['ntfy']['user']:
ntfy_worked = notify_per_ntfy()
if not args.service_name or not ntfy_worked:
notify_per_sms() notify_per_sms()
if CONFIG['ntfy']['user']:
notify_per_ntfy()

View file

@ -17,6 +17,7 @@ defaults = {
'icinga2': {}, 'icinga2': {},
'icinga2-ido-pgsql': {}, 'icinga2-ido-pgsql': {},
'icingaweb2': {}, 'icingaweb2': {},
'icingaweb2-module-monitoring': {},
'python3-easysnmp': {}, 'python3-easysnmp': {},
'python3-flask': {}, 'python3-flask': {},
'snmp': {}, 'snmp': {},

View file

@ -23,7 +23,7 @@ actions = {
git_deploy = { git_deploy = {
'/opt/infobeamer-cms/src': { '/opt/infobeamer-cms/src': {
'rev': 'master', 'rev': 'master',
'repo': 'https://github.com/voc/infobeamer-cms.git', 'repo': 'https://github.com/sophieschi/36c3-cms.git',
'needs': { 'needs': {
'directory:/opt/infobeamer-cms/src', 'directory:/opt/infobeamer-cms/src',
}, },
@ -96,6 +96,14 @@ files = {
}, },
} }
pkg_pip = {
'github-flask': {
'needed_by': {
'svc_systemd:infobeamer-cms',
},
},
}
svc_systemd = { svc_systemd = {
'infobeamer-cms': { 'infobeamer-cms': {
'needs': { 'needs': {

View file

@ -1,13 +1,10 @@
from datetime import datetime, timedelta from datetime import datetime, timedelta
assert node.has_bundle('redis')
defaults = { defaults = {
'infobeamer-cms': { 'infobeamer-cms': {
'config': { 'config': {
'MAX_UPLOADS': 5, 'MAX_UPLOADS': 5,
'PREFERRED_URL_SCHEME': 'https', 'PREFERRED_URL_SCHEME': 'https',
'REDIS_HOST': '127.0.0.1',
'SESSION_COOKIE_NAME': '__Host-sess', 'SESSION_COOKIE_NAME': '__Host-sess',
'STATIC_PATH': '/opt/infobeamer-cms/static', 'STATIC_PATH': '/opt/infobeamer-cms/static',
'URL_KEY': repo.vault.password_for(f'{node.name} infobeamer-cms url key'), 'URL_KEY': repo.vault.password_for(f'{node.name} infobeamer-cms url key'),

View file

@ -1,10 +1,9 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import logging import logging
from datetime import datetime from datetime import datetime, timezone
from json import dumps from json import dumps
from time import sleep from time import sleep
from zoneinfo import ZoneInfo
import paho.mqtt.client as mqtt import paho.mqtt.client as mqtt
from requests import RequestException, get from requests import RequestException, get
@ -25,8 +24,7 @@ logging.basicConfig(
) )
LOG = logging.getLogger("main") LOG = logging.getLogger("main")
TZ = ZoneInfo("Europe/Berlin") MLOG = logging.getLogger("mqtt")
DUMP_TIME = "0900"
state = None state = None
@ -40,10 +38,7 @@ def mqtt_out(message, level="INFO", device=None):
key = "infobeamer" key = "infobeamer"
if device: if device:
key += f"/{device['id']}" key += f"/{device['id']}"
if device["description"]: message = f"[{device['description']}] {message}"
message = f"[{device['description']}] {message}"
else:
message = f"[{device['serial']}] {message}"
client.publish( client.publish(
CONFIG["mqtt"]["topic"], CONFIG["mqtt"]["topic"],
@ -66,14 +61,14 @@ def mqtt_dump_state(device):
out.append("Location: {}".format(device["location"])) out.append("Location: {}".format(device["location"]))
out.append("Setup: {} ({})".format(device["setup"]["name"], device["setup"]["id"])) out.append("Setup: {} ({})".format(device["setup"]["name"], device["setup"]["id"]))
out.append("Resolution: {}".format(device["run"].get("resolution", "unknown"))) out.append("Resolution: {}".format(device["run"].get("resolution", "unknown")))
if not device["is_synced"]:
out.append("syncing ...")
mqtt_out( mqtt_out(
" - ".join(out), " - ".join(out),
device=device, device=device,
) )
def is_dump_time():
return datetime.now(TZ).strftime("%H%M") == DUMP_TIME
mqtt_out("Monitor starting up") mqtt_out("Monitor starting up")
while True: while True:
@ -86,14 +81,15 @@ while True:
r.raise_for_status() r.raise_for_status()
ib_state = r.json()["devices"] ib_state = r.json()["devices"]
except RequestException as e: except RequestException as e:
LOG.exception("Could not get device data from info-beamer") LOG.exception("Could not get data from info-beamer")
mqtt_out( mqtt_out(
f"Could not get device data from info-beamer: {e!r}", f"Could not get data from info-beamer: {e!r}",
level="WARN", level="WARN",
) )
else: else:
new_state = {} new_state = {}
for device in sorted(ib_state, key=lambda x: x["id"]): online_devices = set()
for device in ib_state:
did = str(device["id"]) did = str(device["id"])
if did in new_state: if did in new_state:
@ -101,8 +97,7 @@ while True:
continue continue
new_state[did] = device new_state[did] = device
# force information output for every online device at 09:00 CE(S)T must_dump_state = False
must_dump_state = is_dump_time()
if state is not None: if state is not None:
if did not in state: if did not in state:
@ -145,15 +140,17 @@ while True:
if device["is_online"]: if device["is_online"]:
if device["maintenance"]: if device["maintenance"]:
mqtt_out( mqtt_out(
"maintenance required: {}".format( "maintenance required: {}".join(
" ".join(sorted(device["maintenance"])) sorted(device["maintenance"])
), ),
level="WARN", level="WARN",
device=device, device=device,
) )
must_dump_state = True
if ( if (
device["location"] != state[did]["location"] device["is_synced"] != state[did]["is_synced"]
or device["location"] != state[did]["location"]
or device["setup"]["id"] != state[did]["setup"]["id"] or device["setup"]["id"] != state[did]["setup"]["id"]
or device["run"].get("resolution") or device["run"].get("resolution")
!= state[did]["run"].get("resolution") != state[did]["run"].get("resolution")
@ -165,52 +162,23 @@ while True:
else: else:
LOG.info("adding device {} to empty state".format(device["id"])) LOG.info("adding device {} to empty state".format(device["id"]))
if device["is_online"]:
online_devices.add(
"{} ({})".format(
device["id"],
device["description"],
)
)
state = new_state state = new_state
try: if (
r = get( datetime.now(timezone.utc).strftime("%H%M") == "1312"
"https://info-beamer.com/api/v1/account", and online_devices
auth=("", CONFIG["api_key"]), and int(datetime.now(timezone.utc).strftime("%S")) < 30
) ):
r.raise_for_status() mqtt_out("Online Devices: {}".format(", ".join(sorted(online_devices))))
ib_account = r.json() sleep(30)
except RequestException as e:
LOG.exception("Could not get account data from info-beamer")
mqtt_out(
f"Could not get account data from info-beamer: {e!r}",
level="WARN",
)
else:
available_credits = ib_account["balance"]
if is_dump_time():
mqtt_out(f"Available Credits: {available_credits}")
if available_credits < 50:
mqtt_out(
f"balance has dropped below 50 credits! (available: {available_credits})",
level="ERROR",
)
elif available_credits < 100:
mqtt_out(
f"balance has dropped below 100 credits! (available: {available_credits})",
level="WARN",
)
for quota_name, quota_config in sorted(ib_account["quotas"].items()):
value = quota_config["count"]["value"]
limit = quota_config["count"]["limit"]
if value > limit * 0.9:
mqtt_out(
f"quota {quota_name} is over 90% (limit {limit}, value {value})",
level="ERROR",
)
elif value > limit * 0.8:
mqtt_out(
f"quota {quota_name} is over 80% (limit {limit}, value {value})",
level="WARN",
)
sleep(60)
except KeyboardInterrupt: except KeyboardInterrupt:
break break

View file

@ -3,9 +3,6 @@ repo:
bindAddress: '${node.metadata.get('matrix-media-repo/listen-addr', '127.0.0.1')}' bindAddress: '${node.metadata.get('matrix-media-repo/listen-addr', '127.0.0.1')}'
port: ${node.metadata.get('matrix-media-repo/port', 20090)} port: ${node.metadata.get('matrix-media-repo/port', 20090)}
logDirectory: '-' logDirectory: '-'
logColors: false
jsonLogs: false
logLevel: 'info'
trustAnyForwardedAddress: false trustAnyForwardedAddress: false
useForwardedHost: true useForwardedHost: true
@ -25,13 +22,10 @@ homeservers:
csApi: "${config['domain']}" csApi: "${config['domain']}"
backoffAt: ${config.get('backoff_at', 10)} backoffAt: ${config.get('backoff_at', 10)}
adminApiKind: "${config.get('api', 'matrix')}" adminApiKind: "${config.get('api', 'matrix')}"
% if config.get('signing_key_path'):
signingKeyPath: "${config['signing_key_path']}"
% endif
% endfor % endfor
accessTokens: accessTokens:
maxCacheTimeSeconds: 10 maxCacheTimeSeconds: 0
useLocalAppserviceConfig: false useLocalAppserviceConfig: false
admins: admins:
@ -59,9 +53,7 @@ archiving:
uploads: uploads:
maxBytes: ${node.metadata.get('matrix-media-repo/upload_max_mb')*1024*1024} maxBytes: ${node.metadata.get('matrix-media-repo/upload_max_mb')*1024*1024}
minBytes: 100 minBytes: 100
#reportedMaxBytes: 0 reportedMaxBytes: 0
maxPending: 5
maxAgeSeconds: 1800
quotas: quotas:
enabled: false enabled: false
@ -69,6 +61,14 @@ downloads:
maxBytes: ${node.metadata.get('matrix-media-repo/download_max_mb')*1024*1024} maxBytes: ${node.metadata.get('matrix-media-repo/download_max_mb')*1024*1024}
numWorkers: ${node.metadata.get('matrix-media-repo/workers')} numWorkers: ${node.metadata.get('matrix-media-repo/workers')}
failureCacheMinutes: 5 failureCacheMinutes: 5
cache:
enabled: true
maxSizeBytes: ${node.metadata.get('matrix-media-repo/download_max_mb')*10*1024*1024}
maxFileSizeBytes: ${node.metadata.get('matrix-media-repo/download_max_mb')*1024*1024}
trackedMinutes: 30
minDownloads: 5
minCacheTimeSeconds: 300
minEvictedTimeSeconds: 60
expireAfterDays: 0 expireAfterDays: 0
urlPreviews: urlPreviews:
@ -137,8 +137,8 @@ thumbnails:
rateLimit: rateLimit:
enabled: true enabled: true
requestsPerSecond: 100 requestsPerSecond: 10
burst: 5000 burst: 50
identicons: identicons:
enabled: true enabled: true

View file

@ -19,6 +19,9 @@ files = {
'/opt/matrix-media-repo/config.yaml': { '/opt/matrix-media-repo/config.yaml': {
'owner': 'matrix-media-repo', 'owner': 'matrix-media-repo',
'content_type': 'mako', 'content_type': 'mako',
'triggers': {
'svc_systemd:matrix-media-repo:restart',
},
}, },
'/etc/systemd/system/matrix-media-repo.service': { '/etc/systemd/system/matrix-media-repo.service': {
'triggers': { 'triggers': {

View file

@ -144,14 +144,13 @@ def nginx(metadata):
} }
if node.has_bundle('matrix-media-repo'): if node.has_bundle('matrix-media-repo'):
for path in ('/_matrix/media', '/_matrix/client/v1/media', '/_matrix/federation/v1/media'): locations['/_matrix/media'] = {
locations[path] = { 'target': 'http://localhost:20090',
'target': 'http://localhost:20090', 'max_body_size': '{}M'.format(metadata.get('matrix-media-repo/upload_max_mb')),
'max_body_size': '{}M'.format(metadata.get('matrix-media-repo/upload_max_mb')), # matrix-media-repo needs this to be the
# matrix-media-repo needs this to be the # homeserver address.
# homeserver address. 'x_forwarded_host': metadata.get('matrix-synapse/server_name'),
'x_forwarded_host': metadata.get('matrix-synapse/server_name'), }
}
vhosts = { vhosts = {
'matrix-synapse': { 'matrix-synapse': {

View file

@ -1,15 +1,11 @@
#!/bin/bash #!/bin/bash
OPTS="--netrc" OPTS=""
OPTS="$OPTS --netrc-location /opt/mixcloud-downloader/netrc"
OPTS="$OPTS --retry-sleep linear=1::2"
OPTS="$OPTS --retry-sleep fragment:exp=1:60"
OPTS="$OPTS --extractor-retries 5"
if [[ -n "$DEBUG" ]] if [[ -n "$DEBUG" ]]
then then
set -x set -x
else else
OPTS="$OPTS -q" OPTS="-q"
fi fi
set -euo pipefail set -euo pipefail

View file

@ -1,3 +0,0 @@
% for domain, data in sorted(node.metadata.get('mixcloud-downloader/netrc', {}).items()):
machine ${domain} login ${data['username']} password ${data['password']}
% endfor

View file

@ -6,9 +6,3 @@ files['/opt/mixcloud-downloader/download.sh'] = {
directories['/opt/mixcloud-downloader'] = { directories['/opt/mixcloud-downloader'] = {
'owner': 'kunsi', 'owner': 'kunsi',
} }
files['/opt/mixcloud-downloader/netrc'] = {
'content_type': 'mako',
'mode': '0400',
'owner': 'kunsi',
}

View file

@ -5,6 +5,12 @@ files = {
'svc_systemd:mosquitto:restart', 'svc_systemd:mosquitto:restart',
}, },
}, },
'/usr/local/bin/tasmota-telegraf-plugin': {
'mode': '0755',
'needs': {
'pkg_apt:python3-paho-mqtt',
},
},
} }
svc_systemd = { svc_systemd = {
@ -17,12 +23,6 @@ svc_systemd = {
} }
if node.has_bundle('telegraf'): if node.has_bundle('telegraf'):
files['/usr/local/bin/tasmota-telegraf-plugin'] = { files['/usr/local/bin/tasmota-telegraf-plugin']['triggers'] = {
'mode': '0755', 'svc_systemd:telegraf:restart',
'needs': {
'pkg_apt:python3-paho-mqtt',
},
'triggers': {
'svc_systemd:telegraf:restart',
},
} }

View file

@ -5,6 +5,7 @@ defaults = {
'packages': { 'packages': {
'mosquitto': {}, 'mosquitto': {},
'mosquitto-clients': {}, 'mosquitto-clients': {},
'python3-paho-mqtt': {}, # for telegraf plugin
}, },
}, },
'icinga2_api': { 'icinga2_api': {
@ -23,9 +24,6 @@ defaults = {
}, },
} }
if node.has_bundle('telegraf'):
defaults['apt']['packages']['python3-paho-mqtt'] = {}
@metadata_reactor.provides( @metadata_reactor.provides(
'firewall/port_rules', 'firewall/port_rules',

View file

@ -23,8 +23,9 @@ table inet filter {
icmp type timestamp-request drop icmp type timestamp-request drop
icmp type timestamp-reply drop icmp type timestamp-reply drop
meta l4proto {icmp, ipv6-icmp} accept ip protocol icmp accept
ip6 nexthdr ipv6-icmp accept
% for ruleset, rules in sorted(input.items()): % for ruleset, rules in sorted(input.items()):
# ${ruleset} # ${ruleset}

View file

@ -29,7 +29,7 @@ defaults = {
}, },
} }
if not node.has_bundle('vmhost') and not node.has_bundle('docker-engine'): if not node.has_bundle('vmhost'):
# see comment in bundles/vmhost/items.py # see comment in bundles/vmhost/items.py
defaults['apt']['packages']['iptables'] = { defaults['apt']['packages']['iptables'] = {
'installed': False, 'installed': False,

View file

@ -11,7 +11,7 @@ events {
http { http {
include /etc/nginx/mime.types; include /etc/nginx/mime.types;
types { types {
application/javascript mjs; application/javascript js mjs;
} }
default_type application/octet-stream; default_type application/octet-stream;
charset UTF-8; charset UTF-8;

View file

@ -149,18 +149,18 @@ server {
% if 'target' in options: % if 'target' in options:
proxy_pass ${options['target']}; proxy_pass ${options['target']};
proxy_http_version ${options.get('http_version', '1.1')}; proxy_http_version ${options.get('http_version', '1.1')};
proxy_set_header Host ${options.get('proxy_pass_host', domain)}; proxy_set_header Host ${domain};
% if options.get('websockets', False): % if options.get('websockets', False):
proxy_set_header Connection "upgrade"; proxy_set_header Connection "upgrade";
proxy_set_header Upgrade $http_upgrade; proxy_set_header Upgrade $http_upgrade;
% endif % endif
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host ${options.get('x_forwarded_host', options.get('proxy_pass_host', domain))}; proxy_set_header X-Forwarded-Host ${options.get('x_forwarded_host', domain)};
% for option, value in options.get('proxy_set_header', {}).items(): % for option, value in options.get('proxy_set_header', {}).items():
proxy_set_header ${option} ${value}; proxy_set_header ${option} ${value};
% endfor % endfor
% if location != '/' and location != '= /': % if location != '/':
proxy_set_header X-Script-Name ${location}; proxy_set_header X-Script-Name ${location};
% endif % endif
proxy_buffering off; proxy_buffering off;
@ -201,8 +201,6 @@ server {
fastcgi_hide_header X-XSS-Protection; fastcgi_hide_header X-XSS-Protection;
% endif % endif
fastcgi_hide_header Permissions-Policy; fastcgi_hide_header Permissions-Policy;
fastcgi_request_buffering off;
proxy_buffering off;
} }
% if not max_body_size: % if not max_body_size:
client_max_body_size 5M; client_max_body_size 5M;

View file

@ -0,0 +1,9 @@
actions = {
'nodejs_install_yarn': {
'command': 'npm install -g yarn@latest',
'unless': 'test -e /usr/lib/node_modules/yarn',
'after': {
'pkg_apt:',
},
},
}

View file

@ -1,40 +1,54 @@
defaults = { defaults = {
'apt': { 'apt': {
'additional_update_commands': { 'additional_update_commands': {
# update npm and yarn to latest version # update npm to latest version
'npm install -g npm@latest',
'npm install -g yarn@latest', 'npm install -g yarn@latest',
}, },
'packages': { 'packages': {
'nodejs': { 'nodejs': {},
'triggers': {
'action:apt_execute_update_commands',
},
},
'npm': {
'installed': False,
'triggers': {
'action:apt_execute_update_commands',
},
},
}, },
}, },
'nodejs': {
'version': 18,
},
}
VERSIONS_SHIPPED_BY_DEBIAN = {
10: 10,
11: 12,
12: 18,
13: 18,
} }
@metadata_reactor.provides( @metadata_reactor.provides(
'apt/repos/nodejs/items', 'apt/repos/nodejs/items',
'apt/additional_update_commands',
) )
def nodejs_from_version(metadata): def nodejs_from_version(metadata):
version = metadata.get('nodejs/version') version = metadata.get('nodejs/version')
return { if version != VERSIONS_SHIPPED_BY_DEBIAN[node.os_version[0]]:
'apt': { return {
'repos': { 'apt': {
'nodejs': { 'additional_update_commands': {
'items': { # update npm to latest version
f'deb https://deb.nodesource.com/node_{version}.x nodistro main', 'npm install -g npm@latest',
},
'repos': {
'nodejs': {
'items': {
f'deb https://deb.nodesource.com/node_{version}.x {{os_release}} main',
f'deb-src https://deb.nodesource.com/node_{version}.x {{os_release}} main',
},
}, },
}, },
}, },
}, }
} else:
return {
'apt': {
'packages': {
'npm': {},
},
},
}

View file

@ -32,9 +32,21 @@ Include = /etc/pacman.d/mirrorlist
Server = ${node.metadata.get('pacman/repository')} Server = ${node.metadata.get('pacman/repository')}
Include = /etc/pacman.d/mirrorlist Include = /etc/pacman.d/mirrorlist
% endif % endif
% if node.metadata.get('pacman/enable_aurto'): % if node.metadata.get('pacman/enable_aurto', True):
[aurto] [aurto]
Server = https://aurto.kunbox.net/ Server = https://aurto.kunbox.net/
SigLevel = Optional TrustAll SigLevel = Optional TrustAll
% endif % endif
% if node.has_bundle('zfs'):
[archzfs]
Server = http://archzfs.com/archzfs/x86_64
% if node.metadata.get('pacman/linux-lts', False):
[zfs-linux-lts]
% else:
[zfs-linux]
% endif
Server = http://kernels.archzfs.com/$repo/
% endif

View file

@ -33,7 +33,6 @@ svc_systemd['paccache.timer'] = {
} }
pkg_pacman = { pkg_pacman = {
'acpi_call-lts': {},
'at': {}, 'at': {},
'autoconf': {}, 'autoconf': {},
'automake': {}, 'automake': {},
@ -62,7 +61,6 @@ pkg_pacman = {
'ldns': {}, 'ldns': {},
'less': {}, 'less': {},
'libtool': {}, 'libtool': {},
'linux-lts': {},
'logrotate': {}, 'logrotate': {},
'lsof': {}, 'lsof': {},
'm4': {}, 'm4': {},
@ -104,6 +102,12 @@ pkg_pacman = {
'zip': {}, 'zip': {},
} }
if node.metadata.get('pacman/linux-lts', False):
pkg_pacman['linux-lts'] = {}
pkg_pacman['acpi_call-lts'] = {}
else:
pkg_pacman['linux'] = {}
pkg_pacman['acpi_call'] = {}
for pkg, config in node.metadata.get('pacman/packages', {}).items(): for pkg, config in node.metadata.get('pacman/packages', {}).items():
pkg_pacman[pkg] = config pkg_pacman[pkg] = config

View file

@ -4,7 +4,6 @@ defaults = {
'glibc', 'glibc',
'pacman', 'pacman',
}, },
'enable_aurto': True,
'no_extract': { 'no_extract': {
'etc/cron.d/0hourly', 'etc/cron.d/0hourly',
# don't install systemd-homed pam module. It produces a lot of spam in # don't install systemd-homed pam module. It produces a lot of spam in

View file

@ -33,9 +33,6 @@ defaults = {
'/mnt/paperless', '/mnt/paperless',
}, },
}, },
'nodejs': {
'version': 22,
},
'postgresql': { 'postgresql': {
'roles': { 'roles': {
'paperless': { 'paperless': {

View file

@ -1,5 +1,3 @@
devnull@${node.metadata.get('postfix/myhostname')} DISCARD DEV-NULL
% for address in sorted(blocked): % for address in sorted(blocked):
${address} REJECT ${address} REJECT
% endfor % endfor

View file

@ -3,7 +3,7 @@ biff = no
append_dot_mydomain = no append_dot_mydomain = no
readme_directory = no readme_directory = no
compatibility_level = 2 compatibility_level = 2
myhostname = ${node.metadata.get('postfix/myhostname')} myhostname = ${node.metadata.get('postfix/myhostname', node.metadata['hostname'])}
myorigin = /etc/mailname myorigin = /etc/mailname
mydestination = $myhostname, localhost mydestination = $myhostname, localhost
mynetworks = ${' '.join(sorted(mynetworks))} mynetworks = ${' '.join(sorted(mynetworks))}
@ -25,6 +25,7 @@ inet_interfaces = 127.0.0.1
% endif % endif
<%text> <%text>
smtp_use_tls = yes
smtp_tls_loglevel = 1 smtp_tls_loglevel = 1
smtp_tls_note_starttls_offer = yes smtp_tls_note_starttls_offer = yes
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
@ -37,8 +38,8 @@ smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
</%text> </%text>
% if node.has_bundle('postfixadmin'): % if node.has_bundle('postfixadmin'):
smtpd_tls_cert_file = /var/lib/dehydrated/certs/${node.metadata.get('postfix/myhostname')}/fullchain.pem smtpd_tls_cert_file = /var/lib/dehydrated/certs/${node.metadata.get('postfix/myhostname', node.metadata['hostname'])}/fullchain.pem
smtpd_tls_key_file = /var/lib/dehydrated/certs/${node.metadata.get('postfix/myhostname')}/privkey.pem smtpd_tls_key_file = /var/lib/dehydrated/certs/${node.metadata.get('postfix/myhostname', node.metadata['hostname'])}/privkey.pem
<%text> <%text>
smtpd_use_tls=yes smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
@ -47,7 +48,7 @@ smtpd_client_restrictions = permit_mynetworks permit_sasl_authenticated
smtpd_helo_required = yes smtpd_helo_required = yes
smtpd_helo_restrictions = permit_mynetworks reject_invalid_helo_hostname smtpd_helo_restrictions = permit_mynetworks reject_invalid_helo_hostname
smtpd_data_restrictions = reject_unauth_pipelining smtpd_data_restrictions = reject_unauth_pipelining
smtpd_recipient_restrictions = check_recipient_access hash:/etc/postfix/blocked_recipients, permit_mynetworks smtpd_recipient_restrictions = permit_mynetworks, check_recipient_access hash:/etc/postfix/blocked_recipients
smtpd_relay_before_recipient_restrictions = yes smtpd_relay_before_recipient_restrictions = yes
# https://ssl-config.mozilla.org/#server=postfix&version=3.7.10&config=intermediate&openssl=3.0.11&guideline=5.7 # https://ssl-config.mozilla.org/#server=postfix&version=3.7.10&config=intermediate&openssl=3.0.11&guideline=5.7

View file

@ -25,7 +25,7 @@ my_package = 'pkg_pacman:postfix' if node.os == 'arch' else 'pkg_apt:postfix'
files = { files = {
'/etc/mailname': { '/etc/mailname': {
'content': node.metadata.get('postfix/myhostname'), 'content': node.metadata.get('postfix/myhostname', node.metadata['hostname']),
'before': { 'before': {
my_package, my_package,
}, },

View file

@ -87,7 +87,7 @@ def letsencrypt(metadata):
} }
result['domains'] = { result['domains'] = {
metadata.get('postfix/myhostname'): set(), metadata.get('postfix/myhostname', metadata.get('hostname')): set(),
} }
return { return {
@ -148,14 +148,3 @@ def icinga2(metadata):
}, },
}, },
} }
@metadata_reactor.provides(
'postfix/myhostname',
)
def myhostname(metadata):
return {
'postfix': {
'myhostname': metadata.get('hostname'),
},
}

View file

@ -57,7 +57,7 @@ files = {
}, },
} }
if node.has_bundle('backup-client'): if node.has_bundle('backup-client') and not node.has_bundle('zfs'):
files['/etc/backup-pre-hooks.d/90-postgresql-dump-all'] = { files['/etc/backup-pre-hooks.d/90-postgresql-dump-all'] = {
'source': 'backup-pre-hook', 'source': 'backup-pre-hook',
'content_type': 'mako', 'content_type': 'mako',
@ -67,6 +67,10 @@ if node.has_bundle('backup-client'):
'mode': '0700', 'mode': '0700',
} }
directories['/var/tmp/postgresdumps'] = {} directories['/var/tmp/postgresdumps'] = {}
else:
files['/var/tmp/postgresdumps'] = {
'delete': True,
}
postgres_roles = { postgres_roles = {
'root': { 'root': {

View file

@ -11,7 +11,6 @@ defaults = {
'backups': { 'backups': {
'paths': { 'paths': {
'/var/lib/postgresql', '/var/lib/postgresql',
'/var/tmp/postgresdumps',
}, },
}, },
'bash_functions': { 'bash_functions': {
@ -75,6 +74,8 @@ if node.has_bundle('zfs'):
}, },
}, },
} }
else:
defaults['backups']['paths'].add('/var/tmp/postgresdumps')
@metadata_reactor.provides( @metadata_reactor.provides(

View file

@ -3,8 +3,6 @@ from os import listdir
from os.path import isfile, join from os.path import isfile, join
from subprocess import check_output from subprocess import check_output
from bundlewrap.utils.ui import io
zone_path = join(repo.path, 'data', 'powerdns', 'files', 'bind-zones') zone_path = join(repo.path, 'data', 'powerdns', 'files', 'bind-zones')
nameservers = set() nameservers = set()
@ -67,7 +65,7 @@ svc_systemd = {
actions = { actions = {
'powerdns_reload_zones': { 'powerdns_reload_zones': {
'triggered': True, 'triggered': True,
'command': r'pdns_control rediscover; pdns_control reload; pdns_control notify \*', 'command': 'pdns_control rediscover; pdns_control reload; pdns_control notify \*',
'after': { 'after': {
'svc_systemd:pdns', 'svc_systemd:pdns',
}, },
@ -81,10 +79,9 @@ if node.metadata.get('powerdns/features/bind', False):
continue continue
try: try:
output = check_output(['git', 'log', '-1', '--pretty=%ci']).decode('utf-8').strip() output = check_output(['git', 'log', '-1', '--pretty=%ci', join(zone_path, zone)]).decode('utf-8').strip()
serial = datetime.strptime(output, '%Y-%m-%d %H:%M:%S %z').strftime('%y%m%d%H%M') serial = datetime.strptime(output, '%Y-%m-%d %H:%M:%S %z').strftime('%y%m%d%H%M')
except Exception as e: except:
io.stderr(f"Error while parsing commit time for {zone} serial: {e!r}")
serial = datetime.now().strftime('%y%m%d0000') serial = datetime.now().strftime('%y%m%d0000')
primary_zones.add(zone) primary_zones.add(zone)
@ -163,7 +160,7 @@ if node.metadata.get('powerdns/features/pgsql', node.has_bundle('postgresql')):
actions['powerdns_load_pgsql_schema'] = { actions['powerdns_load_pgsql_schema'] = {
'command': node.metadata.get('postgresql/roles/powerdns/password').format_into('PGPASSWORD={} psql -h 127.0.0.1 -d powerdns -U powerdns -w < /usr/share/pdns-backend-pgsql/schema/schema.pgsql.sql'), 'command': node.metadata.get('postgresql/roles/powerdns/password').format_into('PGPASSWORD={} psql -h 127.0.0.1 -d powerdns -U powerdns -w < /usr/share/pdns-backend-pgsql/schema/schema.pgsql.sql'),
'unless': r'sudo -u postgres psql -d powerdns -c "\dt" | grep domains 2>&1 >/dev/null', 'unless': 'sudo -u postgres psql -d powerdns -c "\dt" | grep domains 2>&1 >/dev/null',
'needs': { 'needs': {
'bundle:postgresql', 'bundle:postgresql',
'pkg_apt:pdns-backend-pgsql', 'pkg_apt:pdns-backend-pgsql',

View file

@ -71,8 +71,8 @@ actions = {
'chown -R powerdnsadmin:powerdnsadmin /opt/powerdnsadmin/src/powerdnsadmin/static/', 'chown -R powerdnsadmin:powerdnsadmin /opt/powerdnsadmin/src/powerdnsadmin/static/',
]), ]),
'needs': { 'needs': {
'action:nodejs_install_yarn',
'action:powerdnsadmin_install_deps', 'action:powerdnsadmin_install_deps',
'bundle:nodejs',
'pkg_apt:', 'pkg_apt:',
}, },
}, },

View file

@ -13,9 +13,6 @@ defaults = {
'python3-wheel': {}, 'python3-wheel': {},
}, },
}, },
'nodejs': {
'version': 22,
},
'users': { 'users': {
'powerdnsadmin': { 'powerdnsadmin': {
'home': '/opt/powerdnsadmin', 'home': '/opt/powerdnsadmin',

View file

@ -7,6 +7,7 @@ from subprocess import check_output
from requests import get from requests import get
UPDATE_URL = '${url}' UPDATE_URL = '${url}'
USERNAME = '${username}' USERNAME = '${username}'
PASSWORD = '${password}' PASSWORD = '${password}'

View file

@ -5,6 +5,7 @@ from ipaddress import ip_address
from json import loads from json import loads
from subprocess import check_output, run from subprocess import check_output, run
DOMAIN = '${domain}' DOMAIN = '${domain}'
# <%text> # <%text>

View file

@ -1,5 +1,5 @@
assert node.has_bundle('redis'), f'{node.name}: pretalx needs redis' assert node.has_bundle('redis'), f'{node.name}: pretalx needs redis'
assert node.has_bundle('nodejs'), f'{node.name}: pretalx needs nodejs for rebuild step' assert node.has_bundle('nodejs'), f'{node.name}: pretalx needs nodejs for rebuild and regenerate_css step'
actions = { actions = {
'pretalx_create_virtualenv': { 'pretalx_create_virtualenv': {
@ -53,6 +53,17 @@ actions = {
}, },
'triggered': True, 'triggered': True,
}, },
'pretalx_regenerate-css': {
'command': 'sudo -u pretalx PRETALX_CONFIG_FILE=/opt/pretalx/pretalx.cfg /opt/pretalx/venv/bin/python -m pretalx regenerate_css',
'needs': {
'action:pretalx_migrate',
'directory:/opt/pretalx/data',
'directory:/opt/pretalx/static',
'file:/opt/pretalx/pretalx.cfg',
'bundle:nodejs',
},
'triggered': True,
},
} }
users = { users = {
@ -79,6 +90,7 @@ git_deploy = {
'action:pretalx_install', 'action:pretalx_install',
'action:pretalx_migrate', 'action:pretalx_migrate',
'action:pretalx_rebuild', 'action:pretalx_rebuild',
'action:pretalx_regenerate-css',
'svc_systemd:pretalx-web:restart', 'svc_systemd:pretalx-web:restart',
'svc_systemd:pretalx-worker:restart', 'svc_systemd:pretalx-worker:restart',
}, },
@ -109,6 +121,7 @@ svc_systemd = {
'action:pretalx_install', 'action:pretalx_install',
'action:pretalx_migrate', 'action:pretalx_migrate',
'action:pretalx_rebuild', 'action:pretalx_rebuild',
'action:pretalx_regenerate-css',
'file:/etc/systemd/system/pretalx-web.service', 'file:/etc/systemd/system/pretalx-web.service',
'file:/opt/pretalx/pretalx.cfg', 'file:/opt/pretalx/pretalx.cfg',
}, },
@ -117,7 +130,6 @@ svc_systemd = {
'needs': { 'needs': {
'action:pretalx_install', 'action:pretalx_install',
'action:pretalx_migrate', 'action:pretalx_migrate',
'action:pretalx_rebuild',
'file:/etc/systemd/system/pretalx-worker.service', 'file:/etc/systemd/system/pretalx-worker.service',
'file:/opt/pretalx/pretalx.cfg', 'file:/opt/pretalx/pretalx.cfg',
}, },
@ -192,6 +204,7 @@ for plugin_name, plugin_config in node.metadata.get('pretalx/plugins', {}).items
'triggers': { 'triggers': {
'action:pretalx_migrate', 'action:pretalx_migrate',
'action:pretalx_rebuild', 'action:pretalx_rebuild',
'action:pretalx_regenerate-css',
'svc_systemd:pretalx-web:restart', 'svc_systemd:pretalx-web:restart',
'svc_systemd:pretalx-worker:restart', 'svc_systemd:pretalx-worker:restart',
}, },

View file

@ -26,9 +26,6 @@ defaults = {
}, },
}, },
}, },
'nodejs': {
'version': 22,
},
'pretalx': { 'pretalx': {
'database': { 'database': {
'user': 'pretalx', 'user': 'pretalx',

View file

@ -1,13 +0,0 @@
files['/etc/proftpd/proftpd.conf'] = {
'source': f'{node.name}.conf',
'triggers': {
'svc_systemd:proftpd:restart',
},
}
svc_systemd['proftpd'] = {
'needs': {
'file:/etc/proftpd/proftpd.conf',
'pkg_apt:proftpd-core',
},
}

View file

@ -1,26 +0,0 @@
from bundlewrap.metadata import atomic
defaults = {
'apt': {
'packages': {
'proftpd-core': {},
},
},
}
@metadata_reactor.provides(
'firewall/port_rules',
)
def firewall(metadata):
sources = atomic(metadata.get('mosquitto/restrict-to', set()))
return {
'firewall': {
'port_rules': {
'20/tcp': sources,
'21/tcp': sources,
'49152-50192/tcp': sources,
},
},
}

View file

@ -1,30 +1,22 @@
disable_overscan=1 disable_overscan=1
hdmi_force_hotplug=1
dtparam=spi=on
dtparam=audio=on dtparam=audio=on
dtoverlay=vc4-kms-v3d dtoverlay=vc4-fkms-v3d
max_framebuffers=2 max_framebuffers=2
hdmi_drive=2
force_turbo=1 force_turbo=1
gpu_mem=${node.metadata.get('raspberrypi/gpu_mem', 128)} gpu_mem=${node.metadata['raspberrypi'].get('gpu_mem', 128)}
% if node.metadata.get('raspberrypi/enable_display'):
display_auto_detect=1
% else:
dtparam=i2c_arm=on
dtparam=i2s=on
dtparam=spi=on
hdmi_drive=2
hdmi_force_hotplug=1
% endif
% if node.os == 'debian': % if node.os == 'debian':
arm_64bit=1 arm_64bit=1
% endif % endif
arm_boost=1
% for item in sorted(node.metadata.get('raspberrypi/config.txt', set())): % for item in sorted(node.metadata['raspberrypi'].get('config.txt', set())):
${item} ${item}
% endfor % endfor
% if node.metadata.get('raspberrypi/enable_camera', False): % if node.metadata['raspberrypi'].get('camera', False):
camera_auto_detect=1 start_x=1
% endif % endif

View file

@ -15,11 +15,11 @@ actions = {
} }
files = { files = {
'/boot/firmware/cmdline.txt': { '/boot/cmdline.txt': {
'content': ' '.join(sorted(node.metadata['raspberrypi']['cmdline'])), 'content': ' '.join(sorted(node.metadata['raspberrypi']['cmdline'])),
**file_perms, **file_perms,
}, },
'/boot/firmware/config.txt': { '/boot/config.txt': {
'content_type': 'mako', 'content_type': 'mako',
'context': node.metadata['raspberrypi'], 'context': node.metadata['raspberrypi'],
**file_perms, **file_perms,

View file

@ -1,6 +1,5 @@
defaults = { defaults = {
'apt': { 'apt': {
'clean_old_kernels': False,
'packages': { 'packages': {
'dhcpcd5': { 'dhcpcd5': {
'installed': False, 'installed': False,
@ -15,16 +14,9 @@ defaults = {
'installed': False, 'installed': False,
}, },
}, },
'repos': {
'raspi': {
'install_gpg_key': False,
'items': {
'deb http://archive.raspberrypi.org/debian/ {os_release} main',
},
},
},
}, },
'raspberrypi': { 'raspberrypi': {
'default-target': 'multi-user.target',
'cmdline': { 'cmdline': {
'console=tty1', 'console=tty1',
'root=/dev/mmcblk0p2', 'root=/dev/mmcblk0p2',
@ -36,8 +28,6 @@ defaults = {
'plymouth.ignore-serial-consoles', 'plymouth.ignore-serial-consoles',
'net.ifnames=0', 'net.ifnames=0',
}, },
'default-target': 'multi-user.target',
'enable_display': False,
}, },
'systemd': { 'systemd': {
'journal': { 'journal': {
@ -47,19 +37,3 @@ defaults = {
}, },
}, },
} }
@metadata_reactor.provides(
'raspberrypi/cmdline',
)
def display(metadata):
if not metadata.get('raspberrypi/enable_display'):
return {}
return {
'raspberrypi': {
'cmdline': {
'video=DSI-1:800x480@60,rotate=180',
},
},
}

View file

@ -48,4 +48,3 @@ tcp-keepalive 0
timeout 0 timeout 0
zset-max-ziplist-entries 128 zset-max-ziplist-entries 128
zset-max-ziplist-value 64 zset-max-ziplist-value 64
protected-mode no

View file

@ -2,84 +2,6 @@ import re
from json import load from json import load
from os.path import join from os.path import join
with open(join(repo.path, 'configs', 'netbox', f'{node.name}.json')) as f:
netbox = load(f)
ips = {}
ports = {}
vlans = {
v['name']: {
'id': v['vid'],
'delete': False,
'tagged': set(),
'untagged': set(),
}
for v in netbox['vlans']
}
for port, conf in netbox['interfaces'].items():
for ip in conf['ips']:
ips[ip] = {'interface': port}
if conf['type'].lower() == 'virtual':
# these are VLAN interfaces (for management IPs)
if conf['ips']:
# this makes management services available in the VLAN
try:
vlans[port]['tagged'].add('bridge')
except KeyError:
raise ValueError(
f'name of virtual interface "{port}" on {node.name} '
f'matches none of the known VLANs: {list(vlans.keys())} '
'(you probably need to rename the interface in Netbox '
'and/or run netbox-dump)'
)
# We do not create the actual VLAN interface here, that
# happens automatically in items.py.
continue
elif not conf['enabled'] or not conf['mode']:
# disable unconfigured ports
ports[port] = {
'disabled': True,
'description': conf.get('description', ''),
}
# dont add vlans for this port
continue
else:
ports[port] = {
'disabled': False,
'description': conf.get('description', ''),
}
if conf.get('ips', []):
ports[port]['ips'] = set(conf['ips'])
if conf['type'] in (
'1000base-t',
'10gbase-x-sfpp',
'A_1000BASE_T',
'A_10GBASE_X_SFPP',
):
ports[port]['hw'] = True
if conf['untagged_vlan']:
vlans[conf['untagged_vlan']]['untagged'].add(port)
if conf['ips']:
# this makes management services available in the VLAN
vlans[conf['untagged_vlan']]['tagged'].add('bridge')
# tagged
if conf['mode'] in ('TAGGED_ALL', 'tagged-all'):
tagged = set(vlans.keys()) - {conf['untagged_vlan']}
else:
tagged = conf['tagged_vlans']
for vlan in tagged:
vlans[vlan]['tagged'].add(port)
# this makes management services available in the VLAN
if conf['ips']:
vlans[vlan]['tagged'].add('bridge')
defaults = { defaults = {
'icinga2_api': { 'icinga2_api': {
'routeros': { 'routeros': {
@ -95,14 +17,100 @@ defaults = {
}, },
}, },
}, },
'routeros': {
'ips': ips,
'ports': ports,
'vlans': vlans,
},
} }
@metadata_reactor.provides(
'routeros/ips',
'routeros/ports',
'routeros/vlans',
)
def get_ports_from_netbox_dump(metadata):
with open(join(repo.path, 'configs', f'netbox_device_{node.name}.json')) as f:
netbox = load(f)
ips = {}
ports = {}
vlans = {
v['name']: {
'id': v['vid'],
'delete': False,
'tagged': set(),
'untagged': set(),
}
for v in netbox['vlans']
}
for port, conf in netbox['interfaces'].items():
for ip in conf['ips']:
ips[ip] = {'interface': port}
if conf['type'] == 'VIRTUAL':
# these are VLAN interfaces (for management IPs)
if conf['ips']:
# this makes management services available in the VLAN
try:
vlans[port]['tagged'].add('bridge')
except KeyError:
raise ValueError(
f'name of virtual interface "{port}" on {node.name} '
f'matches none of the known VLANs: {list(vlans.keys())} '
'(you probably need to rename the interface in Netbox '
'and/or run netbox-dump)'
)
# We do not create the actual VLAN interface here, that
# happens automatically in items.py.
continue
elif not conf['enabled'] or not conf['mode']:
# disable unconfigured ports
ports[port] = {
'disabled': True,
'description': conf.get('description', ''),
}
# dont add vlans for this port
continue
else:
ports[port] = {
'disabled': False,
'description': conf.get('description', ''),
}
if conf.get('ips', []):
ports[port]['ips'] = set(conf['ips'])
if conf['type'] in (
'A_1000BASE_T',
'A_10GBASE_X_SFPP',
):
ports[port]['hw'] = True
if conf['untagged_vlan']:
vlans[conf['untagged_vlan']]['untagged'].add(port)
if conf['ips']:
# this makes management services available in the VLAN
vlans[conf['untagged_vlan']]['tagged'].add('bridge')
# tagged
if conf['mode'] == 'TAGGED_ALL':
tagged = set(vlans.keys()) - {conf['untagged_vlan']}
else:
tagged = conf['tagged_vlans']
for vlan in tagged:
vlans[vlan]['tagged'].add(port)
# this makes management services available in the VLAN
if conf['ips']:
vlans[vlan]['tagged'].add('bridge')
return {
'routeros': {
'ips': ips,
'ports': ports,
'vlans': vlans,
}
}
@metadata_reactor.provides('routeros/gateway') @metadata_reactor.provides('routeros/gateway')
def gateway(metadata): def gateway(metadata):
ip_pattern = re.compile(r'(\d{1,3}\.\d{1,3}\.\d{1,3}\.)\d{1,3}') ip_pattern = re.compile(r'(\d{1,3}\.\d{1,3}\.\d{1,3}\.)\d{1,3}')

View file

@ -1,7 +1,7 @@
reporting { reporting {
enabled = true; enabled = true;
email = 'devnull@${node.metadata.get('postfix/myhostname')}'; email = 'dmarc+${node.name.replace('.', '-')}@kunbox.net';
domain = '${node.metadata.get('postfix/myhostname')}'; domain = '${node.metadata.get('hostname')}';
org_name = 'kunbox.net'; org_name = 'kunbox.net';
smtp = '127.0.0.1'; smtp = '127.0.0.1';
smtp_port = 25; smtp_port = 25;

View file

@ -6,11 +6,6 @@ defaults = {
'rsyslog': {}, 'rsyslog': {},
}, },
}, },
'backups': {
'paths': {
'/var/log/rsyslog',
},
},
'icinga2_api': { 'icinga2_api': {
'rsyslog': { 'rsyslog': {
'services': { 'services': {

View file

@ -1,3 +0,0 @@
[Service]
RestartSec=10
Restart=on-failure

View file

@ -1,67 +0,0 @@
[global]
workgroup = KUNBOX
server string = ${node.name} samba
dns proxy = no
max log size = 1000
syslog = 1
syslog only = 1
panic action = /usr/share/samba/panic-action %d
encrypt passwords = true
passdb backend = tdbsam
obey pam restrictions = yes
map to guest = bad user
load printers = no
usershare allow guests = yes
allow insecure wide links = yes
min protocol = SMB2
% if timemachine:
vfs objects = fruit
fruit:aapl = yes
fruit:copyfile = yes
fruit:model = MacSamba
% endif
% for name, opts in sorted(node.metadata.get('samba/shares', {}).items()):
[${name}]
browseable = yes
comment = ${opts.get('comment', f'share of {opts["path"]}')}
fake oplocks = yes
force group = ${opts.get('force_group', 'nogroup')}
force user = ${opts.get('force_user', 'nobody')}
% if opts.get('guest_ok', True):
guest ok = yes
% else:
guest ok = no
% endif
locking = no
path = ${opts['path']}
printable = no
read only = no
vfs objects = catia fruit
writable = ${'yes' if opts.get('writable', False) else 'no'}
% if opts.get('follow_symlinks', True):
follow symlinks = yes
wide links = yes
% endif
% endfor
% for name in sorted(timemachine):
[timemachine-${name}]
comment = Time Machine backup for ${name}
available = yes
browseable = yes
guest ok = no
read only = false
valid users = timemachine-${name}
path = /srv/timemachine/${name}
durable handles = yes
vfs objects = catia fruit streams_xattr
fruit:delete_empty_adfiles = yes
fruit:metadata = stream
fruit:posix_rename = yes
fruit:time machine = yes
fruit:time machine max size = 750G
fruit:veto_appledouble = no
fruit:wipe_intentionally_left_blank_rfork = yes
% endfor

View file

@ -1,21 +0,0 @@
<?xml version="1.0" standalone='no'?>
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
<name replace-wildcards="yes">%h</name>
<service>
<type>_smb._tcp</type>
<port>445</port>
</service>
<service>
<type>_device-info._tcp</type>
<port>0</port>
<txt-record>model=RackMac1,2</txt-record>
</service>
<service>
<type>_adisk._tcp</type>
% for idx, share_name in enumerate(sorted(shares)):
<txt-record>dk${idx}=adVN=timemachine-${share_name},adVF=0x82</txt-record>
% endfor
<txt-record>sys=waMa=0,adVF=0x100</txt-record>
</service>
</service-group>

View file

@ -1,85 +0,0 @@
svc_systemd = {
'nmbd': {
'needs': {
'pkg_apt:samba',
},
},
'smbd': {
'needs': {
'pkg_apt:samba',
},
},
}
timemachine_shares = node.metadata.get('samba/timemachine-shares', set())
files = {
'/etc/samba/smb.conf': {
'content_type': 'mako',
'context': {
'timemachine': timemachine_shares,
},
'triggers': {
'svc_systemd:nmbd:restart',
'svc_systemd:smbd:restart',
},
},
'/etc/systemd/system/nmbd.service.d/bundlewrap.conf': {
'source': 'override.conf',
'triggers': {
'action:systemd-reload',
'svc_systemd:nmbd:restart',
},
},
'/etc/systemd/system/smbd.service.d/bundlewrap.conf': {
'source': 'override.conf',
'triggers': {
'action:systemd-reload',
'svc_systemd:smbd:restart',
},
},
}
last_action = set()
for user, uconfig in node.metadata.get('users', {}).items():
if (
'password' not in uconfig
or uconfig.get('delete')
or user in ('root',)
):
continue
actions[f'smbpasswd_for_user_{user}'] = {
'command': f'smbpasswd -a -s {user}',
'unless': f'pdbedit -L | grep -E "^{user}:"',
'data_stdin': uconfig['password'] + '\n' + uconfig['password'],
'needs': {
'pkg_apt:samba',
f'user:{user}',
},
'after': last_action,
}
last_action = {
f'action:smbpasswd_for_user_{user}',
}
if timemachine_shares:
assert node.has_bundle('avahi-daemon'), f'{node.name}: samba needs avahi-daemon to publish time machine shares'
files['/etc/avahi/services/timemachine.service'] = {
'content_type': 'mako',
'context': {
'shares': timemachine_shares,
},
}
for share_name in timemachine_shares:
users[f'timemachine-{share_name}'] = {
'home': f'/srv/timemachine/{share_name}',
}
directories[f'/srv/timemachine/{share_name}'] = {
'owner': f'timemachine-{share_name}',
'group': f'timemachine-{share_name}',
'mode': '0700',
}

View file

@ -1,53 +0,0 @@
from bundlewrap.metadata import atomic
defaults = {
'apt': {
'packages': {
'samba': {},
'samba-vfs-modules': {},
}
}
}
@metadata_reactor.provides(
'firewall/port_rules',
)
def firewall(metadata):
return {
'firewall': {
'port_rules': {
'137/udp': atomic(metadata.get('samba/restrict-to', set())),
'138/udp': atomic(metadata.get('samba/restrict-to', set())),
'139/tcp': atomic(metadata.get('samba/restrict-to', set())),
'445/tcp': atomic(metadata.get('samba/restrict-to', set())),
},
},
}
@metadata_reactor.provides(
'zfs/datasets',
)
def timemachine_zfs(metadata):
shares = metadata.get('samba/timemachine-shares', set())
if not shares:
return {}
assert node.has_bundle('zfs'), f'{node.name}: time machine backups require zfs'
datasets = {
'tank/timemachine': {},
}
for share_name in shares:
datasets[f'tank/timemachine/{share_name}'] = {
'mountpoint': f'/srv/timemachine/{share_name}',
}
return {
'zfs': {
'datasets': datasets,
},
}

View file

@ -0,0 +1,21 @@
#!/bin/bash
set -euo pipefail
DATE=$(date +%F_%H-%M-%S)
cd "$1"
convert *.tiff no_ocr.pdf
ocrmypdf -l deu no_ocr.pdf has_ocr.pdf
rm -f *.tiff
rm -f no_ocr.pdf
chown nobody:nogroup has_ocr.pdf
mv has_ocr.pdf "/srv/scansnap/${DATE}.pdf"
cd /
rm -r "$1"

View file

@ -0,0 +1,9 @@
#!/bin/bash
set -euo pipefail
OUTFILE=$(mktemp -d)
scanimage --source 'ADF Duplex' --format tiff --mode Color --brightness 23 --resolution 300 --page-width 210 --page-height 297.3 -x 210 -y 297.3 --batch=${OUTFILE}/p%04d.tiff
/etc/scanbd/scripts/ocr.sh "$OUTFILE" &

View file

@ -0,0 +1,52 @@
global {
debug = true
debug-level = 2
user = saned
group = scanner
saned = "/usr/sbin/saned"
saned_opt = {}
saned_env = { "SANE_CONFIG_DIR=/etc/scanbd" }
scriptdir = /etc/scanbd/scripts
timeout = 500
pidfile = "/var/run/scanbd.pid"
environment {
device = "SCANBD_DEVICE"
action = "SCANBD_ACTION"
}
function function_knob {
filter = "^message.*"
desc = "The value of the function knob / wheel / selector"
env = "SCANBD_FUNCTION"
}
function function_mode {
filter = "^mode.*"
desc = "Color mode"
env = "SCANBD_FUNCTION_MODE"
}
multiple_actions = false
action scan {
filter = "^scan.*"
numerical-trigger {
from-value = 0
to-value = 1
}
desc = "Scan to file"
script = "scan.sh"
}
}
include(scanner.d/avision.conf)
include(scanner.d/fujitsu.conf)
include(scanner.d/hp.conf)
include(scanner.d/pixma.conf)
include(scanner.d/snapscan.conf)
include(scanner.d/canon.conf)
include(scanner.d/plustek.conf)

39
bundles/scansnap/items.py Normal file
View file

@ -0,0 +1,39 @@
directories = {
'/etc/scanbd/scripts': {
'purge': True,
},
'/srv/scansnap': {
'owner': 'nobody',
'group': 'nogroup',
},
}
files = {
'/etc/scanbd/scanbd.conf': {
'triggers': {
'svc_systemd:scanbd:restart',
},
},
'/etc/scanbd/scripts/ocr.sh': {
'mode': '0755',
'needs': {
'directory:/srv/scansnap',
},
},
'/etc/scanbd/scripts/scan.sh': {
'mode': '0755',
'needs': {
'directory:/srv/scansnap',
'file:/etc/scanbd/scripts/ocr.sh',
},
},
}
svc_systemd = {
'scanbd': {
'needs': {
'file:/etc/scanbd/scanbd.conf',
'pkg_apt:scanbd',
},
},
}

View file

@ -0,0 +1,22 @@
defaults = {
'apt': {
'packages': {
'sane-utils': {},
'scanbd': {},
'imagemagick': {},
'ocrmypdf': {},
'tesseract-ocr-deu': {},
},
},
'backups': {
'paths': {
'/srv/scansnap',
},
},
'cron': {
'jobs': {
# Automatically remove files which are older than 14 days
'scansnap_cleanup': '00 00 * * * root /usr/bin/find /srv/scansnap/ -mindepth 1 -mtime +14 -delete',
},
},
}

View file

@ -1,21 +0,0 @@
[Unit]
Description=SDM630 stats printout
Conflicts=getty@tty1.service
After=systemd-user-sessions.service getty@tty1.service plymouth-quit.service
[Service]
User=sdm630_mqtt
Group=sdm630_mqtt
ExecStart=/opt/sdm630_mqtt/venv/bin/python printout.py /opt/sdm630_mqtt/config.toml
WorkingDirectory=/opt/sdm630_mqtt/src
Restart=always
RestartSec=10
StandardInput=tty
StandardOutput=tty
StandardError=journal
TTYPath=/dev/tty1
TTYReset=yes
TTYVHangup=yes
[Install]
WantedBy=multi-user.target

View file

@ -1,14 +0,0 @@
[Unit]
Description=SDM630-to-MQTT bridge
After=network.target
[Service]
User=sdm630_mqtt
Group=sdm630_mqtt
ExecStart=/opt/sdm630_mqtt/venv/bin/python sdm630_mqtt.py /opt/sdm630_mqtt/config.toml
WorkingDirectory=/opt/sdm630_mqtt/src
Restart=always
RestartSec=1
[Install]
WantedBy=multi-user.target

View file

@ -1,76 +0,0 @@
directories['/opt/sdm630_mqtt/src'] = {}
git_deploy['/opt/sdm630_mqtt/src'] = {
'repo': 'https://git.franzi.business/kunsi/sdm630_mqtt.git',
'rev': 'main',
'triggers': {
'action:sdm630_mqtt_install_deps',
},
}
actions['sdm630_mqtt_create_virtualenv'] = {
'command': 'python3 -m virtualenv /opt/sdm630_mqtt/venv',
'unless': 'test -x /opt/sdm630_mqtt/venv/bin/python3',
'needs': {
'directory:/opt/sdm630_mqtt/src',
},
}
actions['sdm630_mqtt_install_deps'] = {
'command': 'cd /opt/sdm630_mqtt/src && /opt/sdm630_mqtt/venv/bin/pip install -r requirements.txt',
'triggered': True,
'needs': {
'action:sdm630_mqtt_create_virtualenv',
},
}
users['sdm630_mqtt'] = {
'home': '/opt/sdm630_mqtt',
}
files['/opt/sdm630_mqtt/config.toml'] = {
'content': repo.libs.faults.dict_as_toml(node.metadata.get('sdm630_mqtt/config')),
'triggers': set(),
}
if node.has_bundle('telegraf'):
files['/opt/sdm630_mqtt/config.toml']['triggers'].add('svc_systemd:telegraf:restart')
git_deploy['/opt/sdm630_mqtt/src']['triggers'].add('svc_systemd:telegraf:restart')
if node.metadata.get('sdm630_mqtt/enable_stats_collection', True):
files['/usr/local/lib/systemd/system/sdm630_to_mqtt.service'] = {
'triggers': {
'action:systemd-reload',
'svc_systemd:sdm630_to_mqtt:restart',
},
}
svc_systemd['sdm630_to_mqtt'] = {
'needs': {
'git_deploy:/opt/sdm630_mqtt/src',
'action:sdm630_mqtt_install_deps',
'file:/usr/local/lib/systemd/system/sdm630_to_mqtt.service',
},
}
files['/opt/sdm630_mqtt/config.toml']['triggers'].add('svc_systemd:sdm630_to_mqtt:restart')
git_deploy['/opt/sdm630_mqtt/src']['triggers'].add('svc_systemd:sdm630_to_mqtt:restart')
if node.metadata.get('sdm630_mqtt/enable_local_printout', False):
files['/usr/local/lib/systemd/system/sdm630_printout.service'] = {
'triggers': {
'action:systemd-reload',
'svc_systemd:sdm630_printout:restart',
},
}
svc_systemd['sdm630_printout'] = {
'needs': {
'git_deploy:/opt/sdm630_mqtt/src',
'action:sdm630_mqtt_install_deps',
'file:/usr/local/lib/systemd/system/sdm630_printout.service',
},
}
files['/opt/sdm630_mqtt/config.toml']['triggers'].add('svc_systemd:sdm630_printout:restart')
git_deploy['/opt/sdm630_mqtt/src']['triggers'].add('svc_systemd:sdm630_printout:restart')

View file

@ -1,38 +0,0 @@
defaults = {
'sdm630_mqtt': {
'config': {
'modbus': {
'host': '127.0.0.1',
'port': 501,
'unit_id': 1,
},
'mqtt': {
'prefix': 'sdm630',
'host': '127.0.0.1',
'port': 1883,
},
'printout': {
'title': 'SDM630',
},
'telegraf': {
'identifier': 'unknown',
},
},
},
'telegraf': {
'input_plugins': {
'execd': {
'sdm630_mqtt': {
'command': [
'/opt/sdm630_mqtt/venv/bin/python',
'/opt/sdm630_mqtt/src/telegraf.py',
'/opt/sdm630_mqtt/config.toml',
],
'signal': 'none',
'restart_delay': '1s',
'data_format': 'influx',
},
},
},
},
}

View file

@ -43,6 +43,30 @@ if node.has_bundle('telegraf'):
} }
@metadata_reactor.provides(
'smartd/disks',
)
def zfs_disks_to_metadata(metadata):
disks = set()
for config in metadata.get('zfs/pools', {}).values():
for option in config['when_creating']['config']:
if option.get('type', '') in {'log', 'cache'}:
continue
for disk in option['devices']:
if search(r'p([0-9]+)$', disk) or disk.startswith('/dev/mapper/'):
continue
disks.add(disk)
return {
'smartd': {
'disks': disks,
},
}
@metadata_reactor.provides( @metadata_reactor.provides(
'icinga2_api/smartd/services', 'icinga2_api/smartd/services',
) )

View file

@ -4,30 +4,27 @@ from re import findall
from subprocess import check_output from subprocess import check_output
from sys import exit from sys import exit
ITERATIONS = 10
try: try:
top_output = None top_output = None
top_output = check_output(rf"top -b -n{ITERATIONS} -d1 | grep -i '^%cpu'", shell=True).decode('UTF-8') for line in check_output(['top', '-b', '-n1', '-d1']).decode('UTF-8').splitlines():
if line.lower().strip().startswith('%cpu'):
top_output = line.lower().split(':', 2)[1]
break
if not top_output:
print('%cpu not found in top output')
exit(3)
cpu_usage = {} cpu_usage = {}
for value, identifier in findall(r'([0-9\.\,]{3,5}) ([a-z]{2})', top_output): for value, identifier in findall('([0-9\.\,]{3,5}) ([a-z]{2})', top_output):
if identifier not in cpu_usage: cpu_usage[identifier] = float(value.replace(',', '.'))
cpu_usage[identifier] = 0.0
cpu_usage[identifier] += float(value.replace(',', '.'))
output = []
for identifier, value_added in cpu_usage.items():
value = value_added / ITERATIONS
output.append(f"{value:.2f} {identifier}")
cpu_usage[identifier] = value
print(f"Average over {ITERATIONS} seconds: " + ", ".join(output))
warn = set() warn = set()
crit = set() crit = set()
print(top_output)
# steal # steal
if cpu_usage['st'] > 10: if cpu_usage['st'] > 10:
crit.add('CPU steal is {}% (>10%)'.format(cpu_usage['st'])) crit.add('CPU steal is {}% (>10%)'.format(cpu_usage['st']))

View file

@ -19,11 +19,7 @@ crit_days=30
case "$issuer_hash" in case "$issuer_hash" in
# 4f06f81d: issuer=C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3 # 4f06f81d: issuer=C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
# 8d33f237: issuer=C = US, O = Let's Encrypt, CN = R3 # 8d33f237: issuer=C = US, O = Let's Encrypt, CN = R3
# 462422cf: issuer=C = US, O = Let's Encrypt, CN = E5 4f06f81d|8d33f237)
# 9aad238c: issuer=C = US, O = Let's Encrypt, CN = E6
# 31dfb39d: issuer=C = US, O = Let's Encrypt, CN = R11
# aa578057: issuer=C = US, O = Let's Encrypt, CN = R10
4f06f81d|8d33f237|462422cf|9aad238c|31dfb39d|aa578057)
warn_days=10 warn_days=10
crit_days=3 crit_days=3
;; ;;

View file

@ -19,8 +19,6 @@ defaults = {
'services': { 'services': {
'CPU': { 'CPU': {
'command_on_monitored_host': '/usr/local/share/icinga/plugins/check_cpu_stats', 'command_on_monitored_host': '/usr/local/share/icinga/plugins/check_cpu_stats',
# takes samples over 10 seconds
'vars.sshmon_timeout': 20
}, },
'LOAD': { 'LOAD': {
'command_on_monitored_host': '/usr/lib/nagios/plugins/check_load -r -w 4,2,1 -c 8,4,2', 'command_on_monitored_host': '/usr/lib/nagios/plugins/check_load -r -w 4,2,1 -c 8,4,2',

View file

@ -3,6 +3,3 @@ Name=${' '.join(sorted(match))}
[Network] [Network]
Bridge=${bridge} Bridge=${bridge}
[Link]
ActivationPolicy=always-up

View file

@ -4,9 +4,6 @@ defaults = {
'isc-dhcp-client': { 'isc-dhcp-client': {
'installed': False, 'installed': False,
}, },
'network-manager': {
'installed': False,
},
'resolvconf': { 'resolvconf': {
'installed': False, 'installed': False,
}, },

View file

@ -1,4 +1,4 @@
timezone = node.metadata.get('timezone') timezone = node.metadata.get('timezone', 'UTC')
actions['systemd-reload'] = { actions['systemd-reload'] = {
'command': 'systemctl daemon-reload', 'command': 'systemctl daemon-reload',

View file

@ -21,7 +21,6 @@ defaults = {
}, },
}, },
}, },
'timezone': 'UTC',
} }
if not node.has_bundle('rsyslogd'): if not node.has_bundle('rsyslogd'):

View file

@ -11,19 +11,7 @@ telegraf_config = {
'quiet': False, 'quiet': False,
'round_interval': False, 'round_interval': False,
}, },
'outputs': { 'inputs': {
'influxdb_v2': [{
'urls': [node.metadata.get('telegraf/influxdb_url', repo.libs.defaults.influxdb_url)],
'token': node.metadata.get('telegraf/influxdb_token', repo.vault.decrypt(repo.libs.defaults.influxdb_token)),
'organization': node.metadata.get('telegraf/influxdb_org', repo.vault.decrypt(repo.libs.defaults.influxdb_org)),
'bucket': node.metadata.get('telegraf/influxdb_bucket', repo.vault.decrypt(repo.libs.defaults.influxdb_bucket)),
}],
},
'inputs': {},
}
if node.metadata.get('telegraf/collect_default_metrics', True):
telegraf_config['inputs'] = {
'cpu': [{ 'cpu': [{
'percpu': False, 'percpu': False,
'totalcpu': True, 'totalcpu': True,
@ -55,9 +43,17 @@ if node.metadata.get('telegraf/collect_default_metrics', True):
'nstat': [{}], 'nstat': [{}],
'processes': [{}], 'processes': [{}],
'system': [{}], 'system': [{}],
} **node.metadata.get('telegraf/input_plugins/builtin', {}),
},
telegraf_config['inputs'].update(node.metadata.get('telegraf/input_plugins/builtin', {})) 'outputs': {
'influxdb_v2': [{
'urls': [node.metadata.get('telegraf/influxdb_url', repo.libs.defaults.influxdb_url)],
'token': node.metadata.get('telegraf/influxdb_token', repo.vault.decrypt(repo.libs.defaults.influxdb_token)),
'organization': node.metadata.get('telegraf/influxdb_org', repo.vault.decrypt(repo.libs.defaults.influxdb_org)),
'bucket': node.metadata.get('telegraf/influxdb_bucket', repo.vault.decrypt(repo.libs.defaults.influxdb_bucket)),
}],
},
}
# Bundlewrap can't merge lists. To work around this, telegraf/input_plugins/exec(d) # Bundlewrap can't merge lists. To work around this, telegraf/input_plugins/exec(d)
# is a dict, of which we only use the value of it. This also allows us # is a dict, of which we only use the value of it. This also allows us

View file

@ -2,9 +2,6 @@ from json import dumps
from bundlewrap.metadata import MetadataJSONEncoder from bundlewrap.metadata import MetadataJSONEncoder
if node.has_bundle('pacman'):
assert node.metadata.get('pacman/enable_aurto'), f'{node.name}: bundle:zfs needs aurto for zfs-linux-lts package'
files = { files = {
'/etc/modprobe.d/zfs.conf': { '/etc/modprobe.d/zfs.conf': {
'source': 'zfs-modprobe.conf', 'source': 'zfs-modprobe.conf',

View file

@ -48,12 +48,6 @@ defaults = {
'etc/sudoers.d/zfs', 'etc/sudoers.d/zfs',
}, },
'packages': { 'packages': {
'zfs-linux-lts': {
'needed_by': {
'zfs_dataset:',
'zfs_pool:',
},
},
'zfs-utils': { 'zfs-utils': {
'needed_by': { 'needed_by': {
'svc_systemd:zfs-zed', 'svc_systemd:zfs-zed',
@ -127,6 +121,27 @@ if node.has_bundle('telegraf'):
} }
@metadata_reactor.provides(
'pacman/packages',
)
def packages(metadata):
if node.metadata.get('pacman/linux-lts', False):
pkgname = 'zfs-linux-lts'
else:
pkgname = 'zfs-linux'
return {
'pacman': {
'packages': {
pkgname: {
'needed_by': {
'zfs_dataset:',
'zfs_pool:',
},
},
},
},
}
@metadata_reactor.provides( @metadata_reactor.provides(
'apt/packages', 'apt/packages',
) )
@ -155,7 +170,7 @@ def scrub_timer(metadata):
'systemd-timers': { 'systemd-timers': {
'timers': { 'timers': {
'zfs-scrub': { 'zfs-scrub': {
'when': metadata.get('zfs/scrub_when', 'Sun 02:00:00 UTC'), 'when': 'Sun 02:00:00 UTC',
'command': scrubs, 'command': scrubs,
}, },
}, },

View file

@ -1,7 +1,5 @@
109.237.176.0/20 109.237.176.0/20
109.72.116.0/24
116.50.16.0/21 116.50.16.0/21
128.65.164.0/22
129.181.208.0/21 129.181.208.0/21
129.181.216.0/22 129.181.216.0/22
137.170.112.0/24 137.170.112.0/24
@ -17,12 +15,13 @@
139.12.4.0/24 139.12.4.0/24
141.169.240.0/20 141.169.240.0/20
141.77.0.0/16 141.77.0.0/16
141.98.44.0/24
143.99.213.0/24 143.99.213.0/24
145.225.16.0/23 145.225.16.0/23
146.247.58.0/24 146.247.58.0/24
147.136.84.0/22
147.161.22.0/24 147.161.22.0/24
147.78.17.0/24 147.78.17.0/24
147.79.8.0/21
149.208.250.0/23 149.208.250.0/23
149.208.252.0/24 149.208.252.0/24
149.208.253.0/24 149.208.253.0/24
@ -35,7 +34,6 @@
149.249.244.0/22 149.249.244.0/22
149.249.244.0/23 149.249.244.0/23
149.249.246.0/23 149.249.246.0/23
153.17.244.8/29
153.17.249.0/24 153.17.249.0/24
153.17.250.0/24 153.17.250.0/24
153.17.251.0/24 153.17.251.0/24
@ -48,11 +46,7 @@
153.97.32.0/24 153.97.32.0/24
158.116.231.0/24 158.116.231.0/24
160.211.126.0/24 160.211.126.0/24
163.5.156.0/24 163.5.168.0/24
163.5.170.0/24
163.5.186.0/24
163.5.220.0/24
163.5.66.0/24
164.133.10.0/24 164.133.10.0/24
164.133.11.0/24 164.133.11.0/24
164.133.150.0/24 164.133.150.0/24
@ -66,9 +60,11 @@
168.199.192.0/22 168.199.192.0/22
168.199.212.0/22 168.199.212.0/22
170.237.92.0/23 170.237.92.0/23
171.25.178.0/24
176.221.24.0/24
176.221.25.0/24
176.53.136.0/24 176.53.136.0/24
176.53.137.0/24 176.53.137.0/24
176.57.59.0/24
185.100.160.0/22 185.100.160.0/22
185.101.244.0/23 185.101.244.0/23
185.101.246.0/23 185.101.246.0/23
@ -80,38 +76,45 @@
185.131.239.0/24 185.131.239.0/24
185.133.12.0/22 185.133.12.0/22
185.136.115.0/24 185.136.115.0/24
185.149.25.0/24
185.149.26.0/24
185.149.27.0/24
185.149.52.0/24 185.149.52.0/24
185.157.101.0/24 185.157.101.0/24
185.161.176.0/22 185.161.176.0/22
185.162.72.0/23
185.163.76.0/24 185.163.76.0/24
185.163.77.0/24 185.163.77.0/24
185.163.78.0/24 185.163.78.0/24
185.163.79.0/24 185.163.79.0/24
185.172.38.0/24
185.172.39.0/24
185.180.224.0/24 185.180.224.0/24
185.183.212.0/23 185.183.212.0/23
185.183.214.0/23 185.183.214.0/23
185.188.64.0/24 185.188.64.0/24
185.195.239.0/24
185.198.13.0/24 185.198.13.0/24
185.202.32.0/21 185.202.32.0/21
185.203.148.0/22
185.207.46.0/24 185.207.46.0/24
185.21.247.0/24 185.235.71.0/24
185.237.0.0/24 185.237.0.0/24
185.237.1.0/24 185.237.1.0/24
185.237.2.0/24 185.237.2.0/24
185.240.85.0/24
185.242.224.0/24 185.242.224.0/24
185.243.44.0/22 185.243.44.0/22
185.243.44.0/24 185.243.44.0/24
185.243.45.0/24 185.243.45.0/24
185.243.46.0/24 185.243.46.0/24
185.243.47.0/24 185.243.47.0/24
185.250.42.0/23
185.28.208.0/22 185.28.208.0/22
185.39.12.0/22 185.39.12.0/22
185.48.0.0/22 185.48.0.0/22
185.57.231.0/24
185.57.24.0/24 185.57.24.0/24
185.82.160.0/23 185.82.160.0/23
188.214.139.0/24 185.91.204.0/22
192.109.121.0/24 192.109.121.0/24
192.109.122.0/24 192.109.122.0/24
192.109.124.0/24 192.109.124.0/24
@ -173,6 +176,7 @@
193.110.102.0/23 193.110.102.0/23
193.110.102.0/24 193.110.102.0/24
193.110.103.0/24 193.110.103.0/24
193.124.35.0/24
193.138.91.0/24 193.138.91.0/24
193.141.143.0/24 193.141.143.0/24
193.141.180.0/23 193.141.180.0/23
@ -239,6 +243,7 @@
193.41.10.0/23 193.41.10.0/23
193.47.164.0/24 193.47.164.0/24
193.53.93.0/24 193.53.93.0/24
193.56.21.0/24
193.58.253.0/24 193.58.253.0/24
193.84.136.0/22 193.84.136.0/22
193.96.230.0/24 193.96.230.0/24
@ -248,7 +253,6 @@
193.98.224.0/24 193.98.224.0/24
193.99.96.0/20 193.99.96.0/20
194.0.151.0/24 194.0.151.0/24
194.0.232.0/24
194.110.133.0/24 194.110.133.0/24
194.113.160.0/22 194.113.160.0/22
194.113.20.0/23 194.113.20.0/23
@ -291,13 +295,6 @@
194.15.64.0/21 194.15.64.0/21
194.15.72.0/22 194.15.72.0/22
194.150.228.0/23 194.150.228.0/23
194.152.128.0/24
194.152.129.0/24
194.152.132.0/24
194.152.141.0/24
194.152.142.0/24
194.152.154.0/24
194.152.155.0/24
194.153.86.0/24 194.153.86.0/24
194.156.128.0/22 194.156.128.0/22
194.156.148.0/24 194.156.148.0/24
@ -340,20 +337,26 @@
194.39.63.0/24 194.39.63.0/24
194.39.88.0/21 194.39.88.0/21
194.39.97.0/24 194.39.97.0/24
194.45.144.0/21
194.49.110.0/24
194.49.117.0/24 194.49.117.0/24
194.49.118.0/23 194.49.118.0/23
194.49.125.0/24 194.49.125.0/24
194.49.48.0/24 194.49.48.0/24
194.49.54.0/24 194.49.54.0/24
194.49.72.0/24
194.49.73.0/24 194.49.73.0/24
194.49.74.0/23 194.49.74.0/23
194.49.85.0/24 194.49.85.0/24
194.55.158.0/24
194.55.180.0/24 194.55.180.0/24
194.55.183.0/24 194.55.183.0/24
194.55.192.0/19 194.55.192.0/19
194.55.63.0/24 194.55.63.0/24
194.55.64.0/20 194.55.64.0/20
194.55.87.0/24 194.55.87.0/24
194.58.40.0/24
194.58.56.0/23
194.59.143.0/24 194.59.143.0/24
194.59.150.0/24 194.59.150.0/24
194.59.151.0/24 194.59.151.0/24
@ -379,22 +382,34 @@
194.76.52.0/24 194.76.52.0/24
194.77.41.0/24 194.77.41.0/24
194.77.42.0/24 194.77.42.0/24
194.85.248.0/24
194.85.251.0/24
194.87.10.0/24
194.87.17.0/24
194.87.255.0/24
194.87.77.0/24
194.88.112.0/20
194.88.16.0/21 194.88.16.0/21
194.88.24.0/23 194.88.24.0/23
194.88.26.0/24 194.88.26.0/24
194.88.28.0/23 194.88.28.0/23
194.88.96.0/21
194.99.118.0/24 194.99.118.0/24
194.99.34.0/24 194.99.34.0/24
194.99.76.0/23 194.99.76.0/23
194.99.83.0/24 194.99.83.0/24
194.99.92.0/22 194.99.92.0/22
195.133.20.0/24
195.133.64.0/22
195.133.7.0/24 195.133.7.0/24
195.133.76.0/24
195.137.216.0/23 195.137.216.0/23
195.138.223.0/24 195.138.223.0/24
195.144.15.0/24 195.144.15.0/24
195.145.0.0/16 195.145.0.0/16
195.149.79.0/24 195.149.79.0/24
195.160.248.0/22 195.160.248.0/22
195.178.132.0/22
195.190.2.0/24 195.190.2.0/24
195.192.254.0/24 195.192.254.0/24
195.200.207.0/24 195.200.207.0/24
@ -421,14 +436,12 @@
198.40.90.0/24 198.40.90.0/24
198.57.10.0/24 198.57.10.0/24
2.160.0.0/12 2.160.0.0/12
2.58.100.0/24
2.58.102.0/24 2.58.102.0/24
204.52.120.0/24
204.52.121.0/24
204.69.32.0/24 204.69.32.0/24
205.142.63.0/24 205.142.63.0/24
212.184.0.0/15 212.184.0.0/15
212.185.0.0/16 212.185.0.0/16
212.87.217.0/24
213.145.90.0/23 213.145.90.0/23
213.145.92.0/23 213.145.92.0/23
213.173.0.0/19 213.173.0.0/19
@ -437,7 +450,6 @@
213.209.156.0/24 213.209.156.0/24
217.0.0.0/13 217.0.0.0/13
217.117.96.0/24 217.117.96.0/24
217.198.189.0/24
217.224.0.0/11 217.224.0.0/11
217.24.32.0/20 217.24.32.0/20
217.24.33.0/24 217.24.33.0/24
@ -447,21 +459,35 @@
31.224.0.0/11 31.224.0.0/11
31.6.56.0/23 31.6.56.0/23
37.143.0.0/22 37.143.0.0/22
37.230.56.0/24
37.230.57.0/24
37.230.58.0/23
37.230.60.0/24
37.230.63.0/24
37.46.11.0/24 37.46.11.0/24
37.50.0.0/15 37.50.0.0/15
37.80.0.0/12 37.80.0.0/12
45.128.14.0/23
45.132.217.0/24
45.132.80.0/22 45.132.80.0/22
45.141.54.0/24 45.140.208.0/24
45.145.16.0/24 45.141.130.0/24
45.142.236.0/24
45.145.241.0/24
45.145.243.0/24
45.147.227.0/24 45.147.227.0/24
45.155.77.0/24
45.81.255.0/24 45.81.255.0/24
45.83.136.0/22 45.83.136.0/22
45.84.214.0/24
45.93.186.0/23 45.93.186.0/23
46.20.216.0/21
46.250.224.0/21 46.250.224.0/21
46.250.232.0/21 46.250.232.0/21
46.78.0.0/15 46.78.0.0/15
46.80.0.0/12 46.80.0.0/12
5.10.208.0/24
5.10.209.0/24
5.10.220.0/24
5.133.112.0/24 5.133.112.0/24
5.249.188.0/22 5.249.188.0/22
5.35.192.0/21 5.35.192.0/21
@ -477,11 +503,14 @@
64.137.119.0/24 64.137.119.0/24
64.137.125.0/24 64.137.125.0/24
64.137.127.0/24 64.137.127.0/24
77.242.149.0/24
77.47.152.0/22 77.47.152.0/22
77.83.136.0/23 77.83.136.0/23
77.83.138.0/23 77.83.138.0/23
77.83.32.0/22
77.90.156.0/24 77.90.156.0/24
77.90.184.0/24 77.90.184.0/24
79.139.52.0/22
79.192.0.0/10 79.192.0.0/10
80.128.0.0/11 80.128.0.0/11
80.128.0.0/12 80.128.0.0/12
@ -493,47 +522,38 @@
80.157.8.0/21 80.157.8.0/21
80.187.0.0/16 80.187.0.0/16
80.187.160.0/20 80.187.160.0/20
80.244.13.0/24
80.64.240.0/22 80.64.240.0/22
80.71.231.0/24 80.71.231.0/24
80.71.233.0/24 80.71.233.0/24
80.71.235.0/24 80.71.235.0/24
80.71.236.0/24 80.71.236.0/24
80.71.238.0/24 80.71.238.0/24
80.83.80.0/21
81.201.32.0/20 81.201.32.0/20
81.31.210.0/23 81.30.96.0/20
82.163.104.0/21 82.152.178.0/24
82.163.60.0/22 82.163.60.0/22
82.206.32.0/21 82.206.32.0/21
82.206.40.0/21 82.206.40.0/21
82.206.48.0/21
82.215.70.0/24 82.215.70.0/24
83.136.208.0/22
83.147.36.0/22
83.243.48.0/21 83.243.48.0/21
84.128.0.0/10 84.128.0.0/10
84.234.16.0/20
84.246.108.0/24 84.246.108.0/24
84.32.108.0/22 84.32.108.0/22
84.32.48.0/22 84.32.48.0/22
84.55.0.0/24
84.55.1.0/24
84.55.2.0/24
84.55.3.0/24
84.55.4.0/24
84.55.5.0/24
84.55.6.0/24
84.55.7.0/24
85.116.28.0/24 85.116.28.0/24
85.116.29.0/24 85.116.29.0/24
85.116.30.0/24 85.116.30.0/24
85.116.31.0/24 85.116.31.0/24
85.119.160.0/23 85.119.160.0/23
85.204.181.0/24 85.204.160.0/22
85.208.248.0/24 85.208.248.0/24
85.208.249.0/24 85.208.249.0/24
85.208.250.0/24 85.208.250.0/24
85.208.251.0/24 85.208.251.0/24
86.105.211.0/24 85.237.76.0/22
86.107.164.0/24
86.38.248.0/21 86.38.248.0/21
86.38.37.0/24 86.38.37.0/24
87.128.0.0/10 87.128.0.0/10
@ -544,40 +564,10 @@
88.216.60.0/22 88.216.60.0/22
89.116.64.0/22 89.116.64.0/22
89.213.186.0/23 89.213.186.0/23
89.39.97.0/24 89.35.127.0/24
89.43.34.0/24 89.43.34.0/24
91.0.0.0/10 91.0.0.0/10
91.103.240.0/21 91.103.240.0/21
91.124.135.0/24
91.124.19.0/24
91.124.20.0/24
91.124.21.0/24
91.124.22.0/24
91.124.23.0/24
91.124.24.0/24
91.124.26.0/24
91.124.27.0/24
91.124.28.0/24
91.124.31.0/24
91.124.32.0/24
91.124.33.0/24
91.124.34.0/24
91.124.36.0/24
91.124.37.0/24
91.124.38.0/24
91.124.39.0/24
91.124.40.0/24
91.124.41.0/24
91.124.42.0/24
91.124.43.0/24
91.124.44.0/24
91.124.45.0/24
91.124.46.0/24
91.124.47.0/24
91.124.50.0/24
91.124.51.0/24
91.124.6.0/24
91.124.7.0/24
91.189.192.0/21 91.189.192.0/21
91.194.232.0/23 91.194.232.0/23
91.198.113.0/24 91.198.113.0/24
@ -602,40 +592,19 @@
91.216.242.0/24 91.216.242.0/24
91.216.45.0/24 91.216.45.0/24
91.217.214.0/24 91.217.214.0/24
91.221.12.0/23
91.222.232.0/22 91.222.232.0/22
91.227.98.0/23 91.227.98.0/23
91.232.136.0/22
91.232.54.0/24 91.232.54.0/24
92.112.128.0/24
92.112.155.0/24
92.112.157.0/24
92.112.16.0/22
92.112.160.0/24
92.112.162.0/24
92.112.165.0/24
92.112.167.0/24
92.112.20.0/22
92.112.48.0/24
92.112.49.0/24
92.112.52.0/24
92.112.54.0/24
92.112.59.0/24
92.112.63.0/24
92.112.64.0/24
92.112.67.0/24
92.112.79.0/24
92.112.81.0/24
92.112.83.0/24
92.112.94.0/24
92.114.44.0/22 92.114.44.0/22
92.119.164.0/22 92.119.164.0/22
92.119.208.0/24 92.119.208.0/24
92.119.209.0/24 92.119.209.0/24
92.119.210.0/24 92.119.210.0/24
92.119.211.0/24 92.119.211.0/24
93.113.70.0/24 93.119.184.0/21
93.119.201.0/24
93.192.0.0/10 93.192.0.0/10
93.95.119.0/24
94.126.98.0/24 94.126.98.0/24
94.26.110.0/23 94.26.110.0/23
94.26.64.0/23 94.26.64.0/23
@ -651,6 +620,7 @@
2001:678:b38::/48 2001:678:b38::/48
2001:678:bdc::/48 2001:678:bdc::/48
2001:678:d4c::/48 2001:678:d4c::/48
2001:678:e9c::/48
2001:678:ff0::/48 2001:678:ff0::/48
2001:67c:11a4::/48 2001:67c:11a4::/48
2001:67c:14c4::/48 2001:67c:14c4::/48
@ -671,7 +641,6 @@
2001:67c:b80::/48 2001:67c:b80::/48
2001:67c:c84::/48 2001:67c:c84::/48
2001:67c:c9c::/48 2001:67c:c9c::/48
2001:67c:ec0::/48
2003:3c0::/28 2003:3c0::/28
2003:3e0::/28 2003:3e0::/28
2003:8:1800::/48 2003:8:1800::/48
@ -694,8 +663,6 @@
2003::/19 2003::/19
2003::/20 2003::/20
2003::/23 2003::/23
2a00:5c60:3::/48
2a00:5c60:a::/48
2a00:6680::/46 2a00:6680::/46
2a01:598::/29 2a01:598::/29
2a01:8fa0::/32 2a01:8fa0::/32
@ -727,11 +694,8 @@
2a0d:480::/29 2a0d:480::/29
2a0d:480::/30 2a0d:480::/30
2a0d:484::/30 2a0d:484::/30
2a0e:cbc4::/32
2a0e:cbc5::/32
2a0e:cbc6::/32
2a0e:cbc7::/32
2a0e:eb40::/32 2a0e:eb40::/32
2a0f:15c0::/32
2a10:cd80::/29 2a10:cd80::/29
2a11:7400:d1::/48 2a11:7400:d1::/48
2a12:6900:1000::/40 2a12:6900:1000::/40

View file

@ -1,13 +1,19 @@
104.151.0.0/17 104.151.0.0/17
109.250.0.0/16 109.250.0.0/16
109.250.0.0/18 109.250.0.0/20
109.250.128.0/19 109.250.128.0/19
109.250.16.0/20
109.250.160.0/19 109.250.160.0/19
109.250.192.0/19 109.250.192.0/19
109.250.224.0/19 109.250.224.0/19
109.250.64.0/18 109.250.32.0/19
109.250.64.0/19
109.250.80.0/22
109.250.84.0/22
109.250.88.0/22
109.250.92.0/22
109.250.96.0/19
134.101.0.0/21 134.101.0.0/21
14.102.90.0/24
143.58.64.0/18 143.58.64.0/18
149.233.32.0/19 149.233.32.0/19
153.94.0.0/20 153.94.0.0/20
@ -29,7 +35,6 @@
185.151.201.0/24 185.151.201.0/24
185.151.203.0/24 185.151.203.0/24
185.158.48.0/22 185.158.48.0/22
185.187.122.0/24
185.199.205.0/24 185.199.205.0/24
185.235.232.0/22 185.235.232.0/22
185.8.230.0/23 185.8.230.0/23
@ -40,13 +45,13 @@
192.166.84.0/22 192.166.84.0/22
192.166.87.0/24 192.166.87.0/24
192.166.88.0/21 192.166.88.0/21
192.189.14.0/24
193.101.4.0/23 193.101.4.0/23
193.102.10.0/24 193.101.5.0/24
193.111.212.0/22 193.111.212.0/22
193.111.212.0/24 193.111.212.0/24
193.163.13.0/24 193.163.13.0/24
193.17.225.0/24 193.163.13.0/25
193.163.13.128/25
193.219.15.0/24 193.219.15.0/24
193.22.120.0/21 193.22.120.0/21
193.22.120.0/24 193.22.120.0/24
@ -87,7 +92,7 @@
194.127.144.0/21 194.127.144.0/21
194.127.203.0/24 194.127.203.0/24
194.139.55.0/24 194.139.55.0/24
194.145.218.0/23 194.145.230.0/24
194.156.216.0/21 194.156.216.0/21
194.156.232.0/23 194.156.232.0/23
194.156.233.0/24 194.156.233.0/24
@ -110,23 +115,24 @@
194.99.0.0/21 194.99.0.0/21
195.149.80.0/23 195.149.80.0/23
195.167.208.0/20 195.167.208.0/20
195.191.20.0/23
195.202.32.0/19 195.202.32.0/19
195.226.160.0/19 195.226.160.0/19
195.226.96.0/19 195.226.96.0/19
195.234.139.0/24 195.234.139.0/24
195.238.233.0/24 195.238.233.0/24
195.238.238.0/24 195.244.10.0/23
195.64.176.0/23 195.64.176.0/23
195.93.158.0/23 195.93.158.0/23
202.71.128.0/20 202.71.128.0/20
202.71.141.0/24
212.204.0.0/19 212.204.0.0/19
212.7.128.0/19 212.7.128.0/19
212.8.0.0/19 212.8.0.0/19
212.80.224.0/19 212.80.224.0/19
212.80.224.0/20
212.80.240.0/20
212.93.0.0/19 212.93.0.0/19
213.138.32.0/19 213.138.32.0/19
213.138.35.0/24
213.139.128.0/19 213.139.128.0/19
213.182.128.0/19 213.182.128.0/19
213.30.192.0/18 213.30.192.0/18
@ -143,155 +149,307 @@
45.13.15.0/24 45.13.15.0/24
46.142.0.0/16 46.142.0.0/16
46.142.0.0/19 46.142.0.0/19
46.142.112.0/20
46.142.128.0/19 46.142.128.0/19
46.142.160.0/19 46.142.160.0/19
46.142.194.0/24
46.142.214.0/24 46.142.214.0/24
46.142.224.0/19 46.142.224.0/19
46.142.32.0/19 46.142.32.0/20
46.142.48.0/20
46.142.64.0/19 46.142.64.0/19
46.142.96.0/19
46.142.96.0/20 46.142.96.0/20
46.189.0.0/17 46.189.0.0/17
46.189.116.0/24
61.8.128.0/19 61.8.128.0/19
61.8.128.0/22
61.8.132.0/22
61.8.136.0/22
61.8.144.0/22
61.8.152.0/22
61.8.156.0/24
61.8.157.0/24
62.214.0.0/16 62.214.0.0/16
62.214.213.0/24
62.214.224.0/19 62.214.224.0/19
62.217.32.0/19 62.217.32.0/19
62.220.0.0/19 62.220.0.0/19
62.68.82.0/24 62.68.82.0/24
62.72.64.0/19 62.72.64.0/19
62.72.70.0/24 62.72.88.0/22
62.72.92.0/23
62.72.94.0/24
77.74.136.0/21 77.74.136.0/21
77.87.190.0/24 77.87.190.0/24
80.241.192.0/20
80.242.160.0/19 80.242.160.0/19
82.119.160.0/19 82.119.160.0/19
82.140.0.0/18 82.140.0.0/18
82.140.48.0/20 82.140.2.0/23
82.140.2.0/24
82.140.3.0/24
82.140.48.0/21
82.144.32.0/19 82.144.32.0/19
82.144.34.0/24
82.144.35.0/24
82.144.36.0/24
82.144.37.0/24
82.145.0.0/19 82.145.0.0/19
82.194.96.0/19 82.194.96.0/19
82.207.128.0/17 82.207.128.0/17
82.207.192.0/19 82.207.192.0/19
82.207.224.0/21
82.207.232.0/22
82.207.236.0/24
82.207.240.0/20
82.207.244.0/24
82.207.245.0/24
82.207.246.0/24
82.207.247.0/24
82.207.248.0/24
82.207.249.0/24
82.207.250.0/24
82.207.251.0/24
82.207.252.0/24
82.207.253.0/24
82.207.254.0/24
82.207.255.0/24
83.135.0.0/16 83.135.0.0/16
83.135.0.0/20 83.135.0.0/22
83.135.112.0/20 83.135.112.0/20
83.135.128.0/19 83.135.128.0/19
83.135.16.0/22
83.135.160.0/21 83.135.160.0/21
83.135.164.0/22
83.135.168.0/21 83.135.168.0/21
83.135.176.0/22 83.135.176.0/22
83.135.180.0/22
83.135.184.0/21 83.135.184.0/21
83.135.192.0/20 83.135.192.0/20
83.135.20.0/24
83.135.208.0/20 83.135.208.0/20
83.135.21.0/24
83.135.22.0/24
83.135.224.0/22 83.135.224.0/22
83.135.23.0/24
83.135.230.0/23
83.135.232.0/21 83.135.232.0/21
83.135.24.0/24
83.135.240.0/22 83.135.240.0/22
83.135.244.0/24
83.135.245.0/24
83.135.248.0/24
83.135.249.0/24
83.135.25.0/24
83.135.250.0/24
83.135.251.0/24
83.135.252.0/24
83.135.253.0/24
83.135.254.0/24
83.135.255.0/24
83.135.26.0/24
83.135.27.0/24
83.135.28.0/24
83.135.29.0/24
83.135.30.0/24
83.135.31.0/24
83.135.32.0/19
83.135.4.0/22
83.135.64.0/19 83.135.64.0/19
83.135.8.0/21
83.135.96.0/20 83.135.96.0/20
84.19.192.0/19 84.19.192.0/19
84.19.192.0/20
84.19.208.0/20
87.122.0.0/15 87.122.0.0/15
87.122.0.0/16
87.122.0.0/20 87.122.0.0/20
87.122.128.0/21 87.122.128.0/21
87.122.136.0/22
87.122.144.0/20 87.122.144.0/20
87.122.16.0/20 87.122.16.0/20
87.122.160.0/20 87.122.160.0/20
87.122.176.0/21 87.122.176.0/21
87.122.184.0/24
87.122.185.0/24
87.122.186.0/24
87.122.187.0/24
87.122.188.0/24
87.122.189.0/24
87.122.190.0/24
87.122.191.0/24
87.122.192.0/19 87.122.192.0/19
87.122.224.0/19 87.122.224.0/19
87.122.32.0/19 87.122.32.0/19
87.122.64.0/19 87.122.64.0/19
87.122.96.0/19 87.122.96.0/19
87.123.0.0/16
87.123.0.0/19 87.123.0.0/19
87.123.112.0/20
87.123.128.0/19 87.123.128.0/19
87.123.160.0/20 87.123.160.0/20
87.123.176.0/20 87.123.176.0/20
87.123.194.0/24 87.123.192.0/20
87.123.196.0/24 87.123.208.0/22
87.123.203.0/24
87.123.216.0/21 87.123.216.0/21
87.123.224.0/20 87.123.224.0/20
87.123.240.0/21 87.123.240.0/22
87.123.244.0/22
87.123.248.0/22
87.123.252.0/24
87.123.253.0/24
87.123.254.0/24
87.123.255.0/24
87.123.32.0/19 87.123.32.0/19
87.123.64.0/20 87.123.64.0/20
87.123.80.0/20 87.123.80.0/20
87.123.96.0/19 87.123.96.0/19
87.123.96.0/20
88.130.0.0/16 88.130.0.0/16
88.130.0.0/19
88.130.130.0/23
88.130.132.0/22
88.130.136.0/21 88.130.136.0/21
88.130.144.0/20 88.130.144.0/21
88.130.152.0/24
88.130.153.0/24
88.130.154.0/24
88.130.155.0/24
88.130.156.0/22
88.130.156.0/24
88.130.157.0/24
88.130.158.0/24
88.130.159.0/24
88.130.160.0/21
88.130.172.0/22
88.130.176.0/21 88.130.176.0/21
88.130.192.0/23 88.130.180.0/24
88.130.194.0/23 88.130.181.0/24
88.130.182.0/24
88.130.183.0/24
88.130.184.0/24
88.130.185.0/24
88.130.186.0/24
88.130.187.0/24
88.130.188.0/24
88.130.189.0/24
88.130.190.0/24
88.130.191.0/24
88.130.192.0/21
88.130.200.0/21
88.130.208.0/21
88.130.216.0/21 88.130.216.0/21
88.130.216.0/22
88.130.220.0/24
88.130.221.0/24
88.130.222.0/24
88.130.223.0/24
88.130.32.0/20
88.130.48.0/24 88.130.48.0/24
88.130.49.0/24 88.130.49.0/24
88.130.50.0/24 88.130.50.0/24
88.130.51.0/24
88.130.52.0/24 88.130.52.0/24
88.130.53.0/24 88.130.53.0/24
88.130.54.0/23 88.130.54.0/24
88.130.55.0/24
88.130.56.0/24 88.130.56.0/24
88.130.57.0/24 88.130.57.0/24
88.130.58.0/24 88.130.58.0/24
88.130.59.0/24 88.130.59.0/24
88.130.60.0/24
88.130.61.0/24 88.130.61.0/24
88.130.62.0/24
88.130.63.0/24 88.130.63.0/24
88.130.64.0/19 88.130.64.0/19
88.130.96.0/19 88.130.96.0/19
89.207.200.0/21
89.244.0.0/14 89.244.0.0/14
89.244.0.0/16
89.244.112.0/21
89.244.120.0/21 89.244.120.0/21
89.244.120.0/22
89.244.124.0/24
89.244.126.0/24
89.244.127.0/24
89.244.160.0/21 89.244.160.0/21
89.244.164.0/22
89.244.168.0/21
89.244.176.0/20 89.244.176.0/20
89.244.192.0/19 89.244.192.0/19
89.244.224.0/20 89.244.224.0/20
89.244.76.0/24 89.244.240.0/20
89.244.78.0/23 89.244.64.0/21
89.244.72.0/22
89.244.80.0/20 89.244.80.0/20
89.244.96.0/22 89.244.96.0/20
89.245.0.0/16
89.245.0.0/20 89.245.0.0/20
89.245.112.0/20
89.245.158.0/24
89.245.159.0/24
89.245.16.0/20 89.245.16.0/20
89.245.160.0/20 89.245.160.0/20
89.245.176.0/21 89.245.176.0/21
89.245.184.0/24
89.245.185.0/24
89.245.186.0/24
89.245.187.0/24
89.245.188.0/24
89.245.189.0/24
89.245.190.0/24
89.245.191.0/24
89.245.192.0/19 89.245.192.0/19
89.245.224.0/19 89.245.224.0/19
89.245.32.0/19 89.245.32.0/19
89.245.64.0/19 89.245.32.0/20
89.245.64.0/20
89.245.80.0/20
89.245.96.0/20 89.245.96.0/20
89.246.0.0/16
89.246.0.0/19 89.246.0.0/19
89.246.104.0/23
89.246.106.0/24
89.246.107.0/24
89.246.108.0/24
89.246.109.0/24
89.246.110.0/24
89.246.111.0/24
89.246.112.0/22 89.246.112.0/22
89.246.116.0/22
89.246.120.0/24
89.246.121.0/24
89.246.122.0/24 89.246.122.0/24
89.246.123.0/24
89.246.124.0/22 89.246.124.0/22
89.246.160.0/20
89.246.160.0/21 89.246.160.0/21
89.246.176.0/22
89.246.180.0/22
89.246.184.0/21 89.246.184.0/21
89.246.192.0/19 89.246.192.0/19
89.246.32.0/19 89.246.32.0/20
89.246.48.0/21
89.246.56.0/21
89.246.96.0/21 89.246.96.0/21
89.247.0.0/16
89.247.0.0/19 89.247.0.0/19
89.247.112.0/21 89.247.112.0/21
89.247.112.0/22
89.247.120.0/22 89.247.120.0/22
89.247.124.0/24
89.247.125.0/24
89.247.126.0/24
89.247.127.0/24
89.247.144.0/20 89.247.144.0/20
89.247.160.0/20 89.247.160.0/20
89.247.179.0/24
89.247.192.0/20 89.247.192.0/20
89.247.208.0/21
89.247.216.0/22 89.247.216.0/22
89.247.228.0/22 89.247.224.0/21
89.247.232.0/21 89.247.232.0/21
89.247.232.0/22
89.247.236.0/22 89.247.236.0/22
89.247.252.0/22 89.247.240.0/21
89.247.240.0/22
89.247.252.0/24
89.247.253.0/24
89.247.254.0/24
89.247.255.0/24
89.247.32.0/19 89.247.32.0/19
89.247.32.0/20 89.247.32.0/20
89.247.64.0/20 89.247.64.0/20
89.247.80.0/20 89.247.80.0/20
89.247.96.0/20
89.27.128.0/17 89.27.128.0/17
89.27.153.0/24
91.194.180.0/23 91.194.180.0/23
91.198.67.0/24 91.198.67.0/24
91.199.158.0/24 91.199.158.0/24
@ -310,7 +468,8 @@
92.116.120.0/21 92.116.120.0/21
92.116.128.0/18 92.116.128.0/18
92.116.16.0/20 92.116.16.0/20
92.116.192.0/18 92.116.192.0/19
92.116.224.0/19
92.116.32.0/19 92.116.32.0/19
92.116.64.0/18 92.116.64.0/18
92.116.96.0/19 92.116.96.0/19
@ -324,34 +483,67 @@
92.117.240.0/21 92.117.240.0/21
92.117.248.0/21 92.117.248.0/21
92.117.64.0/19 92.117.64.0/19
92.117.96.0/19
94.134.0.0/15 94.134.0.0/15
94.134.0.0/18 94.134.0.0/18
94.134.112.0/22 94.134.100.0/22
94.134.112.0/21
94.134.120.0/24
94.134.121.0/24
94.134.122.0/24
94.134.123.0/24
94.134.124.0/24
94.134.125.0/24
94.134.126.0/24
94.134.127.0/24
94.134.128.0/20
94.134.144.0/20 94.134.144.0/20
94.134.160.0/21 94.134.160.0/21
94.134.168.0/22 94.134.168.0/22
94.134.172.0/22 94.134.172.0/22
94.134.176.0/20
94.134.176.0/21 94.134.176.0/21
94.134.192.0/22 94.134.192.0/20
94.134.208.0/21
94.134.216.0/21 94.134.216.0/21
94.134.64.0/22 94.134.224.0/19
94.134.68.0/22 94.134.64.0/20
94.134.80.0/22 94.134.80.0/22
94.134.88.0/22 94.134.84.0/24
94.134.94.0/23 94.134.85.0/24
94.134.86.0/24
94.134.87.0/24
94.134.88.0/24
94.134.89.0/24
94.134.90.0/24
94.134.91.0/24
94.134.92.0/24
94.134.93.0/24
94.134.94.0/24
94.134.95.0/24
94.134.96.0/20 94.134.96.0/20
94.134.96.0/22
2001:1438:1000::/36 2001:1438:1000::/36
2001:1438:1:100::/56
2001:1438:1:200::/56
2001:1438:1:300::/56
2001:1438:1:400::/56
2001:1438:1:900::/56
2001:1438:1:a00::/56
2001:1438:2000::/36 2001:1438:2000::/36
2001:1438:3000::/36 2001:1438:3000::/36
2001:1438:4000::/36 2001:1438:4000::/36
2001:1438::/32 2001:1438::/32
2001:1438:f000::/36
2001:1438:fff:10::/64
2001:1438:fff:11::/64
2001:1438:fff:12::/64
2001:1438:fff:3::/64
2001:1438:fff:4::/64
2001:1438:fff:5::/64
2001:1438:fff:6::/64
2001:1438:fff:7::/64
2001:1438:fff:8::/64
2001:1438:fff:9::/64
2001:1438:fff:a::/64
2001:1438:fff:b::/64
2001:1438:fff:c::/64
2001:1438:fff:d::/64
2001:1438:fff:e::/64
2001:1438:fff:f::/64
2001:16b8:1000::/40 2001:16b8:1000::/40
2001:16b8:100::/40 2001:16b8:100::/40
2001:16b8:1100::/40 2001:16b8:1100::/40
@ -401,14 +593,12 @@
2001:16b8:a000::/35 2001:16b8:a000::/35
2001:16b8:a00::/40 2001:16b8:a00::/40
2001:16b8:b00::/40 2001:16b8:b00::/40
2001:16b8:c000::/35
2001:678:c74::/48 2001:678:c74::/48
2001:67c:27ac::/48 2001:67c:27ac::/48
2001:67c:2878::/48 2001:67c:2878::/48
2001:67c:2e8c::/48 2001:67c:2e8c::/48
2001:67c:660::/48 2001:67c:660::/48
2001:67c:888::/48 2001:67c:888::/48
2001:67c:ed8::/48
2001:7b0::/32 2001:7b0::/32
2001:9e8:2000::/35 2001:9e8:2000::/35
2001:9e8:4000::/35 2001:9e8:4000::/35
@ -425,11 +615,10 @@
2a00:fb8:4000::/35 2a00:fb8:4000::/35
2a00:fb8:6000::/35 2a00:fb8:6000::/35
2a00:fb8::/29 2a00:fb8::/29
2a00:fb8::/32
2a00:fb8::/35 2a00:fb8::/35
2a03:3fc0:2000::/48 2a03:3fc0:2000::/48
2a07:9400::/29 2a07:9400::/29
2a0a:ed40::/29 2a0a:ed40::/29
2a0b:9e80:1000::/36
2a0d:240::/29 2a0d:240::/29
2a0d:ad00::/29 2a0d:ad00::/29
2a11:d00::/32

View file

@ -4,225 +4,225 @@
"description": "home.router (enp1s0)", "description": "home.router (enp1s0)",
"enabled": true, "enabled": true,
"ips": [], "ips": [],
"mode": "tagged-all", "mode": "TAGGED_ALL",
"tagged_vlans": [], "tagged_vlans": [],
"type": "1000base-t", "type": "A_1000BASE_T",
"untagged_vlan": null "untagged_vlan": null
}, },
"ether10": { "ether10": {
"description": "home.mitel-rfp35 (LAN)", "description": "home.mitel-rfp35 (LAN)",
"enabled": true, "enabled": true,
"ips": [], "ips": [],
"mode": "access", "mode": "ACCESS",
"tagged_vlans": [], "tagged_vlans": [],
"type": "1000base-t", "type": "A_1000BASE_T",
"untagged_vlan": "home.clients" "untagged_vlan": "home.clients"
}, },
"ether11": { "ether11": {
"description": "home.usv01 (LAN)", "description": "home.usv01 (LAN)",
"enabled": true, "enabled": true,
"ips": [], "ips": [],
"mode": "access", "mode": "ACCESS",
"tagged_vlans": [], "tagged_vlans": [],
"type": "1000base-t", "type": "A_1000BASE_T",
"untagged_vlan": "home.clients" "untagged_vlan": "home.clients"
}, },
"ether12": { "ether12": {
"description": "", "description": "home.rechenmonster (IPMI)",
"enabled": true, "enabled": true,
"ips": [], "ips": [],
"mode": "access", "mode": "ACCESS",
"tagged_vlans": [], "tagged_vlans": [],
"type": "1000base-t", "type": "A_1000BASE_T",
"untagged_vlan": "home.clients" "untagged_vlan": "home.clients"
}, },
"ether13": { "ether13": {
"description": "", "description": "",
"enabled": true, "enabled": true,
"ips": [], "ips": [],
"mode": "access", "mode": "ACCESS",
"tagged_vlans": [], "tagged_vlans": [],
"type": "1000base-t", "type": "A_1000BASE_T",
"untagged_vlan": "home.clients" "untagged_vlan": "home.clients"
}, },
"ether14": { "ether14": {
"description": "", "description": "home.rechenmonster (LAN)",
"enabled": true, "enabled": true,
"ips": [], "ips": [],
"mode": "access", "mode": "ACCESS",
"tagged_vlans": [], "tagged_vlans": [],
"type": "1000base-t", "type": "A_1000BASE_T",
"untagged_vlan": "home.clients" "untagged_vlan": "home.clients"
}, },
"ether15": { "ether15": {
"description": "", "description": "",
"enabled": true, "enabled": true,
"ips": [], "ips": [],
"mode": "access", "mode": "ACCESS",
"tagged_vlans": [], "tagged_vlans": [],
"type": "1000base-t", "type": "A_1000BASE_T",
"untagged_vlan": "home.clients" "untagged_vlan": "home.clients"
}, },
"ether16": { "ether16": {
"description": "", "description": "",
"enabled": true, "enabled": true,
"ips": [], "ips": [],
"mode": "access", "mode": "ACCESS",
"tagged_vlans": [], "tagged_vlans": [],
"type": "1000base-t", "type": "A_1000BASE_T",
"untagged_vlan": "home.clients" "untagged_vlan": "home.clients"
}, },
"ether17": { "ether17": {
"description": "", "description": "",
"enabled": true, "enabled": true,
"ips": [], "ips": [],
"mode": "access", "mode": "ACCESS",
"tagged_vlans": [], "tagged_vlans": [],
"type": "1000base-t", "type": "A_1000BASE_T",
"untagged_vlan": "home.clients" "untagged_vlan": "home.clients"
}, },
"ether18": { "ether18": {
"description": "", "description": "",
"enabled": true, "enabled": true,
"ips": [], "ips": [],
"mode": "access", "mode": "ACCESS",
"tagged_vlans": [], "tagged_vlans": [],
"type": "1000base-t", "type": "A_1000BASE_T",
"untagged_vlan": "home.clients" "untagged_vlan": "home.clients"
}, },
"ether19": { "ether19": {
"description": "home.lgtv-wohnzimmer", "description": "home.lgtv-wohnzimmer",
"enabled": true, "enabled": true,
"ips": [], "ips": [],
"mode": "access", "mode": "ACCESS",
"tagged_vlans": [], "tagged_vlans": [],
"type": "1000base-t", "type": "A_1000BASE_T",
"untagged_vlan": "home.clients" "untagged_vlan": "home.clients"
}, },
"ether2": { "ether2": {
"description": "Fritz!Box (LAN1)", "description": "Fritz!Box (LAN1)",
"enabled": true, "enabled": true,
"ips": [], "ips": [],
"mode": "access", "mode": "ACCESS",
"tagged_vlans": [], "tagged_vlans": [],
"type": "1000base-t", "type": "A_1000BASE_T",
"untagged_vlan": "home.wan" "untagged_vlan": "home.wan"
}, },
"ether20": { "ether20": {
"description": "Franzi Laptop", "description": "Franzi Laptop",
"enabled": true, "enabled": true,
"ips": [], "ips": [],
"mode": "access", "mode": "ACCESS",
"tagged_vlans": [], "tagged_vlans": [],
"type": "1000base-t", "type": "A_1000BASE_T",
"untagged_vlan": "home.clients" "untagged_vlan": "home.clients"
}, },
"ether21": { "ether21": {
"description": "", "description": "Sophie Laptop",
"enabled": true, "enabled": true,
"ips": [], "ips": [],
"mode": "access", "mode": "ACCESS",
"tagged_vlans": [], "tagged_vlans": [],
"type": "1000base-t", "type": "A_1000BASE_T",
"untagged_vlan": "home.clients" "untagged_vlan": "home.clients"
}, },
"ether22": { "ether22": {
"description": "Arbeitsplatz Regal", "description": "Sophie Desktop",
"enabled": true, "enabled": true,
"ips": [], "ips": [],
"mode": "access", "mode": "ACCESS",
"tagged_vlans": [], "tagged_vlans": [],
"type": "1000base-t", "type": "A_1000BASE_T",
"untagged_vlan": "home.clients" "untagged_vlan": "home.clients"
}, },
"ether23": { "ether23": {
"description": "Wohnzimmer Kabel", "description": "Wohnzimmer Kabel",
"enabled": true, "enabled": true,
"ips": [], "ips": [],
"mode": "access", "mode": "ACCESS",
"tagged_vlans": [], "tagged_vlans": [],
"type": "1000base-t", "type": "A_1000BASE_T",
"untagged_vlan": "home.clients" "untagged_vlan": "home.clients"
}, },
"ether24": { "ether24": {
"description": "home.snom-wohnzimmer", "description": "home.snom-wohnzimmer",
"enabled": true, "enabled": true,
"ips": [], "ips": [],
"mode": "access", "mode": "ACCESS",
"tagged_vlans": [], "tagged_vlans": [],
"type": "1000base-t", "type": "A_1000BASE_T",
"untagged_vlan": "home.clients" "untagged_vlan": "home.clients"
}, },
"ether3": { "ether3": {
"description": "home.aruba325-schlafzimmer", "description": "home.aruba325-schlafzimmer",
"enabled": true, "enabled": true,
"ips": [], "ips": [],
"mode": "tagged", "mode": "TAGGED",
"tagged_vlans": [ "tagged_vlans": [
"ffwi.client", "ffwi.client",
"home.v6only" "home.v6only"
], ],
"type": "1000base-t", "type": "A_1000BASE_T",
"untagged_vlan": "home.clients" "untagged_vlan": "home.clients"
}, },
"ether4": { "ether4": {
"description": "home.aruba325-wohnzimmer", "description": "home.aruba325-wohnzimmer",
"enabled": true, "enabled": true,
"ips": [], "ips": [],
"mode": "tagged", "mode": "TAGGED",
"tagged_vlans": [ "tagged_vlans": [
"ffwi.client", "ffwi.client",
"home.v6only" "home.v6only"
], ],
"type": "1000base-t", "type": "A_1000BASE_T",
"untagged_vlan": "home.clients" "untagged_vlan": "home.clients"
}, },
"ether5": { "ether5": {
"description": "home.nas (eno1)", "description": "home.nas (eno1)",
"enabled": true, "enabled": true,
"ips": [], "ips": [],
"mode": "tagged-all", "mode": "TAGGED_ALL",
"tagged_vlans": [], "tagged_vlans": [],
"type": "1000base-t", "type": "A_1000BASE_T",
"untagged_vlan": null "untagged_vlan": null
}, },
"ether6": { "ether6": {
"description": "home.aruba325-office", "description": "home.aruba325-office",
"enabled": true, "enabled": true,
"ips": [], "ips": [],
"mode": "tagged", "mode": "TAGGED",
"tagged_vlans": [ "tagged_vlans": [
"ffwi.client", "ffwi.client",
"home.v6only" "home.v6only"
], ],
"type": "1000base-t", "type": "A_1000BASE_T",
"untagged_vlan": "home.clients" "untagged_vlan": "home.clients"
}, },
"ether7": { "ether7": {
"description": "RIPE-Probe #28280 (LAN)", "description": "RIPE-Probe #28280 (LAN)",
"enabled": true, "enabled": true,
"ips": [], "ips": [],
"mode": "access", "mode": "ACCESS",
"tagged_vlans": [], "tagged_vlans": [],
"type": "1000base-t", "type": "A_1000BASE_T",
"untagged_vlan": "home.dmz" "untagged_vlan": "home.dmz"
}, },
"ether8": { "ether8": {
"description": "home.drucker-franzi", "description": "home.drucker-sophie",
"enabled": true, "enabled": true,
"ips": [], "ips": [],
"mode": "access", "mode": "ACCESS",
"tagged_vlans": [], "tagged_vlans": [],
"type": "1000base-t", "type": "A_1000BASE_T",
"untagged_vlan": "home.clients" "untagged_vlan": "home.clients"
}, },
"ether9": { "ether9": {
"description": "info-beamer 12199 (LAN)", "description": "info-beamer 12199 (LAN)",
"enabled": true, "enabled": true,
"ips": [], "ips": [],
"mode": "access", "mode": "ACCESS",
"tagged_vlans": [], "tagged_vlans": [],
"type": "1000base-t", "type": "A_1000BASE_T",
"untagged_vlan": "home.clients" "untagged_vlan": "home.clients"
}, },
"home.clients": { "home.clients": {
@ -231,27 +231,27 @@
"ips": [ "ips": [
"172.19.138.4/24" "172.19.138.4/24"
], ],
"mode": "", "mode": null,
"tagged_vlans": [], "tagged_vlans": [],
"type": "virtual", "type": "VIRTUAL",
"untagged_vlan": null "untagged_vlan": null
}, },
"sfp-sfpplus1": { "sfp-sfpplus1": {
"description": "", "description": "",
"enabled": true, "enabled": true,
"ips": [], "ips": [],
"mode": "", "mode": null,
"tagged_vlans": [], "tagged_vlans": [],
"type": "10gbase-x-sfpp", "type": "A_10GBASE_X_SFPP",
"untagged_vlan": null "untagged_vlan": null
}, },
"sfp-sfpplus2": { "sfp-sfpplus2": {
"description": "", "description": "",
"enabled": true, "enabled": true,
"ips": [], "ips": [],
"mode": "", "mode": null,
"tagged_vlans": [], "tagged_vlans": [],
"type": "10gbase-x-sfpp", "type": "A_10GBASE_X_SFPP",
"untagged_vlan": null "untagged_vlan": null
} }
}, },

View file

@ -1,62 +0,0 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBFit2ioBEADhWpZ8/wvZ6hUTiXOwQHXMAlaFHcPH9hAtr4F1y2+OYdbtMuth
lqqwp028AqyY+PRfVMtSYMbjuQuu5byyKR01BbqYhuS3jtqQmljZ/bJvXqnmiVXh
38UuLa+z077PxyxQhu5BbqntTPQMfiyqEiU+BKbq2WmANUKQf+1AmZY/IruOXbnq
L4C1+gJ8vfmXQt99npCaxEjaNRVYfOS8QcixNzHUYnb6emjlANyEVlZzeqo7XKl7
UrwV5inawTSzWNvtjEjj4nJL8NsLwscpLPQUhTQ+7BbQXAwAmeHCUTQIvvWXqw0N
cmhh4HgeQscQHYgOJjjDVfoY5MucvglbIgCqfzAHW9jxmRL4qbMZj+b1XoePEtht
ku4bIQN1X5P07fNWzlgaRL5Z4POXDDZTlIQ/El58j9kp4bnWRCJW0lya+f8ocodo
vZZ+Doi+fy4D5ZGrL4XEcIQP/Lv5uFyf+kQtl/94VFYVJOleAv8W92KdgDkhTcTD
G7c0tIkVEKNUq48b3aQ64NOZQW7fVjfoKwEZdOqPE72Pa45jrZzvUFxSpdiNk2tZ
XYukHjlxxEgBdC/J3cMMNRE1F4NCA3ApfV1Y7/hTeOnmDuDYwr9/obA8t016Yljj
q5rdkywPf4JF8mXUW5eCN1vAFHxeg9ZWemhBtQmGxXnw9M+z6hWwc6ahmwARAQAB
tCtEb2NrZXIgUmVsZWFzZSAoQ0UgZGViKSA8ZG9ja2VyQGRvY2tlci5jb20+iQI3
BBMBCgAhBQJYrefAAhsvBQsJCAcDBRUKCQgLBRYCAwEAAh4BAheAAAoJEI2BgDwO
v82IsskP/iQZo68flDQmNvn8X5XTd6RRaUH33kXYXquT6NkHJciS7E2gTJmqvMqd
tI4mNYHCSEYxI5qrcYV5YqX9P6+Ko+vozo4nseUQLPH/ATQ4qL0Zok+1jkag3Lgk
jonyUf9bwtWxFp05HC3GMHPhhcUSexCxQLQvnFWXD2sWLKivHp2fT8QbRGeZ+d3m
6fqcd5Fu7pxsqm0EUDK5NL+nPIgYhN+auTrhgzhK1CShfGccM/wfRlei9Utz6p9P
XRKIlWnXtT4qNGZNTN0tR+NLG/6Bqd8OYBaFAUcue/w1VW6JQ2VGYZHnZu9S8LMc
FYBa5Ig9PxwGQOgq6RDKDbV+PqTQT5EFMeR1mrjckk4DQJjbxeMZbiNMG5kGECA8
g383P3elhn03WGbEEa4MNc3Z4+7c236QI3xWJfNPdUbXRaAwhy/6rTSFbzwKB0Jm
ebwzQfwjQY6f55MiI/RqDCyuPj3r3jyVRkK86pQKBAJwFHyqj9KaKXMZjfVnowLh
9svIGfNbGHpucATqREvUHuQbNnqkCx8VVhtYkhDb9fEP2xBu5VvHbR+3nfVhMut5
G34Ct5RS7Jt6LIfFdtcn8CaSas/l1HbiGeRgc70X/9aYx/V/CEJv0lIe8gP6uDoW
FPIZ7d6vH+Vro6xuWEGiuMaiznap2KhZmpkgfupyFmplh0s6knymuQINBFit2ioB
EADneL9S9m4vhU3blaRjVUUyJ7b/qTjcSylvCH5XUE6R2k+ckEZjfAMZPLpO+/tF
M2JIJMD4SifKuS3xck9KtZGCufGmcwiLQRzeHF7vJUKrLD5RTkNi23ydvWZgPjtx
Q+DTT1Zcn7BrQFY6FgnRoUVIxwtdw1bMY/89rsFgS5wwuMESd3Q2RYgb7EOFOpnu
w6da7WakWf4IhnF5nsNYGDVaIHzpiqCl+uTbf1epCjrOlIzkZ3Z3Yk5CM/TiFzPk
z2lLz89cpD8U+NtCsfagWWfjd2U3jDapgH+7nQnCEWpROtzaKHG6lA3pXdix5zG8
eRc6/0IbUSWvfjKxLLPfNeCS2pCL3IeEI5nothEEYdQH6szpLog79xB9dVnJyKJb
VfxXnseoYqVrRz2VVbUI5Blwm6B40E3eGVfUQWiux54DspyVMMk41Mx7QJ3iynIa
1N4ZAqVMAEruyXTRTxc9XW0tYhDMA/1GYvz0EmFpm8LzTHA6sFVtPm/ZlNCX6P1X
zJwrv7DSQKD6GGlBQUX+OeEJ8tTkkf8QTJSPUdh8P8YxDFS5EOGAvhhpMBYD42kQ
pqXjEC+XcycTvGI7impgv9PDY1RCC1zkBjKPa120rNhv/hkVk/YhuGoajoHyy4h7
ZQopdcMtpN2dgmhEegny9JCSwxfQmQ0zK0g7m6SHiKMwjwARAQABiQQ+BBgBCAAJ
BQJYrdoqAhsCAikJEI2BgDwOv82IwV0gBBkBCAAGBQJYrdoqAAoJEH6gqcPyc/zY
1WAP/2wJ+R0gE6qsce3rjaIz58PJmc8goKrir5hnElWhPgbq7cYIsW5qiFyLhkdp
YcMmhD9mRiPpQn6Ya2w3e3B8zfIVKipbMBnke/ytZ9M7qHmDCcjoiSmwEXN3wKYI
mD9VHONsl/CG1rU9Isw1jtB5g1YxuBA7M/m36XN6x2u+NtNMDB9P56yc4gfsZVES
KA9v+yY2/l45L8d/WUkUi0YXomn6hyBGI7JrBLq0CX37GEYP6O9rrKipfz73XfO7
JIGzOKZlljb/D9RX/g7nRbCn+3EtH7xnk+TK/50euEKw8SMUg147sJTcpQmv6UzZ
cM4JgL0HbHVCojV4C/plELwMddALOFeYQzTif6sMRPf+3DSj8frbInjChC3yOLy0
6br92KFom17EIj2CAcoeq7UPhi2oouYBwPxh5ytdehJkoo+sN7RIWua6P2WSmon5
U888cSylXC0+ADFdgLX9K2zrDVYUG1vo8CX0vzxFBaHwN6Px26fhIT1/hYUHQR1z
VfNDcyQmXqkOnZvvoMfz/Q0s9BhFJ/zU6AgQbIZE/hm1spsfgvtsD1frZfygXJ9f
irP+MSAI80xHSf91qSRZOj4Pl3ZJNbq4yYxv0b1pkMqeGdjdCYhLU+LZ4wbQmpCk
SVe2prlLureigXtmZfkqevRz7FrIZiu9ky8wnCAPwC7/zmS18rgP/17bOtL4/iIz
QhxAAoAMWVrGyJivSkjhSGx1uCojsWfsTAm11P7jsruIL61ZzMUVE2aM3Pmj5G+W
9AcZ58Em+1WsVnAXdUR//bMmhyr8wL/G1YO1V3JEJTRdxsSxdYa4deGBBY/Adpsw
24jxhOJR+lsJpqIUeb999+R8euDhRHG9eFO7DRu6weatUJ6suupoDTRWtr/4yGqe
dKxV3qQhNLSnaAzqW/1nA3iUB4k7kCaKZxhdhDbClf9P37qaRW467BLCVO/coL3y
Vm50dwdrNtKpMBh3ZpbB1uJvgi9mXtyBOMJ3v8RZeDzFiG8HdCtg9RvIt/AIFoHR
H3S+U79NT6i0KPzLImDfs8T7RlpyuMc4Ufs8ggyg9v3Ae6cN3eQyxcK3w0cbBwsh
/nQNfsA6uu+9H7NhbehBMhYnpNZyrHzCmzyXkauwRAqoCbGCNykTRwsur9gS41TQ
M8ssD1jFheOJf3hODnkKU+HKjvMROl1DK7zdmLdNzA1cvtZH/nCC9KPj1z8QC47S
xx+dTZSx4ONAhwbS/LN3PoKtn8LPjY9NP9uDWI+TWYquS2U+KHDrBDlsgozDbs/O
jCxcpDzNmXpWQHEtHU7649OXHP7UeNST1mCUCH5qdank0V1iejF6/CfTFU4MfcrG
YT90qFF93M3v01BbxP+EIY2/9tiIPbrd
=0YYh
-----END PGP PUBLIC KEY BLOCK-----

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