Преглед на файлове

add support for apprise

Pim Kunis преди 1 година
родител
ревизия
f3295ccb4a
променени са 5 файла, в които са добавени 208 реда и са изтрити 1 реда
  1. 121 0
      borgmatic/config/schema.yaml
  2. 83 0
      borgmatic/hooks/apprise.py
  3. 2 0
      borgmatic/hooks/dispatch.py
  4. 1 1
      borgmatic/hooks/monitor.py
  5. 1 0
      setup.py

+ 121 - 0
borgmatic/config/schema.yaml

@@ -1306,6 +1306,127 @@ properties:
                 example:
                     - start
                     - finish
+    apprise:
+        type: object
+        required: ['service_urls'] # TODO
+        additionalProperties: false
+        properties:
+            service_urls:
+                type: array
+                items:
+                    type: string
+                description: |
+                    List of Apprise service URLs to publish to.
+                example:
+                    - "mastodon://accesskey/host/?visibility=direct"
+                    - "pagerduty://A1BRTD4JD@TIiajkdnlazkcOXrIdevi7F/node01.local/drive_sda/"
+            start:
+                type: object
+                properties:
+                    title:
+                        type: string
+                        description: |
+                            Specify the message title.
+                        example: Ping!
+                    body:
+                        type: string
+                        description: |
+                            Specify the message body.
+                        exampe: Your backups have failed.
+                    notification_type:
+                        type: string
+                        description: |
+                            The Apprise message type.
+                        enum:
+                            - info
+                            - success
+                            - failure
+                            - warning
+                        example:
+                            - failure
+                    # tags:
+                    #     type: array
+                    #     items:
+                    #         type: string
+                    #     description: |
+                    #         One or more tags to filter which services to notify.
+            finish:
+                type: object
+                properties:
+                    title:
+                        type: string
+                        description: |
+                            Specify the message title.
+                        example: Ping!
+                    body:
+                        type: string
+                        description: |
+                            Specify the message body.
+                        exampe: Your backups have failed.
+                    notification_type:
+                        type: string
+                        description: |
+                            The Apprise message type.
+                        enum:
+                            - info
+                            - success
+                            - failure
+                            - warning
+                        example:
+                            - failure
+                    # tags:
+                    #     type: array
+                    #     items:
+                    #         type: string
+                    #     description: |
+                    #         One or more tags to filter which services to notify.
+            fail:
+                type: object
+                properties:
+                    title:
+                        type: string
+                        description: |
+                            Specify the message title.
+                        example: Ping!
+                    body:
+                        type: string
+                        description: |
+                            Specify the message body.
+                        exampe: Your backups have failed.
+                    notification_type:
+                        type: string
+                        description: |
+                            The Apprise message type.
+                        enum:
+                            - info
+                            - success
+                            - failure
+                            - warning
+                        example:
+                            - failure
+                    # tags:
+                    #     type: array
+                    #     items:
+                    #         type: string
+                    #     description: |
+                    #         One or more tags to filter which services to notify.
+            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
+
     healthchecks:
         type: object
         required: ['ping_url']

+ 83 - 0
borgmatic/hooks/apprise.py

@@ -0,0 +1,83 @@
+import logging
+
+import apprise
+from apprise import NotifyType, NotifyFormat
+
+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):
+    '''
+    Ping the configured Apprise service URLs.
+    Use the given configuration filename in any log entries.
+    If this is a dry run, then don't actually ping anything.
+    '''
+    run_states = hook_config.get('states', ['fail'])
+
+    if state.name.lower() not in run_states:
+        return
+
+    state_config = hook_config.get(
+        state.name.lower(),
+        {
+            'title': f'A borgmatic {state.name} event happened',
+            'body': f'A borgmatic {state.name} event happened',
+            'notification_type': 'success',  # TODO: default per state.name
+            # 'tag': ['borgmatic'],
+        },
+    )
+
+    # TODO: Currently not very meaningful message.
+    # However, the Apprise service URLs can contain sensitive info.
+    dry_run_label = ' (dry run; not actually pinging)' if dry_run else ''
+    logger.info(f'{config_filename}: Pinging Apprise {dry_run_label}')
+    logger.debug(f'{config_filename}: Using Apprise ping')
+
+    title = state_config.get('title', '')
+    body = state_config.get('body')
+    notify_type = state_config.get('notification_type', 'success')
+
+    apobj = apprise.Apprise()
+    apobj.add(hook_config.get('service_urls'))
+
+    if dry_run:
+        return
+
+    result = apobj.notify(
+        title=title,
+        body=body,
+        body_format=NotifyFormat.TEXT,
+        notify_type=get_notify_type(notify_type)
+    )
+
+    if result is False:
+        logger.warning(f'{config_filename}: error sending some apprise notifications')
+
+
+def get_notify_type(s):
+    if s == 'info':
+        return NotifyType.INFO
+    if s == 'success':
+        return NotifyType.SUCCESS
+    if s == 'warning':
+        return NotifyType.WARNING
+    if s == 'failure':
+        return NotifyType.FAILURE
+
+
+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

+ 2 - 0
borgmatic/hooks/dispatch.py

@@ -1,6 +1,7 @@
 import logging
 
 from borgmatic.hooks import (
+    apprise,
     cronhub,
     cronitor,
     healthchecks,
@@ -17,6 +18,7 @@ from borgmatic.hooks import (
 logger = logging.getLogger(__name__)
 
 HOOK_NAME_TO_MODULE = {
+    'apprise': apprise,
     'cronhub': cronhub,
     'cronitor': cronitor,
     'healthchecks': healthchecks,

+ 1 - 1
borgmatic/hooks/monitor.py

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

+ 1 - 0
setup.py

@@ -35,6 +35,7 @@ setup(
         'requests',
         'ruamel.yaml>0.15.0,<0.18.0',
         'setuptools',
+        'apprise'
     ),
     include_package_data=True,
     python_requires='>=3.7',