Added new role misc/tg_monitor_cmd

master
Felix Stupp 3 years ago
parent 7f9980903f
commit 0a5b3fc26f
Signed by: zocker
GPG Key ID: 93E1BD26F6B02FB7

@ -12,6 +12,8 @@ ansible_user: "{{ global_username }}"
ansible_become: yes
ansible_become_pass: "{{ zocker_password }}"
default_tg_monitor_recipient_id: "{{ zocker_telegram_id }}"
zocker_authorized_keys_url: "https://git.banananet.work/zocker.keys"
update_scripts_directory: "/root/update"

@ -0,0 +1,26 @@
---
# monitor_name: "echo-output-check"
instance_name: "tg-monitor-cmd-{{ monitor_name }}"
description: "{{ monitor_name }}" # should be human fancy
# command: "/bin/echo Hello" # or command_str
command_str: "{{ command | map('quote') | join(' ') }}"
use_shell: no # read https://docs.python.org/3/library/subprocess.html#security-considerations before using use_shell=yes
system_user: tg-monitor-cmd
recipient_id: "{{ default_tg_monitor_recipient_id }}"
bot_key: "{{ global_telegram_server_bot_key }}"
telegram_timeout: 10
calendar_spec: "*:0:0" # once every hour
service_description: |
Telegram Monitor Command of {{ description }}
# paths
monitoring_directory: "{{ global_deployment_directory }}/tg-monitor-cmd"
instance_directory: "{{ monitoring_directory }}/{{ monitor_name }}"
script_path: "{{ instance_directory }}/script.py"
data_path: "{{ instance_directory }}/data"

@ -0,0 +1,8 @@
---
allow_duplicates: yes
dependencies:
- role: misc/system_user
# system_user
user_directory: "{{ monitoring_directory }}"

@ -0,0 +1,69 @@
---
- name: Create directory for monitoring scripts and data
file:
state: directory
path: "{{ instance_directory }}"
owner: root
group: "{{ system_user }}"
mode: u=rwx,g=rx,o=
- name: Deploy script
template:
src: monitor.py
dest: "{{ script_path }}"
owner: root
group: "{{ system_user }}"
mode: u=rwx,g=rx,o=
register: script_task
- name: Create empty data file
copy:
content: ""
dest: "{{ data_path }}"
force: no # do not overwrite
- name: Ensure permissions on data file
file:
state: file
path: "{{ data_path }}"
owner: root
group: "{{ system_user }}"
mode: u=rw,g=rw,o=
- name: Register service for monitor
template:
src: monitor.service
dest: "{{ global_systemd_configuration_directory }}/{{ instance_name }}.service"
owner: root
group: root
mode: u=rw,g=r,o=
register: service_task
- name: Run service for initial test
systemd:
state: started
daemon_reload: yes
name: "{{ instance_name }}.service"
when: script_task.changed or service_task.changed
- name: Register timer for monitor service
template:
src: monitor.timer
dest: "{{ global_systemd_configuration_directory }}/{{ instance_name }}.timer"
owner: root
group: root
mode: u=rw,g=r,o=
register: timer_task
- name: Restart timer for monitor
systemd:
state: restarted
daemon_reload: yes
name: "{{ instance_name }}.timer"
when: timer_task.changed
- name: Enable timer for monitor
systemd:
name: "{{ instance_name }}.timer"
enabled: yes

@ -0,0 +1,64 @@
#!/usr/bin/env python3
# imports
from pathlib import Path
from hashlib import sha256
import shlex
import subprocess
import sys
import requests
# config
MONITOR_DESC = """{{ description }}"""
MONITOR_COMMAND = """{{ command_str }}"""
USE_SHELL = {{ use_shell | ternary('True', 'False') }}
DATA_PATH = Path("""{{ data_path }}""")
TG_ENDPOINT = "https://api.telegram.org"
TG_KEY = """{{ bot_key }}"""
TG_RECIPIENT = """{{ recipient_id }}"""
# helpers
def print_error(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
def tg_msg(msg: str) -> None:
print(f"Sending message using telegram:\n{msg}")
ret = requests.post(f"{TG_ENDPOINT}/bot{TG_KEY}/sendMessage", data={
"chat_id": TG_RECIPIENT,
"disable_web_page_preview": 1,
"parse_mode": "Markdown",
"text": msg,
})
if 400 <= ret.status_code:
raise Exception(f"Sending telegram message failed: {ret.status_code} {ret.text}")
def run_cmd(cmd: list, **kwargs) -> str:
return subprocess.run(cmd, capture_output=True, check=True, text=True, **kwargs).stdout
def hash_data(data: str) -> bool:
return sha256(data.encode("utf-8")).hexdigest()
def check_cmd(cmd_str: str, use_shell: bool, data_file: Path) -> str:
cmd = shlex.split(cmd_str) if not use_shell else cmd_str
old_hash = data_file.read_text() if data_file.exists() else None
new_data = run_cmd(cmd, shell=use_shell)
new_hash = hash_data(new_data)
if old_hash == new_hash:
return None
data_file.write_text(new_hash)
return new_data
if __name__ == "__main__":
try:
data = check_cmd(MONITOR_COMMAND, USE_SHELL, DATA_PATH)
if data:
tg_msg(f"{MONITOR_DESC} changed to:\n```\n{data}\n```")
except Exception as e:
tg_msg(f"Got exception while running command of {MONITOR_DESC}: {str(e)}")
raise e

@ -0,0 +1,23 @@
[Unit]
Description={{ service_description }}
[Service]
Type=simple
ExecStart={{ script_path | quote }}
User={{ system_user }}
Group={{ system_user }}
UMask=007
PrivateTmp=yes
PrivateDevices=yes
ProtectHome=yes
ReadOnlyPaths=/
ReadWritePaths=-{{ data_path }}
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectControlGroups=true
RestrictRealtime=true
RestrictNamespaces=true
ProtectSystem=full

@ -0,0 +1,8 @@
[Unit]
Description=Timer of {{ service_description }}
[Timer]
OnCalendar={{ calendar_spec }}
[Install]
WantedBy=multi-user.target
Loading…
Cancel
Save