Mini Shell
#!/opt/cloudlinux/venv/bin/python3 -bb
# coding=utf-8
#
# Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2020 All Rights Reserved
#
# Licensed under CLOUD LINUX LICENSE AGREEMENT
# http://cloudlinux.com/docs/LICENCE.TXT
#
import contextlib
import logging
import fcntl
import os
import time
import requests
import subprocess
from clcommon import cpapi
from clcommon.utils import get_rhn_systemid_value
from wmt.common.url_parser import parse
from wmt.common.const import (
CLICKHOUSE_WMT_ENDPOINT,
UNKNOWN_RHN_ID,
SERVICE_BIN,
CHKCONFIG_BIN,
SYSTEMCTL_BIN
)
# logic copied from get_domains script, that is used by go
def get_domains():
domains = set()
if cpapi.CP_NAME == cpapi.PLESK_NAME:
users = [_cpinfo[0] for _cpinfo in cpapi.cpinfo(keyls=('cplogin',))]
else:
users = cpapi.cpusers()
if not users:
return domains
try:
suspended_users = cpapi.suspended_users_list()
except Exception:
logging.exception('Cannot obtain list of suspended users')
suspended_users = []
# dirty hack to reload domains in runtime
# TODO: replace with more suitable solution
if cpapi.CP_NAME == 'cPanel':
cpapi.plugins.cpanel._user_to_domains_map_cpanel = dict()
for user in users:
if user in suspended_users:
logging.warning('User: %s is will not be pinged, because account is suspended', user)
continue
for domain, _ in cpapi.userdomains(user):
domains.add(parse(domain))
return domains
def setup_logger(logger_name):
app_logger = logging.getLogger(logger_name)
app_logger.setLevel(logging.DEBUG)
try:
fh = logging.FileHandler('/var/log/cl_wmt.log')
except IOError:
pass
else:
fh.formatter = logging.Formatter('[%(levelname)s | %(asctime)s]: %(message)s')
app_logger.addHandler(fh)
return app_logger
@contextlib.contextmanager
def save_pid_and_lock(file: str, pid: str):
mode = 'w+' if not os.path.exists(file) else 'r+'
f = open(file, mode)
try:
fcntl.flock(f.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
except OSError:
raise OSError('Process %s already running!' % pid)
try:
f.write(pid)
f.flush()
os.fsync(f)
yield
finally:
fcntl.flock(f.fileno(), fcntl.LOCK_UN)
f.close()
os.remove(file)
def intersect(d1, d2):
result = {}
for key in d1:
if key in d2:
result[key] = d1[key], d2[key]
return result
def send_report(url, report):
error = requests.RequestException('Error while sending report to ClickHouse')
for i in range(5):
try:
response = requests.post(url, json=report, timeout=60)
response.raise_for_status()
except requests.RequestException as err:
error = err
time.sleep(4 ** i)
else:
break
else:
raise error
def send_report_to_clickhouse(report):
systemd_id = get_rhn_systemid_value('system_id') or UNKNOWN_RHN_ID
# ID-XXXXXXXX -> XXXXXXXX
report['server_id'] = systemd_id.replace('ID-', '')
summary = report.pop('summary_report')
send_report(CLICKHOUSE_WMT_ENDPOINT, {**report, **summary})
def enable_wmt_daemon(daemon_name, is_cl6):
"""
Enable cl_wmt_scanner service
"""
if is_cl6:
# CL6
# Start wmt service
subprocess.run('{} {} start >/dev/null 2>&1'.format(SERVICE_BIN, daemon_name),
shell=True, executable='/bin/bash', capture_output=True)
subprocess.run('{} --add {} >/dev/null 2>&1'.format(CHKCONFIG_BIN, daemon_name),
shell=True, executable='/bin/bash', capture_output=True)
else:
# CL7, CL8
subprocess.run('{} daemon-reload'.format(SYSTEMCTL_BIN),
shell=True, executable='/bin/bash', capture_output=True)
# Start wmt daemon
subprocess.run('{} enable {}'.format(SYSTEMCTL_BIN, daemon_name),
shell=True, executable='/bin/bash', capture_output=True)
subprocess.run('{} start {}'.format(SYSTEMCTL_BIN, daemon_name),
shell=True, executable='/bin/bash', capture_output=True)
def disable_wmt_daemon(daemon_name, is_cl6):
"""
Disable WMT daemon
:return:
"""
if is_cl6:
# CL6
subprocess.run('{} {} stop >/dev/null 2>&1'.format(SERVICE_BIN, daemon_name),
shell=True, executable='/bin/bash', capture_output=True)
subprocess.run('{} --del {} >/dev/null 2>&1'.format(CHKCONFIG_BIN, daemon_name),
shell=True, executable='/bin/bash', capture_output=True)
else:
# CL7, CL8
subprocess.run('{} kill {} >/dev/null 2>&1'.format(SYSTEMCTL_BIN, daemon_name),
shell=True, executable='/bin/bash', capture_output=True)
subprocess.run('{} disable {} >/dev/null 2>&1'.format(SYSTEMCTL_BIN, daemon_name),
shell=True, executable='/bin/bash', capture_output=True)
def manage_crons(status=True):
cron_tool = '/usr/share/web-monitoring-tool/cron_control.py'
if status:
command = [cron_tool, '-i']
else:
command = [cron_tool, '-d']
subprocess.run(command, capture_output=True, text=True)
Zerion Mini Shell 1.0