mirror of https://github.com/Aidaho12/haproxy-wi
parent
6b955bf099
commit
36c843bfbe
|
@ -93,11 +93,11 @@ if serv is not None and form.getvalue('config') is not None:
|
|||
print("error: Cannot read import config file")
|
||||
|
||||
if service == 'keepalived':
|
||||
stderr = funct.upload_and_restart(serv, cfg, just_save=save, keepalived=1)
|
||||
stderr = funct.upload_and_restart(serv, cfg, just_save=save, keepalived=1, oldcfg=oldcfg)
|
||||
elif service == 'nginx':
|
||||
stderr = funct.master_slave_upload_and_restart(serv, cfg, just_save=save, nginx=1)
|
||||
stderr = funct.master_slave_upload_and_restart(serv, cfg, just_save=save, nginx=1, oldcfg=oldcfg)
|
||||
else:
|
||||
stderr = funct.master_slave_upload_and_restart(serv, cfg, just_save=save)
|
||||
stderr = funct.master_slave_upload_and_restart(serv, cfg, just_save=save, oldcfg=oldcfg)
|
||||
|
||||
funct.diff_config(oldcfg, cfg)
|
||||
|
||||
|
|
|
@ -806,7 +806,7 @@ def update_db_v_5_3_0(**kwargs):
|
|||
|
||||
|
||||
def update_ver():
|
||||
query = Version.update(version='5.3.0.0')
|
||||
query = Version.update(version='5.3.1.0')
|
||||
try:
|
||||
query.execute()
|
||||
except:
|
||||
|
|
|
@ -438,9 +438,23 @@ class ActionHistory(BaseModel):
|
|||
primary_key = False
|
||||
|
||||
|
||||
class ConfigVersion(BaseModel):
|
||||
id = AutoField()
|
||||
server_id = IntegerField()
|
||||
user_id = IntegerField()
|
||||
service = CharField()
|
||||
local_path = CharField()
|
||||
remote_path = CharField()
|
||||
diff = TextField()
|
||||
message = CharField(null=True)
|
||||
date = DateTimeField(default=datetime.now)
|
||||
|
||||
class Meta:
|
||||
table_name = 'config_versions'
|
||||
|
||||
def create_tables():
|
||||
with conn:
|
||||
conn.create_tables([User, Server, Role, Telegram, Slack, UUID, Token, ApiToken, Groups, UserGroups,
|
||||
conn.create_tables([User, Server, Role, Telegram, Slack, UUID, Token, ApiToken, Groups, UserGroups, ConfigVersion,
|
||||
Setting, Cred, Backup, Metrics, WafMetrics, Version, Option, SavedServer, Waf, ActionHistory,
|
||||
PortScannerSettings, PortScannerPorts, PortScannerHistory, ProvidersCreds, ServiceSetting,
|
||||
ProvisionedServers, MetricsHttpStatus, SMON, WafRules, Alerts, GeoipCodes, NginxMetrics])
|
||||
|
|
44
app/funct.py
44
app/funct.py
|
@ -294,6 +294,18 @@ def check_login(**kwargs):
|
|||
return False
|
||||
|
||||
|
||||
def get_user_id():
|
||||
import sql
|
||||
import http.cookies
|
||||
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
|
||||
user_uuid = cookie.get('uuid')
|
||||
|
||||
if user_uuid is not None:
|
||||
user_id = sql.get_user_id_by_uuid(user_uuid.value)
|
||||
|
||||
return user_id
|
||||
|
||||
|
||||
def is_admin(**kwargs):
|
||||
import sql
|
||||
import http.cookies
|
||||
|
@ -425,7 +437,7 @@ def get_config(server_ip, cfg, **kwargs):
|
|||
return
|
||||
|
||||
|
||||
def diff_config(oldcfg, cfg):
|
||||
def diff_config(oldcfg, cfg, **kwargs):
|
||||
import http.cookies
|
||||
import sql
|
||||
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
|
||||
|
@ -443,8 +455,14 @@ def diff_config(oldcfg, cfg):
|
|||
|
||||
output, stderr = subprocess_execute(cmd)
|
||||
|
||||
for line in output:
|
||||
diff += date + " user: " + login + ", group: " + user_group + " " + line + "\n"
|
||||
if kwargs.get('return_diff'):
|
||||
for line in output:
|
||||
diff += line + "\n"
|
||||
return diff
|
||||
else:
|
||||
for line in output:
|
||||
diff += date + " user: " + login + ", group: " + user_group + " " + line + "\n"
|
||||
|
||||
try:
|
||||
log = open(log_path + "/config_edit-"+get_data('logs')+".log", "a")
|
||||
log.write(diff)
|
||||
|
@ -811,7 +829,6 @@ def check_haproxy_version(server_ip):
|
|||
|
||||
|
||||
def upload(server_ip, path, file, **kwargs):
|
||||
error = ""
|
||||
full_path = path + file
|
||||
if kwargs.get('dir') == "fullpath":
|
||||
full_path = path
|
||||
|
@ -854,6 +871,7 @@ def upload_and_restart(server_ip, cfg, **kwargs):
|
|||
import sql
|
||||
error = ''
|
||||
container_name = ''
|
||||
server_id = sql.select_server_id_by_ip(server_ip=server_ip)
|
||||
|
||||
if kwargs.get("nginx"):
|
||||
service = 'nginx'
|
||||
|
@ -892,7 +910,6 @@ def upload_and_restart(server_ip, cfg, **kwargs):
|
|||
else:
|
||||
commands = ["sudo mv -f " + tmp_file + " /etc/keepalived/keepalived.conf && sudo systemctl restart keepalived"]
|
||||
elif service == "nginx":
|
||||
server_id = sql.select_server_id_by_ip(server_ip=server_ip)
|
||||
is_docker = sql.select_service_setting(server_id, 'nginx', 'dockerized')
|
||||
if is_docker == '1':
|
||||
container_name = sql.get_setting('nginx_container_name')
|
||||
|
@ -917,7 +934,6 @@ def upload_and_restart(server_ip, cfg, **kwargs):
|
|||
if sql.return_firewall(server_ip):
|
||||
commands[0] += open_port_firewalld(cfg, server_ip=server_ip, service='nginx')
|
||||
else:
|
||||
server_id = sql.select_server_id_by_ip(server_ip=server_ip)
|
||||
is_docker = sql.select_service_setting(server_id, 'haproxy', 'dockerized')
|
||||
haproxy_service_name = "haproxy"
|
||||
|
||||
|
@ -958,6 +974,18 @@ def upload_and_restart(server_ip, cfg, **kwargs):
|
|||
service=service)
|
||||
except Exception as e:
|
||||
logging('localhost', str(e), haproxywi=1)
|
||||
# If master then save version of config in a new way
|
||||
if not kwargs.get('slave'):
|
||||
try:
|
||||
diff = diff_config(kwargs.get('oldcfg'), cfg, return_diff=1)
|
||||
except Exception as e:
|
||||
logging('localhost', str(e), haproxywi=1)
|
||||
|
||||
try:
|
||||
user_id = get_user_id()
|
||||
sql.insert_config_version(server_id, user_id, service, cfg, config_path, diff)
|
||||
except Exception as e:
|
||||
logging('localhost', str(e), haproxywi=1)
|
||||
except Exception as e:
|
||||
logging('localhost', str(e), haproxywi=1)
|
||||
return error
|
||||
|
@ -983,9 +1011,9 @@ def master_slave_upload_and_restart(server_ip, cfg, just_save, **kwargs):
|
|||
masters = sql.is_master(server_ip)
|
||||
for master in masters:
|
||||
if master[0] is not None:
|
||||
error = upload_and_restart(master[0], cfg, just_save=just_save, nginx=kwargs.get('nginx'))
|
||||
error = upload_and_restart(master[0], cfg, just_save=just_save, nginx=kwargs.get('nginx'), slave=1)
|
||||
|
||||
error = upload_and_restart(server_ip, cfg, just_save=just_save, nginx=kwargs.get('nginx'))
|
||||
error = upload_and_restart(server_ip, cfg, just_save=just_save, nginx=kwargs.get('nginx'), oldcfg=kwargs.get('oldcfg'))
|
||||
|
||||
return error
|
||||
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
#!/usr/bin/env python3
|
||||
import funct
|
||||
import sql
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
|
||||
env = Environment(loader=FileSystemLoader('templates/'), autoescape=True)
|
||||
template = env.get_template('history.html')
|
||||
|
||||
print('Content-type: text/html\n')
|
||||
funct.check_login()
|
||||
|
||||
try:
|
||||
user, user_id, role, token, servers, user_services = funct.get_users_params()
|
||||
services = []
|
||||
except:
|
||||
pass
|
||||
|
||||
form = funct.form
|
||||
serv = funct.is_ip_or_dns(form.getvalue('serv'))
|
||||
service = form.getvalue('service')
|
||||
|
||||
|
||||
if service == 'nginx':
|
||||
if funct.check_login(service=2):
|
||||
title = 'Nginx service history'
|
||||
if serv:
|
||||
if funct.check_is_server_in_group(serv):
|
||||
server_id = sql.select_server_id_by_ip(serv)
|
||||
history = sql.select_action_history_by_server_id_and_service(server_id, service)
|
||||
elif service == 'keepalived':
|
||||
if funct.check_login(service=3):
|
||||
title = 'Keepalived service history'
|
||||
if serv:
|
||||
if funct.check_is_server_in_group(serv):
|
||||
server_id = sql.select_server_id_by_ip(serv)
|
||||
history = sql.select_action_history_by_server_id_and_service(server_id, service)
|
||||
elif service == 'haproxy':
|
||||
if funct.check_login(service=1):
|
||||
title = "HAProxy service history"
|
||||
if serv:
|
||||
if funct.check_is_server_in_group(serv):
|
||||
server_id = sql.select_server_id_by_ip(serv)
|
||||
history = sql.select_action_history_by_server_id_and_service(server_id, service)
|
||||
|
||||
users = sql.select_users()
|
||||
|
||||
template = template.render(h2=1,
|
||||
autorefresh=0,
|
||||
title=title,
|
||||
role=role,
|
||||
user=user,
|
||||
users=users,
|
||||
serv=serv,
|
||||
service=service,
|
||||
history=history,
|
||||
user_services=user_services,
|
||||
token=token)
|
||||
print(template)
|
|
@ -393,7 +393,8 @@ if form.getvalue('session_delete_id') is not None:
|
|||
|
||||
if form.getvalue("change_pos") is not None:
|
||||
pos = form.getvalue('change_pos')
|
||||
sql.update_server_pos(pos, serv)
|
||||
server_id = form.getvalue('pos_server_id')
|
||||
sql.update_server_pos(pos, server_id)
|
||||
|
||||
if form.getvalue('show_ip') is not None and serv is not None:
|
||||
commands = ["sudo ip a |grep inet |egrep -v '::1' |awk '{ print $2 }' |awk -F'/' '{ print $1 }'"]
|
||||
|
@ -1397,7 +1398,7 @@ if form.getvalue('haproxy_exp_install'):
|
|||
proxy_serv = ''
|
||||
|
||||
commands = ["chmod +x " + script + " && ./" + script + " PROXY=" + proxy_serv +
|
||||
" STAT_PORT=" + stats_port + " STAT_FILE=" + server_state_file +
|
||||
" STAT_PORT=" + str(stats_port) + " STAT_FILE=" + server_state_file +
|
||||
" SSH_PORT=" + ssh_port + " STAT_PAGE=" + stat_page +
|
||||
" STATS_USER=" + stats_user + " STATS_PASS='" + stats_password + "' HOST=" + serv +
|
||||
" USER=" + ssh_user_name + " PASS='" + ssh_user_password + "' KEY=" + ssh_key_name]
|
||||
|
@ -1434,7 +1435,7 @@ if form.getvalue('nginx_exp_install'):
|
|||
proxy_serv = ''
|
||||
|
||||
commands = ["chmod +x " + script + " && ./" + script + " PROXY=" + proxy_serv +
|
||||
" STAT_PORT=" + stats_port + " SSH_PORT=" + ssh_port + " STAT_PAGE=" + stats_page +
|
||||
" STAT_PORT=" + str(stats_port) + " SSH_PORT=" + ssh_port + " STAT_PAGE=" + stats_page +
|
||||
" STATS_USER=" + stats_user + " STATS_PASS='" + stats_password + "' HOST=" + serv +
|
||||
" USER=" + ssh_user_name + " PASS='" + ssh_user_password + "' KEY=" + ssh_key_name]
|
||||
|
||||
|
@ -3817,3 +3818,40 @@ if form.getvalue('serverSettingsSave') is not None:
|
|||
else:
|
||||
funct.logging(server_ip, 'Service has been flagged as a system service', haproxywi=1, login=1,
|
||||
keep_history=1, service=service)
|
||||
|
||||
if act == 'showListOfVersion':
|
||||
service = form.getvalue('service')
|
||||
configver = form.getvalue('configver')
|
||||
for_delver = form.getvalue('for_delver')
|
||||
style = form.getvalue('style')
|
||||
if service == 'keepalived':
|
||||
configs_dir = funct.get_config_var('configs', 'kp_save_configs_dir')
|
||||
files = funct.get_files(dir=configs_dir, format='conf')
|
||||
configs = sql.select_config_version(serv, service)
|
||||
action = 'versions.py?service=keepalived'
|
||||
elif service == 'nginx':
|
||||
configs_dir = funct.get_config_var('configs', 'nginx_save_configs_dir')
|
||||
files = funct.get_files(dir=configs_dir, format='conf')
|
||||
configs = sql.select_config_version(serv, service)
|
||||
action = 'versions.py?service=nginx'
|
||||
else:
|
||||
service = 'haproxy'
|
||||
files = funct.get_files()
|
||||
configs = sql.select_config_version(serv, service)
|
||||
action = "versions.py"
|
||||
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
|
||||
env = Environment(loader=FileSystemLoader('templates/'), autoescape=True,
|
||||
extensions=["jinja2.ext.loopcontrols", "jinja2.ext.do"])
|
||||
template = env.get_template('ajax/show_list_version.html')
|
||||
|
||||
template = template.render(serv=serv,
|
||||
service=service,
|
||||
action=action,
|
||||
return_files=files,
|
||||
configver=configver,
|
||||
for_delver=for_delver,
|
||||
configs=configs,
|
||||
style=style)
|
||||
print(template)
|
|
@ -33,18 +33,6 @@
|
|||
- sestatus.stdout is defined
|
||||
- '"Enforcing" in sestatus.stdout'
|
||||
|
||||
- name: Get HAProxy version.
|
||||
command: haproxy -v
|
||||
register: haproxy_version_result
|
||||
changed_when: false
|
||||
check_mode: false
|
||||
|
||||
|
||||
- name: Set HAProxy version.
|
||||
set_fact:
|
||||
haproxy_version: "{{ '1.5' if '1.5.' in haproxy_version_result.stdout else '1.6' }}"
|
||||
|
||||
|
||||
- name: Open stat port for firewalld
|
||||
firewalld:
|
||||
port: "{{ item }}/tcp"
|
||||
|
@ -70,16 +58,36 @@
|
|||
ignore_errors: yes
|
||||
with_items: [ "{{ STAT_PORT }}", "{{ SOCK_PORT }}" ]
|
||||
|
||||
- name: Create the haproxy group
|
||||
group:
|
||||
name: haproxy
|
||||
state: present
|
||||
system: true
|
||||
|
||||
- name: Create the haproxy user
|
||||
user:
|
||||
name: haproxy
|
||||
groups: haproxy
|
||||
append: true
|
||||
shell: /usr/sbin/nologin
|
||||
system: true
|
||||
create_home: false
|
||||
home: /
|
||||
|
||||
- name: Creates HAProxy directory
|
||||
file:
|
||||
path: /etc/haproxy
|
||||
owner: haproxy
|
||||
group: haproxy
|
||||
state: directory
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Copy HAProxy configuration in place.
|
||||
template:
|
||||
src: haproxy.cfg.j2
|
||||
dest: /etc/haproxy/haproxy.cfg
|
||||
mode: 0644
|
||||
validate: haproxy -f %s -c -q
|
||||
force: no
|
||||
notify: restart haproxy
|
||||
|
||||
|
||||
- name: Creates HAProxy stats directory
|
||||
file:
|
||||
|
@ -88,13 +96,3 @@
|
|||
group: haproxy
|
||||
state: directory
|
||||
ignore_errors: yes
|
||||
|
||||
|
||||
- name: Enable and start service HAProxy
|
||||
systemd:
|
||||
name: haproxy
|
||||
daemon_reload: yes
|
||||
state: started
|
||||
enabled: yes
|
||||
force: no
|
||||
ignore_errors: yes
|
||||
|
|
|
@ -12,10 +12,10 @@
|
|||
|
||||
- include: logs.yml
|
||||
|
||||
- include: installation.yml
|
||||
|
||||
- include: configure.yml
|
||||
|
||||
- include: installation.yml
|
||||
|
||||
- name: Add syn_flood tasks
|
||||
include: syn_flood.yml
|
||||
when: (SYN_FLOOD is defined) and (SYN_FLOOD|length > 0)
|
||||
|
|
|
@ -9,9 +9,7 @@ global
|
|||
stats socket /var/lib/haproxy/stats
|
||||
stats socket *:{{SOCK_PORT}} level admin
|
||||
stats socket /var/run/haproxy.sock mode 600 level admin
|
||||
{% if haproxy_version == '1.6' %}
|
||||
server-state-file {{STAT_FILE}}
|
||||
{% endif %}
|
||||
|
||||
defaults
|
||||
mode http
|
||||
|
|
75
app/sql.py
75
app/sql.py
|
@ -1943,6 +1943,7 @@ def update_firewall(serv):
|
|||
|
||||
def update_server_pos(pos, server_id):
|
||||
query = Server.update(pos=pos).where(Server.server_id == server_id)
|
||||
print(query)
|
||||
try:
|
||||
query.execute()
|
||||
return True
|
||||
|
@ -1960,17 +1961,8 @@ def check_token_exists(token):
|
|||
if get_token(user_id.value) == token:
|
||||
return True
|
||||
else:
|
||||
# try:
|
||||
# funct.logging('localhost', ' Tried do action with wrong token', haproxywi=1, login=1)
|
||||
# except:
|
||||
# funct.logging('localhost', ' An action with wrong token', haproxywi=1)
|
||||
return False
|
||||
except:
|
||||
# try:
|
||||
# funct.logging('localhost', ' Cannot check token', haproxywi=1, login=1)
|
||||
# except:
|
||||
# funct.logging('localhost', ' Cannot check token', haproxywi=1)
|
||||
# finally:
|
||||
return False
|
||||
|
||||
|
||||
|
@ -1992,7 +1984,6 @@ def insert_smon(server, port, enable, proto, uri, body, group, desc, telegram, u
|
|||
|
||||
def select_smon(user_group, **kwargs):
|
||||
cursor = conn.cursor()
|
||||
|
||||
funct.check_user_group()
|
||||
|
||||
if user_group == 1:
|
||||
|
@ -2862,3 +2853,67 @@ def delete_action_history(server_id: int):
|
|||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def select_action_history_by_server_id(server_id: int):
|
||||
query = ActionHistory.select().where(ActionHistory.server_id == server_id)
|
||||
try:
|
||||
query_res = query.execute()
|
||||
except Exception as e:
|
||||
out_error(e)
|
||||
else:
|
||||
return query_res
|
||||
|
||||
|
||||
def select_action_history_by_server_id_and_service(server_id: int, service: str):
|
||||
query = ActionHistory.select().where(
|
||||
(ActionHistory.server_id == server_id) &
|
||||
(ActionHistory.service == service)
|
||||
)
|
||||
try:
|
||||
query_res = query.execute()
|
||||
except Exception as e:
|
||||
out_error(e)
|
||||
else:
|
||||
return query_res
|
||||
|
||||
|
||||
def insert_config_version(server_id: int, user_id: int, service: str, local_path: str, remote_path: str, diff: str):
|
||||
try:
|
||||
ConfigVersion.insert(server_id=server_id,
|
||||
user_id=user_id,
|
||||
service=service,
|
||||
local_path=local_path,
|
||||
remote_path=remote_path,
|
||||
diff=diff,
|
||||
date=funct.get_data('regular')).execute()
|
||||
except Exception as e:
|
||||
out_error(e)
|
||||
|
||||
|
||||
def select_config_version(server_ip: str, service: str) -> str:
|
||||
server_id = select_server_id_by_ip(server_ip)
|
||||
query = ConfigVersion.select().where(
|
||||
(ConfigVersion.server_id == server_id) &
|
||||
(ConfigVersion.service == service)
|
||||
)
|
||||
try:
|
||||
query_res = query.execute()
|
||||
except Exception as e:
|
||||
out_error(e)
|
||||
else:
|
||||
return query_res
|
||||
|
||||
|
||||
def delete_config_version(service: str, local_path: str):
|
||||
query_res = ConfigVersion.delete().where(
|
||||
(ConfigVersion.service == service) &
|
||||
(ConfigVersion.local_path == local_path)
|
||||
)
|
||||
try:
|
||||
query_res.execute()
|
||||
except Exception as e:
|
||||
out_error(e)
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
|
|
@ -0,0 +1,200 @@
|
|||
{% from 'include/input_macros.html' import copy_to_clipboard %}
|
||||
{% if style == 'new' %}
|
||||
{% if for_delver == '1' %}
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('#table_version').on('page.dt')
|
||||
.DataTable( {
|
||||
"pageLength": 25,
|
||||
"order": [ 4, "desc" ],
|
||||
stateSave: true,
|
||||
"columnDefs": [
|
||||
{
|
||||
"searchable": false,
|
||||
"orderable": false
|
||||
}
|
||||
],
|
||||
"lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]]
|
||||
} );
|
||||
} );
|
||||
$('#new_select_all').click(function(){
|
||||
if($(this).prop('checked')) {
|
||||
$("form input[type='checkbox']").attr("checked",true).change();
|
||||
} else {
|
||||
$("form input[type='checkbox']").attr("checked",false).change();
|
||||
}
|
||||
});
|
||||
$.getScript('/inc/script.js');
|
||||
function show_diff(id) {
|
||||
if ($('#show_diff_'+id).css('display') == 'none') {
|
||||
$('#show_diff_'+id).show();
|
||||
$('#link_show_diff_'+id).attr('title', 'Hide the full diff');
|
||||
$('#link_show_diff_'+id).text('Hide diff');
|
||||
} else {
|
||||
$('#show_diff_'+id).hide();
|
||||
$('#link_show_diff_'+id).attr('title', 'Show the full diff');
|
||||
$('#link_show_diff_'+id).text('Show diff');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.diff {
|
||||
overflow: auto;
|
||||
width: 100%;
|
||||
border: 1px solid #DCDCDC;
|
||||
border-radius: 5px;
|
||||
background-color: #fff;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
<form action="{{action}}" method="post">
|
||||
<table class="overview hover order-column display compact" id="table_version">
|
||||
<thead>
|
||||
<tr class="overviewHead">
|
||||
<th class="padding10 first-collumn" style="width: 1%">
|
||||
<label for="new_select_all" id="new_label_select_all"></label>
|
||||
<input type="checkbox" id="new_select_all">
|
||||
</th>
|
||||
<th class="padding10 first-collumn" style="width: 30%">
|
||||
Local path
|
||||
</th>
|
||||
<th class="padding10 first-collumn" style="width: 10%">
|
||||
Remote path
|
||||
</th>
|
||||
<th class="padding10 first-collumn" style="width: 35%">
|
||||
Diff
|
||||
</th>
|
||||
<th style="width: 10%">
|
||||
Created
|
||||
</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for c in configs %}
|
||||
<tr>
|
||||
<td>
|
||||
<label for="{{c.id}}" id="select_{{c.id}}"></label>
|
||||
<input type="checkbox" value="{{c.local_path}}" name="{{c.local_path}}" id="{{c.id}}">
|
||||
</td>
|
||||
<td class="padding10 first-collumn" title="{{c.local_path}}">
|
||||
{% set show = '...'+c.local_path.split('/')[-1] %}
|
||||
{{ copy_to_clipboard(id=c.local_path, value=c.local_path, show=show) }}
|
||||
</td>
|
||||
<td>{{ copy_to_clipboard(id=c.remote_path, value=c.remote_path) }}</td>
|
||||
<td>
|
||||
{% if c.diff == '' %}
|
||||
No diff
|
||||
{% else %}
|
||||
<a id="link_show_diff_{{c.id}}" onclick="show_diff('{{c.id}}')" title="Show a difference between this config and previous one" class="link">Show diff</a>
|
||||
<div id="show_diff_{{c.id}}" style="display: none;">
|
||||
{% set stdout = c.diff.split('\n') %}
|
||||
{% include 'ajax/compare.html' %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{c.date}}</td>
|
||||
<td style="padding-top: 10px;">
|
||||
<a href="/app/versions.py?service={{service}}&serv={{serv}}&open=open&configver={{c.local_path.split('/')[-1]}}"
|
||||
class="ui-button ui-widget ui-corner-all" title="View and upload this version of the config" style="margin-top: -6px;">
|
||||
View/Upload
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<input type="hidden" value="{{serv}}" name="serv">
|
||||
<input type="hidden" value="open" name="open">
|
||||
<input type="hidden" value="del" name="del">
|
||||
<input type="hidden" value="{{style}}" name="style">
|
||||
<input type="hidden" value="{{service}}" name="service">
|
||||
<p>
|
||||
<button type="submit" value="" name="" class="btn btn-default">Delete</button>
|
||||
</p>
|
||||
</form>
|
||||
{% else %}
|
||||
<center>
|
||||
<h4>Select an old version</h4>
|
||||
<p>
|
||||
<select autofocus required name="configver" id="configver">
|
||||
<option disabled selected>------</option>
|
||||
{% for file in return_files %}
|
||||
{% if file == configver %}
|
||||
<option value="{{file}}" selected>{{file.split('-', maxsplit=1)[1]}}</option>
|
||||
{% else %}
|
||||
<option value="{{file}}">{{file.split('-', maxsplit=1)[1]}}</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
<input type="hidden" value="{{serv}}" name="serv">
|
||||
<input type="hidden" value="open" name="open">
|
||||
<input type="hidden" value="{{service}}" name="service" id="service">
|
||||
<a class="ui-button ui-widget ui-corner-all" id="show" title="Enter" onclick="showUploadConfig()">Select</a>
|
||||
</p>
|
||||
<script>
|
||||
$( "select" ).selectmenu();
|
||||
showUploadConfig();
|
||||
</script>
|
||||
</center>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if for_delver == '1' %}
|
||||
<center>
|
||||
<h4>Select a version</h4>
|
||||
<form action="{{action}}" method="post">
|
||||
<label for="select_all" id="label_select_all"><b>Select all</b></label>
|
||||
<input type="checkbox" id="select_all"><br />
|
||||
{% for file in return_files %}
|
||||
<label for="{{file}}"> {{file.split('-', maxsplit=1)[1]}} </label><input type="checkbox" value="{{file}}" name="{{file}}" id="{{file}}">
|
||||
<a href="/app/versions.py?service={{service}}&serv={{serv}}&open=open&configver={{file}}"
|
||||
class="ui-button ui-widget ui-corner-all" title="View and upload this version of the config" style="margin-top: -6px;">
|
||||
View/Upload
|
||||
</a><br />
|
||||
{% endfor %}
|
||||
<input type="hidden" value="{{serv}}" name="serv">
|
||||
<input type="hidden" value="open" name="open">
|
||||
<input type="hidden" value="del" name="del">
|
||||
<p>
|
||||
<button type="submit" value="" name="" class="btn btn-default">Delete</button>
|
||||
</p>
|
||||
</form>
|
||||
</center>
|
||||
{% else %}
|
||||
<center>
|
||||
<h4>Select an old version</h4>
|
||||
<p>
|
||||
<select autofocus required name="configver" id="configver">
|
||||
<option disabled selected>------</option>
|
||||
{% for file in return_files %}
|
||||
{% if file == configver %}
|
||||
<option value="{{file}}" selected>{{file.split('-', maxsplit=1)[1]}}</option>
|
||||
{% else %}
|
||||
<option value="{{file}}">{{file.split('-', maxsplit=1)[1]}}</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
<input type="hidden" value="{{serv}}" name="serv">
|
||||
<input type="hidden" value="open" name="open">
|
||||
<input type="hidden" value="{{service}}" name="service" id="service">
|
||||
<a class="ui-button ui-widget ui-corner-all" id="show" title="Enter" onclick="showUploadConfig()">Select</a>
|
||||
</p>
|
||||
<script>
|
||||
$( "select" ).selectmenu();
|
||||
showUploadConfig();
|
||||
</script>
|
||||
</center>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<script>
|
||||
$('#select_all').click(function(){
|
||||
if($(this).prop('checked')) {
|
||||
$("form input[type='checkbox']").attr("checked",true).change();
|
||||
$("#label_select_all").text("Unselect all");
|
||||
} else {
|
||||
$("form input[type='checkbox']").attr("checked",false).change();
|
||||
$("#label_select_all").text("Select all");
|
||||
}
|
||||
});
|
||||
$("input[type=submit], button").button();
|
||||
</script>
|
|
@ -14,25 +14,8 @@
|
|||
{% endif %}
|
||||
{% endif %}
|
||||
{% if open %}
|
||||
<center>
|
||||
<h4>Choose old version</h4>
|
||||
<p>
|
||||
<select autofocus required name="configver" id="configver">
|
||||
<option disabled selected>Choose version</option>
|
||||
{% for file in return_files %}
|
||||
{% if file == configver %}
|
||||
<option value="{{file}}" selected>{{file.split('-', maxsplit=1)[1]}}</option>
|
||||
{% else %}
|
||||
<option value="{{file}}">{{file.split('-', maxsplit=1)[1]}}</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
<input type="hidden" value="{{serv}}" name="serv">
|
||||
<input type="hidden" value="open" name="open">
|
||||
<input type="hidden" value="{{service}}" name="service" id="service">
|
||||
<a class="ui-button ui-widget ui-corner-all" id="show" title="Enter" onclick="showUploadConfig()">Select</a>
|
||||
</p>
|
||||
</center>
|
||||
<div id="config_version_div"></div>
|
||||
<script>showListOfVersion(0)</script>
|
||||
{% endif %}
|
||||
{% if aftersave %}
|
||||
<div class="alert alert-info alert-two-row">The following version of the configuration file has been uploaded and saved as: {{ configver }} </div>
|
||||
|
@ -44,9 +27,4 @@
|
|||
{% endif %}
|
||||
{% endif %}
|
||||
</center>
|
||||
{% if aftersave != 1 %}
|
||||
<script>
|
||||
showUploadConfig()
|
||||
</script>
|
||||
{% endif %}
|
||||
{% endblock %}
|
|
@ -4,21 +4,19 @@
|
|||
{% if selects|length == 0 %}
|
||||
{% include 'include/getstarted.html' %}
|
||||
{% else %}
|
||||
<link href="/inc/table.css" rel="stylesheet" type="text/css">
|
||||
<script type="text/javascript" charset="utf8" src="/inc/dataTables.min.js"></script>
|
||||
<center>
|
||||
<p>
|
||||
<form action="{{ action }}" method="post">
|
||||
<input type="hidden" value="{{service}}" name="service" id="service">
|
||||
{% include 'include/select.html' %}
|
||||
<button type="submit" value="open" name="open" class="btn btn-default">Open</button>
|
||||
<a class="ui-button ui-widget ui-corner-all" title="View stat" onclick="showListOfVersion(1)">Open</a>
|
||||
{% if service != 'keepalived' %}
|
||||
<a href="config.py" class="ui-button ui-widget ui-corner-all" title="Configs page">Configs</a>
|
||||
<a class="ui-button ui-widget ui-corner-all" title="View stat" onclick="openStats()">Stat</a>
|
||||
{% endif %}
|
||||
</form>
|
||||
{% if not aftersave and not open %}
|
||||
<div class="add-note addName alert-info" style="width: inherit; margin-right: 15px; margin-top: 40%">
|
||||
Here you can work with previous versions of {%if service == 'keepalived' %}Keepalived{%elif service == 'nginx' %}Nginx{%else%}HAProxy{%endif%} configs. Roll back to them, view or delete
|
||||
</div>
|
||||
{% endif %}
|
||||
</p>
|
||||
{% if aftersave %}
|
||||
<div class="alert alert-info"><b>The following files have been deleted:</b><br /> </div>
|
||||
|
@ -32,26 +30,11 @@
|
|||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if open %}
|
||||
<center>
|
||||
<h4>Select a version</h4>
|
||||
<form action="{{action}}" method="post">
|
||||
<label for="select_all" id="label_select_all"><b>Select all</b></label>
|
||||
<input type="checkbox" id="select_all"><br />
|
||||
{% for file in return_files %}
|
||||
<label for="{{file}}"> {{file.split('-', maxsplit=1)[1]}} </label><input type="checkbox" value="{{file}}" name="{{file}}" id="{{file}}">
|
||||
<a href="/app/versions.py?service={{service}}&serv={{serv}}&open=open&configver={{file}}" class="ui-button ui-widget ui-corner-all" title="View and upload this version of the config" style="margin-top: -6px;">
|
||||
View/Upload
|
||||
</a><br />
|
||||
{% endfor %}
|
||||
<input type="hidden" value="{{serv}}" name="serv">
|
||||
<input type="hidden" value="open" name="open">
|
||||
<input type="hidden" value="del" name="del">
|
||||
<p>
|
||||
<button type="submit" value="" name="" class="btn btn-default">Delete</button>
|
||||
</p>
|
||||
</form>
|
||||
</center>
|
||||
<div id="config_version_div"></div>
|
||||
{% if not aftersave %}
|
||||
<div class="add-note addName alert-info" style="width: inherit; margin-right: 15px; margin-top: 40%">
|
||||
Here you can work with previous versions of {%if service == 'keepalived' %}Keepalived{%elif service == 'nginx' %}Nginx{%else%}HAProxy{%endif%} configs. Roll back to them, view or delete
|
||||
</div>
|
||||
{% endif %}
|
||||
</center>
|
||||
{% endif %}
|
||||
|
|
|
@ -123,19 +123,6 @@
|
|||
<div class="server-name">
|
||||
<input type="hidden" id="server-name-{{s.0}}" value="{{s.1}}" />
|
||||
<input type="hidden" id="service" value="{{service}}" />
|
||||
{% if service == 'nginx' or service == 'keepalived' %}
|
||||
{% if s.5.0.1 == 'active' %}
|
||||
<span class="serverUp server-status" title="Started: {{s.5.0.4}}"></span>
|
||||
{% else %}
|
||||
<span class="serverDown server-status" title="Stopped: {{s.5.0.4}}"></span>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if s.5 != False %}
|
||||
<span class="serverUp server-status" title="{{s.5.0.2}}"></span>
|
||||
{% else %}
|
||||
<span class="serverDown server-status" title="HAProxy is down"></span>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if not serv %}
|
||||
<a href="/app/hapservers.py?service={{service}}&serv={{s.2}}" title="More about {{s.1}}" style="color: #5d9ceb">{{s.1}}</a>
|
||||
{% else %}
|
||||
|
@ -172,8 +159,9 @@
|
|||
<a id="stop-{{ s.2 }}" class="stop" title="Stop {{service}} service">
|
||||
<span class="service-stop" onclick="confirmAjaxAction('stop', '{{action_service}}', '{{s.2}}')"></span>
|
||||
</a>
|
||||
<a href="history.py?service={{service}}&serv={{s.2}}" title="View history for this service" class="history" style="margin: 0 5px 0 10px;"></a>
|
||||
{% if service != 'keepalived' %}
|
||||
<span class="menu-bar" onclick="serverSettings('{{s.0}}', '{{s.1}}')" title="Edit settings for {{s.1}} service" style="margin: 0 0 0 10px;"></span>
|
||||
<span class="menu-bar" onclick="serverSettings('{{s.0}}', '{{s.1}}')" title="Edit settings for {{s.1}} service"></span>
|
||||
{% endif %}
|
||||
</span>
|
||||
{% endif %}
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
{% from 'include/input_macros.html' import copy_to_clipboard %}
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<link href="/inc/table.css" rel="stylesheet" type="text/css">
|
||||
<script type="text/javascript" charset="utf8" src="/inc/dataTables.min.js"></script>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('#table_history').on('page.dt')
|
||||
.DataTable( {
|
||||
"pageLength": 25,
|
||||
"order": [ 4, "desc" ],
|
||||
stateSave: true,
|
||||
"columnDefs": [
|
||||
{
|
||||
"searchable": false,
|
||||
"orderable": false
|
||||
}
|
||||
],
|
||||
"lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]]
|
||||
} );
|
||||
} );
|
||||
</script>
|
||||
<table class="overview hover order-column display compact" id="table_history">
|
||||
<thead>
|
||||
<tr class="overviewHead">
|
||||
<th class="padding10 first-collumn" style="width: 100px;">Service</th>
|
||||
<th>User</th>
|
||||
<th>User IP</th>
|
||||
<th>Action</th>
|
||||
<th>Date</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for h in history %}
|
||||
<tr>
|
||||
<td>{{h.service[0].upper()}}{{h.service[1:]}}</td>
|
||||
<td>
|
||||
{% for u in users %}
|
||||
{% if u.user_id == h.user_id %}
|
||||
{{ u.username }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td>{{ copy_to_clipboard(id=h.ip, value=h.ip) }}</td>
|
||||
<td>{{h.action}}</td>
|
||||
<td>{{h.date}}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock %}
|
|
@ -14,43 +14,40 @@ serv = form.getvalue('serv')
|
|||
Select = form.getvalue('del')
|
||||
configver = form.getvalue('configver')
|
||||
service = form.getvalue('service')
|
||||
conf_format = 'cfg'
|
||||
configs_dir = ''
|
||||
stderr = ""
|
||||
aftersave = ""
|
||||
file = set()
|
||||
|
||||
if form.getvalue('configver'):
|
||||
if configver:
|
||||
template = env.get_template('configver.html')
|
||||
|
||||
try:
|
||||
user, user_id, role, token, servers, user_services = funct.get_users_params(disable=1)
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
if service == 'keepalived':
|
||||
if funct.check_login(service=3):
|
||||
configs_dir = funct.get_config_var('configs', 'kp_save_configs_dir')
|
||||
title = "Working with versions Keepalived configs"
|
||||
files = funct.get_files(dir=configs_dir, format='conf')
|
||||
action = 'versions.py?service=keepalived'
|
||||
format = 'conf'
|
||||
conf_format = 'conf'
|
||||
servers = sql.get_dick_permit(keepalived=1)
|
||||
action = 'versions.py?service=keepalived'
|
||||
elif service == 'nginx':
|
||||
if funct.check_login(service=2):
|
||||
configs_dir = funct.get_config_var('configs', 'nginx_save_configs_dir')
|
||||
title = "Working with versions Nginx configs"
|
||||
files = funct.get_files(dir=configs_dir, format='conf')
|
||||
action = 'versions.py?service=nginx'
|
||||
format = 'conf'
|
||||
conf_format = 'conf'
|
||||
servers = sql.get_dick_permit(nginx=1)
|
||||
action = 'versions.py?service=nginx'
|
||||
else:
|
||||
service = 'haproxy'
|
||||
if funct.check_login(service=1):
|
||||
title = "Working with versions HAProxy configs"
|
||||
files = funct.get_files()
|
||||
action = "versions.py"
|
||||
configs_dir = funct.get_config_var('configs', 'haproxy_save_configs_dir')
|
||||
format = 'cfg'
|
||||
|
||||
action = "versions.py"
|
||||
|
||||
if serv is not None and form.getvalue('del') is not None:
|
||||
if Select is not None:
|
||||
|
@ -58,15 +55,21 @@ if serv is not None and form.getvalue('del') is not None:
|
|||
env = Environment(loader=FileSystemLoader('templates/'))
|
||||
template = env.get_template('delver.html')
|
||||
for get in form:
|
||||
if format in get:
|
||||
if conf_format in get:
|
||||
try:
|
||||
os.remove(os.path.join(configs_dir, form.getvalue(get)))
|
||||
if form.getvalue('style') == 'new':
|
||||
if sql.delete_config_version(form.getvalue('service'), form.getvalue(get)):
|
||||
try:
|
||||
os.remove(form.getvalue(get))
|
||||
except OSError as e:
|
||||
if 'No such file or directory' in str(e):
|
||||
pass
|
||||
else:
|
||||
os.remove(os.path.join(configs_dir, form.getvalue(get)))
|
||||
file.add(form.getvalue(get) + "<br />")
|
||||
funct.logging(serv, "versions.py were deleted configs: %s" % form.getvalue(get))
|
||||
except OSError as e:
|
||||
funct.logging(serv, "versions.py were deleted configs: %s" % form.getvalue(get))
|
||||
except OSError as e:
|
||||
stderr = "Error: %s - %s." % (e.filename,e.strerror)
|
||||
print('<meta http-equiv="refresh" content="10; url=versions.py?service=%s&serv=%s&open=open">' % (service, form.getvalue('serv')))
|
||||
|
||||
|
||||
if serv is not None and form.getvalue('config') is not None:
|
||||
configver = configs_dir + configver
|
||||
|
@ -88,19 +91,18 @@ if serv is not None and form.getvalue('config') is not None:
|
|||
|
||||
template = template.render(h2=1, title=title,
|
||||
role=role,
|
||||
action=action,
|
||||
user=user,
|
||||
select_id="serv",
|
||||
serv=serv,
|
||||
aftersave=aftersave,
|
||||
return_files=files,
|
||||
selects=servers,
|
||||
stderr=stderr,
|
||||
open=form.getvalue('open'),
|
||||
Select=form.getvalue('del'),
|
||||
file=file,
|
||||
file=file,
|
||||
configver=configver,
|
||||
service=service,
|
||||
user_services=user_services,
|
||||
action=action,
|
||||
token=token)
|
||||
print(template)
|
||||
|
|
|
@ -396,3 +396,12 @@
|
|||
margin-left: 5px;
|
||||
content: "\f0c5";
|
||||
}
|
||||
.history::before {
|
||||
display: none;
|
||||
font-family: "Font Awesome 5 Solid";
|
||||
content: "\f1da";
|
||||
}
|
||||
.history .fa-history {
|
||||
margin-bottom: 3px;
|
||||
color: #aaa;
|
||||
}
|
|
@ -61,7 +61,7 @@ $( function() {
|
|||
type: frm.attr('method'),
|
||||
success: function( data ) {
|
||||
data = data.replace('\n', '<br>');
|
||||
if (data.indexOf('error: ') != '-1' || data.indexOf('Fatal') != '-1' || data.indexOf('Error(s)') != '-1' || data.indexOf('failed ') != '-1' || data.indexOf('emerg] ') != '-1') {
|
||||
if (data.indexOf('error: ') != '-1' || data.indexOf('Fatal') != '-1' || data.indexOf('Error') != '-1' || data.indexOf('failed ') != '-1' || data.indexOf('emerg] ') != '-1') {
|
||||
toastr.clear();
|
||||
toastr.error(data);
|
||||
} else {
|
||||
|
|
|
@ -119,7 +119,7 @@ function add_master_addr(kp) {
|
|||
type: "POST",
|
||||
success: function( data ) {
|
||||
data = data.replace(/\s+/g,' ');
|
||||
if (data.indexOf('error:') != '-1' || data.indexOf('UNREACHABLE') != '-1') {
|
||||
if (data.indexOf('error:') != '-1' || data.indexOf('UNREACHABLE') != '-1' || data.indexOf('FAILED') != '-1') {
|
||||
showProvisioningError(data, '#creating-master-add', '#wait-mess-add', '#creating-error-add');
|
||||
} else if (data == '' ){
|
||||
showProvisioningWarning('#creating-master-add', 'master Keepalived', '#creating-warning-add', '#wait_mess-add');
|
||||
|
@ -143,7 +143,7 @@ function add_slave_addr(kp) {
|
|||
type: "POST",
|
||||
success: function( data ) {
|
||||
data = data.replace(/\s+/g,' ');
|
||||
if (data.indexOf('error:') != '-1' || data.indexOf('UNREACHABLE') != '-1') {
|
||||
if (data.indexOf('error:') != '-1' || data.indexOf('UNREACHABLE') != '-1' || data.indexOf('FAILED') != '-1') {
|
||||
showProvisioningError(data, '#creating-slave-add', '#wait-mess-add', '#creating-error-add');
|
||||
} else if (data == '' ){
|
||||
showProvisioningWarning('#creating-slave-add', 'master Keepalived', '#creating-warning-add', '#wait_mess-add');
|
||||
|
|
|
@ -320,7 +320,7 @@ function renderNginxChart(data, labels, server) {
|
|||
maintainAspectRatio: false,
|
||||
title: {
|
||||
display: true,
|
||||
text: "Nginx "+data[1],
|
||||
text: data[1],
|
||||
fontSize: 20,
|
||||
padding: 0,
|
||||
},
|
||||
|
|
|
@ -389,7 +389,7 @@ function change_pos(pos, id) {
|
|||
url: "options.py",
|
||||
data: {
|
||||
change_pos: pos,
|
||||
serv: id,
|
||||
pos_server_id: id,
|
||||
token: $('#token').val()
|
||||
},
|
||||
error: function(){
|
||||
|
|
13
inc/users.js
13
inc/users.js
|
@ -1,18 +1,5 @@
|
|||
var awesome = "/inc/fontawesome.min.js"
|
||||
|
||||
jQuery.expr[':'].regex = function(elem, index, match) {
|
||||
var matchParams = match[3].split(','),
|
||||
validLabels = /^(data|css):/,
|
||||
attr = {
|
||||
method: matchParams[0].match(validLabels) ?
|
||||
matchParams[0].split(':')[0] : 'attr',
|
||||
property: matchParams.shift().replace(validLabels,'')
|
||||
},
|
||||
regexFlags = 'ig',
|
||||
regex = new RegExp(matchParams.join('').replace(/^\s+|\s+$/g,''), regexFlags);
|
||||
return regex.test(jQuery(elem)[attr.method](attr.property));
|
||||
}
|
||||
|
||||
$( function() {
|
||||
$( "#interface" ).autocomplete({
|
||||
source: function( request, response ) {
|
||||
|
|
Loading…
Reference in New Issue