diff --git a/cgi-bin/config.py b/cgi-bin/config.py new file mode 100644 index 00000000..e1f319e8 --- /dev/null +++ b/cgi-bin/config.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 +import html +import cgi +import listserv as listhap +import os +import http.cookies +import configparser +import funct +import paramiko +from paramiko import SSHClient +from datetime import datetime +from pytz import timezone + +form = cgi.FieldStorage() +serv = form.getvalue('serv') +servNew = form.getvalue('serNew') +cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE")) +login = cookie.get('login') + +funct.head("Edit HAproxy config") +funct.check_config() + +path_config = "haproxy-webintarface.config" +config = configparser.ConfigParser() +config.read(path_config) + +fullpath = config.get('main', 'fullpath') +hap_configs_dir = config.get('configs', 'haproxy_save_configs_dir') + +if login is None: + print('') + +if serv is not None: + fmt = "%Y-%m-%d.%H:%M:%S" + now_utc = datetime.now(timezone('Asia/Almaty')) + cfg = hap_configs_dir + serv + "-" + now_utc.strftime(fmt) + ".cfg" + +funct.chooseServer("config.py#conf", "Edit HAproxy config", "y") + +if form.getvalue('serv') is not None and form.getvalue('open') is not None : + funct.logging(serv, "config.py open config") + funct.get_config(serv, cfg) + + conf = open(cfg, "r") + print('') + print("

Config from %s

" % serv) + print('
') + print('' % serv) + print('' % cfg) + print('' % conf.read()) + print('

') + print('

UP

') + conf.close + + os.system("/bin/sudo /bin/mv %s %s.old" % (cfg, cfg)) + +if form.getvalue('serv') is not None and form.getvalue('config') is not None : + funct.logging(serv, "config.py edited config and restarted service") + config = form.getvalue('config') + oldcfg = form.getvalue('oldconfig') + + try: + with open(cfg, "a") as conf: + conf.write(config) + except IOError: + print("Can't read import config file") + + print("New config was saved as: %s

" % cfg) + + funct.upload_and_restart(serv, cfg) + + os.system("/bin/diff -ub %s %s >> %slog/config_edit.log" % (oldcfg, cfg, fullpath)) + os.system("/bin/sudo /bin/rm -f " + hap_configs_dir + "*.old") + + print('
Go to view stats
') + +funct.footer() \ No newline at end of file diff --git a/cgi-bin/configshow.py b/cgi-bin/configshow.py new file mode 100644 index 00000000..8c2f3b22 --- /dev/null +++ b/cgi-bin/configshow.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +import html +import cgi +import os +import funct +import paramiko +import configparser +from paramiko import SSHClient +from datetime import datetime +from pytz import timezone + +form = cgi.FieldStorage() +serv = form.getvalue('serv') +servNew = form.getvalue('serNew') + +funct.head("Show HAproxy config") +funct.check_config() + +path_config = "haproxy-webintarface.config" +config = configparser.ConfigParser() +config.read(path_config) + +ssh_keys = config.get('ssh', 'ssh_keys') +ssh_user_name = config.get('ssh', 'ssh_user_name') +hap_configs_dir = config.get('configs', 'haproxy_save_configs_dir') +haproxy_config_path = config.get('haproxy', 'haproxy_config_path') + +if serv is not None: + fmt = "%Y-%m-%d.%H:%M:%S" + now_utc = datetime.now(timezone('Asia/Almaty')) + cfg = hap_configs_dir + serv + "-" + now_utc.strftime(fmt) + ".cfg" + +funct.chooseServer("configshow.py#conf", "Show HAproxy config", "n") + +if form.getvalue('serv') is not None and form.getvalue('open') is not None : + funct.get_config(serv, cfg) + + conf = open(cfg, "r") + print('') + print("

Config from %s

" % serv) + print('' % conf.read()) + print('

UP

') + conf.close + + os.system("/bin/sudo /bin/rm -f " + cfg) + +funct.footer() \ No newline at end of file diff --git a/cgi-bin/configver.py b/cgi-bin/configver.py new file mode 100644 index 00000000..300a12cf --- /dev/null +++ b/cgi-bin/configver.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python3 +import html +import cgi +import subprocess +import os +import http.cookies +import funct +import paramiko +import configparser +from paramiko import SSHClient +from datetime import datetime +from pytz import timezone + +form = cgi.FieldStorage() +serv = form.getvalue('serv') +configver = form.getvalue('configver') +cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE")) +login = cookie.get('login') + +funct.head("Old Versions HAproxy config") +funct.check_config() + +path_config = "haproxy-webintarface.config" +config = configparser.ConfigParser() +config.read(path_config) + +hap_configs_dir = config.get('configs', 'haproxy_save_configs_dir') + +if login is None: + print('') + +funct.chooseServer("configver.py#conf", "Old Versions HAproxy config", "y") + +if serv is not None and form.getvalue('open') is not None: + + print('

Choose old version

') + print('
') + print('

') + print('' % serv) + print('') + print('

') + + Select = form.getvalue('Select') + + if Select is not None: + + configver = form.getvalue('configver') + funct.logging(serv, "open old config %s" % configver) + + conf = open(configver, "r") + print("

Config from %s, and version is: %s

" % (serv, configver)) + print('
') + print('' % serv) + print('' % configver) + print('') + print('' % conf.read()) + print('

') + print('

UP

') + conf.close + +if form.getvalue('serv') is not None and form.getvalue('config') is not None: + configver = form.getvalue('configver') + configver = hap_configs_dir + configver + + funct.logging(serv, "configver.py upload old config %s" % configver) + + print("Uploaded old config ver: %s

" % configver) + + funct.upload_and_restart(serv, configver) + + print('
Go to view stats
') diff --git a/cgi-bin/diff.py b/cgi-bin/diff.py new file mode 100644 index 00000000..c18345c8 --- /dev/null +++ b/cgi-bin/diff.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 +import html +import cgi +import listserv as listhap +import subprocess +import os +import funct +import glob +import paramiko +import configparser +from paramiko import SSHClient + +form = cgi.FieldStorage() +serv = form.getvalue('serv') +left = form.getvalue('left') +right = form.getvalue('right') + +funct.head("Compare HAproxy configs") +funct.check_config() + +path_config = "haproxy-webintarface.config" +config = configparser.ConfigParser() +config.read(path_config) + +ssh_keys = config.get('ssh', 'ssh_keys') +ssh_user_name = config.get('ssh', 'ssh_user_name') +haproxy_configs_server = config.get('configs', 'haproxy_configs_server') +hap_configs_dir = config.get('configs', 'haproxy_save_configs_dir') + +funct.chooseServer("diff.py#diff", "Compare HAproxy configs", "n") + +if form.getvalue('serv') is not None and form.getvalue('open') is not None : + + print('
') + print('

Choose leftChoose right

') + + print('

') + + print('') + print('' % serv) + print('') + print('

') + +if form.getvalue('serv') is not None and form.getvalue('right') is not None: + commands = [ 'diff -ub %s%s %s%s' % (hap_configs_dir, left, hap_configs_dir, right) ] + + funct.ssh_command(haproxy_configs_server, commands) + + print('

UP

') + +funct.footer() \ No newline at end of file diff --git a/cgi-bin/edit.py b/cgi-bin/edit.py new file mode 100644 index 00000000..f1db9b4c --- /dev/null +++ b/cgi-bin/edit.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python3 +import html +import cgi +import listserv as listhap +import subprocess +import os +import http.cookies +import funct +from funct import head as head + +form = cgi.FieldStorage() +serv = form.getvalue('serv') +cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE")) +login = cookie.get('login') + +head("Edit & show HAproxy settings") + +if login is None: + print('') + + +print('

Edit & show HAproxy settings

') +print('

Choose server & action: Disable/Enable server or output any information about the server:

') +print('
') +print('

') +print('') +print('') +print('

') + +if form.getvalue('servaction') is not None: + action = form.getvalue('servaction') + backend = form.getvalue('servbackend') + + if action == '1': + enable = 'disable server' + elif action == '2': + enable = 'enable server' + elif action == '3': + enable = 'show' + + cmd='echo "%s %s" |nc %s 1999' % (enable, backend, serv) + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, universal_newlines=True) + stdout, stderr = p.communicate() + output = stdout.splitlines() + + print('

You %s %s on HAproxy %s. Look it or Edit something else' % (enable, backend, serv, serv)) + print('

') + + print('\n

'.join(map(str, output))) + + action = 'edit.py ' + enable + ' ' + backend + funct.logging(serv, action) + +funct.footer() \ No newline at end of file diff --git a/cgi-bin/funct.py b/cgi-bin/funct.py new file mode 100644 index 00000000..5a07e3bc --- /dev/null +++ b/cgi-bin/funct.py @@ -0,0 +1,164 @@ +import cgi +import os +import paramiko +import http.cookies +from paramiko import SSHClient +import listserv as listhap +from datetime import datetime +from pytz import timezone +import configparser + +def check_config(): + path_config = "haproxy-webintarface.config" + config = configparser.ConfigParser() + config.read(path_config) + + + for section in [ 'main', 'configs', 'ssh', 'logs', 'haproxy' ]: + if not config.has_section(section): + print('Check config file, no %s section' % section) + + +path_config = "haproxy-webintarface.config" +config = configparser.ConfigParser() +config.read(path_config) + +fullpath = config.get('main', 'fullpath') +ssh_keys = config.get('ssh', 'ssh_keys') +ssh_user_name = config.get('ssh', 'ssh_user_name') +haproxy_configs_server = config.get('configs', 'haproxy_configs_server') +hap_configs_dir = config.get('configs', 'haproxy_save_configs_dir') +haproxy_config_path = config.get('haproxy', 'haproxy_config_path') +restart_command = config.get('haproxy', 'restart_command') + +def logging(serv, action): + dateFormat = "%b %d %H:%M:%S" + now_utc = datetime.now(timezone('Asia/Almaty')) + IP = cgi.escape(os.environ["REMOTE_ADDR"]) + cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE")) + firstName = cookie.get('FirstName') + lastName = cookie.get('LastName') + mess = now_utc.strftime(dateFormat) + " from " + IP + " user: " + firstName.value + " " + lastName.value + " " + action + " for: " + serv + "\n" + log = open(fullpath + "log/config_edit.log", "a") + log.write(mess) + log.close + +def head(title): + print("Content-type: text/html\n") + print('%s' % title) + print('') + print('') + print('') + print('

') + +def footer(): + print('
') + +def get_config(serv, cfg): + os.chdir(hap_configs_dir) + + ssh = SSHClient() + ssh.load_system_host_keys() + k = paramiko.RSAKey.from_private_key_file(ssh_keys) + ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + ssh.connect(hostname = serv, username = ssh_user_name, pkey = k ) + sftp = ssh.open_sftp() + sftp.get(haproxy_config_path, cfg) + sftp.close() + ssh.close() + +def upload_and_restart(serv, cfg): + ssh = SSHClient() + ssh.load_system_host_keys() + k = paramiko.RSAKey.from_private_key_file(ssh_keys) + ssh = paramiko.SSHClient() + ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + print("connecting
") + ssh.connect( hostname = serv, username = ssh_user_name, pkey = k ) + print("connected
") + sftp = ssh.open_sftp() + sftp.put(cfg, haproxy_config_path) + sftp.close() + commands = [ "service haproxy restart" ] + for command in commands: + print("
Executing: {}".format( command )) + print("
") + stdin , stdout, stderr = ssh.exec_command(command) + print(stdout.read().decode(encoding='UTF-8')) + print("
Errors:") + print(stderr.read().decode(encoding='UTF-8')) + print("
") + ssh.close() + +def ssh_command(serv, commands): + ssh = SSHClient() + ssh.load_system_host_keys() + k = paramiko.RSAKey.from_private_key_file(ssh_keys) + ssh = paramiko.SSHClient() + ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + ssh.connect( hostname = serv, username = ssh_user_name, pkey = k ) + for command in commands: + stdin , stdout, stderr = ssh.exec_command(command) + print('
')
+		print(stdout.read().decode(encoding='UTF-8'))
+		print('
') + ssh.close() + +def chooseServer(formName, title, note): + print('

' + title + '

') + print('

Choose server

') + print('
') + print('

') + print('

') + if note == "y": + print('

Note: If you reconfigure First server, second will reconfigured automatically


') + +def choose_server_with_vip(serv): + import listserv as listhap + listhap.listhap = merge_two_dicts(listhap.listhap, listhap.list_hap_vip) + for i in sorted(listhap.listhap): + if listhap.listhap.get(i) == serv: + selected = 'selected' + else: + selected = '' + print('' % (listhap.listhap.get(i), selected, i)) + +def merge_two_dicts(x, y): + z = x.copy() + z.update(y) + return z diff --git a/cgi-bin/listserv.py b/cgi-bin/listserv.py new file mode 100644 index 00000000..b88c2c07 --- /dev/null +++ b/cgi-bin/listserv.py @@ -0,0 +1,10 @@ +listhap= { + 'kz-webhap01': '172.28.9.159', + 'kz-webhap02': '172.28.9.160', + 'kz-mysqlhap01': '172.28.5.6', + 'kz-mysqlhap02': '172.28.5.5', + } +list_hap_vip = { + 'kz-webhap-vip': '172.28.9.161', + 'kz-mysqlhap-vip': '172.28.5.17' + } diff --git a/cgi-bin/login.py b/cgi-bin/login.py new file mode 100644 index 00000000..52c80c65 --- /dev/null +++ b/cgi-bin/login.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 +import cgi +import html +import os +import funct +import http.cookies +import json + +cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE")) +form = cgi.FieldStorage() +ref = form.getvalue('ref') +login = form.getvalue('login') +password = form.getvalue('pass') +USERS = 'cgi-bin/users' + +try: + with open(USERS, "r") as user: + pass +except IOError: + print("Can't load users DB") + +def login_page(error): + if error == "error": + printError = "Somthing wrong :( I'm sad about this, but try again!

" + else: + printError = "First you need to login.

" + + funct.head("Login page") + + print('
') + print(printError) + print(' ') + print(' ') + print('' % ref) + print('') + print('
') + +if login is None: + login_page("n") + +if login is not None and password is not None: + for f in open(USERS, 'r'): + users = json.loads(f) + if login in users['login'] and password == users['password']: + print("Set-cookie: login=%s; expires=Wed May 18 03:33:20 2033; path=/cgi-bin/; httponly" % login) + print("Set-cookie: FirstName=%s; expires=Wed May 18 03:33:20 2033; path=/cgi-bin/; httponly" % users['firstName']) + print("Set-cookie: LastName=%s; expires=Wed May 18 03:33:20 2033; path=/cgi-bin/; httponly" % users['lastName']) + if ref is None: + ref = "index.html" + print("Content-type: text/html\n") + print('Redirecting') + print('') + print('' % ref) + else: + login_page("error") + break + +funct.footer() + + + diff --git a/cgi-bin/logs.py b/cgi-bin/logs.py new file mode 100644 index 00000000..f60f5be9 --- /dev/null +++ b/cgi-bin/logs.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 +import html +import cgi +import listserv as listhap +import subprocess +import os +import funct +import configparser + +form = cgi.FieldStorage() +serv = form.getvalue('serv') + +funct.head("HAproxy Logs") +funct.check_config() + +path_config = "haproxy-webintarface.config" +config = configparser.ConfigParser() +config.read(path_config) + +print('

HAproxy Logs

') +print('

Choose server & number rows

') +print('
') +print('

') + +if form.getvalue('serv') is not None: + rows = 'value='+form.getvalue('rows') +else: + rows = 'value=10' + +if form.getvalue('grep') is not None: + grep = 'value='+form.getvalue('grep') +else: + grep = 'value=' + +print('' % rows) +print('|grep') +print('' % grep) +print('

') + +if form.getvalue('serv') is not None: + rows = form.getvalue('rows') + grep = form.getvalue('grep') + + if grep is not None: + grep_act = '|grep' + else: + grep_act = '' + grep = '' + + syslog_server_enable = config.get('logs', 'syslog_server_enable') + if syslog_server_enable is None or syslog_server_enable == "disable": + local_path_logs = config.get('logs', 'local_path_logs') + syslog_server = serv + commands = [ 'sudo tail -%s %s %s %s' % (rows, local_path_logs, grep_act, grep) ] + else: + commands = [ 'sudo tail -%s /var/log/%s/syslog.log %s %s' % (rows, serv, grep_act, grep) ] + syslog_server = config.get('logs', 'syslog_server') + + funct.ssh_command(syslog_server, commands) + + print('

UP

') + +funct.footer() \ No newline at end of file diff --git a/cgi-bin/users b/cgi-bin/users new file mode 100644 index 00000000..c42529ed --- /dev/null +++ b/cgi-bin/users @@ -0,0 +1 @@ +{ "firstName": "admin", "lastName": "admin", "login": "admin", "password": "admin" } diff --git a/cgi-bin/viewsttats.py b/cgi-bin/viewsttats.py new file mode 100644 index 00000000..89446a28 --- /dev/null +++ b/cgi-bin/viewsttats.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +import html +import cgi +import requests +import funct +import listserv as listhap +import configparser +from requests_toolbelt.utils import dump + +funct.check_config() + +path_config = "haproxy-webintarface.config" +config = configparser.ConfigParser() +config.read(path_config) +haproxy_user = config.get('haproxy', 'user') +haproxy_pass = config.get('haproxy', 'password') +stats_port = config.get('haproxy', 'stats_port') + +listhap.listhap = funct.merge_two_dicts(listhap.listhap, listhap.list_hap_vip) + +form = cgi.FieldStorage() +serv = form.getvalue('serv') + +if serv is None: + serv = '172.28.9.161' + +try: + response = requests.get('http://%s:%s/stats' % (serv, stats_port), auth=(haproxy_user, haproxy_pass)) +except requests.exceptions.ConnectTimeout: + print('Oops. Connection timeout occured!') +except requests.exceptions.ReadTimeout: + print('Oops. Read timeout occured') + +print("Content-type: text/html\n") + +for i in listhap.listhap: + if listhap.listhap.get(i) == serv: + servname = i + +print('

Curent server IP - %s, name - %s


' % (serv, servname)) +print('Home Page

') + +print('

Choose server!


') +print('
') +print('

') + +data = dump.dump_all(response) +print('') +print(data.decode('utf-8')) +