Compare commits

...

7 commits

Author SHA1 Message Date
mwiegand
6e9610d797 wip 2021-07-14 12:06:43 +02:00
mwiegand
ac5482335d wip 2021-07-14 11:48:36 +02:00
mwiegand
10eaaa7e12 wip 2021-07-13 19:47:12 +02:00
mwiegand
da11f49cfb wip 2021-07-13 19:38:54 +02:00
mwiegand
2eb23a5827 wip 2021-07-13 19:30:45 +02:00
mwiegand
77ed1970e1 wip 2021-07-13 19:00:26 +02:00
mwiegand
5a1ca9142d wip 2021-07-13 18:53:48 +02:00
66 changed files with 323 additions and 469 deletions

View file

@ -91,9 +91,9 @@ for package, options in node.metadata.get('apt/packages', {}).items():
f"Pin: release a={node.metadata.get('os_release')}-backports",
f"Pin-Priority: 900",
]),
'needed_by': [
'needed_by': {
f'pkg_apt:{package}',
],
},
'triggers': {
'action:apt_update',
},

View file

@ -1,6 +1,6 @@
defaults = {
'apt': {
'packages': {},
'sources': [],
'sources': set(),
},
}

View file

@ -29,9 +29,9 @@ files['/opt/archive/archive'] = {
'processes': 4,
'threads': 4,
},
'needs': [
'needs': {
'bundle:gcloud',
],
},
}
files['/opt/archive/get_file'] = {

View file

@ -19,10 +19,10 @@ def paths(metadata):
'paths': {
path: {
'encrypted_path': f'/mnt/archive.enc{path}',
'exclude': [
'exclude': {
'^\..*',
'/\..*',
],
},
} for path in metadata.get('archive/paths')
},
}

View file

@ -8,7 +8,7 @@ defaults = {
},
'users': {
'backup-receiver': {
'authorized_keys': [],
'authorized_keys': set(),
},
},
'sudoers': {

View file

@ -7,7 +7,7 @@ defaults = {
},
'backup': {
'server': None,
'paths': [],
'paths': set(),
},
'systemd-timers': {
f'backup': {

View file

@ -15,36 +15,36 @@ else:
directories[f'/var/lib/bind'] = {
'purge': True,
'needed_by': [
'needed_by': {
'svc_systemd:bind9',
],
'triggers': [
},
'triggers': {
'svc_systemd:bind9:restart',
],
},
}
files['/etc/default/bind9'] = {
'source': 'defaults',
'needed_by': [
'needed_by': {
'svc_systemd:bind9',
],
'triggers': [
},
'triggers': {
'svc_systemd:bind9:restart',
],
},
}
files['/etc/bind/named.conf'] = {
'owner': 'root',
'group': 'bind',
'needs': [
'needs': {
'pkg_apt:bind9',
],
'needed_by': [
},
'needed_by': {
'svc_systemd:bind9',
],
'triggers': [
},
'triggers': {
'svc_systemd:bind9:restart',
],
},
}
files['/etc/bind/named.conf.options'] = {
'content_type': 'mako',
@ -54,15 +54,15 @@ files['/etc/bind/named.conf.options'] = {
},
'owner': 'root',
'group': 'bind',
'needs': [
'needs': {
'pkg_apt:bind9',
],
'needed_by': [
},
'needed_by': {
'svc_systemd:bind9',
],
'triggers': [
},
'triggers': {
'svc_systemd:bind9:restart',
],
},
}
views = [
@ -96,15 +96,15 @@ files['/etc/bind/named.conf.local'] = {
},
'owner': 'root',
'group': 'bind',
'needs': [
'needs': {
'pkg_apt:bind9',
],
'needed_by': [
},
'needed_by': {
'svc_systemd:bind9',
],
'triggers': [
},
'triggers': {
'svc_systemd:bind9:restart',
],
},
}
def record_matches_view(record, records, view):
@ -128,12 +128,12 @@ def record_matches_view(record, records, view):
for view in views:
directories[f"/var/lib/bind/{view['name']}"] = {
'purge': True,
'needed_by': [
'needed_by': {
'svc_systemd:bind9',
],
'triggers': [
},
'triggers': {
'svc_systemd:bind9:restart',
],
},
}
for zone, records in zones.items():
@ -157,15 +157,15 @@ for view in views:
)),
'hostname': node.metadata.get('bind/hostname'),
},
'needs': [
'needs': {
f"directory:/var/lib/bind/{view['name']}",
],
'needed_by': [
},
'needed_by': {
'svc_systemd:bind9',
],
'triggers': [
},
'triggers': {
'svc_systemd:bind9:restart',
],
},
}
svc_systemd['bind9'] = {}
@ -173,7 +173,7 @@ svc_systemd['bind9'] = {}
actions['named-checkconf'] = {
'command': 'named-checkconf -z',
'unless': 'named-checkconf -z',
'needs': [
'needs': {
'svc_systemd:bind9',
]
},
}

View file

@ -122,10 +122,10 @@ def slaves(metadata):
return {
'bind': {
'slaves': [
'slaves': {
other_node.name
for other_node in repo.nodes
if other_node.has_bundle('bind') and other_node.metadata.get('bind/master_node', None) == node.name
],
},
},
}

View file

@ -10,10 +10,10 @@ directories = {
},
'/etc/dovecot/conf.d': {
'purge': True,
'needs': [
'needs': {
'pkg_apt:dovecot-sieve',
'pkg_apt:dovecot-managesieved',
]
},
},
'/etc/dovecot/ssl': {},
'/var/vmail': {

View file

@ -21,23 +21,23 @@ files['/etc/gcloud/service_account.json'] = {
join(repo.path, 'data', 'gcloud', 'service_accounts', f'{service_account}@{project}.json.enc')
),
'mode': '500',
'needs': [
'needs': {
'pkg_apt:google-cloud-sdk',
],
},
}
actions['gcloud_activate_service_account'] = {
'command': 'gcloud auth activate-service-account --key-file /etc/gcloud/service_account.json',
'unless': f"gcloud auth list | grep -q '^\*[[:space:]]*{service_account}@{project}.iam.gserviceaccount.com'",
'needs': [
'needs': {
f'file:/etc/gcloud/service_account.json'
],
},
}
actions['gcloud_select_project'] = {
'command': f"gcloud config set project '{project}'",
'unless': f"gcloud config get-value project | grep -q '^{project}$'",
'needs': [
'needs': {
f'action:gcloud_activate_service_account'
],
},
}

View file

@ -7,8 +7,8 @@ defaults = {
'google-cloud-sdk': {},
'python3-crcmod': {},
},
'sources': [
'sources': {
'deb https://packages.cloud.google.com/apt cloud-sdk main',
],
},
},
}

View file

@ -45,9 +45,9 @@ files['/etc/gitea/app.ini'] = {
}
svc_systemd['gitea'] = {
'needs': [
'needs': {
'action:chmod_gitea',
'download:/usr/local/bin/gitea',
'file:/etc/gitea/app.ini',
],
},
}

View file

@ -34,10 +34,10 @@ for path, options in node.metadata.get('gocryptfs/paths').items():
'owner': None,
'group': None,
'mode': None,
'preceded_by': [
'preceded_by': {
f'svc_systemd:gocryptfs-{options["id"]}:stop',
],
'needed_by': [
},
'needed_by': {
f'svc_systemd:gocryptfs-{options["id"]}',
],
},
}

View file

@ -76,12 +76,12 @@ def systemd(metadata):
'PLAIN': path,
'CIPHER': options["mountpoint"]
},
'ExecStart': [
'ExecStart': {
'/usr/bin/gocryptfs -fg -plaintextnames -reverse -masterkey $MASTERKEY -ctlsock $SOCKET $PLAIN $CIPHER',
],
'ExecStopPost': [
},
'ExecStopPost': {
'/usr/bin/umount $CIPHER'
],
},
},
},
'needs': [

View file

@ -9,9 +9,9 @@ import yaml
import json
svc_systemd['grafana-server'] = {
'needs': [
'needs': {
'pkg_apt:grafana',
],
},
}
admin_password = node.metadata.get('grafana/config/security/admin_password')
@ -25,10 +25,8 @@ actions['reset_grafana_admin_password'] = {
}
directories = {
'/etc/grafana': {
},
'/etc/grafana/provisioning': {
},
'/etc/grafana': {},
'/etc/grafana/provisioning': {},
'/etc/grafana/provisioning/datasources': {
'purge': True,
},
@ -42,18 +40,18 @@ directories = {
files = {
'/etc/grafana/grafana.ini': {
'content': repo.libs.ini.dumps(node.metadata.get('grafana/config')),
'triggers': [
'triggers': {
'svc_systemd:grafana-server:restart',
],
},
},
'/etc/grafana/provisioning/datasources/managed.yaml': {
'content': yaml.dump({
'apiVersion': 1,
'datasources': list(node.metadata.get('grafana/datasources').values()),
}),
'triggers': [
'triggers': {
'svc_systemd:grafana-server:restart',
],
},
},
'/etc/grafana/provisioning/dashboards/managed.yaml': {
'content': yaml.dump({
@ -67,9 +65,9 @@ files = {
},
}],
}),
'triggers': [
'triggers': {
'svc_systemd:grafana-server:restart',
],
},
},
}
@ -143,8 +141,8 @@ for dashboard_id, monitored_node in enumerate(monitored_nodes, start=1):
files[f'/var/lib/grafana/dashboards/{monitored_node.name}.json'] = {
'content': json.dumps(dashboard, indent=4),
'triggers': [
'triggers': {
'svc_systemd:grafana-server:restart',
]
},
}

View file

@ -1,8 +0,0 @@
# defaults = {
# 'network': {
# 'external': {
# 'gateway4': '172.31.1.1',
# 'gateway6': 'fe80::1',
# },
# },
# }

View file

@ -1,28 +1,28 @@
defaults = {
'hosts': {
'127.0.0.1': [
'127.0.0.1': {
'localhost',
node.name,
],
'::1': [
},
'::1': {
'localhost',
'ip6-localhost',
'ip6-loopback',
],
'fe00::0': [
},
'fe00::0': {
'ip6-localnet'
],
'ff00::0': [
},
'ff00::0': {
'ip6-mcastprefix'
],
'ff02::1': [
},
'ff02::1': {
'ip6-allnodes'
],
'ff02::2': [
},
'ff02::2': {
'ip6-allrouters'
],
'ff02::3': [
},
'ff02::3': {
'ip6-allhosts'
],
},
},
}

View file

@ -4,9 +4,9 @@ from shlex import quote
directories['/var/lib/influxdb'] = {
'owner': 'influxdb',
'group': 'influxdb',
'needs': [
'needs': {
'zfs_dataset:tank/influxdb',
],
},
}
directories['/etc/influxdb'] = {
@ -14,26 +14,26 @@ directories['/etc/influxdb'] = {
}
files['/etc/influxdb/config.toml'] = {
'content': dumps(node.metadata.get('influxdb/config')),
'triggers': [
'triggers': {
'svc_systemd:influxdb:restart',
]
},
}
svc_systemd['influxdb'] = {
'needs': [
'needs': {
'directory:/var/lib/influxdb',
'file:/etc/influxdb/config.toml',
'pkg_apt:influxdb2',
]
},
}
actions['wait_for_influxdb_start'] = {
'command': 'sleep 15',
'triggered': True,
'triggered_by': [
'triggered_by': {
'svc_systemd:influxdb',
'svc_systemd:influxdb:restart',
]
},
}
actions['setup_influxdb'] = {
@ -45,9 +45,9 @@ actions['setup_influxdb'] = {
token=str(node.metadata.get('influxdb/admin_token')),
),
'unless': 'influx bucket list',
'needs': [
'needs': {
'action:wait_for_influxdb_start',
],
},
}
files['/root/.influxdbv2/configs'] = {
@ -59,9 +59,9 @@ files['/root/.influxdbv2/configs'] = {
'active': True,
},
}),
'needs': [
'needs': {
'action:setup_influxdb',
],
},
}
for description, permissions in {
@ -71,7 +71,7 @@ for description, permissions in {
actions[f'influxdb_{description}_token'] = {
'command': f'influx auth create --description {description} {permissions}',
'unless': f'''influx auth list --json | jq -r '.[] | select (.description == "{description}") | .token' | wc -l | grep -q ^1$''',
'needs': [
'needs': {
'file:/root/.influxdbv2/configs',
],
},
}

View file

@ -5,9 +5,9 @@ defaults = {
'packages': {
'influxdb2': {},
},
'sources': [
'sources': {
'deb https://repos.influxdata.com/debian {release} stable',
],
},
},
'influxdb': {
'port': '8200',

View file

@ -45,8 +45,8 @@ def dns(metadata):
for domain in metadata.get('mailserver/domains'):
dns[domain] = {
'MX': [f"5 {metadata.get('mailserver/hostname')}."],
'TXT': ['v=spf1 a mx -all'],
'MX': {f"5 {metadata.get('mailserver/hostname')}."},
'TXT': {'v=spf1 a mx -all'},
}
return {

View file

@ -1,15 +1,14 @@
from ipaddress import ip_interface
defaults = {
'network': {
}
'network': {},
}
@metadata_reactor.provides(
'systemd/units',
)
def units(metadata):
def network_units(metadata):
units = {}
for type, network in metadata.get('network').items():

View file

@ -39,13 +39,13 @@ actions['delete_nextcloud'] = {
actions['extract_nextcloud'] = {
'command': f'tar xfvj /tmp/nextcloud-{version}.tar.bz2 --strip 1 -C /opt/nextcloud nextcloud',
'unless': f"""php -r 'include "/opt/nextcloud/version.php"; echo "$OC_VersionString";' | grep -q '^{version}$'""",
'preceded_by': [
'preceded_by': {
'action:delete_nextcloud',
f'download:/tmp/nextcloud-{version}.tar.bz2',
],
'needs': [
},
'needs': {
'directory:/opt/nextcloud',
],
},
}
symlinks = {
@ -53,17 +53,17 @@ symlinks = {
'target': '/etc/nextcloud',
'owner': 'www-data',
'group': 'www-data',
'needs': [
'needs': {
'action:extract_nextcloud',
],
},
},
'/opt/nextcloud/userapps': {
'target': '/var/lib/nextcloud/.userapps',
'owner': 'www-data',
'group': 'www-data',
'needs': [
'needs': {
'action:extract_nextcloud',
],
},
},
}
@ -76,9 +76,9 @@ files = {
'context': {
'db_password': node.metadata.get('postgresql/roles/nextcloud/password'),
},
'needs': [
'needs': {
'directory:/etc/nextcloud',
],
},
},
}
@ -98,7 +98,7 @@ actions['install_nextcloud'] = {
data_dir='/var/lib/nextcloud',
),
'unless': repo.libs.nextcloud.occ('status') + ' | grep -q "installed: true"',
'needs': [
'needs': {
'directory:/etc/nextcloud',
'directory:/opt/nextcloud',
'directory:/var/lib/nextcloud',
@ -109,7 +109,7 @@ actions['install_nextcloud'] = {
'action:extract_nextcloud',
'file:/etc/nextcloud/managed.config.php',
'postgres_db:nextcloud',
],
},
}
# UPGRADE
@ -117,18 +117,18 @@ actions['install_nextcloud'] = {
actions['upgrade_nextcloud'] = {
'command': repo.libs.nextcloud.occ('upgrade'),
'unless': "! " + repo.libs.nextcloud.occ('status') + ' | grep -q "Nextcloud or one of the apps require upgrade"',
'needs': [
'needs': {
'action:install_nextcloud',
],
},
}
actions['nextcloud_add_missing_inidces'] = {
'command': repo.libs.nextcloud.occ('db:add-missing-indices'),
'needs': [
'needs': {
'action:upgrade_nextcloud',
],
},
'triggered': True,
'triggered_by': [
'triggered_by': {
f'action:extract_nextcloud',
],
},
}

View file

@ -19,7 +19,7 @@ defaults = {
'archive': {
'paths': {
'/var/lib/nextcloud': {
'exclude': [
'exclude': {
'^appdata_',
'^updater-',
'^nextcloud\.log',
@ -27,7 +27,7 @@ defaults = {
'^[^/]+/cache',
'^[^/]+/files_versions',
'^[^/]+/files_trashbin',
],
},
},
},
},
@ -56,9 +56,9 @@ defaults = {
'datasets': {
'tank/nextcloud': {
'mountpoint': '/var/lib/nextcloud',
'needed_by': [
'needed_by': {
'bundle:nextcloud',
],
},
},
},
},

View file

@ -73,7 +73,7 @@ for name, config in node.metadata.get('nginx/vhosts').items():
server_name=name,
**config.get('context', {}),
),
'needs': [],
'needs': set(),
'needed_by': {
'svc_systemd:nginx',
'svc_systemd:nginx:restart',
@ -84,6 +84,6 @@ for name, config in node.metadata.get('nginx/vhosts').items():
}
if name in node.metadata.get('letsencrypt/domains'):
files[f'/etc/nginx/sites/{name}']['needs'].append(
files[f'/etc/nginx/sites/{name}']['needs'].add(
f'action:letsencrypt_ensure-some-certificate_{name}',
)

View file

@ -7,82 +7,10 @@ defaults = {
},
},
'nginx': {
'default_vhosts': {
'80': {
'listen': [
'80',
'[::]:80',
],
'location /.well-known/acme-challenge/': {
'alias': '/var/lib/dehydrated/acme-challenges/',
},
'location /': {
'return': '301 https://$host$request_uri',
},
},
'stub_status': {
'listen': '127.0.0.1:22999 default_server',
'server_name': '_',
'stub_status': '',
},
},
'vhosts': {
# '80': {
# 'content': 'nginx/80.conf',
# },
# 'stub_status': {
# 'content': 'nginx/stub_status.conf',
# },
},
'includes': {},
'vhosts': {},
},
}
@metadata_reactor.provides(
'nginx/includes',
)
def includes(metadata):
return {
'nginx': {
'includes': {
'php': {
'location ~ \.php$': {
'include': 'fastcgi.conf',
'fastcgi_split_path_info': '^(.+\.php)(/.+)$',
'fastcgi_pass': f"unix:/run/php/php{metadata.get('php/version')}-fpm.sock",
},
},
},
},
}
@metadata_reactor.provides(
'nginx/vhosts',
)
def vhosts(metadata):
vhosts = {}
for name, config in metadata.get('nginx/vhosts').items():
vhosts[name] = {
'server_name': name,
'listen': [
'443 ssl http2',
'[::]:443 ssl http2',
],
'ssl_certificate': f'/var/lib/dehydrated/certs/{name}/fullchain.pem',
'ssl_certificate_key': f'/var/lib/dehydrated/certs/{name}/privkey.pem',
'location /.well-known/acme-challenge/': {
'alias': '/var/lib/dehydrated/acme-challenges/',
},
}
return {
'nginx': {
'vhosts': vhosts,
}
}
@metadata_reactor.provides(
'dns',

View file

@ -2,9 +2,9 @@ file_attributes = {
'owner': 'opendkim',
'group': 'opendkim',
'mode': '700',
'triggers': [
'triggers': {
'svc_systemd:opendkim:restart',
],
},
}
users['opendkim'] = {}
@ -53,33 +53,12 @@ for domain in node.metadata.get('mailserver/domains'):
**file_attributes,
'content': node.metadata.get(f'opendkim/keys/{domain}/private'),
}
# files[f'/etc/opendkim/keys/{domain}/mail.txt'] = {
# **file_attributes,
# 'content_type': 'any',
# }
# actions[f'generate_{domain}_dkim_key'] = {
# 'command': (
# f'sudo --user opendkim'
# f' opendkim-genkey'
# f' --selector=mail'
# f' --directory=/etc/opendkim/keys/{domain}'
# f' --domain={domain}'
# ),
# 'unless': f'test -f /etc/opendkim/keys/{domain}/mail.private',
# 'needs': [
# 'svc_systemd:opendkim',
# f'directory:/etc/opendkim/keys/{domain}',
# ],
# 'triggers': [
# 'svc_systemd:opendkim:restart',
# ],
# }
svc_systemd['opendkim'] = {
'needs': [
'needs': {
'pkg_apt:opendkim',
'file:/etc/opendkim.conf',
'file:/etc/opendkim/key_table',
'file:/etc/opendkim/signing_table',
],
},
}

View file

@ -15,13 +15,6 @@ defaults = {
'opendkim': {
'keys': {},
},
'dns': {
'mail._domainkey.mail2.sublimity.de': {
'TXT': [
]
}
}
}
@ -85,7 +78,7 @@ def dns(metadata):
for domain, keys in metadata.get('opendkim/keys').items():
raw_key = sub('^ssh-rsa ', '', keys['public'])
dns[f'mail._domainkey.{domain}'] = {
'TXT': [f'v=DKIM1; k=rsa; p={raw_key}'],
'TXT': {f'v=DKIM1; k=rsa; p={raw_key}'},
}
return {

View file

@ -1,15 +1,15 @@
assert node.has_bundle('mailserver')
file_options = {
'needs': [
'needs': {
'pkg_apt:postfix',
],
'needed_by': [
},
'needed_by': {
'svc_systemd:postfix',
],
'triggers': [
},
'triggers': {
'svc_systemd:postfix:restart',
],
},
}
files = {
@ -41,39 +41,39 @@ files = {
}
svc_systemd['postfix'] = {
'needs': [
'needs': {
'postgres_db:mailserver',
],
},
}
actions['test_postfix_config'] = {
'command': 'false',
'unless': "postconf check | grep -v 'symlink leaves directory' | wc -l | grep -q '^0$'",
'needs': [
'needs': {
'svc_systemd:postfix',
],
},
}
actions['test_virtual_mailbox_domains'] = {
'command': 'false',
'unless': "postmap -q example.com pgsql:/etc/postfix/virtual_mailbox_domains.cf | grep -q '^example.com$'",
'needs': [
'needs': {
'svc_systemd:postfix',
'action:mailserver_update_test_pw',
],
},
}
actions['test_virtual_mailbox_maps'] = {
'command': 'false',
'unless': "postmap -q bw_test_user@example.com pgsql:/etc/postfix/virtual_mailbox_maps.cf | grep -q '^bw_test_user@example.com$'",
'needs': [
'needs': {
'svc_systemd:postfix',
'action:mailserver_update_test_pw',
],
},
}
actions['test_virtual_alias_maps'] = {
'command': 'false',
'unless': "postmap -q bw_test_alias@example.com pgsql:/etc/postfix/virtual_alias_maps.cf | grep -q '^somewhere@example.com$'",
'needs': [
'needs': {
'svc_systemd:postfix',
'action:mailserver_update_test_pw',
],
},
}

View file

@ -6,9 +6,9 @@ defaults = {
}
},
'backup': {
'paths': [
'paths': {
'/var/vmail',
],
},
},
'letsencrypt': {
'reload_after': {

View file

@ -4,32 +4,32 @@ directories = {
'/var/lib/postgresql': {
'owner': 'postgres',
'group': 'postgres',
'needs': [
'needs': {
'zfs_dataset:tank/postgresql',
],
'needed_by': [
},
'needed_by': {
'svc_systemd:postgresql',
],
},
}
}
svc_systemd['postgresql'] = {
'needs': [
'needs': {
'pkg_apt:postgresql',
],
},
}
for user, config in node.metadata.get('postgresql/roles').items():
postgres_roles[user] = merge_dict(config, {
'needs': [
'needs': {
'svc_systemd:postgresql',
],
},
})
for database, config in node.metadata.get('postgresql/databases').items():
postgres_dbs[database] = merge_dict(config, {
'needs': [
'needs': {
'svc_systemd:postgresql',
],
},
})

View file

@ -7,9 +7,9 @@ defaults = {
},
},
'backup': {
'paths': [
'paths': {
'/var/lib/postgresql',
],
},
},
'postgresql': {
'roles': {
@ -20,7 +20,7 @@ defaults = {
},
'databases': {},
},
'grafana_rows': [],
'grafana_rows': set(),
}
if node.has_bundle('zfs'):

View file

@ -9,15 +9,15 @@ directories = {
},
'/opt/roundcube/logs': {
'owner': 'www-data',
'needs': [
'needs': {
'action:extract_roundcube',
],
},
},
'/opt/roundcube/temp': {
'owner': 'www-data',
'needs': [
'needs': {
'action:extract_roundcube',
],
},
}
}
@ -39,13 +39,13 @@ actions['extract_roundcube'] = {
'action:delete_roundcube',
f'download:/tmp/roundcube-{version}.tar.gz',
],
'needs': [
'needs': {
'directory:/opt/roundcube',
],
'triggers': [
},
'triggers': {
'action:chown_roundcube',
'action:composer_install',
],
},
}
actions['chown_roundcube'] = {
'command': 'chown -R www-data /opt/roundcube',
@ -63,9 +63,9 @@ files = {
'database': node.metadata.get('roundcube/database'),
'plugins': node.metadata.get('roundcube/plugins'),
},
'needs': [
'needs': {
'action:chown_roundcube',
],
},
},
'/opt/roundcube/plugins/password/config.inc.php': {
'source': 'password.config.inc.php',
@ -73,16 +73,16 @@ files = {
'context': {
'mailserver_db_password': node.metadata.get('mailserver/database/password'),
},
'needs': [
'needs': {
'action:chown_roundcube',
],
},
},
}
actions['composer_install'] = {
'command': "cp /opt/roundcube/composer.json-dist /opt/roundcube/composer.json && su www-data -s /bin/bash -c '/usr/bin/composer -d /opt/roundcube install'",
'triggered': True,
'needs': [
'needs': {
'action:chown_roundcube',
],
},
}

View file

@ -52,7 +52,7 @@ defaults = {
},
},
'sudoers': {
'www-data': ['/usr/bin/doveadm pw -s ARGON2ID'],
'www-data': {'/usr/bin/doveadm pw -s ARGON2ID'},
},
}

View file

@ -1,11 +1,11 @@
files['/etc/ssh/sshd_config'] = {
'triggers': [
'svc_systemd:ssh:restart'
],
'triggers': {
'svc_systemd:ssh:restart',
},
}
svc_systemd['ssh'] = {
'needs': [
'needs': {
'tag:ssh_users',
],
},
}

View file

@ -5,6 +5,6 @@ defaults = {
},
},
'sudoers': {
'root': ['ALL'],
'root': {'ALL'},
},
}

View file

@ -1,27 +0,0 @@
# # svc_systemd['cron'] = {
# # 'enabled': False,
# # }
#
# for name, config in node.metadata.get('systemd-timers').items():
# files[f'/etc/systemd/system/{name}.timer'] = {
# 'content': repo.libs.systemd.generate_unitfile({
# 'Unit':{
# 'Description': f'{name} timer',
# },
# 'Timer': {
# 'OnCalendar': config['when'],
# 'Persistent': config.get('persistent', False),
# 'Unit': f'{name}.service',
# },
# 'Install': {
# 'WantedBy': 'multi-user.target',
# }
# }),
# 'triggers': [
# 'action:systemd-reload',
# f'svc_systemd:{name}:restart',
# ],
# }
#
# svc_systemd[f'{name}.timer'] = {}
# #

View file

@ -14,16 +14,16 @@ for name, unit in node.metadata.get('systemd/units').items():
if extension in ['netdev', 'network']:
path = f'/etc/systemd/network/{name}'
dependencies = {
'triggers': [
'triggers': {
'svc_systemd:systemd-networkd:restart',
],
},
}
elif extension in ['timer', 'service']:
path = f'/etc/systemd/system/{name}'
dependencies = {
'triggers': [
'triggers': {
"action:systemd-reload",
],
},
}
files[path] = {
@ -33,7 +33,7 @@ for name, unit in node.metadata.get('systemd/units').items():
for name, config in node.metadata.get('systemd/services').items():
svc_systemd[name] = merge_dict(config, {
'needs': [
'needs': {
'action:systemd-reload',
],
},
})

View file

@ -2,14 +2,14 @@ from tomlkit import dumps
files['/etc/telegraf/telegraf.conf'] = {
'content': dumps(node.metadata.get('telegraf/config'), sort_keys=True),
'triggers': [
'triggers': {
'svc_systemd:telegraf:restart',
],
},
}
svc_systemd['telegraf'] = {
'needs': [
'needs': {
'file:/etc/telegraf/telegraf.conf',
'pkg_apt:telegraf',
],
},
}

View file

@ -3,11 +3,11 @@ defaults = {
'packages': {
'telegraf': {},
},
'sources': [
'sources': {
# FIXME
# 'deb https://repos.influxdata.com/debian {release} stable',
'deb https://repos.influxdata.com/debian buster stable',
],
},
},
'telegraf': {
'config': {
@ -50,12 +50,12 @@ defaults = {
},
},
},
'grafana_rows': [
'grafana_rows': {
'cpu',
'mem',
'disk_io',
'net_io',
],
},
}

View file

@ -11,25 +11,25 @@ for name, config in node.metadata.get('users').items():
'content': config['privkey'] + '\n',
'owner': name,
'mode': '0600',
'tags': [
'tags': {
'ssh_users',
],
},
}
files[f"{config['home']}/.ssh/id_{config['keytype']}.pub"] = {
'content': config['pubkey'] + '\n',
'owner': name,
'mode': '0600',
'tags': [
'tags': {
'ssh_users',
],
},
}
files[config['home'] + '/.ssh/authorized_keys'] = {
'content': '\n'.join(sorted(config['authorized_keys'])) + '\n',
'owner': name,
'mode': '0600',
'tags': [
'tags': {
'ssh_users',
],
},
}
users[name] = config

View file

@ -1,3 +1 @@
from ipaddress import ip_network
repo.libs.tools.require_bundle(node, 'systemd-networkd')

View file

@ -10,12 +10,12 @@ defaults = {
'linux-headers-amd64': {},
'wireguard': {
'backports': node.os_version < (11,),
'needs': [
'needs': {
'pkg_apt:linux-headers-amd64',
],
'triggers': [
},
'triggers': {
'svc_systemd:systemd-networkd:restart',
],
},
},
},
},
@ -90,10 +90,10 @@ def systemd_networkd_netdevs(metadata):
'Endpoint': config['endpoint'],
'PublicKey': config['pubkey'],
'PresharedKey': config['psk'],
'AllowedIPs': ', '.join([
'AllowedIPs': ', '.join(sorted([
str(ip_interface(repo.get_node(peer).metadata.get(f'wireguard/my_ip')).ip),
*config.get('route', []),
]), # FIXME
])), # FIXME
'PersistentKeepalive': 30,
}
})

View file

@ -30,7 +30,7 @@ actions = {
svc_systemd = {
'zfs-zed': {
'needs': {
'pkg_apt:zfs-zed'
'pkg_apt:zfs-zed',
},
},
}
@ -45,7 +45,7 @@ for name, config in node.metadata.get('zfs/pools', {}).items():
actions[f'pool_{name}_enable_trim'] = {
'command': f'zpool set autotrim=on {name}',
'unless': f'zpool get autotrim -H -o value {name} | grep -q on',
'needs': [
f'zfs_pool:{name}'
]
'needs': {
f'zfs_pool:{name}',
},
}

View file

@ -103,10 +103,10 @@ def dataset_defaults(metadata):
def backup(metadata):
return {
'backup': {
'paths': [
'paths': {
options['mountpoint']
for options in metadata.get('zfs/datasets').values()
if options.get('backup', True)
],
},
},
}

View file

@ -13,9 +13,9 @@ for name, user_config in node.metadata.get('users').items():
},
join(user_config['home'], '.zsh/oh-my-zsh/custom/plugins/zsh-autosuggestions'): {
'owner': name,
'needs': [
'needs': {
f"git_deploy:{join(user_config['home'], '.zsh/oh-my-zsh')}",
]
},
},
}
@ -38,9 +38,9 @@ for name, user_config in node.metadata.get('users').items():
},
join(user_config['home'], '.zsh/oh-my-zsh/themes/bw.zsh-theme'): {
'owner': name,
'needs': [
'needs': {
f"git_deploy:{join(user_config['home'], '.zsh/oh-my-zsh')}",
]
},
},
}

View file

@ -1,20 +1,20 @@
{
'bundles': [
'bundles': {
'sudo',
'users',
'zsh',
],
},
'metadata': {
'dns': {},
'nameservers': [
'nameservers': {
'10.0.10.2',
],
},
'users': {
'root': {
'shell': '/usr/bin/zsh',
'authorized_keys': [
'authorized_keys': {
'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEU1l2ijW3ZqzFGZcdWg2ESgTGehdNfBTfafxsjWvWdS mwiegand@macbook',
],
},
},
},
}

View file

@ -1,10 +1,10 @@
{
'supergroups': [
'supergroups': {
'gcloud',
],
'bundles': [
},
'bundles': {
'archive',
'gocryptfs',
'gocryptfs-inspect',
],
},
}

View file

@ -1,6 +1,6 @@
{
'bundles': [
'bundles': {
'backup-server',
'zfs',
],
},
}

View file

@ -1,7 +1,7 @@
{
'bundles': [
'bundles': {
'backup',
],
},
'metadata': {
'backup': {
'server': 'home.backups',

View file

@ -1,5 +1,5 @@
{
'bundles': [
'bundles': {
'bind',
],
},
}

View file

@ -1,7 +1,7 @@
{
'bundles': [
'bundles': {
'gcloud',
],
},
'metadata': {
'gcloud': {
'service_account': 'backup',

View file

@ -1,5 +1,5 @@
{
'bundles': [
'bundles': {
'opendkim',
'dovecot',
'letsencrypt',
@ -11,5 +11,5 @@
'redis',
'roundcube',
'rspamd',
],
},
}

View file

@ -1,7 +1,7 @@
{
'bundles': [
'bundles': {
'telegraf',
],
},
'metadata': {
'telegraf': {
'influxdb_node': 'home.server',

View file

@ -1,6 +1,6 @@
{
'bundles': [
'bundles': {
'nextcloud',
'php',
],
},
}

View file

@ -1,6 +1,6 @@
{
'bundles': [
'bundles': {
'nginx',
'letsencrypt',
],
},
}

View file

@ -1,5 +0,0 @@
{
'bundles': [
'hetzner-cloud',
],
}

View file

@ -1,12 +1,12 @@
{
'supergroups': [
'supergroups': {
'debian',
],
},
'metadata': {
'apt': {
'sources': [
'sources': {
'deb http://security.debian.org/debian-security {release}/updates main contrib non-free',
],
},
},
'php': {
'version': '7.3',

View file

@ -1,12 +1,12 @@
{
'supergroups': [
'supergroups': {
'debian',
],
},
'metadata': {
'apt': {
'sources': [
'sources': {
'deb http://security.debian.org/ {release}-security main contrib non-free',
],
},
},
'php': {
'version': '7.4',

View file

@ -1,17 +1,17 @@
{
'supergroups': [
'supergroups': {
'linux',
],
'bundles': [
},
'bundles': {
'apt',
],
},
'metadata': {
'apt': {
'sources': [
'sources': {
'deb http://deb.debian.org/debian {release} main non-free contrib',
'deb http://deb.debian.org/debian {release}-updates main contrib non-free',
'deb http://deb.debian.org/debian {release}-backports main contrib non-free',
],
},
'packages': {
'mtr-tiny': {},
},

View file

@ -1,8 +1,8 @@
{
'supergroups': [
'supergroups': {
'all',
],
'bundles': [
},
'bundles': {
'hostname',
'hosts',
'network',
@ -10,14 +10,14 @@
'systemd',
'systemd-networkd',
'systemd-timers',
],
},
'metadata': {
'hosts': {
'10.0.10.2': [
'10.0.10.2': {
'resolver.name',
'first.resolver.name',
'second.resolver.name',
],
},
},
},
}

View file

@ -7,9 +7,9 @@ template = '''
# ${segment.split('#', 2)[1]}
% endif
[${segment.split('#')[0]}]
% for option, value in options.items():
% for option, value in sorted(options.items()):
% if isinstance(value, dict):
% for k, v in value.items():
% for k, v in sorted(value.items()):
${option}=${k}=${v}
% endfor
% elif isinstance(value, (list, set, tuple)):

View file

@ -1,13 +1,13 @@
{
'hostname': '10.0.0.5',
'groups': [
'groups': {
'debian-10',
'backup-server',
'monitored',
],
'bundles': [
},
'bundles': {
'zfs',
],
},
'metadata': {
'id': '9cf52515-63a1-4659-a8ec-6c3c881727e5',
'network': {
@ -23,11 +23,11 @@
'zfs': {
'pools': {
'tank': {
'raidz': [
'raidz': {
'/dev/disk/by-id/ata-HGST_HDN726040ALE614_K3GV6TPL',
'/dev/disk/by-id/ata-HGST_HDN726040ALE614_K4KAJXEB',
'/dev/disk/by-id/ata-TOSHIBA_HDWQ140_19VZK0EMFAYG',
],
},
},
},
},

View file

@ -1,13 +1,13 @@
{
'hostname': '10.0.0.2',
'groups': [
'groups': {
'backup',
'debian-10',
'nextcloud',
'monitored',
'webserver',
],
'bundles': [
},
'bundles': {
'gitea',
'grafana',
'influxdb2',
@ -16,7 +16,7 @@
'redis',
'wireguard',
'zfs',
],
},
'metadata': {
'id': 'af96709e-b13f-4965-a588-ef2cd476437a',
'network': {
@ -61,20 +61,20 @@
'my_ip': '172.30.0.2/24',
'peers': {
'htz.mails': {
'route': [
'route': {
'10.0.10.0/24',
'10.0.11.0/24',
],
},
},
},
},
'zfs': {
'pools': {
'tank': {
'mirrors': [
'mirrors': [[
'/dev/disk/by-partlabel/zfs-data-1',
'/dev/disk/by-partlabel/zfs-data-2',
],
]],
},
},
},

View file

@ -1,13 +1,13 @@
{
'dummy': True,
'groups': [
'groups': {
'backup',
'debian-10',
],
'bundles': [
},
'bundles': {
'steam',
'l4d2',
],
},
'metadata': {
'id': '353bb086-f3ce-4f36-8533-e91786c91ed9',
},

View file

@ -1,18 +1,17 @@
{
'hostname': '162.55.188.157',
'groups': [
'groups': {
'backup',
'hetzner-cloud',
'debian-11',
'mailserver',
'monitored',
'webserver',
'dnsserver',
],
'bundles': [
},
'bundles': {
'wireguard',
'zfs',
],
},
'metadata': {
'id': 'ea29bdf0-0b47-4bf4-8346-67d60c9dc4ae',
'network': {
@ -46,12 +45,12 @@
},
'dns': {
'ckn.li': {
'A': ['162.55.188.157'],
'AAAA': ['2a01:4f8:1c1c:4121::2'],
'A': {'162.55.188.157'},
'AAAA': {'2a01:4f8:1c1c:4121::2'},
},
'freibrief.net': {
'A': ['162.55.188.157'],
'AAAA': ['2a01:4f8:1c1c:4121::2'],
'A': {'162.55.188.157'},
'AAAA': {'2a01:4f8:1c1c:4121::2'},
},
},
'letsencrypt': {
@ -64,7 +63,7 @@
'mailserver': {
'hostname': 'mail.sublimity.de',
'admin_email': 'postmaster@sublimity.de',
'domains': [
'domains': {
'ckn.li',
'sublimity.de',
'freibrief.net',
@ -74,7 +73,7 @@
'wettengl.net',
'wingl.de',
'woodpipe.de',
],
},
},
'nginx': {
'vhosts': {
@ -122,12 +121,12 @@
},
'users': {
'root': {
'authorized_users': [
'authorized_users': {
'root@home.server',
],
'authorized_keys': [
},
'authorized_keys': {
'ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHMKTJLw6Cb+MLt+9JFOkuo2QBpuA8EoTKOFpb3IFQHEq19YLMzOhcErWmzaRfiCnILhnwTQz0njS+n9Qu4aghk= root@mail.sublimity.de'
],
},
},
},
'vm': {
@ -138,16 +137,16 @@
'my_ip': '172.30.0.1/24',
'peers': {
'home.server': {
'route': [
'route': {
'10.0.0.0/24',
'10.0.2.0/24',
'10.0.9.0/24',
],
},
},
'netcup.secondary': {
'route': [
'route': {
'10.0.11.0/24',
],
},
},
},
},

View file

@ -1,12 +1,12 @@
{
'hostname': '46.38.240.85',
'groups': [
'groups': {
'debian-10',
'dnsserver',
],
'bundles': [
},
'bundles': {
'wireguard',
],
},
'metadata': {
'id': '890848b2-a900-4f74-ad5b-b811fbb4f0bc',
'network': {
@ -34,12 +34,12 @@
'my_ip': '172.30.0.3/24',
'peers': {
'htz.mails': {
'route': [
'route': {
'10.0.0.0/24',
'10.0.2.0/24',
'10.0.9.0/24',
'10.0.10.0/24',
],
},
},
},
},