Skip to content

Commit 27e69fb

Browse files
committed
Allow arbitrary URLs for success hooks
An extension to #56.
1 parent 85de8e4 commit 27e69fb

File tree

3 files changed

+53
-10
lines changed

3 files changed

+53
-10
lines changed

README.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,13 @@ Mount your backup directory as `/var/backups` (or override `$BACKUP_DIR`). Backu
1919

2020
Backups run daily at midnight. To change this, add a cron-style schedule to `$SCHEDULE`. For more information on the format of the cron strings, please see the [croniter documentation on PyPI](https://pypi.org/project/croniter/).
2121

22-
Additionally, there is support for [healthchecks.io](https://healthchecks.io) and [Uptime Kuma](https://github.com/louislam/uptime-kuma/) for monitoring purposes. `$HEALTHCHECKS_ID` can be used to specify the id to ping. If you're using a self-hosted instance, set `$HEALTHCHECKS_HOST`. To use the generated URL by the Monitor Type `Push` in Uptime Kuma, set `$UPTIME_KUMA_URL`.
22+
### Success hooks
23+
24+
When backups are completed successfully, a request can be made to the URL defined in `$SUCCESS_HOOK_URL`. By default, a `GET` request is made. To include logs, also set `$INCLUDE_LOGS` to a non-empty value, which sends a `POST` request instead with helpful details in the body.
25+
26+
Note: Previous versions also supported `$HEALTHCHECKS_ID`, `$HEALTHCHECKS_HOST` and `$UPTIME_KUMA_URL`, or native support for [healthchecks.io](https://healthchecks.io) and [Uptime Kuma](https://github.com/louislam/uptime-kuma/) respectively. These are all still supported, however `$SUCCESS_HOOK_URL` is preferred.
27+
28+
### Compression
2329

2430
Files are backed up uncompressed by default, on the assumption a snapshotting or native compressed filesystem is being used (eg ZFS). To enable compression, set `$COMPRESSION` to one of the supported algorithms:
2531

@@ -41,7 +47,8 @@ services:
4147
- /var/run/docker.sock:/var/run/docker.sock:ro
4248
- ./backups:/var/backups
4349
environment:
44-
- HEALTHCHECKS_ID=id
50+
- SUCCESS_HOOK_URL=https://hc-ping.com/1234
51+
- INCLUDE_LOGS=true
4552
```
4653
4754
### Oneshot

db-auto-backup.py

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,20 @@ def get_compressed_file_extension(algorithm: str) -> str:
7979
raise ValueError(f"Unknown compression method {algorithm}")
8080

8181

82+
def get_success_hook_url() -> Optional[str]:
83+
if success_hook_url := os.environ.get("SUCCESS_HOOK_URL"):
84+
return success_hook_url
85+
86+
if healthchecks_id := os.environ.get("HEALTHCHECKS_ID"):
87+
healthchecks_host = os.environ.get("HEALTHCHECKS_HOST", "hc-ping.com")
88+
return f"https://{healthchecks_host}/{healthchecks_id}"
89+
90+
if uptime_kuma_url := os.environ.get("UPTIME_KUMA_URL"):
91+
return uptime_kuma_url
92+
93+
return None
94+
95+
8296
def backup_psql(container: Container) -> str:
8397
env = get_container_env(container)
8498
user = env.get("POSTGRES_USER", "postgres")
@@ -131,6 +145,7 @@ def backup_redis(container: Container) -> str:
131145
SCHEDULE = os.environ.get("SCHEDULE", "0 0 * * *")
132146
SHOW_PROGRESS = sys.stdout.isatty()
133147
COMPRESSION = os.environ.get("COMPRESSION", "plain")
148+
INCLUDE_LOGS = bool(os.environ.get("INCLUDE_LOGS"))
134149

135150

136151
def get_backup_provider(container_names: Sequence[str]) -> Optional[BackupProvider]:
@@ -187,15 +202,15 @@ def backup(now: datetime) -> None:
187202
duration = (datetime.now() - now).total_seconds()
188203
print(f"Backup complete in {duration:.2f} seconds.")
189204

190-
if healthchecks_id := os.environ.get("HEALTHCHECKS_ID"):
191-
healthchecks_host = os.environ.get("HEALTHCHECKS_HOST", "hc-ping.com")
192-
requests.post(
193-
f"https://{healthchecks_host}/{healthchecks_id}",
194-
data="\n".join(backed_up_containers),
195-
).raise_for_status()
205+
if success_hook_url := get_success_hook_url():
206+
if INCLUDE_LOGS:
207+
response = requests.post(
208+
success_hook_url, data="\n".join(backed_up_containers)
209+
)
210+
else:
211+
response = requests.get(success_hook_url)
196212

197-
if uptime_kuma_url := os.environ.get("UPTIME_KUMA_URL"):
198-
requests.get(uptime_kuma_url).raise_for_status()
213+
response.raise_for_status()
199214

200215

201216
if __name__ == "__main__":

tests/tests.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,24 @@ def test_backup_runs_compressed(
6969
)
7070
def test_compressed_file_extension(algorithm: str, extension: str) -> None:
7171
assert db_auto_backup.get_compressed_file_extension(algorithm) == extension
72+
73+
74+
def test_success_hook_url(monkeypatch: Any) -> None:
75+
monkeypatch.setenv("SUCCESS_HOOK_URL", "https://example.com")
76+
assert db_auto_backup.get_success_hook_url() == "https://example.com"
77+
78+
79+
def test_healthchecks_success_hook_url(monkeypatch: Any) -> None:
80+
monkeypatch.setenv("HEALTHCHECKS_ID", "1234")
81+
assert db_auto_backup.get_success_hook_url() == "https://hc-ping.com/1234"
82+
83+
84+
def test_healthchecks_success_hook_url_custom_host(monkeypatch: Any) -> None:
85+
monkeypatch.setenv("HEALTHCHECKS_ID", "1234")
86+
monkeypatch.setenv("HEALTHCHECKS_HOST", "my-healthchecks.com")
87+
assert db_auto_backup.get_success_hook_url() == "https://my-healthchecks.com/1234"
88+
89+
90+
def test_uptime_kuma_success_hook_url(monkeypatch: Any) -> None:
91+
monkeypatch.setenv("UPTIME_KUMA_URL", "https://uptime-kuma.com")
92+
assert db_auto_backup.get_success_hook_url() == "https://uptime-kuma.com"

0 commit comments

Comments
 (0)