diff --git a/borgmatic/commands/arguments.py b/borgmatic/commands/arguments.py index 0b4b259c..eef24535 100644 --- a/borgmatic/commands/arguments.py +++ b/borgmatic/commands/arguments.py @@ -249,6 +249,12 @@ def make_parsers(): action='store_true', help='Go through the motions, but do not actually write to any repositories', ) + global_group.add_argument( + '--skip-monitoring', + dest='skip_monitoring', + action='store_true', + help='Skip reporting any data to the configured monitoring services', + ) global_group.add_argument( '-nc', '--no-color', dest='no_color', action='store_true', help='Disable colored output' ) diff --git a/borgmatic/commands/borgmatic.py b/borgmatic/commands/borgmatic.py index 8f61a0d3..d3eead5b 100644 --- a/borgmatic/commands/borgmatic.py +++ b/borgmatic/commands/borgmatic.py @@ -68,6 +68,10 @@ def run_configuration(config_filename, config, arguments): error_repository = '' using_primary_action = {'create', 'prune', 'compact', 'check'}.intersection(arguments) monitoring_log_level = verbosity_to_log_level(global_arguments.monitoring_verbosity) + skip_monitoring = global_arguments.skip_monitoring + action_names = [ + action for action in arguments.keys() if action != 'global' + ] monitoring_hooks_are_activated = using_primary_action and monitoring_log_level != DISABLED try: @@ -77,7 +81,7 @@ def run_configuration(config_filename, config, arguments): return try: - if monitoring_hooks_are_activated: + if using_primary_action and not skip_monitoring and monitoring_hooks_are_activated: dispatch.call_hooks( 'initialize_monitor', config, @@ -87,15 +91,17 @@ def run_configuration(config_filename, config, arguments): global_arguments.dry_run, ) - dispatch.call_hooks( - 'ping_monitor', - config, - config_filename, - monitor.MONITOR_HOOK_NAMES, - monitor.State.START, - monitoring_log_level, - global_arguments.dry_run, - ) + for action_name in action_names: + dispatch.call_hooks( + 'ping_monitor', + config, + config_filename, + monitor.MONITOR_HOOK_NAMES, + monitor.State.START, + monitoring_log_level, + global_arguments.dry_run, + action_name, + ) except (OSError, CalledProcessError) as error: if command.considered_soft_failure(config_filename, error): return @@ -160,17 +166,19 @@ def run_configuration(config_filename, config, arguments): error_repository = repository['path'] try: - if monitoring_hooks_are_activated: + if using_primary_action and not skip_monitoring and monitoring_hooks_are_activated: # send logs irrespective of error - dispatch.call_hooks( - 'ping_monitor', - config, - config_filename, - monitor.MONITOR_HOOK_NAMES, - monitor.State.LOG, - monitoring_log_level, - global_arguments.dry_run, - ) + for action_name in action_names: + dispatch.call_hooks( + 'ping_monitor', + config, + config_filename, + monitor.MONITOR_HOOK_NAMES, + monitor.State.LOG, + monitoring_log_level, + global_arguments.dry_run, + action_name, + ) except (OSError, CalledProcessError) as error: if command.considered_soft_failure(config_filename, error): return @@ -180,16 +188,18 @@ def run_configuration(config_filename, config, arguments): if not encountered_error: try: - if monitoring_hooks_are_activated: - dispatch.call_hooks( - 'ping_monitor', - config, - config_filename, - monitor.MONITOR_HOOK_NAMES, - monitor.State.FINISH, - monitoring_log_level, - global_arguments.dry_run, - ) + if using_primary_action and not skip_monitoring and monitoring_hooks_are_activated: + for action_name in action_names: + dispatch.call_hooks( + 'ping_monitor', + config, + config_filename, + monitor.MONITOR_HOOK_NAMES, + monitor.State.FINISH, + monitoring_log_level, + global_arguments.dry_run, + action_name, + ) dispatch.call_hooks( 'destroy_monitor', config, @@ -217,15 +227,17 @@ def run_configuration(config_filename, config, arguments): error=encountered_error, output=getattr(encountered_error, 'output', ''), ) - dispatch.call_hooks( - 'ping_monitor', - config, - config_filename, - monitor.MONITOR_HOOK_NAMES, - monitor.State.FAIL, - monitoring_log_level, - global_arguments.dry_run, - ) + for action_name in action_names: + dispatch.call_hooks( + 'ping_monitor', + config, + config_filename, + monitor.MONITOR_HOOK_NAMES, + monitor.State.FAIL, + monitoring_log_level, + global_arguments.dry_run, + action_name, + ) dispatch.call_hooks( 'destroy_monitor', config, diff --git a/borgmatic/config/normalize.py b/borgmatic/config/normalize.py index a80744b9..af8e6b15 100644 --- a/borgmatic/config/normalize.py +++ b/borgmatic/config/normalize.py @@ -104,6 +104,13 @@ def normalize(config_filename, config): ) ) config['cronitor'] = {'ping_url': cronitor} + if isinstance(cronitor, dict) and 'ping_url' in cronitor: + config['hooks']['cronitor'] = { + 'create': cronitor['ping_url'], + 'prune': cronitor['ping_url'], + 'compact': cronitor['ping_url'], + 'check': cronitor['ping_url'], + } pagerduty = config.get('pagerduty') if isinstance(pagerduty, str): diff --git a/borgmatic/config/schema.yaml b/borgmatic/config/schema.yaml index f5eb0017..bb20d61d 100644 --- a/borgmatic/config/schema.yaml +++ b/borgmatic/config/schema.yaml @@ -1151,13 +1151,49 @@ properties: example: incoming_envelope fail: type: object + additionalProperties: false properties: - title: + create: type: string description: | - The title of the message. - example: Ping! - message: + Cronitor ping URL to notify when a backup + begins, ends, or errors. + example: https://cronitor.link/d3x0c1 + prune: + type: string + description: | + Cronitor ping URL to notify when a prune action + begins, ends, or errors. + example: https://cronitor.link/d3x0c1 + compact: + type: string + description: | + Cronitor ping URL to notify when a compact action + begins, ends, or errors. + example: https://cronitor.link/d3x0c1 + check: + type: string + description: | + Cronitor ping URL to notify when a check action + begins, ends, or errors. + example: https://cronitor.link/d3x0c1 + ping_url: + type: string + description: | + If this is set, other properties will be ignored + and replaced by this value. + example: https://cronitor.link/d3x0c1 + description: | + Configuration for a monitoring integration with Cronitor. + Create an account at https://cronitor.io if you'd + like to use this service. See borgmatic monitoring + documentation for details. + pagerduty: + type: object + required: ['integration_key'] + additionalProperties: false + properties: + integration_key: type: string description: | The message body to publish. @@ -1242,19 +1278,43 @@ properties: documentation for details. cronitor: type: object - required: ['ping_url'] additionalProperties: false properties: + create: + type: string + description: | + Cronitor ping URL to notify when a backup + begins, ends, or errors. + example: https://cronitor.link/d3x0c1 + prune: + type: string + description: | + Cronitor ping URL to notify when a prune action + begins, ends, or errors. + example: https://cronitor.link/d3x0c1 + compact: + type: string + description: | + Cronitor ping URL to notify when a compact action + begins, ends, or errors. + example: https://cronitor.link/d3x0c1 + check: + type: string + description: | + Cronitor ping URL to notify when a check action + begins, ends, or errors. + example: https://cronitor.link/d3x0c1 ping_url: type: string description: | - Cronitor ping URL to notify when a backup begins, - ends, or errors. + If this is set, other properties will be ignored + and replaced by this value. example: https://cronitor.link/d3x0c1 description: | - Configuration for a monitoring integration with Cronitor. Create an - account at https://cronitor.io if you'd like to use this service. - See borgmatic monitoring documentation for details. + Configuration for a monitoring integration with Cronitor. + Create an account at https://cronitor.io if you'd + like to use this service. See borgmatic monitoring + documentation for details. pagerduty: type: object required: ['integration_key'] diff --git a/borgmatic/hooks/cronhub.py b/borgmatic/hooks/cronhub.py index bbdc19a8..d7bf2abe 100644 --- a/borgmatic/hooks/cronhub.py +++ b/borgmatic/hooks/cronhub.py @@ -22,7 +22,7 @@ def initialize_monitor( pass -def ping_monitor(hook_config, config, config_filename, state, monitoring_log_level, dry_run): +def ping_monitor(hook_config, config, config_filename, state, monitoring_log_level, dry_run, action_name): ''' Ping the configured Cronhub URL, modified with the monitor.State. Use the given configuration filename in any log entries. If this is a dry run, then don't actually ping anything. diff --git a/borgmatic/hooks/cronitor.py b/borgmatic/hooks/cronitor.py index fe4cc1d8..f17b3a70 100644 --- a/borgmatic/hooks/cronitor.py +++ b/borgmatic/hooks/cronitor.py @@ -22,7 +22,7 @@ def initialize_monitor( pass -def ping_monitor(hook_config, config, config_filename, state, monitoring_log_level, dry_run): +def ping_monitor(hook_config, config, config_filename, state, monitoring_log_level, dry_run, action_name): ''' Ping the configured Cronitor URL, modified with the monitor.State. Use the given configuration filename in any log entries. If this is a dry run, then don't actually ping anything. @@ -34,7 +34,13 @@ def ping_monitor(hook_config, config, config_filename, state, monitoring_log_lev return dry_run_label = ' (dry run; not actually pinging)' if dry_run else '' - ping_url = f"{hook_config['ping_url']}/{MONITOR_STATE_TO_CRONITOR[state]}" + try: + ping_url = f"{hook_config[action_name]}/{MONITOR_STATE_TO_CRONITOR[state]}" + except KeyError: + logger.debug( + f'{config_filename}: Skipping Cronitor {state.name.lower()} ping due to unconfigured action: {action_name}' + ) + return logger.info(f'{config_filename}: Pinging Cronitor {state.name.lower()}{dry_run_label}') logger.debug(f'{config_filename}: Using Cronitor ping URL {ping_url}') diff --git a/borgmatic/hooks/healthchecks.py b/borgmatic/hooks/healthchecks.py index ae0772c5..aa75778a 100644 --- a/borgmatic/hooks/healthchecks.py +++ b/borgmatic/hooks/healthchecks.py @@ -90,7 +90,7 @@ def initialize_monitor(hook_config, config, config_filename, monitoring_log_leve ) -def ping_monitor(hook_config, config, config_filename, state, monitoring_log_level, dry_run): +def ping_monitor(hook_config, config, config_filename, state, monitoring_log_level, dry_run, action_name): ''' Ping the configured Healthchecks URL or UUID, modified with the monitor.State. Use the given configuration filename in any log entries, and log to Healthchecks with the giving log level. diff --git a/borgmatic/hooks/ntfy.py b/borgmatic/hooks/ntfy.py index c1be2a1b..5a46047e 100644 --- a/borgmatic/hooks/ntfy.py +++ b/borgmatic/hooks/ntfy.py @@ -14,7 +14,7 @@ def initialize_monitor( pass -def ping_monitor(hook_config, config, config_filename, state, monitoring_log_level, dry_run): +def ping_monitor(hook_config, config, config_filename, state, monitoring_log_level, dry_run, action_name): ''' Ping the configured Ntfy topic. Use the given configuration filename in any log entries. If this is a dry run, then don't actually ping anything. diff --git a/borgmatic/hooks/pagerduty.py b/borgmatic/hooks/pagerduty.py index aeeec97c..87cf71a7 100644 --- a/borgmatic/hooks/pagerduty.py +++ b/borgmatic/hooks/pagerduty.py @@ -21,7 +21,7 @@ def initialize_monitor( pass -def ping_monitor(hook_config, config, config_filename, state, monitoring_log_level, dry_run): +def ping_monitor(hook_config, config, config_filename, state, monitoring_log_level, dry_run, action_name): ''' If this is an error state, create a PagerDuty event with the configured integration key. Use the given configuration filename in any log entries. If this is a dry run, then don't actually diff --git a/tests/unit/commands/test_borgmatic.py b/tests/unit/commands/test_borgmatic.py index 1c44e281..9d5217ad 100644 --- a/tests/unit/commands/test_borgmatic.py +++ b/tests/unit/commands/test_borgmatic.py @@ -16,7 +16,7 @@ def test_run_configuration_runs_actions_for_each_repository(): expected_results[1:] ) config = {'repositories': [{'path': 'foo'}, {'path': 'bar'}]} - arguments = {'global': flexmock(monitoring_verbosity=1)} + arguments = {'global': flexmock(monitoring_verbosity=1, skip_monitoring=False)} results = list(module.run_configuration('test.yaml', config, arguments)) @@ -30,7 +30,7 @@ def test_run_configuration_with_invalid_borg_version_errors(): flexmock(module.dispatch).should_receive('call_hooks').never() flexmock(module).should_receive('run_actions').never() config = {'repositories': ['foo']} - arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'prune': flexmock()} + arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False, skip_monitoring=False), 'prune': flexmock()} list(module.run_configuration('test.yaml', config, arguments)) @@ -45,7 +45,7 @@ def test_run_configuration_logs_monitor_start_error(): flexmock(module).should_receive('log_error_records').and_return(expected_results) flexmock(module).should_receive('run_actions').never() config = {'repositories': ['foo']} - arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()} + arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False, skip_monitoring=False), 'create': flexmock()} results = list(module.run_configuration('test.yaml', config, arguments)) @@ -60,7 +60,7 @@ def test_run_configuration_bails_for_monitor_start_soft_failure(): flexmock(module).should_receive('log_error_records').never() flexmock(module).should_receive('run_actions').never() config = {'repositories': ['foo']} - arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()} + arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False, skip_monitoring=False), 'create': flexmock()} results = list(module.run_configuration('test.yaml', config, arguments)) @@ -76,7 +76,7 @@ def test_run_configuration_logs_actions_error(): flexmock(module).should_receive('log_error_records').and_return(expected_results) flexmock(module).should_receive('run_actions').and_raise(OSError) config = {'repositories': [{'path': 'foo'}]} - arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False)} + arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False, skip_monitoring=False)} results = list(module.run_configuration('test.yaml', config, arguments)) @@ -92,7 +92,7 @@ def test_run_configuration_bails_for_actions_soft_failure(): flexmock(module).should_receive('log_error_records').never() flexmock(module.command).should_receive('considered_soft_failure').and_return(True) config = {'repositories': [{'path': 'foo'}]} - arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()} + arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False, skip_monitoring=False), 'create': flexmock()} results = list(module.run_configuration('test.yaml', config, arguments)) @@ -109,7 +109,7 @@ def test_run_configuration_logs_monitor_log_error(): flexmock(module).should_receive('log_error_records').and_return(expected_results) flexmock(module).should_receive('run_actions').and_return([]) config = {'repositories': [{'path': 'foo'}]} - arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()} + arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False, skip_monitoring=False), 'create': flexmock()} results = list(module.run_configuration('test.yaml', config, arguments)) @@ -127,7 +127,7 @@ def test_run_configuration_bails_for_monitor_log_soft_failure(): flexmock(module).should_receive('run_actions').and_return([]) flexmock(module.command).should_receive('considered_soft_failure').and_return(True) config = {'repositories': [{'path': 'foo'}]} - arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()} + arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False, skip_monitoring=False), 'create': flexmock()} results = list(module.run_configuration('test.yaml', config, arguments)) @@ -144,7 +144,7 @@ def test_run_configuration_logs_monitor_finish_error(): flexmock(module).should_receive('log_error_records').and_return(expected_results) flexmock(module).should_receive('run_actions').and_return([]) config = {'repositories': [{'path': 'foo'}]} - arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()} + arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False, skip_monitoring=False), 'create': flexmock()} results = list(module.run_configuration('test.yaml', config, arguments)) @@ -162,7 +162,7 @@ def test_run_configuration_bails_for_monitor_finish_soft_failure(): flexmock(module).should_receive('run_actions').and_return([]) flexmock(module.command).should_receive('considered_soft_failure').and_return(True) config = {'repositories': [{'path': 'foo'}]} - arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()} + arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False, skip_monitoring=False), 'create': flexmock()} results = list(module.run_configuration('test.yaml', config, arguments)) @@ -177,7 +177,7 @@ def test_run_configuration_does_not_call_monitoring_hooks_if_monitoring_hooks_ar flexmock(module).should_receive('run_actions').and_return([]) config = {'repositories': [{'path': 'foo'}]} - arguments = {'global': flexmock(monitoring_verbosity=-2, dry_run=False), 'create': flexmock()} + arguments = {'global': flexmock(monitoring_verbosity=-2, dry_run=False, skip_monitoring=False), 'create': flexmock()} results = list(module.run_configuration('test.yaml', config, arguments)) assert results == [] @@ -192,7 +192,7 @@ def test_run_configuration_logs_on_error_hook_error(): ).and_return(expected_results[1:]) flexmock(module).should_receive('run_actions').and_raise(OSError) config = {'repositories': [{'path': 'foo'}]} - arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()} + arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False, skip_monitoring=False), 'create': flexmock()} results = list(module.run_configuration('test.yaml', config, arguments)) @@ -208,7 +208,7 @@ def test_run_configuration_bails_for_on_error_hook_soft_failure(): flexmock(module).should_receive('log_error_records').and_return(expected_results) flexmock(module).should_receive('run_actions').and_raise(OSError) config = {'repositories': [{'path': 'foo'}]} - arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()} + arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False, skip_monitoring=False), 'create': flexmock()} results = list(module.run_configuration('test.yaml', config, arguments)) @@ -223,7 +223,7 @@ def test_run_configuration_retries_soft_error(): flexmock(module).should_receive('run_actions').and_raise(OSError).and_return([]) flexmock(module).should_receive('log_error_records').and_return([flexmock()]).once() config = {'repositories': [{'path': 'foo'}], 'retries': 1} - arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()} + arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False, skip_monitoring=False), 'create': flexmock()} results = list(module.run_configuration('test.yaml', config, arguments)) assert results == [] @@ -246,7 +246,7 @@ def test_run_configuration_retries_hard_error(): OSError, ).and_return(error_logs) config = {'repositories': [{'path': 'foo'}], 'retries': 1} - arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()} + arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False, skip_monitoring=False), 'create': flexmock()} results = list(module.run_configuration('test.yaml', config, arguments)) assert results == error_logs @@ -264,7 +264,7 @@ def test_run_configuration_repos_ordered(): 'bar: Error running actions for repository', OSError ).and_return(expected_results[1:]).ordered() config = {'repositories': [{'path': 'foo'}, {'path': 'bar'}]} - arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()} + arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False, skip_monitoring=False), 'create': flexmock()} results = list(module.run_configuration('test.yaml', config, arguments)) assert results == expected_results @@ -298,7 +298,7 @@ def test_run_configuration_retries_round_robin(): 'repositories': [{'path': 'foo'}, {'path': 'bar'}], 'retries': 1, } - arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()} + arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False, skip_monitoring=False), 'create': flexmock()} results = list(module.run_configuration('test.yaml', config, arguments)) assert results == foo_error_logs + bar_error_logs @@ -330,7 +330,7 @@ def test_run_configuration_retries_one_passes(): 'repositories': [{'path': 'foo'}, {'path': 'bar'}], 'retries': 1, } - arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()} + arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False, skip_monitoring=False), 'create': flexmock()} results = list(module.run_configuration('test.yaml', config, arguments)) assert results == error_logs @@ -373,7 +373,7 @@ def test_run_configuration_retry_wait(): 'retries': 3, 'retry_wait': 10, } - arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()} + arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False, skip_monitoring=False), 'create': flexmock()} results = list(module.run_configuration('test.yaml', config, arguments)) assert results == error_logs @@ -412,7 +412,7 @@ def test_run_configuration_retries_timeout_multiple_repos(): 'retries': 1, 'retry_wait': 10, } - arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()} + arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False, skip_monitoring=False), 'create': flexmock()} results = list(module.run_configuration('test.yaml', config, arguments)) assert results == error_logs diff --git a/tests/unit/hooks/test_cronhub.py b/tests/unit/hooks/test_cronhub.py index edb167ad..332768d7 100644 --- a/tests/unit/hooks/test_cronhub.py +++ b/tests/unit/hooks/test_cronhub.py @@ -16,6 +16,7 @@ def test_ping_monitor_rewrites_ping_url_for_start_state(): module.monitor.State.START, monitoring_log_level=1, dry_run=False, + action_name='create', ) @@ -32,6 +33,7 @@ def test_ping_monitor_rewrites_ping_url_and_state_for_start_state(): module.monitor.State.START, monitoring_log_level=1, dry_run=False, + action_name='create', ) @@ -48,6 +50,7 @@ def test_ping_monitor_rewrites_ping_url_for_finish_state(): module.monitor.State.FINISH, monitoring_log_level=1, dry_run=False, + action_name='create', ) @@ -64,6 +67,7 @@ def test_ping_monitor_rewrites_ping_url_for_fail_state(): module.monitor.State.FAIL, monitoring_log_level=1, dry_run=False, + action_name='create', ) @@ -78,6 +82,7 @@ def test_ping_monitor_dry_run_does_not_hit_ping_url(): module.monitor.State.START, monitoring_log_level=1, dry_run=True, + action_name='create', ) @@ -95,6 +100,7 @@ def test_ping_monitor_with_connection_error_logs_warning(): module.monitor.State.START, monitoring_log_level=1, dry_run=False, + action_name='create', ) @@ -116,6 +122,7 @@ def test_ping_monitor_with_other_error_logs_warning(): module.monitor.State.START, monitoring_log_level=1, dry_run=False, + action_name='create', ) @@ -130,4 +137,5 @@ def test_ping_monitor_with_unsupported_monitoring_state_bails(): module.monitor.State.LOG, monitoring_log_level=1, dry_run=False, + action_name='create', ) diff --git a/tests/unit/hooks/test_cronitor.py b/tests/unit/hooks/test_cronitor.py index 9daa2c11..d717c275 100644 --- a/tests/unit/hooks/test_cronitor.py +++ b/tests/unit/hooks/test_cronitor.py @@ -4,7 +4,7 @@ from borgmatic.hooks import cronitor as module def test_ping_monitor_hits_ping_url_for_start_state(): - hook_config = {'ping_url': 'https://example.com'} + hook_config = {'create': 'https://example.com'} flexmock(module.requests).should_receive('get').with_args('https://example.com/run').and_return( flexmock(ok=True) ) @@ -16,11 +16,12 @@ def test_ping_monitor_hits_ping_url_for_start_state(): module.monitor.State.START, monitoring_log_level=1, dry_run=False, + action_name='create', ) def test_ping_monitor_hits_ping_url_for_finish_state(): - hook_config = {'ping_url': 'https://example.com'} + hook_config = {'create': 'https://example.com'} flexmock(module.requests).should_receive('get').with_args( 'https://example.com/complete' ).and_return(flexmock(ok=True)) @@ -32,11 +33,12 @@ def test_ping_monitor_hits_ping_url_for_finish_state(): module.monitor.State.FINISH, monitoring_log_level=1, dry_run=False, + action_name='create', ) def test_ping_monitor_hits_ping_url_for_fail_state(): - hook_config = {'ping_url': 'https://example.com'} + hook_config = {'create': 'https://example.com'} flexmock(module.requests).should_receive('get').with_args( 'https://example.com/fail' ).and_return(flexmock(ok=True)) @@ -48,11 +50,12 @@ def test_ping_monitor_hits_ping_url_for_fail_state(): module.monitor.State.FAIL, monitoring_log_level=1, dry_run=False, + action_name='create', ) def test_ping_monitor_dry_run_does_not_hit_ping_url(): - hook_config = {'ping_url': 'https://example.com'} + hook_config = {'create': 'https://example.com'} flexmock(module.requests).should_receive('get').never() module.ping_monitor( @@ -62,11 +65,12 @@ def test_ping_monitor_dry_run_does_not_hit_ping_url(): module.monitor.State.START, monitoring_log_level=1, dry_run=True, + action_name='create', ) def test_ping_monitor_with_connection_error_logs_warning(): - hook_config = {'ping_url': 'https://example.com'} + hook_config = {'create': 'https://example.com'} flexmock(module.requests).should_receive('get').and_raise( module.requests.exceptions.ConnectionError ) @@ -79,11 +83,12 @@ def test_ping_monitor_with_connection_error_logs_warning(): module.monitor.State.START, monitoring_log_level=1, dry_run=False, + action_name='create', ) def test_ping_monitor_with_other_error_logs_warning(): - hook_config = {'ping_url': 'https://example.com'} + hook_config = {'create': 'https://example.com'} response = flexmock(ok=False) response.should_receive('raise_for_status').and_raise( module.requests.exceptions.RequestException @@ -100,11 +105,12 @@ def test_ping_monitor_with_other_error_logs_warning(): module.monitor.State.START, monitoring_log_level=1, dry_run=False, + action_name='create', ) def test_ping_monitor_with_unsupported_monitoring_state_bails(): - hook_config = {'ping_url': 'https://example.com'} + hook_config = {'create': 'https://example.com'} flexmock(module.requests).should_receive('get').never() module.ping_monitor( @@ -114,4 +120,5 @@ def test_ping_monitor_with_unsupported_monitoring_state_bails(): module.monitor.State.LOG, monitoring_log_level=1, dry_run=False, + action_name='create', ) diff --git a/tests/unit/hooks/test_healthchecks.py b/tests/unit/hooks/test_healthchecks.py index e3ab4386..cfabbd16 100644 --- a/tests/unit/hooks/test_healthchecks.py +++ b/tests/unit/hooks/test_healthchecks.py @@ -148,6 +148,7 @@ def test_ping_monitor_hits_ping_url_for_start_state(): state=module.monitor.State.START, monitoring_log_level=1, dry_run=False, + action_name='create', ) @@ -166,6 +167,7 @@ def test_ping_monitor_hits_ping_url_for_finish_state(): state=module.monitor.State.FINISH, monitoring_log_level=1, dry_run=False, + action_name='create', ) @@ -184,6 +186,7 @@ def test_ping_monitor_hits_ping_url_for_fail_state(): state=module.monitor.State.FAIL, monitoring_log_level=1, dry_run=False, + action_name='create', ) @@ -202,6 +205,7 @@ def test_ping_monitor_hits_ping_url_for_log_state(): state=module.monitor.State.LOG, monitoring_log_level=1, dry_run=False, + action_name='create', ) @@ -222,6 +226,7 @@ def test_ping_monitor_with_ping_uuid_hits_corresponding_url(): state=module.monitor.State.FINISH, monitoring_log_level=1, dry_run=False, + action_name='create', ) @@ -240,6 +245,7 @@ def test_ping_monitor_skips_ssl_verification_when_verify_tls_false(): state=module.monitor.State.FINISH, monitoring_log_level=1, dry_run=False, + action_name='create', ) @@ -258,6 +264,7 @@ def test_ping_monitor_executes_ssl_verification_when_verify_tls_true(): state=module.monitor.State.FINISH, monitoring_log_level=1, dry_run=False, + action_name='create', ) @@ -273,6 +280,7 @@ def test_ping_monitor_dry_run_does_not_hit_ping_url(): state=module.monitor.State.START, monitoring_log_level=1, dry_run=True, + action_name='create', ) @@ -288,6 +296,7 @@ def test_ping_monitor_does_not_hit_ping_url_when_states_not_matching(): state=module.monitor.State.START, monitoring_log_level=1, dry_run=True, + action_name='create', ) @@ -305,6 +314,7 @@ def test_ping_monitor_hits_ping_url_when_states_matching(): state=module.monitor.State.START, monitoring_log_level=1, dry_run=False, + action_name='create', ) @@ -323,6 +333,7 @@ def test_ping_monitor_with_connection_error_logs_warning(): state=module.monitor.State.START, monitoring_log_level=1, dry_run=False, + action_name='create', ) @@ -345,4 +356,5 @@ def test_ping_monitor_with_other_error_logs_warning(): state=module.monitor.State.START, monitoring_log_level=1, dry_run=False, + action_name='create', ) diff --git a/tests/unit/hooks/test_ntfy.py b/tests/unit/hooks/test_ntfy.py index 2d790fa2..ccff131e 100644 --- a/tests/unit/hooks/test_ntfy.py +++ b/tests/unit/hooks/test_ntfy.py @@ -49,6 +49,7 @@ def test_ping_monitor_minimal_config_hits_hosted_ntfy_on_fail(): borgmatic.hooks.monitor.State.FAIL, monitoring_log_level=1, dry_run=False, + action_name='create', ) @@ -71,6 +72,7 @@ def test_ping_monitor_with_auth_hits_hosted_ntfy_on_fail(): borgmatic.hooks.monitor.State.FAIL, monitoring_log_level=1, dry_run=False, + action_name='create', ) @@ -90,6 +92,7 @@ def test_ping_monitor_auth_with_no_username_warning(): borgmatic.hooks.monitor.State.FAIL, monitoring_log_level=1, dry_run=False, + action_name='create', ) @@ -109,6 +112,7 @@ def test_ping_monitor_auth_with_no_password_warning(): borgmatic.hooks.monitor.State.FAIL, monitoring_log_level=1, dry_run=False, + action_name='create', ) @@ -123,6 +127,7 @@ def test_ping_monitor_minimal_config_does_not_hit_hosted_ntfy_on_start(): borgmatic.hooks.monitor.State.START, monitoring_log_level=1, dry_run=False, + action_name='create', ) @@ -137,6 +142,7 @@ def test_ping_monitor_minimal_config_does_not_hit_hosted_ntfy_on_finish(): borgmatic.hooks.monitor.State.FINISH, monitoring_log_level=1, dry_run=False, + action_name='create', ) @@ -155,6 +161,7 @@ def test_ping_monitor_minimal_config_hits_selfhosted_ntfy_on_fail(): borgmatic.hooks.monitor.State.FAIL, monitoring_log_level=1, dry_run=False, + action_name='create', ) @@ -169,6 +176,7 @@ def test_ping_monitor_minimal_config_does_not_hit_hosted_ntfy_on_fail_dry_run(): borgmatic.hooks.monitor.State.FAIL, monitoring_log_level=1, dry_run=True, + action_name='create', ) @@ -185,6 +193,7 @@ def test_ping_monitor_custom_message_hits_hosted_ntfy_on_fail(): borgmatic.hooks.monitor.State.FAIL, monitoring_log_level=1, dry_run=False, + action_name='create', ) @@ -203,6 +212,7 @@ def test_ping_monitor_custom_state_hits_hosted_ntfy_on_start(): borgmatic.hooks.monitor.State.START, monitoring_log_level=1, dry_run=False, + action_name='create', ) @@ -222,6 +232,7 @@ def test_ping_monitor_with_connection_error_logs_warning(): borgmatic.hooks.monitor.State.FAIL, monitoring_log_level=1, dry_run=False, + action_name='create', ) @@ -245,4 +256,5 @@ def test_ping_monitor_with_other_error_logs_warning(): borgmatic.hooks.monitor.State.FAIL, monitoring_log_level=1, dry_run=False, + action_name='create', ) diff --git a/tests/unit/hooks/test_pagerduty.py b/tests/unit/hooks/test_pagerduty.py index 5a5ed12a..62a4ddba 100644 --- a/tests/unit/hooks/test_pagerduty.py +++ b/tests/unit/hooks/test_pagerduty.py @@ -13,6 +13,7 @@ def test_ping_monitor_ignores_start_state(): module.monitor.State.START, monitoring_log_level=1, dry_run=False, + action_name='create', ) @@ -26,6 +27,7 @@ def test_ping_monitor_ignores_finish_state(): module.monitor.State.FINISH, monitoring_log_level=1, dry_run=False, + action_name='create', ) @@ -39,6 +41,7 @@ def test_ping_monitor_calls_api_for_fail_state(): module.monitor.State.FAIL, monitoring_log_level=1, dry_run=False, + action_name='create', ) @@ -52,6 +55,7 @@ def test_ping_monitor_dry_run_does_not_call_api(): module.monitor.State.FAIL, monitoring_log_level=1, dry_run=True, + action_name='create', ) @@ -68,6 +72,7 @@ def test_ping_monitor_with_connection_error_logs_warning(): module.monitor.State.FAIL, monitoring_log_level=1, dry_run=False, + action_name='create', ) @@ -86,4 +91,5 @@ def test_ping_monitor_with_other_error_logs_warning(): module.monitor.State.FAIL, monitoring_log_level=1, dry_run=False, + action_name='create', )