From 8ad92c13426f524aa071e1656bde942be4337ef4 Mon Sep 17 00:00:00 2001 From: Pavel Loginov Date: Fri, 20 Sep 2019 09:42:19 +0300 Subject: [PATCH] v3.4.8 Appeared ability edit not whole config. just separate sections Some new design Improved Options Bugs fixed --- README.md | 10 +- app/funct.py | 71 ++++++- app/login.py | 1 + app/ovw.py | 11 +- app/sections.py | 111 +++++++++++ app/sql.py | 6 +- app/templates/add.html | 30 +-- app/templates/ajax/config_show.html | 48 ++++- app/templates/ajax/new_option.html | 4 +- app/templates/ajax/overviewServers.html | 14 +- app/templates/ajax/show_compare_configs.html | 4 +- app/templates/base.html | 46 +++-- app/templates/config.html | 17 +- app/templates/configver.html | 2 +- app/templates/delver.html | 2 +- app/templates/ha.html | 4 +- app/templates/lists.html | 3 + app/templates/sections.html | 63 ++++++ app/templates/settings.html | 2 +- app/templates/update.html | 4 +- app/templates/viewstats.html | 8 +- inc/configshow.js | 4 + inc/images/ui-icons_555555_256x240.png | Bin 0 -> 3274 bytes inc/script.js | 195 +++++++++++++------ inc/style.css | 95 ++++++--- inc/users.js | 4 + 26 files changed, 589 insertions(+), 170 deletions(-) create mode 100644 app/sections.py create mode 100644 app/templates/sections.html create mode 100644 inc/images/ui-icons_555555_256x240.png diff --git a/README.md b/README.md index 908ebb0d..e9fd6d79 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Web interface(user-friendly web GUI, alerting, monitoring and secure) for managi # Donate Support the project -[![Donate](https://img.shields.io/badge/PayPal-Donate-brightgreen.svg)](https://www.paypal.me/haproxywi) or [Patreon](https://www.patreon.com/haproxy_wi/overview) +[![Donate](https://img.shields.io/badge/PayPal-Donate-brightgreen.svg)](https://www.paypal.me/loginovpavel) or [Patreon](https://www.patreon.com/haproxy_wi/overview) # Youtube [Demo video](https://www.youtube.com/channel/UCo0lCg24j-H4f0S9kMjp-_w) @@ -47,8 +47,14 @@ Support the project # Install ## RPM +Install repository^ +``` yum install https://repo.haproxy-wi.org/el7/haproxy-wi-release-7-1-0.noarch.rpm - +``` +After install HAProxy-WI: +``` +yum install haproxy-wi +``` ## Script The installer will ask you a few questions ``` diff --git a/app/funct.py b/app/funct.py index ec1a749d..21061619 100644 --- a/app/funct.py +++ b/app/funct.py @@ -234,6 +234,66 @@ def diff_config(oldcfg, cfg): print('
Can\'t read write change to log. %s
' % stderr) pass + +def get_sections(config): + record = False + return_config = list() + with open(config, 'r') as f: + for line in f: + if line.startswith('listen') or line.startswith('frontend') or line.startswith('backend') or line.startswith('cache') or line.startswith('defaults') or line.startswith('global'): + line = line.strip() + return_config.append(line) + + return return_config + + +def get_section_from_config(config, section): + record = False + start_line = "" + end_line = "" + return_config = "" + with open(config, 'r') as f: + for index, line in enumerate(f): + if line.startswith(section): + start_line = index + return_config += line + record = True + continue + if record: + + if line.startswith('listen') or line.startswith('frontend') or line.startswith('backend') or line.startswith('cache') or line.startswith('defaults') or line.startswith('global'): + record = False + end_line = index + end_line = end_line - 1 + else: + return_config += line + + return start_line, end_line, return_config + + +def rewrite_section(start_line, end_line, config, section): + record = False + start_line = int(start_line) + end_line = int(end_line) + return_config = "" + with open(config, 'r') as f: + for index, line in enumerate(f): + index = int(index) + if index == start_line: + record = True + return_config += section + continue + if index == end_line: + record = False + continue + if record: + continue + + return_config += line + + return return_config + + def install_haproxy(serv, **kwargs): import sql script = "install_haproxy.sh" @@ -484,15 +544,18 @@ def show_backends(serv, **kwargs): haproxy_sock_port = sql.get_setting('haproxy_sock_port') cmd='echo "show backend" |nc %s %s' % (serv, haproxy_sock_port) output, stderr = subprocess_execute(cmd) - ret = "" + if kwargs.get('ret'): + ret = list() + else: + ret = "" for line in output: if "#" in line or "stats" in line or "MASTER" in line: continue - if line != "": + if len(line) > 1: back = json.dumps(line).split("\"") if kwargs.get('ret'): - ret += back[1] - ret += "
" + ret.append(back[1]) + #ret += "," else: print(back[1], end="
") diff --git a/app/login.py b/app/login.py index 004007a9..3c1663e7 100644 --- a/app/login.py +++ b/app/login.py @@ -122,6 +122,7 @@ if form.getvalue('logout'): print("Set-cookie: uuid=; expires=Wed May 18 03:33:20 2003; path=/app/; httponly") print("Content-type: text/html\n") print('') + sys.exit() if login is not None and password is not None: diff --git a/app/ovw.py b/app/ovw.py index 974d5763..b2b2bb43 100644 --- a/app/ovw.py +++ b/app/ovw.py @@ -72,6 +72,11 @@ async def async_get_overviewServers(serv1, serv2, desc): cmd = 'echo "show info" |nc %s %s |grep -e "Ver\|CurrConns\|SessRate\|Maxco\|MB\|Uptime:"' % (serv2, haproxy_sock_port) out = funct.subprocess_execute(cmd) out1 = "" + hap_configs_dir = funct.get_config_var('configs', 'haproxy_save_configs_dir') + cfg = hap_configs_dir + serv2 + "-" + funct.get_data('config') + ".cfg" + funct.get_config(serv2, cfg) + backends = funct.get_sections(cfg) + os.system("/bin/rm -f " + cfg) for k in out: if "Ncat: Connection refused." not in k: @@ -80,7 +85,9 @@ async def async_get_overviewServers(serv1, serv2, desc): out1 += "
" else: out1 = "Can\'t connect to HAproxy" - server_status = (serv1,serv2, out1, funct.ssh_command(serv2, commands),funct.show_backends(serv2, ret=1), desc) + + # server_status = (serv1,serv2, out1, funct.ssh_command(serv2, commands),funct.show_backends(serv2, ret=1), desc) + server_status = (serv1,serv2, out1, funct.ssh_command(serv2, commands),backends, desc) return server_status async def get_runner_overviewServers(): @@ -114,7 +121,7 @@ def get_map(serv): cfg = hap_configs_dir + serv + "-" + date + ".cfg" print('
') - print("

Map from %s


" % serv) + print("

Map from %s


" % serv) G = nx.DiGraph() diff --git a/app/sections.py b/app/sections.py new file mode 100644 index 00000000..fa660523 --- /dev/null +++ b/app/sections.py @@ -0,0 +1,111 @@ +#!/usr/bin/env python3 +import cgi +import os +import http.cookies +import funct +import sql +from jinja2 import Environment, FileSystemLoader +env = Environment(loader=FileSystemLoader('templates/'), autoescape=True) +template = env.get_template('sections.html') + +print('Content-type: text/html\n') +funct.check_login() + +form = cgi.FieldStorage() +serv = form.getvalue('serv') +section = form.getvalue('section') +sections = "" +config_read = "" +cfg = "" +stderr = "" +error = "" +aftersave = "" +start_line = "" +end_line = "" + +try: + cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE")) + user_id = cookie.get('uuid') + user = sql.get_user_name_by_uuid(user_id.value) + servers = sql.get_dick_permit() + token = sql.get_token(user_id.value) + role = sql.get_user_role_by_uuid(user_id.value) +except: + pass + +hap_configs_dir = funct.get_config_var('configs', 'haproxy_save_configs_dir') + +if serv is not None and open is not None: + cfg = hap_configs_dir + serv + "-" + funct.get_data('config') + ".cfg" + error = funct.get_config(serv, cfg) + sections = funct.get_sections(cfg) + +if serv is not None and section is not None : + + try: + funct.logging(serv, "sections.py open config") + except: + pass + + start_line, end_line, config_read = funct.get_section_from_config(cfg, section) + + os.system("/bin/mv %s %s.old" % (cfg, cfg)) + +if serv is not None and form.getvalue('config') is not None: + try: + funct.logging(serv, "config.py edited config") + except: + pass + + config = form.getvalue('config') + oldcfg = form.getvalue('oldconfig') + save = form.getvalue('save') + start_line = form.getvalue('start_line') + end_line = form.getvalue('end_line') + aftersave = 1 + + config = funct.rewrite_section(start_line, end_line, oldcfg, config) + + try: + with open(cfg, "w") as conf: + conf.write(config) + except IOError: + error = "Can't read import config file" + + MASTERS = sql.is_master(serv) + for master in MASTERS: + if master[0] != None: + funct.upload_and_restart(master[0], cfg, just_save=save) + + stderr = funct.upload_and_restart(serv, cfg, just_save=save) + + funct.diff_config(oldcfg, cfg) + + #if save: + # c = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE")) + # c["restart"] = form.getvalue('serv') + # print(c) + + os.system("/bin/rm -f " + hap_configs_dir + "*.old") + + +template = template.render(h2 = 1, title = "Working with HAProxy configs", + role = role, + action = "sections.py", + user = user, + select_id = "serv", + serv = serv, + aftersave = aftersave, + config = config_read, + cfg = cfg, + selects = servers, + stderr = stderr, + error = error, + start_line = start_line, + end_line = end_line, + section = section, + sections = sections, + note = 1, + versions = funct.versions(), + token = token) +print(template) \ No newline at end of file diff --git a/app/sql.py b/app/sql.py index d7e1d336..7ebffe69 100644 --- a/app/sql.py +++ b/app/sql.py @@ -677,7 +677,7 @@ def select_options(**kwargs): def update_options(option, id): con, cur = create_db.get_cur() sql = """ update options set - `option` = '%s', + options = '%s' where id = '%s' """ % (option, id) try: cur.execute(sql) @@ -1483,9 +1483,9 @@ if form.getvalue('newtoption'): if form.getvalue('updateoption') is not None: option = form.getvalue('updateoption') - id = form.getvalue('optionid') + id = form.getvalue('id') print('Content-type: text/html\n') - if token is None or chanel is None or group is None: + if option is None or id is None: print(error_mess) else: update_options(option, id) diff --git a/app/templates/add.html b/app/templates/add.html index 5a78e43a..f1cd4430 100644 --- a/app/templates/add.html +++ b/app/templates/add.html @@ -16,7 +16,7 @@
- + -

Add listen

Add listen

Select server: @@ -28,7 +28,7 @@
Note: If you reconfigure Master server, Slave will reconfigured automatically
+ A "listen" section defines a complete proxy with its frontend and backend parts combined in one section. It is generally useful for TCP-only traffic.

All proxy names must be formed from upper and lower case letters, digits, @@ -242,7 +242,7 @@
- + - + {% endif %} {% set section.section = set.2 %} diff --git a/app/templates/update.html b/app/templates/update.html index 927c2f5f..fba10305 100644 --- a/app/templates/update.html +++ b/app/templates/update.html @@ -21,7 +21,7 @@ {% endif %}

Add frontend

Add frontend

Select server: @@ -254,7 +254,7 @@
Note: If you reconfigure Master server, Slave will reconfigured automatically
+ A "frontend" section describes a set of listening sockets accepting client connections.

All proxy names must be formed from upper and lower case letters, digits, @@ -387,7 +387,7 @@
- + - @@ -580,7 +580,7 @@

Add backend

Add backend

Select server: @@ -399,7 +399,7 @@
Note: If you reconfigure Master server, Slave will reconfigured automatically
+ A "backend" section describes a set of servers to which the proxy will connect to forward incoming connections.

All proxy names must be formed from upper and lower case letters, digits, @@ -427,11 +427,11 @@ - +
- + @@ -601,7 +601,7 @@
View certificatesView certificates Exist certificates
- + @@ -642,8 +642,8 @@ -
Upload SSL certificatesUpload SSL certificates Certificate name {{ option.0 }} - + + @@ -674,6 +674,9 @@
+
+ In this section you can create, edit and delete options with given parameters. And after use them as autocomplete in the "Add" sections +
{% if add %}
@@ -688,7 +691,8 @@
- +
+ - @@ -21,41 +20,27 @@ - - -
- HAproxy-WI - - - - - + HAproxy-WI
+
+ diff --git a/app/templates/config.html b/app/templates/config.html index e7cbc2fc..bb159e46 100644 --- a/app/templates/config.html +++ b/app/templates/config.html @@ -27,15 +27,14 @@ {% endif %} {% endfor %} - {% if role <= 2 %} - - {% endif %} {% if not keepalived %} - Show + Open Compare Map Stat - Verisons + {% if role <= 2 %} + Verisons + {% endif %} {% endif %}

@@ -53,10 +52,7 @@ {% if config %} {% if role <= 2 %}
- {% if note %} -
Note: If you reconfigure Master server, Slave will reconfigured automatically
- {% endif %} -

Config from {{ serv }}

+

Config from {{ serv }}

@@ -67,6 +63,9 @@

+ {% if note %} +
Note: If you reconfigure Master server, Slave will reconfigured automatically
+ {% endif %}
{% endif %} {% endif %} diff --git a/app/templates/configver.html b/app/templates/configver.html index ad5ffb78..2ea9ddde 100644 --- a/app/templates/configver.html +++ b/app/templates/configver.html @@ -33,7 +33,7 @@ {% endif %} {% if open %}
-

Choose old version

+

Choose old version


diff --git a/app/templates/ha.html b/app/templates/ha.html index 833f0907..98f4861c 100644 --- a/app/templates/ha.html +++ b/app/templates/ha.html @@ -2,7 +2,7 @@ {% block content %} - + @@ -48,7 +48,7 @@

Create new HA cluster

Create new HA cluster

Master Slave
- + diff --git a/app/templates/lists.html b/app/templates/lists.html index 23362bd9..bd876ce6 100644 --- a/app/templates/lists.html +++ b/app/templates/lists.html @@ -30,6 +30,9 @@

Or add VRRP to exist

Or add VRRP to exist

Master Slave

+
+ In this section you can create and edit black and white lists. And after use them in the HAProxy configs +

{{ set.2 }} section

{{ set.2 }} section

-
+
Note: For update you have to use HAProxy-WI repository. If do not use repositiry then use update.sh script in HAProxy-WI home directory

@@ -30,6 +30,6 @@
Read more about update in docs and changelog -
+
{% endblock %} \ No newline at end of file diff --git a/app/templates/viewstats.html b/app/templates/viewstats.html index c5f37856..1fc93938 100644 --- a/app/templates/viewstats.html +++ b/app/templates/viewstats.html @@ -18,7 +18,7 @@
Please choose a server -
+