finished /reboot host and /restart host functions, added authorization for actions by telegram ID, added nginx to default services
This commit is contained in:
parent
0afffee697
commit
e68739966a
2 changed files with 58 additions and 26 deletions
2
.authorized_users
Normal file
2
.authorized_users
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
AUTHORIZED_USER_ID_1
|
||||||
|
AUTHORIZED_USER_ID_2
|
||||||
|
|
@ -5,20 +5,27 @@
|
||||||
import subprocess
|
import subprocess
|
||||||
import threading
|
import threading
|
||||||
from time import sleep
|
from time import sleep
|
||||||
import telebot
|
from telebot import *
|
||||||
|
|
||||||
|
|
||||||
#define the variables
|
#define the variables
|
||||||
status, hostname, uptime, zerotier, prosody, postgres, tailscale, disk, ping = 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown'
|
status, hostname, uptime, zerotier, prosody, postgres, tailscale, nginx, disk, ping = 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown'
|
||||||
nodes, hostnames, reach, threads = [], [], [], []
|
nodes, hostnames, reach, threads = [], [], [], []
|
||||||
|
|
||||||
#change this to your hostname
|
#change this to your instance's hostname
|
||||||
host = 'lainlounge'
|
host = subprocess.check_output(['hostname']).decode().strip()
|
||||||
|
#print ('host:', host) # debug
|
||||||
|
|
||||||
#load the token
|
#load the token
|
||||||
token = open('.env', 'r').read().strip()
|
token = open('.env', 'r').read().strip()
|
||||||
|
|
||||||
|
#load the authorized users
|
||||||
|
authorized_users = [line.strip() for line in open('.authorized_users', 'r').readlines()]
|
||||||
|
#print('authorized users:', authorized_users) # debug
|
||||||
|
|
||||||
#bot init
|
#bot init
|
||||||
bot = telebot.TeleBot(token)
|
bot = telebot.TeleBot(token)
|
||||||
|
updater = bot.update_listener
|
||||||
|
|
||||||
#get system info
|
#get system info
|
||||||
def getinfo():
|
def getinfo():
|
||||||
|
|
@ -30,12 +37,13 @@ def getinfo():
|
||||||
prosody = subprocess.Popen("sudo systemctl status prosody | grep 'Active'", shell=True, stdout=subprocess.PIPE).stdout.read().decode().strip()
|
prosody = subprocess.Popen("sudo systemctl status prosody | grep 'Active'", shell=True, stdout=subprocess.PIPE).stdout.read().decode().strip()
|
||||||
postgres = subprocess.Popen("sudo systemctl status postgresql | grep 'Active'", shell=True, stdout=subprocess.PIPE).stdout.read().decode().strip()
|
postgres = subprocess.Popen("sudo systemctl status postgresql | grep 'Active'", shell=True, stdout=subprocess.PIPE).stdout.read().decode().strip()
|
||||||
tailscale = subprocess.Popen("sudo systemctl status tailscaled | grep 'Active'", shell=True, stdout=subprocess.PIPE).stdout.read().decode().strip()
|
tailscale = subprocess.Popen("sudo systemctl status tailscaled | grep 'Active'", shell=True, stdout=subprocess.PIPE).stdout.read().decode().strip()
|
||||||
|
nginx = subprocess.Popen("sudo systemctl status nginx | grep 'Active'", shell=True, stdout=subprocess.PIPE).stdout.read().decode().strip()
|
||||||
disk = subprocess.check_output(['df', '-h']).decode().strip()
|
disk = subprocess.check_output(['df', '-h']).decode().strip()
|
||||||
if hostname == 'unknown':
|
if hostname == 'unknown':
|
||||||
status = 'offline'
|
status = 'offline'
|
||||||
else:
|
else:
|
||||||
status = 'online'
|
status = 'online'
|
||||||
return hostname, uptime, zerotier, prosody, postgres, tailscale, disk
|
return hostname, uptime, zerotier, prosody, postgres, tailscale, nginx, disk
|
||||||
|
|
||||||
#function to ping tailscale nodes
|
#function to ping tailscale nodes
|
||||||
def ping_node(node, hostname):
|
def ping_node(node, hostname):
|
||||||
|
|
@ -64,27 +72,43 @@ def check_tailscale():
|
||||||
|
|
||||||
#restart services
|
#restart services
|
||||||
def restart_service(service):
|
def restart_service(service):
|
||||||
|
print(f'restarting {service}...')
|
||||||
subprocess.Popen(f'sudo systemctl restart {service}', shell=True, stdout=subprocess.PIPE).stdout.read().decode().strip()
|
subprocess.Popen(f'sudo systemctl restart {service}', shell=True, stdout=subprocess.PIPE).stdout.read().decode().strip()
|
||||||
sleep(3)
|
sleep(3)
|
||||||
service_status = subprocess.Popen(f'sudo systemctl status {service} | grep "Active"', shell=True, stdout=subprocess.PIPE).stdout.read().decode().strip()
|
service_status = subprocess.Popen(f'sudo systemctl status {service} | grep "Active"', shell=True, stdout=subprocess.PIPE).stdout.read().decode().strip()
|
||||||
message = f'{service} restarted! status: {service_status}'
|
status_message = f'{service} restarted! status: {service_status}'
|
||||||
|
return status_message
|
||||||
|
|
||||||
#restart services menu
|
#restart services menu
|
||||||
def restart_menu():
|
def restart_menu():
|
||||||
keyboard = telebot.types.ReplyKeyboardMarkup(resize_keyboard=True)
|
keyboard = [
|
||||||
zerotier_button = telebot.types.KeyboardButton('zerotier-one', callback_data='zerotier')
|
[telebot.types.InlineKeyboardButton('zerotier-one', callback_data='zerotier-one')],
|
||||||
prosody_button = telebot.types.KeyboardButton('prosody', callback_data='prosody')
|
[telebot.types.InlineKeyboardButton('prosody', callback_data='prosody')],
|
||||||
postgres_button = telebot.types.KeyboardButton('postgresql', callback_data='postgresql')
|
[telebot.types.InlineKeyboardButton('postgresql', callback_data='postgresql')],
|
||||||
tailscale_button = telebot.types.KeyboardButton('tailscaled', callback_data='tailscaled')
|
[telebot.types.InlineKeyboardButton('tailscaled', callback_data='tailscaled')],
|
||||||
|
[telebot.types.InlineKeyboardButton('nginx', callback_data='nginx')],
|
||||||
|
[telebot.types.InlineKeyboardButton('cancel', callback_data='cancel')]
|
||||||
|
]
|
||||||
|
reply_markup = telebot.types.InlineKeyboardMarkup(keyboard)
|
||||||
|
return reply_markup
|
||||||
|
|
||||||
return keyboard
|
#callback query handler
|
||||||
|
@bot.callback_query_handler(func=lambda call: True)
|
||||||
|
def callback_query(call):
|
||||||
|
service = call.data
|
||||||
|
if service != 'cancel':
|
||||||
|
status_message = restart_service(service)
|
||||||
|
bot.send_message(call.message.chat.id, status_message)
|
||||||
|
else:
|
||||||
|
bot.edit_message_reply_markup(call.message.chat.id, call.message.message_id, reply_markup=None)
|
||||||
|
bot.send_message(call.message.chat.id, 'canceled')
|
||||||
|
|
||||||
def reboot():
|
def reboot():
|
||||||
subprocess.Popen('sudo reboot', shell=True, stdout=subprocess.PIPE).stdout.read().decode().strip()
|
subprocess.Popen('sudo reboot', shell=True, stdout=subprocess.PIPE).stdout.read().decode().strip()
|
||||||
|
|
||||||
#debug handler
|
#debug handler
|
||||||
def check():
|
def check():
|
||||||
global status, hostname, uptime, zerotier, prosody, postgres, tailscale, disk
|
global status, hostname, uptime, zerotier, prosody, postgres, tailscale, nginx, disk
|
||||||
getinfo()
|
getinfo()
|
||||||
print('system status:', status)
|
print('system status:', status)
|
||||||
print('hostname:', hostname)
|
print('hostname:', hostname)
|
||||||
|
|
@ -94,7 +118,7 @@ def check():
|
||||||
print('postgres:', postgres)
|
print('postgres:', postgres)
|
||||||
print('tailscale:', tailscale)
|
print('tailscale:', tailscale)
|
||||||
print('disk:', disk)
|
print('disk:', disk)
|
||||||
return status, hostname, uptime, zerotier, prosody, postgres, tailscale, disk
|
return status, hostname, uptime, zerotier, prosody, postgres, tailscale, nginx, disk
|
||||||
|
|
||||||
#message handling
|
#message handling
|
||||||
@bot.message_handler(commands=['start', 'help', 'status', 'restart', 'reboot', 'ping'])
|
@bot.message_handler(commands=['start', 'help', 'status', 'restart', 'reboot', 'ping'])
|
||||||
|
|
@ -102,26 +126,32 @@ def handle(message):
|
||||||
if message.text == '/start':
|
if message.text == '/start':
|
||||||
bot.reply_to(message, 'lainmonitor v1.0 --- standing by...')
|
bot.reply_to(message, 'lainmonitor v1.0 --- standing by...')
|
||||||
elif message.text == '/help':
|
elif message.text == '/help':
|
||||||
bot.reply_to(message, 'commands: /start, /help, /status, /reboot, /ping')
|
bot.reply_to(message, 'commands: /start, /help, /status, /restart, /reboot, /ping')
|
||||||
elif message.text == '/status':
|
elif message.text == '/status':
|
||||||
check()
|
check()
|
||||||
status_message = f'hostname: {hostname}\nsystem status: {status}\nuptime: {uptime}\nzerotier: {zerotier}\nprosody: {prosody}\npostgres: {postgres}\ntailscale: {tailscale}'
|
status_message = f'hostname: {hostname}\nsystem status: {status}\nuptime: {uptime}\nzerotier: {zerotier}\nprosody: {prosody}\npostgres: {postgres}\ntailscale: {tailscale}\nnginx: {nginx}'
|
||||||
bot.reply_to(message, status_message)
|
bot.reply_to(message, status_message)
|
||||||
bot.reply_to(message, f'filesystem info for {hostname}: \n\n{disk}')
|
bot.reply_to(message, f'filesystem info for {hostname}: \n\n{disk}')
|
||||||
elif message.text == f'/restart {host}':
|
elif message.text == f'/restart {host}':
|
||||||
if host == hostname:
|
if message.text == f'/restart {host}' and str(message.from_user.id) in authorized_users:
|
||||||
bot.send_message(message.chat.id, 'select a service to restart:', reply_markup=restart_menu())
|
bot.send_message(message.chat.id, 'select a service to restart:', reply_markup=restart_menu())
|
||||||
else:
|
else:
|
||||||
pass
|
bot.reply_to(message, 'you are not authorized to restart services on this host')
|
||||||
elif message.text == f'/reboot {hostname}':
|
elif message.text == f'/reboot {host}':
|
||||||
bot.reply_to(message, f'rebooting {host}...')
|
if message.text == f'/reboot {host}' and str(message.from_user.id) in authorized_users:
|
||||||
reboot()
|
bot.reply_to(message, f'rebooting {host}...')
|
||||||
|
reboot()
|
||||||
|
else:
|
||||||
|
bot.reply_to(message, 'you are not authorized to reboot this host')
|
||||||
elif message.text == '/ping':
|
elif message.text == '/ping':
|
||||||
check_tailscale()
|
if message.text == f'/restart {host}' and str(message.from_user.id) in authorized_users:
|
||||||
ping_status = '\n'.join(reach)
|
check_tailscale()
|
||||||
bot.reply_to(message, f'ping status:\n\n{ping_status}')
|
ping_status = '\n'.join(reach)
|
||||||
ping_status = ''
|
bot.reply_to(message, f'ping status:\n\n{ping_status}')
|
||||||
reach.clear()
|
ping_status = ''
|
||||||
|
reach.clear()
|
||||||
|
else:
|
||||||
|
bot.reply_to(message, 'you are not authorized to view ping status')
|
||||||
|
|
||||||
#polling
|
#polling
|
||||||
bot.polling()
|
bot.polling()
|
||||||
Loading…
Add table
Reference in a new issue