cloudfall 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cloudfall/__init__.py +19 -0
- cloudfall/__main__.py +5 -0
- cloudfall/_bundled/schemas/v1/alert-rule.schema.json +63 -0
- cloudfall/_bundled/schemas/v1/application.schema.json +60 -0
- cloudfall/_bundled/schemas/v1/artifact.schema.json +71 -0
- cloudfall/_bundled/schemas/v1/backup-receipt.schema.json +58 -0
- cloudfall/_bundled/schemas/v1/common.schema.json +115 -0
- cloudfall/_bundled/schemas/v1/component.schema.json +234 -0
- cloudfall/_bundled/schemas/v1/deployment-receipt.schema.json +53 -0
- cloudfall/_bundled/schemas/v1/domain.schema.json +208 -0
- cloudfall/_bundled/schemas/v1/environment-receipt.schema.json +55 -0
- cloudfall/_bundled/schemas/v1/logging-stack.schema.json +473 -0
- cloudfall/_bundled/schemas/v1/observed-domain.schema.json +158 -0
- cloudfall/_bundled/schemas/v1/observed-server.schema.json +627 -0
- cloudfall/_bundled/schemas/v1/operator-policy.schema.json +97 -0
- cloudfall/_bundled/schemas/v1/operator-proposal.schema.json +253 -0
- cloudfall/_bundled/schemas/v1/release-receipt.schema.json +66 -0
- cloudfall/_bundled/schemas/v1/server-type.schema.json +289 -0
- cloudfall/_bundled/schemas/v1/server.schema.json +146 -0
- cloudfall/_bundled/schemas/v1/service.schema.json +222 -0
- cloudfall/_bundled/schemas/v1/ssh-public-key.schema.json +55 -0
- cloudfall/agent_tools.py +868 -0
- cloudfall/arguments.py +92 -0
- cloudfall/audit.py +905 -0
- cloudfall/authoring.py +341 -0
- cloudfall/cli.py +1748 -0
- cloudfall/commands.py +257 -0
- cloudfall/cutover.py +370 -0
- cloudfall/dashboard.py +407 -0
- cloudfall/dashboard_server.py +201 -0
- cloudfall/domain.py +1157 -0
- cloudfall/importer.py +906 -0
- cloudfall/inventory.py +2116 -0
- cloudfall/lifecycle.py +874 -0
- cloudfall/mcp_server.py +704 -0
- cloudfall/migrate.py +730 -0
- cloudfall/observation.py +143 -0
- cloudfall/operations.py +1228 -0
- cloudfall/operator.py +1099 -0
- cloudfall/project.py +841 -0
- cloudfall/py.typed +0 -0
- cloudfall/render_api.py +338 -0
- cloudfall/resources.py +67 -0
- cloudfall/secrets.py +262 -0
- cloudfall/service_evidence.py +659 -0
- cloudfall/validation.py +1340 -0
- cloudfall-0.2.0.dist-info/METADATA +408 -0
- cloudfall-0.2.0.dist-info/RECORD +165 -0
- cloudfall-0.2.0.dist-info/WHEEL +4 -0
- cloudfall-0.2.0.dist-info/entry_points.txt +4 -0
- cloudfall-0.2.0.dist-info/licenses/LICENSE +661 -0
- cloudfall_engine/__init__.py +5 -0
- cloudfall_engine/__main__.py +5 -0
- cloudfall_engine/_bundled/ansible/ansible.cfg +7 -0
- cloudfall_engine/_bundled/ansible/playbooks/backup.yml +86 -0
- cloudfall_engine/_bundled/ansible/playbooks/baseline.yml +35 -0
- cloudfall_engine/_bundled/ansible/playbooks/bootstrap.yml +24 -0
- cloudfall_engine/_bundled/ansible/playbooks/data.yml +28 -0
- cloudfall_engine/_bundled/ansible/playbooks/deploy.yml +35 -0
- cloudfall_engine/_bundled/ansible/playbooks/domains.yml +21 -0
- cloudfall_engine/_bundled/ansible/playbooks/health.yml +31 -0
- cloudfall_engine/_bundled/ansible/playbooks/inspect.yml +15 -0
- cloudfall_engine/_bundled/ansible/playbooks/logging.yml +35 -0
- cloudfall_engine/_bundled/ansible/playbooks/restart.yml +31 -0
- cloudfall_engine/_bundled/ansible/playbooks/rollback.yml +33 -0
- cloudfall_engine/_bundled/ansible/playbooks/services.yml +37 -0
- cloudfall_engine/_bundled/ansible/playbooks/time.yml +9 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_access/defaults/main.yml +2 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_access/handlers/main.yml +5 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_access/meta/argument_specs.yml +34 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_access/meta/main.yml +13 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_access/tasks/main.yml +59 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_bootstrap/defaults/main.yml +11 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_bootstrap/meta/argument_specs.yml +52 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_bootstrap/meta/main.yml +13 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_bootstrap/tasks/main.yml +99 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_data_migration/defaults/main.yml +15 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_data_migration/meta/argument_specs.yml +36 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_data_migration/meta/main.yml +13 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_data_migration/tasks/main.yml +201 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_deploy/defaults/main.yml +10 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_deploy/meta/argument_specs.yml +125 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_deploy/meta/main.yml +13 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_deploy/tasks/health.yml +3 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_deploy/tasks/health_gate.yml +37 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_deploy/tasks/main.yml +285 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_deploy/tasks/restart.yml +17 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_deploy/tasks/rollback.yml +52 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_deploy/templates/component.service.j2 +24 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_firewall/defaults/main.yml +2 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_firewall/handlers/main.yml +5 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_firewall/meta/argument_specs.yml +33 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_firewall/meta/main.yml +13 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_firewall/tasks/main.yml +51 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_firewall/templates/nftables.conf.j2 +31 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_inspect/defaults/main.yml +6 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_inspect/meta/argument_specs.yml +24 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_inspect/meta/main.yml +13 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_inspect/tasks/main.yml +643 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/defaults/main.yml +6 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/handlers/main.yml +29 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/meta/argument_specs.yml +227 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/meta/main.yml +11 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/tasks/main.yml +487 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/templates/alertmanager-defaults.j2 +2 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/templates/alertmanager.yaml.j2 +33 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/templates/grafana.ini.j2 +20 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/templates/loki-datasource.yml.j2 +11 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/templates/loki-systemd-override.conf.j2 +3 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/templates/loki.yaml.j2 +49 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/templates/nginx-loki-gateway.conf.j2 +45 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/templates/prometheus-datasource.yml.j2 +11 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/templates/prometheus-defaults.j2 +2 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/templates/prometheus-rules.yaml.j2 +20 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/templates/prometheus.yaml.j2 +24 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_collector/defaults/main.yml +7 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_collector/handlers/main.yml +6 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_collector/meta/argument_specs.yml +122 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_collector/meta/main.yml +11 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_collector/tasks/main.yml +224 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_collector/templates/alloy-systemd-override.conf.j2 +3 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_collector/templates/config.alloy.j2 +127 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_nginx_site/defaults/main.yml +4 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_nginx_site/handlers/main.yml +5 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_nginx_site/meta/argument_specs.yml +69 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_nginx_site/meta/main.yml +13 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_nginx_site/tasks/main.yml +212 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_nginx_site/templates/domain-site.conf.j2 +54 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/defaults/main.yml +6 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/handlers/main.yml +9 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/meta/argument_specs.yml +91 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/meta/main.yml +13 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/tasks/main.yml +295 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/templates/backup.service.j2 +11 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/templates/backup.sh.j2 +17 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/templates/backup.timer.j2 +10 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/templates/cloudfall.conf.j2 +3 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/templates/restore-check.service.j2 +11 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/templates/restore-check.sh.j2 +27 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/templates/restore-check.timer.j2 +10 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/defaults/main.yml +2 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/handlers/main.yml +6 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/meta/argument_specs.yml +68 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/meta/main.yml +13 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/tasks/main.yml +148 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/templates/backup.service.j2 +11 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/templates/backup.sh.j2 +14 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/templates/backup.timer.j2 +10 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/templates/cloudfall.conf.j2 +6 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/templates/restore-check.service.j2 +11 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/templates/restore-check.sh.j2 +15 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/templates/restore-check.timer.j2 +10 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_time/defaults/main.yml +2 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_time/meta/argument_specs.yml +10 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_time/meta/main.yml +13 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_time/tasks/main.yml +119 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_unattended_upgrades/defaults/main.yml +3 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_unattended_upgrades/meta/argument_specs.yml +8 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_unattended_upgrades/meta/main.yml +13 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_unattended_upgrades/tasks/main.yml +37 -0
- cloudfall_engine/ansible_inventory.py +253 -0
- cloudfall_engine/artifact.py +258 -0
- cloudfall_engine/cli.py +273 -0
- cloudfall_engine/playbook.py +175 -0
- cloudfall_engine/py.typed +0 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Managed by Cloudfall. Local changes will be overwritten.
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
backup_directory="{{ cloudfall_postgresql_service.backup.directory }}"
|
|
6
|
+
port="{{ cloudfall_postgresql_service.bind.port }}"
|
|
7
|
+
retention_days="{{ cloudfall_postgresql_service.backup.retentionDays }}"
|
|
8
|
+
timestamp="$(date --utc +%Y%m%dT%H%M%SZ)"
|
|
9
|
+
|
|
10
|
+
{% for database in cloudfall_postgresql_service.postgresql.databases %}
|
|
11
|
+
pg_dump --port "${port}" --format=custom \
|
|
12
|
+
--file "${backup_directory}/{{ database.name }}-${timestamp}.dump" \
|
|
13
|
+
"{{ database.name }}"
|
|
14
|
+
{% endfor %}
|
|
15
|
+
|
|
16
|
+
find "${backup_directory}" -name '*.dump' -type f \
|
|
17
|
+
-mtime "+${retention_days}" -delete
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Managed by Cloudfall. Local changes will be overwritten.
|
|
2
|
+
[Unit]
|
|
3
|
+
Description=Cloudfall PostgreSQL backup schedule for {{ cloudfall_postgresql_service.id }}
|
|
4
|
+
|
|
5
|
+
[Timer]
|
|
6
|
+
OnCalendar={{ cloudfall_postgresql_service.backup.onCalendar }}
|
|
7
|
+
Persistent=true
|
|
8
|
+
|
|
9
|
+
[Install]
|
|
10
|
+
WantedBy=timers.target
|
cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/templates/restore-check.service.j2
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Managed by Cloudfall. Local changes will be overwritten.
|
|
2
|
+
[Unit]
|
|
3
|
+
Description=Cloudfall PostgreSQL restore drill for {{ cloudfall_postgresql_service.id }}
|
|
4
|
+
After=postgresql@{{ cloudfall_postgresql_service.postgresql.majorVersion }}-main.service
|
|
5
|
+
Requires=postgresql@{{ cloudfall_postgresql_service.postgresql.majorVersion }}-main.service
|
|
6
|
+
|
|
7
|
+
[Service]
|
|
8
|
+
Type=oneshot
|
|
9
|
+
User=postgres
|
|
10
|
+
Group=postgres
|
|
11
|
+
ExecStart=/usr/local/sbin/cloudfall-postgresql-restore-check
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Managed by Cloudfall. Local changes will be overwritten.
|
|
3
|
+
# Restores the newest dump of every declared database into a scratch
|
|
4
|
+
# database, counts catalog rows, and drops the scratch database again.
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
backup_directory="{{ cloudfall_postgresql_service.backup.directory }}"
|
|
8
|
+
port="{{ cloudfall_postgresql_service.bind.port }}"
|
|
9
|
+
|
|
10
|
+
{% for database in cloudfall_postgresql_service.postgresql.databases %}
|
|
11
|
+
latest="$(find "${backup_directory}" -name '{{ database.name }}-*.dump' \
|
|
12
|
+
-type f | sort | tail -n 1)"
|
|
13
|
+
if [ -z "${latest}" ]; then
|
|
14
|
+
echo "no backup found for {{ database.name }}" >&2
|
|
15
|
+
exit 1
|
|
16
|
+
fi
|
|
17
|
+
scratch="{{ database.name }}_restore_check"
|
|
18
|
+
dropdb --port "${port}" --if-exists "${scratch}"
|
|
19
|
+
createdb --port "${port}" "${scratch}"
|
|
20
|
+
pg_restore --port "${port}" --dbname "${scratch}" --no-owner \
|
|
21
|
+
--exit-on-error "${latest}"
|
|
22
|
+
relations="$(psql --port "${port}" --tuples-only --no-align \
|
|
23
|
+
--command 'SELECT count(*) FROM pg_class' "${scratch}")"
|
|
24
|
+
dropdb --port "${port}" "${scratch}"
|
|
25
|
+
echo "restore check passed for {{ database.name }}:" \
|
|
26
|
+
"${latest} (${relations} catalog relations)"
|
|
27
|
+
{% endfor %}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Managed by Cloudfall. Local changes will be overwritten.
|
|
2
|
+
[Unit]
|
|
3
|
+
Description=Cloudfall PostgreSQL restore-drill schedule for {{ cloudfall_postgresql_service.id }}
|
|
4
|
+
|
|
5
|
+
[Timer]
|
|
6
|
+
OnCalendar={{ cloudfall_postgresql_service.backup.restoreCheckOnCalendar }}
|
|
7
|
+
Persistent=true
|
|
8
|
+
|
|
9
|
+
[Install]
|
|
10
|
+
WantedBy=timers.target
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
argument_specs:
|
|
3
|
+
main:
|
|
4
|
+
short_description: Converge one declared Redis service
|
|
5
|
+
options:
|
|
6
|
+
cloudfall_redis_service:
|
|
7
|
+
type: dict
|
|
8
|
+
required: true
|
|
9
|
+
options:
|
|
10
|
+
id:
|
|
11
|
+
type: str
|
|
12
|
+
required: true
|
|
13
|
+
serviceKind:
|
|
14
|
+
type: str
|
|
15
|
+
choices:
|
|
16
|
+
- redis
|
|
17
|
+
required: true
|
|
18
|
+
environment:
|
|
19
|
+
type: str
|
|
20
|
+
required: true
|
|
21
|
+
server:
|
|
22
|
+
type: str
|
|
23
|
+
required: true
|
|
24
|
+
bind:
|
|
25
|
+
type: dict
|
|
26
|
+
required: true
|
|
27
|
+
options:
|
|
28
|
+
address:
|
|
29
|
+
type: str
|
|
30
|
+
choices:
|
|
31
|
+
- 127.0.0.1
|
|
32
|
+
required: true
|
|
33
|
+
port:
|
|
34
|
+
type: int
|
|
35
|
+
required: true
|
|
36
|
+
redis:
|
|
37
|
+
type: dict
|
|
38
|
+
required: true
|
|
39
|
+
options:
|
|
40
|
+
packageVersion:
|
|
41
|
+
type: str
|
|
42
|
+
maxmemoryMb:
|
|
43
|
+
type: int
|
|
44
|
+
required: true
|
|
45
|
+
appendOnly:
|
|
46
|
+
type: bool
|
|
47
|
+
required: true
|
|
48
|
+
backup:
|
|
49
|
+
type: dict
|
|
50
|
+
required: true
|
|
51
|
+
options:
|
|
52
|
+
directory:
|
|
53
|
+
type: path
|
|
54
|
+
required: true
|
|
55
|
+
onCalendar:
|
|
56
|
+
type: str
|
|
57
|
+
required: true
|
|
58
|
+
restoreCheckOnCalendar:
|
|
59
|
+
type: str
|
|
60
|
+
retentionDays:
|
|
61
|
+
type: int
|
|
62
|
+
required: true
|
|
63
|
+
metrics:
|
|
64
|
+
type: dict
|
|
65
|
+
options:
|
|
66
|
+
enabled:
|
|
67
|
+
type: bool
|
|
68
|
+
required: true
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
galaxy_info:
|
|
3
|
+
role_name: cloudfall_redis
|
|
4
|
+
author: cloudfall
|
|
5
|
+
description: Converge one declared loopback Redis service
|
|
6
|
+
license: AGPL-3.0-or-later
|
|
7
|
+
min_ansible_version: "2.16"
|
|
8
|
+
platforms:
|
|
9
|
+
- name: Debian
|
|
10
|
+
versions:
|
|
11
|
+
- bookworm
|
|
12
|
+
- trixie
|
|
13
|
+
dependencies: []
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
---
|
|
2
|
+
- name: Validate Redis service target and declaration
|
|
3
|
+
ansible.builtin.assert:
|
|
4
|
+
that:
|
|
5
|
+
- ansible_facts["distribution"] == "Debian"
|
|
6
|
+
- ansible_facts["service_mgr"] == "systemd"
|
|
7
|
+
- cloudfall_redis_service.serviceKind == "redis"
|
|
8
|
+
- cloudfall_redis_service.server == cloudfall_server_id
|
|
9
|
+
- cloudfall_redis_service.bind.address == "127.0.0.1"
|
|
10
|
+
fail_msg: >-
|
|
11
|
+
Redis deployment requires its declared Debian server and a
|
|
12
|
+
loopback-only bind address
|
|
13
|
+
|
|
14
|
+
- name: Validate the declared backup calendar expression
|
|
15
|
+
ansible.builtin.command:
|
|
16
|
+
argv:
|
|
17
|
+
- /usr/bin/systemd-analyze
|
|
18
|
+
- calendar
|
|
19
|
+
- "{{ cloudfall_redis_service.backup.onCalendar }}"
|
|
20
|
+
changed_when: false
|
|
21
|
+
|
|
22
|
+
- name: Install the pinned Redis server
|
|
23
|
+
ansible.builtin.apt:
|
|
24
|
+
name: >-
|
|
25
|
+
{{
|
|
26
|
+
'redis-server=' ~ cloudfall_redis_service.redis.packageVersion
|
|
27
|
+
if 'packageVersion' in cloudfall_redis_service.redis
|
|
28
|
+
else 'redis-server'
|
|
29
|
+
}}
|
|
30
|
+
state: present
|
|
31
|
+
update_cache: true
|
|
32
|
+
cache_valid_time: 3600
|
|
33
|
+
policy_rc_d: 101
|
|
34
|
+
|
|
35
|
+
- name: Install the managed Redis configuration
|
|
36
|
+
ansible.builtin.template:
|
|
37
|
+
src: cloudfall.conf.j2
|
|
38
|
+
dest: /etc/redis/cloudfall.conf
|
|
39
|
+
owner: redis
|
|
40
|
+
group: redis
|
|
41
|
+
mode: "0640"
|
|
42
|
+
notify: Restart Redis
|
|
43
|
+
|
|
44
|
+
- name: Include the managed configuration from the distribution config
|
|
45
|
+
ansible.builtin.blockinfile:
|
|
46
|
+
path: /etc/redis/redis.conf
|
|
47
|
+
marker: "# {mark} CLOUDFALL MANAGED"
|
|
48
|
+
append_newline: true
|
|
49
|
+
prepend_newline: true
|
|
50
|
+
block: include /etc/redis/cloudfall.conf
|
|
51
|
+
notify: Restart Redis
|
|
52
|
+
|
|
53
|
+
- name: Enable and start the Redis server
|
|
54
|
+
ansible.builtin.systemd_service:
|
|
55
|
+
name: redis-server.service
|
|
56
|
+
enabled: true
|
|
57
|
+
state: started
|
|
58
|
+
daemon_reload: true
|
|
59
|
+
|
|
60
|
+
- name: Apply the validated Redis configuration
|
|
61
|
+
ansible.builtin.meta: flush_handlers
|
|
62
|
+
|
|
63
|
+
- name: Wait for Redis readiness
|
|
64
|
+
ansible.builtin.command:
|
|
65
|
+
argv:
|
|
66
|
+
- /usr/bin/redis-cli
|
|
67
|
+
- -p
|
|
68
|
+
- "{{ cloudfall_redis_service.bind.port }}"
|
|
69
|
+
- ping
|
|
70
|
+
register: cloudfall_redis_readiness
|
|
71
|
+
changed_when: false
|
|
72
|
+
retries: 12
|
|
73
|
+
delay: 5
|
|
74
|
+
until: cloudfall_redis_readiness.stdout == "PONG"
|
|
75
|
+
when: not ansible_check_mode
|
|
76
|
+
|
|
77
|
+
- name: Create the backup directory
|
|
78
|
+
ansible.builtin.file:
|
|
79
|
+
path: "{{ cloudfall_redis_service.backup.directory }}"
|
|
80
|
+
state: directory
|
|
81
|
+
owner: redis
|
|
82
|
+
group: redis
|
|
83
|
+
mode: "0700"
|
|
84
|
+
|
|
85
|
+
- name: Install the backup script
|
|
86
|
+
ansible.builtin.template:
|
|
87
|
+
src: backup.sh.j2
|
|
88
|
+
dest: /usr/local/sbin/cloudfall-redis-backup
|
|
89
|
+
owner: root
|
|
90
|
+
group: root
|
|
91
|
+
mode: "0755"
|
|
92
|
+
|
|
93
|
+
- name: Install the restore-check script
|
|
94
|
+
ansible.builtin.template:
|
|
95
|
+
src: restore-check.sh.j2
|
|
96
|
+
dest: /usr/local/sbin/cloudfall-redis-restore-check
|
|
97
|
+
owner: root
|
|
98
|
+
group: root
|
|
99
|
+
mode: "0755"
|
|
100
|
+
|
|
101
|
+
- name: Install the backup service unit
|
|
102
|
+
ansible.builtin.template:
|
|
103
|
+
src: backup.service.j2
|
|
104
|
+
dest: /etc/systemd/system/cloudfall-redis-backup.service
|
|
105
|
+
owner: root
|
|
106
|
+
group: root
|
|
107
|
+
mode: "0644"
|
|
108
|
+
|
|
109
|
+
- name: Install the backup timer unit
|
|
110
|
+
ansible.builtin.template:
|
|
111
|
+
src: backup.timer.j2
|
|
112
|
+
dest: /etc/systemd/system/cloudfall-redis-backup.timer
|
|
113
|
+
owner: root
|
|
114
|
+
group: root
|
|
115
|
+
mode: "0644"
|
|
116
|
+
|
|
117
|
+
- name: Enable the backup timer
|
|
118
|
+
ansible.builtin.systemd_service:
|
|
119
|
+
name: cloudfall-redis-backup.timer
|
|
120
|
+
enabled: true
|
|
121
|
+
state: started
|
|
122
|
+
daemon_reload: true
|
|
123
|
+
|
|
124
|
+
- name: Install the restore-drill service unit
|
|
125
|
+
ansible.builtin.template:
|
|
126
|
+
src: restore-check.service.j2
|
|
127
|
+
dest: /etc/systemd/system/cloudfall-redis-restore-check.service
|
|
128
|
+
owner: root
|
|
129
|
+
group: root
|
|
130
|
+
mode: "0644"
|
|
131
|
+
when: cloudfall_redis_service.backup.restoreCheckOnCalendar is defined
|
|
132
|
+
|
|
133
|
+
- name: Install the restore-drill timer unit
|
|
134
|
+
ansible.builtin.template:
|
|
135
|
+
src: restore-check.timer.j2
|
|
136
|
+
dest: /etc/systemd/system/cloudfall-redis-restore-check.timer
|
|
137
|
+
owner: root
|
|
138
|
+
group: root
|
|
139
|
+
mode: "0644"
|
|
140
|
+
when: cloudfall_redis_service.backup.restoreCheckOnCalendar is defined
|
|
141
|
+
|
|
142
|
+
- name: Enable the restore-drill timer
|
|
143
|
+
ansible.builtin.systemd_service:
|
|
144
|
+
name: cloudfall-redis-restore-check.timer
|
|
145
|
+
enabled: true
|
|
146
|
+
state: started
|
|
147
|
+
daemon_reload: true
|
|
148
|
+
when: cloudfall_redis_service.backup.restoreCheckOnCalendar is defined
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Managed by Cloudfall. Local changes will be overwritten.
|
|
2
|
+
[Unit]
|
|
3
|
+
Description=Cloudfall Redis backup for {{ cloudfall_redis_service.id }}
|
|
4
|
+
After=redis-server.service
|
|
5
|
+
Requires=redis-server.service
|
|
6
|
+
|
|
7
|
+
[Service]
|
|
8
|
+
Type=oneshot
|
|
9
|
+
User=redis
|
|
10
|
+
Group=redis
|
|
11
|
+
ExecStart=/usr/local/sbin/cloudfall-redis-backup
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Managed by Cloudfall. Local changes will be overwritten.
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
backup_directory="{{ cloudfall_redis_service.backup.directory }}"
|
|
6
|
+
port="{{ cloudfall_redis_service.bind.port }}"
|
|
7
|
+
retention_days="{{ cloudfall_redis_service.backup.retentionDays }}"
|
|
8
|
+
timestamp="$(date --utc +%Y%m%dT%H%M%SZ)"
|
|
9
|
+
|
|
10
|
+
redis-cli -p "${port}" --rdb "${backup_directory}/redis-${timestamp}.rdb" \
|
|
11
|
+
> /dev/null
|
|
12
|
+
|
|
13
|
+
find "${backup_directory}" -name 'redis-*.rdb' -type f \
|
|
14
|
+
-mtime "+${retention_days}" -delete
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Managed by Cloudfall. Local changes will be overwritten.
|
|
2
|
+
[Unit]
|
|
3
|
+
Description=Cloudfall Redis backup schedule for {{ cloudfall_redis_service.id }}
|
|
4
|
+
|
|
5
|
+
[Timer]
|
|
6
|
+
OnCalendar={{ cloudfall_redis_service.backup.onCalendar }}
|
|
7
|
+
Persistent=true
|
|
8
|
+
|
|
9
|
+
[Install]
|
|
10
|
+
WantedBy=timers.target
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Managed by Cloudfall. Local changes will be overwritten.
|
|
2
|
+
bind {{ cloudfall_redis_service.bind.address }}
|
|
3
|
+
port {{ cloudfall_redis_service.bind.port }}
|
|
4
|
+
protected-mode yes
|
|
5
|
+
maxmemory {{ cloudfall_redis_service.redis.maxmemoryMb }}mb
|
|
6
|
+
appendonly {{ 'yes' if cloudfall_redis_service.redis.appendOnly else 'no' }}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Managed by Cloudfall. Local changes will be overwritten.
|
|
2
|
+
[Unit]
|
|
3
|
+
Description=Cloudfall Redis restore drill for {{ cloudfall_redis_service.id }}
|
|
4
|
+
After=redis-server.service
|
|
5
|
+
Requires=redis-server.service
|
|
6
|
+
|
|
7
|
+
[Service]
|
|
8
|
+
Type=oneshot
|
|
9
|
+
User=redis
|
|
10
|
+
Group=redis
|
|
11
|
+
ExecStart=/usr/local/sbin/cloudfall-redis-restore-check
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Managed by Cloudfall. Local changes will be overwritten.
|
|
3
|
+
# Verifies the newest RDB snapshot is structurally restorable.
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
backup_directory="{{ cloudfall_redis_service.backup.directory }}"
|
|
7
|
+
|
|
8
|
+
latest="$(find "${backup_directory}" -name 'redis-*.rdb' -type f \
|
|
9
|
+
| sort | tail -n 1)"
|
|
10
|
+
if [ -z "${latest}" ]; then
|
|
11
|
+
echo "no backup found for {{ cloudfall_redis_service.id }}" >&2
|
|
12
|
+
exit 1
|
|
13
|
+
fi
|
|
14
|
+
redis-check-rdb "${latest}"
|
|
15
|
+
echo "restore check passed for {{ cloudfall_redis_service.id }}: ${latest}"
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Managed by Cloudfall. Local changes will be overwritten.
|
|
2
|
+
[Unit]
|
|
3
|
+
Description=Cloudfall Redis restore-drill schedule for {{ cloudfall_redis_service.id }}
|
|
4
|
+
|
|
5
|
+
[Timer]
|
|
6
|
+
OnCalendar={{ cloudfall_redis_service.backup.restoreCheckOnCalendar }}
|
|
7
|
+
Persistent=true
|
|
8
|
+
|
|
9
|
+
[Install]
|
|
10
|
+
WantedBy=timers.target
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
galaxy_info:
|
|
3
|
+
role_name: cloudfall_time
|
|
4
|
+
author: Cloudfall
|
|
5
|
+
description: Enforce UTC and synchronized system time on Debian hosts
|
|
6
|
+
license: AGPL-3.0-or-later
|
|
7
|
+
min_ansible_version: "2.21"
|
|
8
|
+
platforms:
|
|
9
|
+
- name: Debian
|
|
10
|
+
versions:
|
|
11
|
+
- bookworm
|
|
12
|
+
- trixie
|
|
13
|
+
dependencies: []
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
---
|
|
2
|
+
- name: Validate UTC time target
|
|
3
|
+
ansible.builtin.assert:
|
|
4
|
+
that:
|
|
5
|
+
- ansible_facts["distribution"] == "Debian"
|
|
6
|
+
- ansible_facts["service_mgr"] == "systemd"
|
|
7
|
+
- cloudfall_time_timezone == "Etc/UTC"
|
|
8
|
+
fail_msg: Cloudfall time management requires Debian, systemd, and Etc/UTC
|
|
9
|
+
|
|
10
|
+
- name: Read current time configuration
|
|
11
|
+
ansible.builtin.command:
|
|
12
|
+
argv:
|
|
13
|
+
- /usr/bin/timedatectl
|
|
14
|
+
- show
|
|
15
|
+
- --property=Timezone
|
|
16
|
+
- --property=LocalRTC
|
|
17
|
+
- --property=NTP
|
|
18
|
+
- --property=NTPSynchronized
|
|
19
|
+
changed_when: false
|
|
20
|
+
check_mode: false
|
|
21
|
+
register: cloudfall_time_before
|
|
22
|
+
|
|
23
|
+
- name: Report timezone drift in check mode
|
|
24
|
+
ansible.builtin.debug:
|
|
25
|
+
msg: >-
|
|
26
|
+
Would change timezone from
|
|
27
|
+
{{ cloudfall_time_before.stdout_lines
|
|
28
|
+
| select('match', '^Timezone=')
|
|
29
|
+
| first
|
|
30
|
+
| default('Timezone=unknown') }}
|
|
31
|
+
to Timezone={{ cloudfall_time_timezone }}
|
|
32
|
+
changed_when: true
|
|
33
|
+
when:
|
|
34
|
+
- ansible_check_mode
|
|
35
|
+
- "'Timezone=' ~ cloudfall_time_timezone not in cloudfall_time_before.stdout_lines"
|
|
36
|
+
|
|
37
|
+
- name: Set UTC timezone
|
|
38
|
+
ansible.builtin.command:
|
|
39
|
+
argv:
|
|
40
|
+
- /usr/bin/timedatectl
|
|
41
|
+
- set-timezone
|
|
42
|
+
- "{{ cloudfall_time_timezone }}"
|
|
43
|
+
changed_when: true
|
|
44
|
+
when:
|
|
45
|
+
- not ansible_check_mode
|
|
46
|
+
- "'Timezone=' ~ cloudfall_time_timezone not in cloudfall_time_before.stdout_lines"
|
|
47
|
+
|
|
48
|
+
- name: Report local hardware clock drift in check mode
|
|
49
|
+
ansible.builtin.debug:
|
|
50
|
+
msg: Would configure the hardware clock to use UTC
|
|
51
|
+
changed_when: true
|
|
52
|
+
when:
|
|
53
|
+
- ansible_check_mode
|
|
54
|
+
- "'LocalRTC=no' not in cloudfall_time_before.stdout_lines"
|
|
55
|
+
|
|
56
|
+
- name: Configure hardware clock for UTC
|
|
57
|
+
ansible.builtin.command:
|
|
58
|
+
argv:
|
|
59
|
+
- /usr/bin/timedatectl
|
|
60
|
+
- set-local-rtc
|
|
61
|
+
- "0"
|
|
62
|
+
changed_when: true
|
|
63
|
+
when:
|
|
64
|
+
- not ansible_check_mode
|
|
65
|
+
- "'LocalRTC=no' not in cloudfall_time_before.stdout_lines"
|
|
66
|
+
|
|
67
|
+
- name: Report NTP drift in check mode
|
|
68
|
+
ansible.builtin.debug:
|
|
69
|
+
msg: Would enable network time synchronization
|
|
70
|
+
changed_when: true
|
|
71
|
+
when:
|
|
72
|
+
- ansible_check_mode
|
|
73
|
+
- "'NTP=yes' not in cloudfall_time_before.stdout_lines"
|
|
74
|
+
|
|
75
|
+
- name: Enable network time synchronization
|
|
76
|
+
ansible.builtin.command:
|
|
77
|
+
argv:
|
|
78
|
+
- /usr/bin/timedatectl
|
|
79
|
+
- set-ntp
|
|
80
|
+
- "true"
|
|
81
|
+
changed_when: true
|
|
82
|
+
when:
|
|
83
|
+
- not ansible_check_mode
|
|
84
|
+
- "'NTP=yes' not in cloudfall_time_before.stdout_lines"
|
|
85
|
+
|
|
86
|
+
- name: Read applied time configuration
|
|
87
|
+
ansible.builtin.command:
|
|
88
|
+
argv:
|
|
89
|
+
- /usr/bin/timedatectl
|
|
90
|
+
- show
|
|
91
|
+
- --property=Timezone
|
|
92
|
+
- --property=LocalRTC
|
|
93
|
+
- --property=NTP
|
|
94
|
+
changed_when: false
|
|
95
|
+
check_mode: false
|
|
96
|
+
register: cloudfall_time_after
|
|
97
|
+
|
|
98
|
+
- name: Require applied UTC time configuration
|
|
99
|
+
ansible.builtin.assert:
|
|
100
|
+
that:
|
|
101
|
+
- ansible_check_mode or 'Timezone=' ~ cloudfall_time_timezone in cloudfall_time_after.stdout_lines
|
|
102
|
+
- ansible_check_mode or 'LocalRTC=no' in cloudfall_time_after.stdout_lines
|
|
103
|
+
- ansible_check_mode or 'NTP=yes' in cloudfall_time_after.stdout_lines
|
|
104
|
+
fail_msg: The host did not converge to the Cloudfall UTC time baseline
|
|
105
|
+
|
|
106
|
+
- name: Wait for synchronized network time
|
|
107
|
+
ansible.builtin.command:
|
|
108
|
+
argv:
|
|
109
|
+
- /usr/bin/timedatectl
|
|
110
|
+
- show
|
|
111
|
+
- --property=NTPSynchronized
|
|
112
|
+
- --value
|
|
113
|
+
changed_when: false
|
|
114
|
+
check_mode: false
|
|
115
|
+
register: cloudfall_time_synchronized
|
|
116
|
+
until: cloudfall_time_synchronized.stdout == "yes"
|
|
117
|
+
retries: 12
|
|
118
|
+
delay: 5
|
|
119
|
+
when: not ansible_check_mode
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
galaxy_info:
|
|
3
|
+
role_name: cloudfall_unattended_upgrades
|
|
4
|
+
author: Cloudfall
|
|
5
|
+
description: Enable automatic Debian security upgrades
|
|
6
|
+
license: AGPL-3.0-or-later
|
|
7
|
+
min_ansible_version: "2.21"
|
|
8
|
+
platforms:
|
|
9
|
+
- name: Debian
|
|
10
|
+
versions:
|
|
11
|
+
- bookworm
|
|
12
|
+
- trixie
|
|
13
|
+
dependencies: []
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
- name: Validate unattended-upgrades target
|
|
3
|
+
ansible.builtin.assert:
|
|
4
|
+
that:
|
|
5
|
+
- ansible_facts["distribution"] == "Debian"
|
|
6
|
+
- ansible_facts["service_mgr"] == "systemd"
|
|
7
|
+
fail_msg: Cloudfall unattended upgrades require a Debian systemd host
|
|
8
|
+
|
|
9
|
+
- name: Install unattended-upgrades
|
|
10
|
+
ansible.builtin.apt:
|
|
11
|
+
name: unattended-upgrades
|
|
12
|
+
state: present
|
|
13
|
+
update_cache: true
|
|
14
|
+
cache_valid_time: 3600
|
|
15
|
+
|
|
16
|
+
- name: Enable periodic unattended security upgrades
|
|
17
|
+
ansible.builtin.copy:
|
|
18
|
+
dest: "{{ cloudfall_unattended_upgrades_configuration_path }}"
|
|
19
|
+
content: |
|
|
20
|
+
// Managed by Cloudfall. Local changes will be overwritten.
|
|
21
|
+
APT::Periodic::Update-Package-Lists "1";
|
|
22
|
+
APT::Periodic::Unattended-Upgrade "1";
|
|
23
|
+
owner: root
|
|
24
|
+
group: root
|
|
25
|
+
mode: "0644"
|
|
26
|
+
|
|
27
|
+
- name: Enable the apt update timer
|
|
28
|
+
ansible.builtin.systemd_service:
|
|
29
|
+
name: apt-daily.timer
|
|
30
|
+
enabled: true
|
|
31
|
+
state: started
|
|
32
|
+
|
|
33
|
+
- name: Enable the apt upgrade timer
|
|
34
|
+
ansible.builtin.systemd_service:
|
|
35
|
+
name: apt-daily-upgrade.timer
|
|
36
|
+
enabled: true
|
|
37
|
+
state: started
|