2
0
Paul Wilde 1 жил өмнө
parent
commit
a509cdedd5

+ 1 - 1
borgmatic/hooks/dispatch.py

@@ -13,7 +13,7 @@ from borgmatic.hooks import (
     pagerduty,
     postgresql,
     sqlite,
-    uptimekuma
+    uptimekuma,
 )
 
 logger = logging.getLogger(__name__)

+ 10 - 1
borgmatic/hooks/monitor.py

@@ -1,6 +1,15 @@
 from enum import Enum
 
-MONITOR_HOOK_NAMES = ('apprise', 'healthchecks', 'cronitor', 'cronhub', 'pagerduty', 'ntfy', 'loki', 'uptimekuma')
+MONITOR_HOOK_NAMES = (
+    'apprise',
+    'healthchecks',
+    'cronitor',
+    'cronhub',
+    'pagerduty',
+    'ntfy',
+    'loki',
+    'uptimekuma',
+)
 
 
 class State(Enum):

+ 12 - 9
borgmatic/hooks/uptimekuma.py

@@ -20,28 +20,31 @@ def ping_monitor(hook_config, config, config_filename, state, monitoring_log_lev
     If this is a dry run, then don't actually ping anything.
     '''
 
-    run_states = hook_config.get('states', ['start','finish','fail'])
+    run_states = hook_config.get('states', ['start', 'finish', 'fail'])
 
     if state.name.lower() in run_states:
-        
+
         dry_run_label = ' (dry run; not actually pinging)' if dry_run else ''
 
+        status = 'up'
+        if state.name.lower() == 'fail':
+            status = 'down'
 
-        status = "up"
-        if state.name.lower() == "fail":
-            status = "down"
-        
-        base_url = hook_config.get('server', 'https://example.uptime.kuma') + "/api/push"
+        base_url = hook_config.get('server', 'https://example.uptime.kuma') + '/api/push'
         push_code = hook_config.get('push_code')
 
         logger.info(f'{config_filename}: Pinging Uptime Kuma push_code {push_code}{dry_run_label}')
         logger.debug(f'{config_filename}: Using Uptime Kuma ping URL {base_url}/{push_code}')
-        logger.debug(f'{config_filename}: Full Uptime Kuma state URL {base_url}/{push_code}?status={status}&msg={state.name.lower()}&ping=')
+        logger.debug(
+            f'{config_filename}: Full Uptime Kuma state URL {base_url}/{push_code}?status={status}&msg={state.name.lower()}&ping='
+        )
 
         if not dry_run:
             logging.getLogger('urllib3').setLevel(logging.ERROR)
             try:
-                response = requests.get(f'{base_url}/{push_code}?status={status}&msg={state.name.lower()}&ping=')
+                response = requests.get(
+                    f'{base_url}/{push_code}?status={status}&msg={state.name.lower()}&ping='
+                )
                 if not response.ok:
                     response.raise_for_status()
             except requests.exceptions.RequestException as error:

+ 62 - 102
tests/unit/hooks/test_uptimekuma.py

@@ -1,5 +1,3 @@
-from enum import Enum
-
 from flexmock import flexmock
 
 import borgmatic.hooks.monitor
@@ -9,10 +7,11 @@ default_base_url = 'https://example.uptime.kuma'
 custom_base_url = 'https://uptime.example.com'
 push_code = 'abcd1234'
 
-def test_ping_monitor_minimal_config_hits_hosted_ntfy_on_fail():
+
+def test_ping_monitor_hits_default_uptimekuma_on_fail():
     hook_config = {'push_code': push_code}
     flexmock(module.requests).should_receive('get').with_args(
-        f'{default_base_url}/api/push/{push_code}'
+        f'{default_base_url}/api/push/{push_code}?status=down&msg=fail&ping='
     ).and_return(flexmock(ok=True)).once()
 
     module.ping_monitor(
@@ -21,19 +20,14 @@ def test_ping_monitor_minimal_config_hits_hosted_ntfy_on_fail():
         'config.yaml',
         borgmatic.hooks.monitor.State.FAIL,
         monitoring_log_level=1,
-        dry_run=True,
+        dry_run=False,
     )
 
 
-def test_ping_monitor_with_access_token_hits_hosted_ntfy_on_fail():
-    hook_config = {
-        'topic': topic,
-        'access_token': 'abc123',
-    }
-    flexmock(module.requests).should_receive('post').with_args(
-        f'{default_base_url}/{topic}',
-        headers=return_default_message_headers(borgmatic.hooks.monitor.State.FAIL),
-        auth=module.requests.auth.HTTPBasicAuth('', 'abc123'),
+def test_ping_monitor_hits_custom_uptimekuma_on_fail():
+    hook_config = {'server': custom_base_url, 'push_code': push_code}
+    flexmock(module.requests).should_receive('get').with_args(
+        f'{custom_base_url}/api/push/{push_code}?status=down&msg=fail&ping='
     ).and_return(flexmock(ok=True)).once()
 
     module.ping_monitor(
@@ -46,190 +40,158 @@ def test_ping_monitor_with_access_token_hits_hosted_ntfy_on_fail():
     )
 
 
-def test_ping_monitor_with_username_password_and_access_token_ignores_username_password():
-    hook_config = {
-        'topic': topic,
-        'username': 'testuser',
-        'password': 'fakepassword',
-        'access_token': 'abc123',
-    }
-    flexmock(module.requests).should_receive('post').with_args(
-        f'{default_base_url}/{topic}',
-        headers=return_default_message_headers(borgmatic.hooks.monitor.State.FAIL),
-        auth=module.requests.auth.HTTPBasicAuth('', 'abc123'),
+def test_ping_monitor_hits_default_uptimekuma_on_start():
+    hook_config = {'push_code': push_code}
+    flexmock(module.requests).should_receive('get').with_args(
+        f'{default_base_url}/api/push/{push_code}?status=up&msg=start&ping='
     ).and_return(flexmock(ok=True)).once()
-    flexmock(module.logger).should_receive('warning').once()
 
     module.ping_monitor(
         hook_config,
         {},
         'config.yaml',
-        borgmatic.hooks.monitor.State.FAIL,
+        borgmatic.hooks.monitor.State.START,
         monitoring_log_level=1,
         dry_run=False,
     )
 
 
-def test_ping_monitor_with_username_password_hits_hosted_ntfy_on_fail():
-    hook_config = {
-        'topic': topic,
-        'username': 'testuser',
-        'password': 'fakepassword',
-    }
-    flexmock(module.requests).should_receive('post').with_args(
-        f'{default_base_url}/{topic}',
-        headers=return_default_message_headers(borgmatic.hooks.monitor.State.FAIL),
-        auth=module.requests.auth.HTTPBasicAuth('testuser', 'fakepassword'),
+def test_ping_monitor_custom_uptimekuma_on_start():
+    hook_config = {'server': custom_base_url, 'push_code': push_code}
+    flexmock(module.requests).should_receive('get').with_args(
+        f'{custom_base_url}/api/push/{push_code}?status=up&msg=start&ping='
     ).and_return(flexmock(ok=True)).once()
 
     module.ping_monitor(
         hook_config,
         {},
         'config.yaml',
-        borgmatic.hooks.monitor.State.FAIL,
+        borgmatic.hooks.monitor.State.START,
         monitoring_log_level=1,
         dry_run=False,
     )
 
 
-def test_ping_monitor_with_password_but_no_username_warns():
-    hook_config = {'topic': topic, 'password': 'fakepassword'}
-    flexmock(module.requests).should_receive('post').with_args(
-        f'{default_base_url}/{topic}',
-        headers=return_default_message_headers(borgmatic.hooks.monitor.State.FAIL),
-        auth=None,
+def test_ping_monitor_hits_default_uptimekuma_on_finish():
+    hook_config = {'push_code': push_code}
+    flexmock(module.requests).should_receive('get').with_args(
+        f'{default_base_url}/api/push/{push_code}?status=up&msg=finish&ping='
     ).and_return(flexmock(ok=True)).once()
-    flexmock(module.logger).should_receive('warning').once()
 
     module.ping_monitor(
         hook_config,
         {},
         'config.yaml',
-        borgmatic.hooks.monitor.State.FAIL,
+        borgmatic.hooks.monitor.State.FINISH,
         monitoring_log_level=1,
         dry_run=False,
     )
 
 
-def test_ping_monitor_with_username_but_no_password_warns():
-    hook_config = {'topic': topic, 'username': 'testuser'}
-    flexmock(module.requests).should_receive('post').with_args(
-        f'{default_base_url}/{topic}',
-        headers=return_default_message_headers(borgmatic.hooks.monitor.State.FAIL),
-        auth=None,
+def test_ping_monitor_custom_uptimekuma_on_finish():
+    hook_config = {'server': custom_base_url, 'push_code': push_code}
+    flexmock(module.requests).should_receive('get').with_args(
+        f'{custom_base_url}/api/push/{push_code}?status=up&msg=finish&ping='
     ).and_return(flexmock(ok=True)).once()
-    flexmock(module.logger).should_receive('warning').once()
 
     module.ping_monitor(
         hook_config,
         {},
         'config.yaml',
-        borgmatic.hooks.monitor.State.FAIL,
+        borgmatic.hooks.monitor.State.FINISH,
         monitoring_log_level=1,
         dry_run=False,
     )
 
 
-def test_ping_monitor_minimal_config_does_not_hit_hosted_ntfy_on_start():
-    hook_config = {'topic': topic}
-    flexmock(module.requests).should_receive('post').never()
+def test_ping_monitor_does_not_hit_default_uptimekuma_on_fail_dry_run():
+    hook_config = {'push_code': push_code}
+    flexmock(module.requests).should_receive('get').never()
 
     module.ping_monitor(
         hook_config,
         {},
         'config.yaml',
-        borgmatic.hooks.monitor.State.START,
+        borgmatic.hooks.monitor.State.FAIL,
         monitoring_log_level=1,
-        dry_run=False,
+        dry_run=True,
     )
 
 
-def test_ping_monitor_minimal_config_does_not_hit_hosted_ntfy_on_finish():
-    hook_config = {'topic': topic}
-    flexmock(module.requests).should_receive('post').never()
+def test_ping_monitor_does_not_hit_custom_uptimekuma_on_fail_dry_run():
+    hook_config = {'server': custom_base_url, 'push_code': push_code}
+    flexmock(module.requests).should_receive('get').never()
 
     module.ping_monitor(
         hook_config,
         {},
         'config.yaml',
-        borgmatic.hooks.monitor.State.FINISH,
+        borgmatic.hooks.monitor.State.FAIL,
         monitoring_log_level=1,
-        dry_run=False,
+        dry_run=True,
     )
 
 
-def test_ping_monitor_minimal_config_hits_selfhosted_ntfy_on_fail():
-    hook_config = {'topic': topic, 'server': custom_base_url}
-    flexmock(module.requests).should_receive('post').with_args(
-        f'{custom_base_url}/{topic}',
-        headers=return_default_message_headers(borgmatic.hooks.monitor.State.FAIL),
-        auth=None,
-    ).and_return(flexmock(ok=True)).once()
+def test_ping_monitor_does_not_hit_default_uptimekuma_on_start_dry_run():
+    hook_config = {'push_code': push_code}
+    flexmock(module.requests).should_receive('get').never()
 
     module.ping_monitor(
         hook_config,
         {},
         'config.yaml',
-        borgmatic.hooks.monitor.State.FAIL,
+        borgmatic.hooks.monitor.State.START,
         monitoring_log_level=1,
-        dry_run=False,
+        dry_run=True,
     )
 
 
-def test_ping_monitor_minimal_config_does_not_hit_hosted_ntfy_on_fail_dry_run():
-    hook_config = {'topic': topic}
-    flexmock(module.requests).should_receive('post').never()
+def test_ping_monitor_does_not_hit_custom_uptimekuma_on_start_dry_run():
+    hook_config = {'server': custom_base_url, 'push_code': push_code}
+    flexmock(module.requests).should_receive('get').never()
 
     module.ping_monitor(
         hook_config,
         {},
         'config.yaml',
-        borgmatic.hooks.monitor.State.FAIL,
+        borgmatic.hooks.monitor.State.START,
         monitoring_log_level=1,
         dry_run=True,
     )
 
 
-def test_ping_monitor_custom_message_hits_hosted_ntfy_on_fail():
-    hook_config = {'topic': topic, 'fail': custom_message_config}
-    flexmock(module.requests).should_receive('post').with_args(
-        f'{default_base_url}/{topic}', headers=custom_message_headers, auth=None
-    ).and_return(flexmock(ok=True)).once()
+def test_ping_monitor_does_not_hit_default_uptimekuma_on_finish_dry_run():
+    hook_config = {'push_code': push_code}
+    flexmock(module.requests).should_receive('get').never()
 
     module.ping_monitor(
         hook_config,
         {},
         'config.yaml',
-        borgmatic.hooks.monitor.State.FAIL,
+        borgmatic.hooks.monitor.State.FINISH,
         monitoring_log_level=1,
-        dry_run=False,
+        dry_run=True,
     )
 
 
-def test_ping_monitor_custom_state_hits_hosted_ntfy_on_start():
-    hook_config = {'topic': topic, 'states': ['start', 'fail']}
-    flexmock(module.requests).should_receive('post').with_args(
-        f'{default_base_url}/{topic}',
-        headers=return_default_message_headers(borgmatic.hooks.monitor.State.START),
-        auth=None,
-    ).and_return(flexmock(ok=True)).once()
+def test_ping_monitor_does_not_hit_custom_uptimekuma_on_finish_dry_run():
+    hook_config = {'server': custom_base_url, 'push_code': push_code}
+    flexmock(module.requests).should_receive('get').never()
 
     module.ping_monitor(
         hook_config,
         {},
         'config.yaml',
-        borgmatic.hooks.monitor.State.START,
+        borgmatic.hooks.monitor.State.FINISH,
         monitoring_log_level=1,
-        dry_run=False,
+        dry_run=True,
     )
 
 
 def test_ping_monitor_with_connection_error_logs_warning():
-    hook_config = {'topic': topic}
-    flexmock(module.requests).should_receive('post').with_args(
-        f'{default_base_url}/{topic}',
-        headers=return_default_message_headers(borgmatic.hooks.monitor.State.FAIL),
-        auth=None,
+    hook_config = {'push_code': push_code}
+    flexmock(module.requests).should_receive('get').with_args(
+        f'{default_base_url}/api/push/{push_code}?status=down&msg=fail&ping='
     ).and_raise(module.requests.exceptions.ConnectionError)
     flexmock(module.logger).should_receive('warning').once()
 
@@ -244,15 +206,13 @@ def test_ping_monitor_with_connection_error_logs_warning():
 
 
 def test_ping_monitor_with_other_error_logs_warning():
-    hook_config = {'topic': topic}
+    hook_config = {'push_code': push_code}
     response = flexmock(ok=False)
     response.should_receive('raise_for_status').and_raise(
         module.requests.exceptions.RequestException
     )
     flexmock(module.requests).should_receive('post').with_args(
-        f'{default_base_url}/{topic}',
-        headers=return_default_message_headers(borgmatic.hooks.monitor.State.FAIL),
-        auth=None,
+        f'{default_base_url}/api/push/{push_code}?status=down&msg=fail&ping='
     ).and_return(response)
     flexmock(module.logger).should_receive('warning').once()