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: release a={node.metadata.get('os_release')}-backports",
f"Pin-Priority: 900", f"Pin-Priority: 900",
]), ]),
'needed_by': [ 'needed_by': {
f'pkg_apt:{package}', f'pkg_apt:{package}',
], },
'triggers': { 'triggers': {
'action:apt_update', 'action:apt_update',
}, },

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -122,10 +122,10 @@ def slaves(metadata):
return { return {
'bind': { 'bind': {
'slaves': [ 'slaves': {
other_node.name other_node.name
for other_node in repo.nodes for other_node in repo.nodes
if other_node.has_bundle('bind') and other_node.metadata.get('bind/master_node', None) == node.name 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': { '/etc/dovecot/conf.d': {
'purge': True, 'purge': True,
'needs': [ 'needs': {
'pkg_apt:dovecot-sieve', 'pkg_apt:dovecot-sieve',
'pkg_apt:dovecot-managesieved', 'pkg_apt:dovecot-managesieved',
] },
}, },
'/etc/dovecot/ssl': {}, '/etc/dovecot/ssl': {},
'/var/vmail': { '/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') join(repo.path, 'data', 'gcloud', 'service_accounts', f'{service_account}@{project}.json.enc')
), ),
'mode': '500', 'mode': '500',
'needs': [ 'needs': {
'pkg_apt:google-cloud-sdk', 'pkg_apt:google-cloud-sdk',
], },
} }
actions['gcloud_activate_service_account'] = { actions['gcloud_activate_service_account'] = {
'command': 'gcloud auth activate-service-account --key-file /etc/gcloud/service_account.json', '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'", 'unless': f"gcloud auth list | grep -q '^\*[[:space:]]*{service_account}@{project}.iam.gserviceaccount.com'",
'needs': [ 'needs': {
f'file:/etc/gcloud/service_account.json' f'file:/etc/gcloud/service_account.json'
], },
} }
actions['gcloud_select_project'] = { actions['gcloud_select_project'] = {
'command': f"gcloud config set project '{project}'", 'command': f"gcloud config set project '{project}'",
'unless': f"gcloud config get-value project | grep -q '^{project}$'", 'unless': f"gcloud config get-value project | grep -q '^{project}$'",
'needs': [ 'needs': {
f'action:gcloud_activate_service_account' f'action:gcloud_activate_service_account'
], },
} }

View file

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

View file

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

View file

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

View file

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

View file

@ -9,9 +9,9 @@ import yaml
import json import json
svc_systemd['grafana-server'] = { svc_systemd['grafana-server'] = {
'needs': [ 'needs': {
'pkg_apt:grafana', 'pkg_apt:grafana',
], },
} }
admin_password = node.metadata.get('grafana/config/security/admin_password') admin_password = node.metadata.get('grafana/config/security/admin_password')
@ -25,10 +25,8 @@ actions['reset_grafana_admin_password'] = {
} }
directories = { directories = {
'/etc/grafana': { '/etc/grafana': {},
}, '/etc/grafana/provisioning': {},
'/etc/grafana/provisioning': {
},
'/etc/grafana/provisioning/datasources': { '/etc/grafana/provisioning/datasources': {
'purge': True, 'purge': True,
}, },
@ -42,18 +40,18 @@ directories = {
files = { files = {
'/etc/grafana/grafana.ini': { '/etc/grafana/grafana.ini': {
'content': repo.libs.ini.dumps(node.metadata.get('grafana/config')), 'content': repo.libs.ini.dumps(node.metadata.get('grafana/config')),
'triggers': [ 'triggers': {
'svc_systemd:grafana-server:restart', 'svc_systemd:grafana-server:restart',
], },
}, },
'/etc/grafana/provisioning/datasources/managed.yaml': { '/etc/grafana/provisioning/datasources/managed.yaml': {
'content': yaml.dump({ 'content': yaml.dump({
'apiVersion': 1, 'apiVersion': 1,
'datasources': list(node.metadata.get('grafana/datasources').values()), 'datasources': list(node.metadata.get('grafana/datasources').values()),
}), }),
'triggers': [ 'triggers': {
'svc_systemd:grafana-server:restart', 'svc_systemd:grafana-server:restart',
], },
}, },
'/etc/grafana/provisioning/dashboards/managed.yaml': { '/etc/grafana/provisioning/dashboards/managed.yaml': {
'content': yaml.dump({ 'content': yaml.dump({
@ -67,9 +65,9 @@ files = {
}, },
}], }],
}), }),
'triggers': [ 'triggers': {
'svc_systemd:grafana-server:restart', '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'] = { files[f'/var/lib/grafana/dashboards/{monitored_node.name}.json'] = {
'content': json.dumps(dashboard, indent=4), 'content': json.dumps(dashboard, indent=4),
'triggers': [ 'triggers': {
'svc_systemd:grafana-server:restart', '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 = { defaults = {
'hosts': { 'hosts': {
'127.0.0.1': [ '127.0.0.1': {
'localhost', 'localhost',
node.name, node.name,
], },
'::1': [ '::1': {
'localhost', 'localhost',
'ip6-localhost', 'ip6-localhost',
'ip6-loopback', 'ip6-loopback',
], },
'fe00::0': [ 'fe00::0': {
'ip6-localnet' 'ip6-localnet'
], },
'ff00::0': [ 'ff00::0': {
'ip6-mcastprefix' 'ip6-mcastprefix'
], },
'ff02::1': [ 'ff02::1': {
'ip6-allnodes' 'ip6-allnodes'
], },
'ff02::2': [ 'ff02::2': {
'ip6-allrouters' 'ip6-allrouters'
], },
'ff02::3': [ 'ff02::3': {
'ip6-allhosts' 'ip6-allhosts'
], },
}, },
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -73,7 +73,7 @@ for name, config in node.metadata.get('nginx/vhosts').items():
server_name=name, server_name=name,
**config.get('context', {}), **config.get('context', {}),
), ),
'needs': [], 'needs': set(),
'needed_by': { 'needed_by': {
'svc_systemd:nginx', 'svc_systemd:nginx',
'svc_systemd:nginx:restart', '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'): 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}', f'action:letsencrypt_ensure-some-certificate_{name}',
) )

View file

@ -7,82 +7,10 @@ defaults = {
}, },
}, },
'nginx': { 'nginx': {
'default_vhosts': { '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': {},
}, },
} }
@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( @metadata_reactor.provides(
'dns', 'dns',

View file

@ -2,9 +2,9 @@ file_attributes = {
'owner': 'opendkim', 'owner': 'opendkim',
'group': 'opendkim', 'group': 'opendkim',
'mode': '700', 'mode': '700',
'triggers': [ 'triggers': {
'svc_systemd:opendkim:restart', 'svc_systemd:opendkim:restart',
], },
} }
users['opendkim'] = {} users['opendkim'] = {}
@ -53,33 +53,12 @@ for domain in node.metadata.get('mailserver/domains'):
**file_attributes, **file_attributes,
'content': node.metadata.get(f'opendkim/keys/{domain}/private'), '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'] = { svc_systemd['opendkim'] = {
'needs': [ 'needs': {
'pkg_apt:opendkim', 'pkg_apt:opendkim',
'file:/etc/opendkim.conf', 'file:/etc/opendkim.conf',
'file:/etc/opendkim/key_table', 'file:/etc/opendkim/key_table',
'file:/etc/opendkim/signing_table', 'file:/etc/opendkim/signing_table',
], },
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -9,15 +9,15 @@ directories = {
}, },
'/opt/roundcube/logs': { '/opt/roundcube/logs': {
'owner': 'www-data', 'owner': 'www-data',
'needs': [ 'needs': {
'action:extract_roundcube', 'action:extract_roundcube',
], },
}, },
'/opt/roundcube/temp': { '/opt/roundcube/temp': {
'owner': 'www-data', 'owner': 'www-data',
'needs': [ 'needs': {
'action:extract_roundcube', 'action:extract_roundcube',
], },
} }
} }
@ -39,13 +39,13 @@ actions['extract_roundcube'] = {
'action:delete_roundcube', 'action:delete_roundcube',
f'download:/tmp/roundcube-{version}.tar.gz', f'download:/tmp/roundcube-{version}.tar.gz',
], ],
'needs': [ 'needs': {
'directory:/opt/roundcube', 'directory:/opt/roundcube',
], },
'triggers': [ 'triggers': {
'action:chown_roundcube', 'action:chown_roundcube',
'action:composer_install', 'action:composer_install',
], },
} }
actions['chown_roundcube'] = { actions['chown_roundcube'] = {
'command': 'chown -R www-data /opt/roundcube', 'command': 'chown -R www-data /opt/roundcube',
@ -63,9 +63,9 @@ files = {
'database': node.metadata.get('roundcube/database'), 'database': node.metadata.get('roundcube/database'),
'plugins': node.metadata.get('roundcube/plugins'), 'plugins': node.metadata.get('roundcube/plugins'),
}, },
'needs': [ 'needs': {
'action:chown_roundcube', 'action:chown_roundcube',
], },
}, },
'/opt/roundcube/plugins/password/config.inc.php': { '/opt/roundcube/plugins/password/config.inc.php': {
'source': 'password.config.inc.php', 'source': 'password.config.inc.php',
@ -73,16 +73,16 @@ files = {
'context': { 'context': {
'mailserver_db_password': node.metadata.get('mailserver/database/password'), 'mailserver_db_password': node.metadata.get('mailserver/database/password'),
}, },
'needs': [ 'needs': {
'action:chown_roundcube', 'action:chown_roundcube',
], },
}, },
} }
actions['composer_install'] = { 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'", '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, 'triggered': True,
'needs': [ 'needs': {
'action:chown_roundcube', 'action:chown_roundcube',
], },
} }

View file

@ -52,7 +52,7 @@ defaults = {
}, },
}, },
'sudoers': { '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'] = { files['/etc/ssh/sshd_config'] = {
'triggers': [ 'triggers': {
'svc_systemd:ssh:restart' 'svc_systemd:ssh:restart',
], },
} }
svc_systemd['ssh'] = { svc_systemd['ssh'] = {
'needs': [ 'needs': {
'tag:ssh_users', 'tag:ssh_users',
], },
} }

View file

@ -5,6 +5,6 @@ defaults = {
}, },
}, },
'sudoers': { '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']: if extension in ['netdev', 'network']:
path = f'/etc/systemd/network/{name}' path = f'/etc/systemd/network/{name}'
dependencies = { dependencies = {
'triggers': [ 'triggers': {
'svc_systemd:systemd-networkd:restart', 'svc_systemd:systemd-networkd:restart',
], },
} }
elif extension in ['timer', 'service']: elif extension in ['timer', 'service']:
path = f'/etc/systemd/system/{name}' path = f'/etc/systemd/system/{name}'
dependencies = { dependencies = {
'triggers': [ 'triggers': {
"action:systemd-reload", "action:systemd-reload",
], },
} }
files[path] = { 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(): for name, config in node.metadata.get('systemd/services').items():
svc_systemd[name] = merge_dict(config, { svc_systemd[name] = merge_dict(config, {
'needs': [ 'needs': {
'action:systemd-reload', 'action:systemd-reload',
], },
}) })

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -30,7 +30,7 @@ actions = {
svc_systemd = { svc_systemd = {
'zfs-zed': { 'zfs-zed': {
'needs': { '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'] = { actions[f'pool_{name}_enable_trim'] = {
'command': f'zpool set autotrim=on {name}', 'command': f'zpool set autotrim=on {name}',
'unless': f'zpool get autotrim -H -o value {name} | grep -q on', 'unless': f'zpool get autotrim -H -o value {name} | grep -q on',
'needs': [ 'needs': {
f'zfs_pool:{name}' f'zfs_pool:{name}',
] },
} }

View file

@ -103,10 +103,10 @@ def dataset_defaults(metadata):
def backup(metadata): def backup(metadata):
return { return {
'backup': { 'backup': {
'paths': [ 'paths': {
options['mountpoint'] options['mountpoint']
for options in metadata.get('zfs/datasets').values() for options in metadata.get('zfs/datasets').values()
if options.get('backup', True) 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'): { join(user_config['home'], '.zsh/oh-my-zsh/custom/plugins/zsh-autosuggestions'): {
'owner': name, 'owner': name,
'needs': [ 'needs': {
f"git_deploy:{join(user_config['home'], '.zsh/oh-my-zsh')}", 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'): { join(user_config['home'], '.zsh/oh-my-zsh/themes/bw.zsh-theme'): {
'owner': name, 'owner': name,
'needs': [ 'needs': {
f"git_deploy:{join(user_config['home'], '.zsh/oh-my-zsh')}", f"git_deploy:{join(user_config['home'], '.zsh/oh-my-zsh')}",
] },
}, },
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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