Add Zabbix monitoring hook.
Merge pull request #85 from tony1661/zabbix-hook
This commit is contained in:
commit
c85bf46ad9
@ -1609,6 +1609,86 @@ properties:
|
||||
example:
|
||||
- start
|
||||
- finish
|
||||
zabbix:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
properties:
|
||||
itemid:
|
||||
type: integer
|
||||
description: |
|
||||
The ID of the Zabbix item used for collecting data.
|
||||
Unique across the entire Zabbix system.
|
||||
example: 55105
|
||||
host:
|
||||
type: string
|
||||
description: |
|
||||
Host name where the item is stored. Required if "itemid" is not set.
|
||||
example: borg-server
|
||||
key:
|
||||
type: string
|
||||
description: |
|
||||
Key of the host where the item is stored. Required if "itemid" is not set.
|
||||
example: borg.status
|
||||
server:
|
||||
type: string
|
||||
description: |
|
||||
The address of your Zabbix instance.
|
||||
example: https://zabbix.your-domain.com
|
||||
username:
|
||||
type: string
|
||||
description: |
|
||||
The username used for authentication. Not needed if using an API key.
|
||||
example: testuser
|
||||
password:
|
||||
type: string
|
||||
description: |
|
||||
The password used for authentication. Not needed if using an API key.
|
||||
example: fakepassword
|
||||
api_key:
|
||||
type: string
|
||||
description: |
|
||||
The API key used for authentication. Not needed if using an username/password.
|
||||
example: fakekey
|
||||
start:
|
||||
type: object
|
||||
properties:
|
||||
value:
|
||||
type: ["integer", "string"]
|
||||
description: |
|
||||
The value to set the item to on start.
|
||||
example: STARTED
|
||||
finish:
|
||||
type: object
|
||||
properties:
|
||||
value:
|
||||
type: ["integer", "string"]
|
||||
description: |
|
||||
The value to set the item to on finish.
|
||||
example: FINISH
|
||||
fail:
|
||||
type: object
|
||||
properties:
|
||||
value:
|
||||
type: ["integer", "string"]
|
||||
description: |
|
||||
The value to set the item to on fail.
|
||||
example: ERROR
|
||||
states:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
enum:
|
||||
- start
|
||||
- finish
|
||||
- fail
|
||||
uniqueItems: true
|
||||
description: |
|
||||
List of one or more monitoring states to ping for: "start",
|
||||
"finish", and/or "fail". Defaults to pinging for failure
|
||||
only.
|
||||
example:
|
||||
- start
|
||||
- finish
|
||||
apprise:
|
||||
type: object
|
||||
required: ['services']
|
||||
|
@ -14,6 +14,7 @@ from borgmatic.hooks import (
|
||||
postgresql,
|
||||
sqlite,
|
||||
uptimekuma,
|
||||
zabbix,
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@ -32,6 +33,7 @@ HOOK_NAME_TO_MODULE = {
|
||||
'postgresql_databases': postgresql,
|
||||
'sqlite_databases': sqlite,
|
||||
'uptime_kuma': uptimekuma,
|
||||
'zabbix': zabbix,
|
||||
}
|
||||
|
||||
|
||||
|
@ -9,6 +9,7 @@ MONITOR_HOOK_NAMES = (
|
||||
'ntfy',
|
||||
'pagerduty',
|
||||
'uptime_kuma',
|
||||
'zabbix',
|
||||
)
|
||||
|
||||
|
||||
|
139
borgmatic/hooks/zabbix.py
Normal file
139
borgmatic/hooks/zabbix.py
Normal file
@ -0,0 +1,139 @@
|
||||
import json
|
||||
import logging
|
||||
|
||||
import requests
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def initialize_monitor(
|
||||
ping_url, config, config_filename, monitoring_log_level, dry_run
|
||||
): # pragma: no cover
|
||||
'''
|
||||
No initialization is necessary for this monitor.
|
||||
'''
|
||||
pass
|
||||
|
||||
|
||||
def ping_monitor(hook_config, config, config_filename, state, monitoring_log_level, dry_run):
|
||||
'''
|
||||
Update the configured Zabbix item using either the itemid, or a host and key.
|
||||
If this is a dry run, then don't actually update anything.
|
||||
'''
|
||||
|
||||
run_states = hook_config.get('states', ['fail'])
|
||||
|
||||
if state.name.lower() not in run_states:
|
||||
return
|
||||
|
||||
dry_run_label = ' (dry run; not actually updating)' if dry_run else ''
|
||||
|
||||
state_config = hook_config.get(
|
||||
state.name.lower(),
|
||||
{
|
||||
'value': state.name.lower(),
|
||||
},
|
||||
)
|
||||
|
||||
server = hook_config.get('server')
|
||||
username = hook_config.get('username')
|
||||
password = hook_config.get('password')
|
||||
api_key = hook_config.get('api_key')
|
||||
itemid = hook_config.get('itemid')
|
||||
host = hook_config.get('host')
|
||||
key = hook_config.get('key')
|
||||
value = state_config.get('value')
|
||||
headers = {'Content-Type': 'application/json-rpc'}
|
||||
|
||||
logger.info(f'{config_filename}: Updating Zabbix{dry_run_label}')
|
||||
logger.debug(f'{config_filename}: Using Zabbix URL: {server}')
|
||||
|
||||
if server is None:
|
||||
logger.warning(f'{config_filename}: Server missing for Zabbix')
|
||||
return
|
||||
|
||||
# Determine the zabbix method used to store the value: itemid or host/key
|
||||
if itemid is not None:
|
||||
logger.info(f'{config_filename}: Updating {itemid} on Zabbix')
|
||||
data = {
|
||||
"jsonrpc": "2.0",
|
||||
"method": "history.push",
|
||||
"params": {"itemid": itemid, "value": value},
|
||||
"id": 1,
|
||||
}
|
||||
|
||||
elif (host and key) is not None:
|
||||
logger.info(f'{config_filename}: Updating Host:{host} and Key:{key} on Zabbix')
|
||||
data = {
|
||||
"jsonrpc": "2.0",
|
||||
"method": "history.push",
|
||||
"params": {"host": host, "key": key, "value": value},
|
||||
"id": 1,
|
||||
}
|
||||
|
||||
elif host is not None:
|
||||
logger.warning(f'{config_filename}: Key missing for Zabbix')
|
||||
return
|
||||
|
||||
elif key is not None:
|
||||
logger.warning(f'{config_filename}: Host missing for Zabbix.')
|
||||
return
|
||||
else:
|
||||
logger.warning(f'{config_filename}: No zabbix itemid or host/key provided.')
|
||||
return
|
||||
|
||||
# Determine the authentication method: API key or username/password
|
||||
if api_key is not None:
|
||||
logger.info(f'{config_filename}: Using API key auth for Zabbix')
|
||||
headers['Authorization'] = 'Bearer ' + api_key
|
||||
|
||||
elif (username and password) is not None:
|
||||
logger.info(f'{config_filename}: Using user/pass auth with user {username} for Zabbix')
|
||||
auth_data = {
|
||||
"jsonrpc": "2.0",
|
||||
"method": "user.login",
|
||||
"params": {
|
||||
"username": username,
|
||||
"password": password
|
||||
},
|
||||
"id": 1
|
||||
}
|
||||
if not dry_run:
|
||||
logging.getLogger('urllib3').setLevel(logging.ERROR)
|
||||
try:
|
||||
response = requests.post(server, headers=headers, json=auth_data)
|
||||
data['auth'] = response.json().get('result')
|
||||
if not response.ok:
|
||||
response.raise_for_status()
|
||||
except requests.exceptions.RequestException as error:
|
||||
logger.warning(f'{config_filename}: Zabbix error: {error}')
|
||||
|
||||
elif username is not None:
|
||||
logger.warning(f'{config_filename}: Password missing for Zabbix authentication')
|
||||
return
|
||||
|
||||
elif password is not None:
|
||||
logger.warning(f'{config_filename}: Username missing for Zabbix authentication')
|
||||
return
|
||||
else:
|
||||
logger.warning(f'{config_filename}: Authentication data missing for Zabbix')
|
||||
return
|
||||
|
||||
|
||||
if not dry_run:
|
||||
logging.getLogger('urllib3').setLevel(logging.ERROR)
|
||||
try:
|
||||
response = requests.post(server, headers=headers, json=data)
|
||||
if not response.ok:
|
||||
response.raise_for_status()
|
||||
except requests.exceptions.RequestException as error:
|
||||
logger.warning(f'{config_filename}: Zabbix error: {error}')
|
||||
|
||||
|
||||
def destroy_monitor(
|
||||
ping_url_or_uuid, config, config_filename, monitoring_log_level, dry_run
|
||||
): # pragma: no cover
|
||||
'''
|
||||
No destruction is necessary for this monitor.
|
||||
'''
|
||||
pass
|
@ -47,6 +47,7 @@ them as backups happen:
|
||||
* [ntfy](https://torsion.org/borgmatic/docs/how-to/monitor-your-backups/#ntfy-hook)
|
||||
* [PagerDuty](https://torsion.org/borgmatic/docs/how-to/monitor-your-backups/#pagerduty-hook)
|
||||
* [Uptime Kuma](https://torsion.org/borgmatic/docs/how-to/monitor-your-backups/#uptime-kuma-hook)
|
||||
* [Zabbix](https://torsion.org/borgmatic/docs/how-to/monitor-your-backups/#zabbix-hook)
|
||||
|
||||
The idea is that you'll receive an alert when something goes wrong or when the
|
||||
service doesn't hear from borgmatic for a configured interval (if supported).
|
||||
@ -562,6 +563,58 @@ Heartbeat Retry = 360 # = 10 minutes
|
||||
Resend Notification every X times = 1
|
||||
```
|
||||
|
||||
## Zabbix hook
|
||||
|
||||
<span class="minilink minilink-addedin">New in version 1.9.0</span>
|
||||
[zabbix](https://www.zabbix.com/) is an open-source monitoring tool used for tracking and managing the performance and availability of networks, servers, and applications in real-time.
|
||||
|
||||
This hook does not do any notifications on its own. Instead, it relies on
|
||||
your Zabbix instance to notify and perform escalations based on the Zabbix
|
||||
configuration. The `states` defined in the configuration will determine which states
|
||||
will trigger the hook. The value defined in the configuration of each state is
|
||||
used to populate the data of the configured Zabbix item. If none are provided,
|
||||
it default to a lower-case string of the state.
|
||||
|
||||
An example configuration is shown here with all the available options.
|
||||
|
||||
```yaml
|
||||
zabbix:
|
||||
server: http://cloud.zabbix.com/zabbix/api_jsonrpc.php
|
||||
|
||||
username: myuser
|
||||
password: secret
|
||||
api_key: b2ecba64d8beb47fc161ae48b164cfd7104a79e8e48e6074ef5b141d8a0aeeca
|
||||
|
||||
host: "borg-server"
|
||||
key: borg.status
|
||||
itemid: 55105
|
||||
|
||||
start:
|
||||
value: "STARTED"
|
||||
finish:
|
||||
value: "OK"
|
||||
fail:
|
||||
value: "ERROR"
|
||||
states:
|
||||
- start
|
||||
- finish
|
||||
- fail
|
||||
```
|
||||
|
||||
### Zabbix 7.0+
|
||||
This hook requires the Zabbix server be running version 7.0+
|
||||
|
||||
<span class="minilink minilink-addedin">Authentication Methods</span>
|
||||
Authentication can be accomplished via `api_key` or `username` and `password`.
|
||||
If both are declared, `api_key` will be chosen.
|
||||
|
||||
<span class="minilink minilink-addedin">Items</span> The item
|
||||
to be updated can be chosen by either declaring the `itemid` or
|
||||
`host` and `key`. If both are declared, `itemid` will be chosen.
|
||||
|
||||
Keep in mind that `host` is referring to the 'Host name' on the
|
||||
Zabbix host and not the 'Visual name'.
|
||||
|
||||
|
||||
## Scripting borgmatic
|
||||
|
||||
|
324
tests/unit/hooks/test_zabbix.py
Normal file
324
tests/unit/hooks/test_zabbix.py
Normal file
@ -0,0 +1,324 @@
|
||||
from enum import Enum
|
||||
|
||||
from flexmock import flexmock
|
||||
|
||||
import borgmatic.hooks.monitor
|
||||
from borgmatic.hooks import zabbix as module
|
||||
|
||||
SERVER = 'https://zabbix.com/zabbix/api_jsonrpc.php'
|
||||
ITEMID = 55105
|
||||
USERNAME = 'testuser'
|
||||
PASSWORD = 'fakepassword'
|
||||
API_KEY = 'fakekey'
|
||||
HOST = 'borg-server'
|
||||
KEY = 'borg.status'
|
||||
VALUE = 'fail'
|
||||
|
||||
DATA_HOST_KEY = {
|
||||
"jsonrpc": "2.0",
|
||||
"method": "history.push",
|
||||
"params": {"host": HOST, "key": KEY, "value": VALUE},
|
||||
"id": 1,
|
||||
}
|
||||
|
||||
DATA_HOST_KEY_WITH_TOKEN = {
|
||||
"jsonrpc": "2.0",
|
||||
"method": "history.push",
|
||||
"params": {"host": HOST, "key": KEY, "value": VALUE},
|
||||
"id": 1,
|
||||
"auth": "3fe6ed01a69ebd79907a120bcd04e494"
|
||||
}
|
||||
|
||||
DATA_ITEMID = {
|
||||
"jsonrpc": "2.0",
|
||||
"method": "history.push",
|
||||
"params": {"itemid": ITEMID, "value": VALUE},
|
||||
"id": 1,
|
||||
}
|
||||
|
||||
DATA_HOST_KEY_WITH_TOKEN = {
|
||||
"jsonrpc": "2.0",
|
||||
"method": "history.push",
|
||||
"params": {"itemid": ITEMID, "value": VALUE},
|
||||
"id": 1,
|
||||
"auth": "3fe6ed01a69ebd79907a120bcd04e494"
|
||||
}
|
||||
|
||||
DATA_USER_LOGIN = {
|
||||
"jsonrpc": "2.0",
|
||||
"method": "user.login",
|
||||
"params": {"username": USERNAME, "password": PASSWORD},
|
||||
"id": 1,
|
||||
}
|
||||
|
||||
AUTH_HEADERS_API_KEY = {
|
||||
'Content-Type': 'application/json-rpc',
|
||||
'Authorization': f'Bearer {API_KEY}'
|
||||
}
|
||||
|
||||
AUTH_HEADERS_USERNAME_PASSWORD = {
|
||||
'Content-Type': 'application/json-rpc'
|
||||
}
|
||||
|
||||
def test_ping_monitor_config_with_api_key_only_exit_early():
|
||||
# This test should exit early since only providing an API KEY is not enough
|
||||
# for the hook to work
|
||||
hook_config = {
|
||||
'api_key': API_KEY
|
||||
}
|
||||
flexmock(module.logger).should_receive('warning').once()
|
||||
|
||||
module.ping_monitor(
|
||||
hook_config,
|
||||
{},
|
||||
'config.yaml',
|
||||
borgmatic.hooks.monitor.State.FAIL,
|
||||
monitoring_log_level=1,
|
||||
dry_run=False,
|
||||
)
|
||||
|
||||
def test_ping_monitor_config_with_host_only_exit_early():
|
||||
# This test should exit early since only providing a HOST is not enough
|
||||
# for the hook to work
|
||||
hook_config = {
|
||||
'host': HOST
|
||||
}
|
||||
flexmock(module.logger).should_receive('warning').once()
|
||||
|
||||
module.ping_monitor(
|
||||
hook_config,
|
||||
{},
|
||||
'config.yaml',
|
||||
borgmatic.hooks.monitor.State.FAIL,
|
||||
monitoring_log_level=1,
|
||||
dry_run=False,
|
||||
)
|
||||
|
||||
def test_ping_monitor_config_with_key_only_exit_early():
|
||||
# This test should exit early since only providing a KEY is not enough
|
||||
# for the hook to work
|
||||
hook_config = {
|
||||
'key': KEY
|
||||
}
|
||||
flexmock(module.logger).should_receive('warning').once()
|
||||
|
||||
module.ping_monitor(
|
||||
hook_config,
|
||||
{},
|
||||
'config.yaml',
|
||||
borgmatic.hooks.monitor.State.FAIL,
|
||||
monitoring_log_level=1,
|
||||
dry_run=False,
|
||||
)
|
||||
|
||||
def test_ping_monitor_config_with_server_only_exit_early():
|
||||
# This test should exit early since only providing a SERVER is not enough
|
||||
# for the hook to work
|
||||
hook_config = {
|
||||
'server': SERVER
|
||||
}
|
||||
flexmock(module.logger).should_receive('warning').once()
|
||||
|
||||
module.ping_monitor(
|
||||
hook_config,
|
||||
{},
|
||||
'config.yaml',
|
||||
borgmatic.hooks.monitor.State.FAIL,
|
||||
monitoring_log_level=1,
|
||||
dry_run=False,
|
||||
)
|
||||
|
||||
def test_ping_monitor_config_user_password_no_zabbix_data_exit_early():
|
||||
# This test should exit early since there are HOST/KEY or ITEMID provided to publish data to
|
||||
hook_config = {
|
||||
'server': SERVER,
|
||||
'username': USERNAME,
|
||||
'password': PASSWORD
|
||||
}
|
||||
flexmock(module.logger).should_receive('warning').once()
|
||||
|
||||
module.ping_monitor(
|
||||
hook_config,
|
||||
{},
|
||||
'config.yaml',
|
||||
borgmatic.hooks.monitor.State.FAIL,
|
||||
monitoring_log_level=1,
|
||||
dry_run=False,
|
||||
)
|
||||
|
||||
def test_ping_monitor_config_api_key_no_zabbix_data_exit_early():
|
||||
# This test should exit early since there are HOST/KEY or ITEMID provided to publish data to
|
||||
hook_config = {
|
||||
'server': SERVER,
|
||||
'api_key': API_KEY
|
||||
}
|
||||
flexmock(module.logger).should_receive('warning').once()
|
||||
|
||||
module.ping_monitor(
|
||||
hook_config,
|
||||
{},
|
||||
'config.yaml',
|
||||
borgmatic.hooks.monitor.State.FAIL,
|
||||
monitoring_log_level=1,
|
||||
dry_run=False,
|
||||
)
|
||||
|
||||
def test_ping_monitor_config_itemid_no_auth_data_exit_early():
|
||||
# This test should exit early since there is no authentication provided
|
||||
# and Zabbix requires authentication to use it's API
|
||||
hook_config = {
|
||||
'server': SERVER,
|
||||
'itemid': ITEMID
|
||||
}
|
||||
flexmock(module.logger).should_receive('warning').once()
|
||||
|
||||
module.ping_monitor(
|
||||
hook_config,
|
||||
{},
|
||||
'config.yaml',
|
||||
borgmatic.hooks.monitor.State.FAIL,
|
||||
monitoring_log_level=1,
|
||||
dry_run=False,
|
||||
)
|
||||
|
||||
def test_ping_monitor_config_host_and_key_no_auth_data_exit_early():
|
||||
# This test should exit early since there is no authentication provided
|
||||
# and Zabbix requires authentication to use it's API
|
||||
hook_config = {
|
||||
'server': SERVER,
|
||||
'host': HOST,
|
||||
'key': KEY
|
||||
}
|
||||
flexmock(module.logger).should_receive('warning').once()
|
||||
|
||||
module.ping_monitor(
|
||||
hook_config,
|
||||
{},
|
||||
'config.yaml',
|
||||
borgmatic.hooks.monitor.State.FAIL,
|
||||
monitoring_log_level=1,
|
||||
dry_run=False,
|
||||
)
|
||||
|
||||
def test_ping_monitor_config_host_and_key_with_api_key_auth_data_successful():
|
||||
# This test should simulate a successful POST to a Zabbix server. This test uses API_KEY
|
||||
# to authenticate and HOST/KEY to know which item to populate in Zabbix.
|
||||
hook_config = {
|
||||
'server': SERVER,
|
||||
'host': HOST,
|
||||
'key': KEY,
|
||||
'api_key': API_KEY
|
||||
}
|
||||
flexmock(module.requests).should_receive('post').with_args(
|
||||
f'{SERVER}',
|
||||
headers=AUTH_HEADERS_API_KEY,
|
||||
json=DATA_HOST_KEY,
|
||||
).and_return(flexmock(ok=True)).once()
|
||||
flexmock(module.logger).should_receive('warning').never()
|
||||
|
||||
module.ping_monitor(
|
||||
hook_config,
|
||||
{},
|
||||
'config.yaml',
|
||||
borgmatic.hooks.monitor.State.FAIL,
|
||||
monitoring_log_level=1,
|
||||
dry_run=False,
|
||||
)
|
||||
|
||||
def test_ping_monitor_config_host_and_key_with_username_password_auth_data_successful():
|
||||
# This test should simulate a successful POST to a Zabbix server. This test uses USERNAME/PASSWORD
|
||||
# to authenticate and HOST/KEY to know which item to populate in Zabbix.
|
||||
hook_config = {
|
||||
'server': SERVER,
|
||||
'host': HOST,
|
||||
'key': KEY,
|
||||
'username': USERNAME,
|
||||
'password': PASSWORD
|
||||
}
|
||||
|
||||
auth_response = flexmock(ok=True)
|
||||
auth_response.should_receive('json').and_return({"jsonrpc":"2.0","result":"3fe6ed01a69ebd79907a120bcd04e494","id":1})
|
||||
|
||||
flexmock(module.requests).should_receive('post').with_args(
|
||||
f'{SERVER}',
|
||||
headers=AUTH_HEADERS_USERNAME_PASSWORD,
|
||||
json=DATA_USER_LOGIN,
|
||||
).and_return(auth_response).once()
|
||||
|
||||
flexmock(module.logger).should_receive('warning').never()
|
||||
|
||||
flexmock(module.requests).should_receive('post').with_args(
|
||||
f'{SERVER}',
|
||||
headers=AUTH_HEADERS_USERNAME_PASSWORD,
|
||||
json=DATA_HOST_KEY_WITH_TOKEN,
|
||||
).and_return(flexmock(ok=True)).once()
|
||||
|
||||
module.ping_monitor(
|
||||
hook_config,
|
||||
{},
|
||||
'config.yaml',
|
||||
borgmatic.hooks.monitor.State.FAIL,
|
||||
monitoring_log_level=1,
|
||||
dry_run=False,
|
||||
)
|
||||
|
||||
def test_ping_monitor_config_itemid_with_api_key_auth_data_successful():
|
||||
# This test should simulate a successful POST to a Zabbix server. This test uses API_KEY
|
||||
# to authenticate and HOST/KEY to know which item to populate in Zabbix.
|
||||
hook_config = {
|
||||
'server': SERVER,
|
||||
'itemid': ITEMID,
|
||||
'api_key': API_KEY
|
||||
}
|
||||
flexmock(module.requests).should_receive('post').with_args(
|
||||
f'{SERVER}',
|
||||
headers=AUTH_HEADERS_API_KEY,
|
||||
json=DATA_ITEMID,
|
||||
).and_return(flexmock(ok=True)).once()
|
||||
flexmock(module.logger).should_receive('warning').never()
|
||||
|
||||
module.ping_monitor(
|
||||
hook_config,
|
||||
{},
|
||||
'config.yaml',
|
||||
borgmatic.hooks.monitor.State.FAIL,
|
||||
monitoring_log_level=1,
|
||||
dry_run=False,
|
||||
)
|
||||
|
||||
def test_ping_monitor_config_itemid_with_username_password_auth_data_successful():
|
||||
# This test should simulate a successful POST to a Zabbix server. This test uses USERNAME/PASSWORD
|
||||
# to authenticate and HOST/KEY to know which item to populate in Zabbix.
|
||||
hook_config = {
|
||||
'server': SERVER,
|
||||
'itemid': ITEMID,
|
||||
'username': USERNAME,
|
||||
'password': PASSWORD
|
||||
}
|
||||
|
||||
auth_response = flexmock(ok=True)
|
||||
auth_response.should_receive('json').and_return({"jsonrpc":"2.0","result":"3fe6ed01a69ebd79907a120bcd04e494","id":1})
|
||||
|
||||
flexmock(module.requests).should_receive('post').with_args(
|
||||
f'{SERVER}',
|
||||
headers=AUTH_HEADERS_USERNAME_PASSWORD,
|
||||
json=DATA_USER_LOGIN,
|
||||
).and_return(auth_response).once()
|
||||
|
||||
flexmock(module.logger).should_receive('warning').never()
|
||||
|
||||
flexmock(module.requests).should_receive('post').with_args(
|
||||
f'{SERVER}',
|
||||
headers=AUTH_HEADERS_USERNAME_PASSWORD,
|
||||
json=DATA_HOST_KEY_WITH_TOKEN,
|
||||
).and_return(flexmock(ok=True)).once()
|
||||
|
||||
module.ping_monitor(
|
||||
hook_config,
|
||||
{},
|
||||
'config.yaml',
|
||||
borgmatic.hooks.monitor.State.FAIL,
|
||||
monitoring_log_level=1,
|
||||
dry_run=False,
|
||||
)
|
||||
test_ping_monitor_config_itemid_with_username_password_auth_data_successful()
|
Loading…
x
Reference in New Issue
Block a user