v7.3.1.0: Refactor and optimize server applications for better error handling and accuracy

The code changes focus on enhancing the server application's functionality by improving the error handling mechanism and streamlining the logic. Modifications include refining how servers get created, updated, and deleted, optimizing how ssh related actions are performed, and ensuring more accurate server scanning. The changes help reduce potential errors and make the application more efficient.
pull/390/head
Aidaho 2024-06-16 22:54:41 +03:00
parent ea8e51ee29
commit 112ecd5ce6
23 changed files with 956 additions and 166 deletions

View File

@ -2,14 +2,13 @@ import os
import shutil
import datetime
import distro
from app import scheduler
import app.modules.db.sql as sql
import app.modules.db.user as user_sql
import app.modules.db.roxy as roxy_sql
import app.modules.db.history as history_sql
import app.modules.roxywi.roxy as roxy
import app.modules.common.common as common
import app.modules.tools.common as tools_common
import app.modules.roxy_wi_tools as roxy_wi_tools
@ -76,10 +75,7 @@ def delete_old_logs():
def update_owner_on_log():
log_path = get_config.get_config_var('main', 'log_path')
try:
if distro.id() == 'ubuntu':
os.system(f'sudo chown www-data:www-data -R {log_path}')
else:
os.system(f'sudo chown apache:apache -R {log_path}')
common.set_correct_owner(log_path)
except Exception:
pass

View File

@ -1,7 +1,9 @@
import re
import os
import dateutil
from datetime import datetime
import distro
from shlex import quote
from shutil import which
from pytz import timezone
@ -194,7 +196,30 @@ def sanitize_input_word(word: str) -> str:
def return_proxy_dict() -> dict:
"""
Return a dictionary containing proxy information for HTTP and HTTPS.
:return: A dictionary with the following key-value pairs:
- "https": The proxy setting for HTTPS.
- "http": The proxy setting for HTTP.
If the proxy setting is None, an empty string, or "None", an empty dictionary is returned.
"""
proxy = sql.get_setting('proxy')
if proxy in {None, '', 'None'}:
return {}
return {"https": proxy, "http": proxy}
def set_correct_owner(path: str) -> None:
"""
Sets the correct owner of the specified path.
:param path: The path for which to set the correct owner.
:type path: str
:return: None
:rtype: None
"""
if distro.id() == 'ubuntu':
os.system(f'sudo chown www-data:www-data -R {path}')
else:
os.system(f'sudo chown apache:apache -R {path}')

View File

@ -290,20 +290,18 @@ def create_map(server_ip: str, map_name: str, group: str) -> str:
lib_path = get_config.get_config_var('main', 'lib_path')
map_name = f"{map_name.split('.')[0]}.map"
map_path = f'{lib_path}/maps/{group}/'
full_path = f'{map_path}/{map_name}'
full_path = f'{map_path}{map_name}'
try:
server_mod.subprocess_execute(f'mkdir -p {map_path}')
server_mod.subprocess_execute(f'sudo mkdir -p {map_path}')
common.set_correct_owner(lib_path)
except Exception as e:
raise Exception(f'error: cannot create a local folder for maps: {e}')
try:
open(full_path, 'a').close()
try:
roxywi_common.logging(server_ip, f'A new map {map_name} has been created', roxywi=1, login=1)
except Exception:
pass
os.mknod(full_path)
roxywi_common.logging(server_ip, f'A new map {map_name} has been created', roxywi=1, login=1)
except IOError as e:
raise Exception(f'error: Cannot create a new {map_name} map. {e}, ')
raise Exception(f'error: Cannot create a new {map_name} map. {e}')
else:
return 'success: '
@ -488,17 +486,17 @@ def get_ssl_cert(server_ip: str, cert_id: int) -> str:
try:
return server_mod.ssh_command(server_ip, command)
except Exception as e:
return f'error: Cannot connect to the server {e.args[0]}'
return f'error: Cannot connect to the server {e}'
def get_ssl_raw_cert(server_ip: str, cert_id: int) -> str:
def get_ssl_raw_cert(server_ip: str, cert_id: str) -> str:
cert_path = sql.get_setting('cert_path')
command = f"cat {cert_path}/{cert_id}"
try:
return server_mod.ssh_command(server_ip, command)
except Exception as e:
return f'error: Cannot connect to the server {e.args[0]}'
return f'error: Cannot connect to the server {e}'
def get_ssl_certs(server_ip: str) -> str:
@ -507,7 +505,7 @@ def get_ssl_certs(server_ip: str) -> str:
try:
return server_mod.ssh_command(server_ip, command)
except Exception as e:
return f'error: Cannot connect to the server: {e.args[0]}'
return f'error: Cannot connect to the server: {e}'
def del_ssl_cert(server_ip: str, cert_id: str) -> str:
@ -517,7 +515,7 @@ def del_ssl_cert(server_ip: str, cert_id: str) -> str:
try:
return server_mod.ssh_command(server_ip, command)
except Exception as e:
return f'error: Cannot delete the certificate {e.args[0]}'
return f'error: Cannot delete the certificate {e}'
def upload_ssl_cert(server_ip: str, ssl_name: str, ssl_cont: str) -> str:

View File

@ -83,7 +83,7 @@ def update_user_status() -> None:
roxy_wi_get_plan = requests.Session()
roxy_wi_get_plan.mount("https://", adapter)
json_body = {'license': user_license}
roxy_wi_get_plan = requests.post(f'https://roxy-wi.org/user/license', timeout=5, proxies=proxy_dict, json=json_body)
roxy_wi_get_plan = requests.post('https://roxy-wi.org/user/license', timeout=5, proxies=proxy_dict, json=json_body)
try:
status = roxy_wi_get_plan.json()
roxy_sql.update_user_status(status['status'], status['plan'], status['method'])

View File

@ -414,25 +414,22 @@ def show_firewalld_rules(server_ip) -> str:
return render_template('ajax/firewall_rules.html', input_chain=input_chain2, IN_public_allow=in_public_allow, output_chain=output_chain, lang=lang)
def create_server(hostname, ip, group, typeip, enable, master, cred, port, desc, haproxy, nginx, apache, firewall, **kwargs) -> bool:
def create_server(hostname, ip, group, typeip, enable, master, cred, port, desc, haproxy, nginx, apache, firewall, **kwargs) -> int:
if not roxywi_auth.is_admin(level=2, role_id=kwargs.get('role_id')):
raise Exception('error: not enough permission')
if server_sql.add_server(hostname, ip, group, typeip, enable, master, cred, port, desc, haproxy, nginx, apache, firewall):
return True
else:
return False
last_id = server_sql.add_server(hostname, ip, group, typeip, enable, master, cred, port, desc, haproxy, nginx, apache, firewall)
return last_id
def update_server_after_creating(hostname: str, ip: str, scan_server: int) -> str:
def update_server_after_creating(hostname: str, ip: str, scan_server: int) -> None:
try:
checker_sql.insert_new_checker_setting_for_server(ip)
except Exception as e:
roxywi_common.logging(f'Cannot insert Checker settings for {hostname}', str(e), roxywi=1)
raise Exception(f'error: Cannot insert Checker settings for {hostname} {e}')
roxywi_common.handle_exceptions(e, ip, f'Cannot insert Checker settings for {hostname}', roxywi=1, login=1)
try:
if scan_server == '1':
if scan_server:
nginx_config_path = sql.get_setting('nginx_config_path')
haproxy_config_path = sql.get_setting('haproxy_config_path')
haproxy_dir = sql.get_setting('haproxy_dir')
@ -459,19 +456,15 @@ def update_server_after_creating(hostname: str, ip: str, scan_server: int) -> st
server_sql.update_firewall(ip)
except Exception as e:
roxywi_common.logging(f'Cannot scan a new server {hostname}', str(e), roxywi=1)
raise Exception(f'error: Cannot scan a new server {hostname} {e}')
roxywi_common.handle_exceptions(e, ip, f'Cannot get scan the server {hostname}', roxywi=1, login=1)
try:
get_system_info(ip)
except Exception as e:
roxywi_common.logging(f'Cannot get information from {hostname}', str(e), roxywi=1, login=1)
raise Exception(f'error: Cannot get information from {hostname} {e}')
return 'ok'
roxywi_common.handle_exceptions(e, ip, f'Cannot get information from {hostname}', roxywi=1, login=1)
def delete_server(server_id: int) -> str:
def delete_server(server_id: int) -> None:
server = server_sql.select_servers(id=server_id)
server_ip = ''
hostname = ''
@ -481,9 +474,9 @@ def delete_server(server_id: int) -> str:
server_ip = s[2]
if backup_sql.check_exists_backup(server_ip):
return 'warning: Delete the backup first'
raise 'warning: Delete the backup first'
if backup_sql.check_exists_s3_backup(server_ip):
return 'warning: Delete the S3 backup first'
raise 'warning: Delete the S3 backup first'
if server_sql.delete_server(server_id):
waf_sql.delete_waf_server(server_id)
ps_sql.delete_port_scanner_settings(server_id)
@ -492,7 +485,6 @@ def delete_server(server_id: int) -> str:
server_sql.delete_system_info(server_id)
service_sql.delete_service_settings(server_id)
roxywi_common.logging(server_ip, f'The server {hostname} has been deleted', roxywi=1, login=1)
return 'Ok'
def server_is_up(server_ip: str) -> str:

View File

@ -577,9 +577,10 @@ def upload_cert():
return add_mod.upload_ssl_cert(server_ip, ssl_name, ssl_cont)
@bp.route('/cert/get/raw/<server_ip>/<int:cert_id>')
@bp.route('/cert/get/raw/<server_ip>/<cert_id>')
def get_cert_raw(server_ip, cert_id):
server_ip = common.is_ip_or_dns(server_ip)
cert_id = common.checkAjaxInput(cert_id)
return add_mod.get_ssl_raw_cert(server_ip, cert_id)

View File

@ -147,6 +147,6 @@ def install_udp():
listener_id = int(json_data['listener_id'])
try:
inv, server_ips = service_mod.generate_udp_inv(listener_id, 'install')
return service_mod.run_ansible(inv, server_ips, f'udp'), 201
return service_mod.run_ansible(inv, server_ips, 'udp'), 201
except Exception as e:
return jsonify({'status': 'failed', 'error': f'Cannot create listener: {e}'})

View File

@ -176,7 +176,7 @@ def service_history(service, server_ip):
elif service == 'user':
history = history_sql.select_action_history_by_user_id(server_ip)
else:
abort(404, f'History not found')
abort(404, 'History not found')
kwargs = {
'user_subscription': roxywi_common.return_user_subscription(),

View File

@ -73,118 +73,111 @@ def show_ip(server_id):
return server_mod.ssh_command(server_ip.ip, commands, ip="1")
@bp.post('/create')
@bp.route('', methods=['POST', 'PUT', 'DELETE', 'PATCH'])
@get_user_params()
def create_server():
roxywi_auth.page_for_admin(level=2)
hostname = common.checkAjaxInput(request.form.get('servername'))
ip = common.is_ip_or_dns(request.form.get('newip'))
group = common.checkAjaxInput(request.form.get('newservergroup'))
typeip = common.checkAjaxInput(request.form.get('typeip'))
haproxy = common.checkAjaxInput(request.form.get('haproxy'))
nginx = common.checkAjaxInput(request.form.get('nginx'))
apache = common.checkAjaxInput(request.form.get('apache'))
firewall = common.checkAjaxInput(request.form.get('firewall'))
enable = common.checkAjaxInput(request.form.get('enable'))
master = common.checkAjaxInput(request.form.get('slave'))
cred = common.checkAjaxInput(request.form.get('cred'))
page = common.checkAjaxInput(request.form.get('page'))
page = page.split("#")[0]
port = common.checkAjaxInput(request.form.get('newport'))
desc = common.checkAjaxInput(request.form.get('desc'))
add_to_smon = common.checkAjaxInput(request.form.get('add_to_smon'))
json_data = request.get_json()
lang = roxywi_common.get_user_lang_for_flask()
if request.method in ('POST', 'PUT'):
hostname = common.checkAjaxInput(json_data['name'])
group = int(json_data['group'])
type_ip = int(json_data['type_ip'])
firewall = int(json_data['firewall'])
enable = int(json_data['enable'])
cred = int(json_data['cred'])
port = int(json_data['port'])
desc = common.checkAjaxInput(json_data['desc'])
master = int(json_data['slave'])
protected = int(json_data['protected'])
if ip == '':
return 'error: IP or DNS name is not valid'
try:
if server_mod.create_server(hostname, ip, group, typeip, enable, master, cred, port, desc, haproxy, nginx,
apache, firewall):
if request.method == 'POST':
ip = common.is_ip_or_dns(json_data['ip'])
haproxy = int(json_data['haproxy'])
nginx = int(json_data['nginx'])
apache = int(json_data['apache'])
add_to_smon = int(json_data['add_to_smon'])
if ip == '':
return jsonify({'status': 'failed','error': 'IP or DNS name is not valid'})
try:
last_id = server_mod.create_server(hostname, ip, group, type_ip, enable, master, cred, port, desc, haproxy, nginx, apache, firewall)
except Exception as e:
return roxywi_common.handle_json_exceptions(e, 'Roxy-WI server', 'Cannot create server')
try:
user_subscription = roxywi_common.return_user_status()
except Exception as e:
user_subscription = roxywi_common.return_unsubscribed_user_status()
roxywi_common.logging('Roxy-WI server', f'Cannot get a user plan: {e}', roxywi=1)
if add_to_smon:
try:
user_subscription = roxywi_common.return_user_status()
user_group = roxywi_common.get_user_group(id=1)
json_data = {
"name": hostname,
"ip": ip,
"port": "0",
"enabled": "1",
"url": "",
"body": "",
"group": hostname,
"desc": f"Ping {hostname}",
"tg": "0",
"slack": "0",
"pd": "0",
"resolver": "",
"record_type": "",
"packet_size": "56",
"http_method": "",
"check_type": "ping",
"agent_id": "1",
"interval": "120",
}
smon_mod.create_smon(json_data, user_group)
except Exception as e:
user_subscription = roxywi_common.return_unsubscribed_user_status()
roxywi_common.logging('Roxy-WI server', f'Cannot get a user plan: {e}', roxywi=1)
roxywi_common.logging(ip, f'error: Cannot add server {hostname} to SMON: {e}', roxywi=1)
if add_to_smon:
try:
user_group = roxywi_common.get_user_group(id=1)
json_data = {
"name": hostname,
"ip": ip,
"port": "0",
"enabled": "1",
"url": "",
"body": "",
"group": hostname,
"desc": f"Ping {hostname}",
"tg": "0",
"slack": "0",
"pd": "0",
"resolver": "",
"record_type": "",
"packet_size": "56",
"http_method": "",
"check_type": "ping",
"agent_id": "1",
"interval": "120",
}
smon_mod.create_smon(json_data, user_group)
except Exception as e:
roxywi_common.logging(ip, f'error: Cannot add server {hostname} to SMON: {e}', roxywi=1)
roxywi_common.logging(ip, f'A new server {hostname} has been created', roxywi=1, login=1, keep_history=1, service='server')
roxywi_common.logging(ip, f'A new server {hostname} has been created', roxywi=1, login=1, keep_history=1, service='server')
return render_template(
'ajax/new_server.html', groups=group_sql.select_groups(), servers=server_sql.select_servers(server=ip), lang=lang,
masters=server_sql.select_servers(get_master_servers=1), sshs=cred_sql.select_ssh(group=group), page=page,
user_subscription=user_subscription, adding=1
)
except Exception as e:
return f'{e}'
@bp.post('/create/after')
def after_add():
hostname = common.checkAjaxInput(request.form.get('servername'))
ip = common.is_ip_or_dns(request.form.get('newip'))
scan_server = common.checkAjaxInput(request.form.get('scan_server'))
try:
return server_mod.update_server_after_creating(hostname, ip, scan_server)
except Exception as e:
return str(e)
@bp.post('/update')
def update_server():
roxywi_auth.page_for_admin(level=2)
name = request.form.get('updateserver')
group = request.form.get('servergroup')
typeip = request.form.get('typeip')
firewall = request.form.get('firewall')
enable = request.form.get('enable')
master = int(request.form.get('slave'))
serv_id = request.form.get('id')
cred = request.form.get('cred')
port = request.form.get('port')
protected = request.form.get('protected')
desc = request.form.get('desc')
if name is None or port is None:
return error_mess
else:
server_sql.update_server(name, group, typeip, enable, master, serv_id, cred, port, desc, firewall, protected)
server_ip = server_sql.select_server_ip_by_id(serv_id)
roxywi_common.logging(server_ip, f'The server {name} has been update', roxywi=1, login=1, keep_history=1, service='server')
return 'ok'
@bp.route('/delete/<int:server_id>')
def delete_server(server_id):
roxywi_auth.page_for_admin(level=2)
return server_mod.delete_server(server_id)
kwargs = {
'groups': group_sql.select_groups(),
'servers': server_sql.select_servers(server=ip),
'lang': lang,
'masters': server_sql.select_servers(get_master_servers=1),
'sshs': cred_sql.select_ssh(group=group),
'user_subscription': user_subscription,
'adding': 1
}
return jsonify({'status': 'created', 'id': last_id, 'data': render_template('ajax/new_server.html', **kwargs)})
elif request.method == 'PUT':
serv_id = int(json_data['id'])
if hostname is None or port is None:
return jsonify({'status': 'failed', 'error': 'Cannot find server ip or port'})
else:
try:
server_sql.update_server(hostname, group, type_ip, enable, master, serv_id, cred, port, desc, firewall, protected)
except Exception as e:
return roxywi_common.handle_json_exceptions(e, 'Roxy-WI server', 'Cannot update server')
server_ip = server_sql.select_server_ip_by_id(serv_id)
roxywi_common.logging(server_ip, f'The server {hostname} has been update', roxywi=1, login=1,
keep_history=1, service='server')
return jsonify({'status': 'updated'})
elif request.method == 'DELETE':
server_id = int(json_data['id'])
try:
server_mod.delete_server(server_id)
return jsonify({'status': 'deleted'})
except Exception as e:
roxywi_common.handle_json_exceptions(e, 'Roxy-WI server', 'Cannot delete the server')
elif request.method == 'PATCH':
hostname = common.checkAjaxInput(json_data['name'])
ip = common.is_ip_or_dns(json_data['ip'])
scan_server = int(json_data['scan_server'])
try:
server_mod.update_server_after_creating(hostname, ip, scan_server)
return jsonify({'status': 'updated'})
except Exception as e:
return roxywi_common.handle_json_exceptions(e, 'Roxy-WI server', 'Cannot scan the server')
@bp.route('/group', methods=['POST', 'PUT', 'DELETE'])
@ -222,8 +215,6 @@ def create_group():
return jsonify({'status': 'deleted'})
except Exception as e:
return roxywi_common.handle_json_exceptions(e, 'Roxy-WI server', f'Cannot delete {group_id}')
else:
abort(405)
@bp.route('/ssh', methods=['POST', 'PUT', 'DELETE', 'PATCH'])
@ -236,20 +227,20 @@ def create_ssh():
data = ssh_mod.create_ssh_cred(json_data)
return jsonify({'status': 'created', 'id': data['id'], 'data': data['template']})
except Exception as e:
return roxywi_common.handle_json_exceptions(e, 'Roxy-WI server', f'Cannot create SSH')
return roxywi_common.handle_json_exceptions(e, 'Roxy-WI server', 'Cannot create SSH')
elif request.method == 'PUT':
try:
ssh_mod.update_ssh_key(json_data)
return jsonify({'status': 'updated'})
except Exception as e:
return roxywi_common.handle_json_exceptions(e, 'Roxy-WI server', f'Cannot update SSH')
return roxywi_common.handle_json_exceptions(e, 'Roxy-WI server', 'Cannot update SSH')
elif request.method == 'DELETE':
ssh_id = int(json_data.get('id'))
try:
ssh_mod.delete_ssh_key(ssh_id)
return jsonify({'status': 'deleted'})
except Exception as e:
return roxywi_common.handle_json_exceptions(e, 'Roxy-WI server', f'Cannot delete SSH')
return roxywi_common.handle_json_exceptions(e, 'Roxy-WI server', 'Cannot delete SSH')
elif request.method == 'PATCH':
user_group = roxywi_common.get_user_group()
name = common.checkAjaxInput(json_data['name'])
@ -260,7 +251,7 @@ def create_ssh():
saved_path = ssh_mod.upload_ssh_key(name, user_group, key, passphrase)
return jsonify({'status': 'uploaded', 'message': saved_path})
except Exception as e:
return roxywi_common.handle_json_exceptions(e, 'Roxy-WI server', f'Cannot upload ssh')
return roxywi_common.handle_json_exceptions(e, 'Roxy-WI server', 'Cannot upload ssh')
@bp.app_template_filter('string_to_dict')

View File

@ -61,7 +61,7 @@ def listener_funct(service):
listener_id = int(kwargs['listener_id'])
try:
inv, server_ips = service_mod.generate_udp_inv(listener_id, 'uninstall')
service_mod.run_ansible(inv, server_ips, f'udp'), 201
service_mod.run_ansible(inv, server_ips, 'udp'), 201
roxywi_common.logging(listener_id, f'UDP listener has been deleted {listener_id}', roxywi=1, keep_history=1, login=1, service='UDP listener')
except Exception as e:
return roxywi_common.handle_json_exceptions(e, 'Roxy-WI server',f'Cannot create inventory for UDP listener deleting {listener_id}')

View File

@ -113,7 +113,7 @@ def waf_rule_edit(service, server_ip, rule_id):
conf = open(cfg, "r")
config_read = conf.read()
conf.close()
except IOError:
except IOError as e:
return f'error: Cannot read imported config file: {e}'
kwargs = {

View File

@ -0,0 +1,307 @@
$( function() {
$("#tabs ul li").click(function () {
let activeTab = $(this).find("a").attr("href");
let activeTabClass = activeTab.replace('#', '');
$('.menu li ul li').each(function () {
$(this).find('a').css('border-left', '0px solid var(--right-menu-blue-rolor)');
$(this).find('a').css('padding-left', '20px')
$(this).find('a').css('background-color', '#48505A');
$(this).children("." + activeTabClass).css('padding-left', '30px');
$(this).children("." + activeTabClass).css('border-left', '4px solid var(--right-menu-blue-rolor)');
$(this).children("." + activeTabClass).css('background-color', 'var(--right-menu-blue-rolor)');
});
if (activeTab == '#tools') {
loadServices();
} else if (activeTab == '#settings') {
loadSettings();
} else if (activeTab == '#updatehapwi') {
loadupdatehapwi();
} else if (activeTab == '#openvpn') {
loadopenvpn();
} else if (activeTab == '#backup') {
loadBackup();
}
});
} );
window.onload = function() {
$('#tabs').tabs();
let activeTabIdx = $('#tabs').tabs('option','active')
if (cur_url[0].split('#')[0] == 'admin') {
if (activeTabIdx == 6) {
loadServices();
} else if (activeTabIdx == 3) {
loadSettings();
} else if (activeTabIdx == 4) {
loadBackup();
} else if (activeTabIdx == 7) {
loadupdatehapwi();
} else if (activeTabIdx == 8) {
loadopenvpn();
}
}
}
function updateService(service, action='update') {
$("#ajax-update").html('')
$("#ajax-update").html(wait_mess);
$.ajax({
url: "/app/admin/tools/update/" + service,
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data.indexOf('Complete!') != '-1' || data.indexOf('Unpacking') != '-1') {
toastr.clear();
toastr.success(service + ' has been ' + action + 'ed');
} else if (data.indexOf('Unauthorized') != '-1' || data.indexOf('Status code: 401') != '-1') {
toastr.clear();
toastr.error('It looks like there is no authorization in the Roxy-WI repository. Your subscription may have expired or there is no subscription. How to get the <b><a href="https://roxy-wi.org/pricing" title="Pricing" target="_blank">subscription</a></b>');
} else if (data.indexOf('but not installed') != '-1') {
toastr.clear();
toastr.error('There is setting for Roxy-WI repository, but Roxy-WI is installed without repository. Please reinstall with package manager');
} else if (data.indexOf('No Match for argument') != '-1' || data.indexOf('Unable to find a match') != '-1') {
toastr.clear();
toastr.error('It seems like Roxy-WI repository is not set. Please read docs for <b><a href="https://roxy-wi.org/updates">detail</a></b>');
} else if (data.indexOf('password for') != '-1') {
toastr.clear();
toastr.error('It seems like apache user needs to be add to sudoers. Please read docs for <b><a href="https://roxy-wi.org/installation#ansible">detail</a></b>');
} else if (data.indexOf('No packages marked for update') != '-1') {
toastr.clear();
toastr.info('It seems like the lastest version Roxy-WI is installed');
} else if (data.indexOf('Connection timed out') != '-1') {
toastr.clear();
toastr.error('Cannot connect to Roxy-WI repository. Connection timed out');
} else if (data.indexOf('--disable') != '-1') {
toastr.clear();
toastr.error('It seems like there is a problem with repositories');
} else if (data.indexOf('Error: Package') != '-1') {
toastr.clear();
toastr.error(data);
} else if (data.indexOf('conflicts with file from') != '-1') {
toastr.clear();
toastr.error(data);
} else if (data.indexOf('error:') != '-1' || data.indexOf('Failed') != '-1') {
toastr.error(data);
} else if (data.indexOf('0 upgraded, 0 newly installed') != '-1') {
toastr.info('There is no a new version of ' + service);
} else {
toastr.clear();
toastr.success(service + ' has been ' + action + 'ed');
}
$("#ajax-update").html('');
loadupdatehapwi();
loadServices();
show_version();
}
});
}
function confirmDeleteOpenVpnProfile(id) {
$( "#dialog-confirm" ).dialog({
resizable: false,
height: "auto",
width: 400,
modal: true,
title: "Are you sure you want to delete profile " +id+ "?",
buttons: {
"Delete": function() {
$( this ).dialog( "close" );
removeOpenVpnProfile(id);
},
Cancel: function() {
$( this ).dialog( "close" );
}
}
});
}
function removeOpenVpnProfile(id) {
$("#" + id).css("background-color", "#f2dede");
$.ajax({
url: "/app/admin/openvpn/delete",
data: {
openvpndel: id
},
type: "POST",
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data == "ok") {
$("#" + id).remove();
} else if (data.indexOf('error:') != '-1' || data.indexOf('unique') != '-1') {
toastr.error(data);
}
}
});
}
function uploadOvpn() {
toastr.clear();
if ($("#ovpn_upload_name").val() == '' || $('#ovpn_upload_file').val() == '') {
toastr.error('All fields must be completed');
} else {
$.ajax({
url: "/app/admin/openvpn/upload",
data: {
uploadovpn: $('#ovpn_upload_file').val(),
ovpnname: $('#ovpn_upload_name').val()
},
type: "POST",
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data.indexOf('danger') != '-1' || data.indexOf('unique') != '-1' || data.indexOf('error:') != '-1') {
toastr.error(data);
} else if (data.indexOf('success') != '-1') {
toastr.clear();
toastr.success(data);
location.reload();
} else {
toastr.error('Something wrong, check and try again');
}
}
});
}
}
function OpenVpnSess(id, action) {
$.ajax({
url: "/app/admin/openvpn/" + action + "/" + id,
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data.indexOf('danger') != '-1' || data.indexOf('unique') != '-1' || data.indexOf('error:') != '-1') {
toastr.error(data);
} else if (data.indexOf('success') != '-1') {
toastr.clear();
toastr.success(data)
location.reload()
} else {
toastr.error('Something wrong, check and try again');
}
}
});
}
function loadSettings() {
$.ajax({
url: "/app/admin/settings",
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data.indexOf('error:') != '-1') {
toastr.error(data);
} else {
$('#settings').html(data);
$.getScript(awesome);
$( "input[type=checkbox]" ).checkboxradio();
$( "select" ).selectmenu();
}
}
} );
}
function loadServices() {
$.ajax({
url: "/app/admin/tools",
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data.indexOf('danger') != '-1' || data.indexOf('unique') != '-1' || data.indexOf('error:') != '-1') {
toastr.error(data);
} else {
$('#ajax-services-body').html(data);
$.getScript(awesome);
}
}
} );
}
function loadupdatehapwi() {
$.ajax({
url: "/app/admin/update",
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data.indexOf('danger') != '-1' || data.indexOf('unique') != '-1' || data.indexOf('error:') != '-1') {
toastr.error(data);
} else {
$('#ajax-updatehapwi-body').html(data);
}
}
} );
}
function checkUpdateRoxy() {
$.ajax({
url: "/app/admin/update/check",
success: function (data) {
loadupdatehapwi();
}
} );
}
function loadopenvpn() {
$.ajax({
url: "/app/admin/openvpn",
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data.indexOf('group_error') == '-1' && data.indexOf('error:') != '-1') {
toastr.error(data);
} else {
$('#openvpn').html(data);
$.getScript(awesome);
}
}
} );
}
function confirmAjaxServiceAction(action, service) {
let action_word = translate_div.attr('data-'+action);
$( "#dialog-confirm-services" ).dialog({
resizable: false,
height: "auto",
width: 400,
modal: true,
title: action_word + " " + service+"?",
buttons: [{
text: action_word,
click: function () {
$(this).dialog("close");
ajaxActionServices(action, service);
}
}, {
text: cancel_word,
click: function() {
$( this ).dialog( "close" );
}
}]
});
}
function ajaxActionServices(action, service) {
$.ajax( {
url: "/app/admin/tools/action/" + service + "/" + action,
success: function( data ) {
if (data.indexOf('error:') != '-1' || data.indexOf('Failed') != '-1') {
toastr.error(data);
} else if (data.indexOf('warning: ') != '-1') {
toastr.warning(data);
} else {
window.history.pushState("services", "services", cur_url[0].split("#")[0] + "#tools");
toastr.success('The ' + service + ' has been ' + action +'ed');
loadServices();
}
},
error: function(){
alert(w.data_error);
}
} );
}
function showApacheLog(serv) {
let rows = $('#rows').val();
let grep = $('#grep').val();
let exgrep = $('#exgrep').val();
let hour = $('#time_range_out_hour').val();
let minute = $('#time_range_out_minut').val();
let hour1 = $('#time_range_out_hour1').val();
let minute1 = $('#time_range_out_minut1').val();
let url = "/app/logs/apache_internal/" + serv + "/" + rows;
$.ajax( {
url: url,
data: {
rows: rows,
serv: serv,
grep: grep,
exgrep: exgrep,
hour: hour,
minute: minute,
hour1: hour1,
minute1: minute1
},
type: "POST",
success: function( data ) {
$("#ajax").html(data);
}
} );
}

View File

@ -0,0 +1,484 @@
$( function() {
$('#add-server-button').click(function() {
addServerDialog.dialog('open');
});
let server_tabel_title = $( "#server-add-table-overview" ).attr('title');
let addServerDialog = $( "#server-add-table" ).dialog({
autoOpen: false,
resizable: false,
height: "auto",
width: 600,
modal: true,
title: server_tabel_title,
show: {
effect: "fade",
duration: 200
},
hide: {
effect: "fade",
duration: 200
},
buttons: [{
text: add_word,
click: function () {
addServer(this);
}
}, {
text: cancel_word,
click: function () {
$(this).dialog("close");
clearTips();
}
}]
});
$( "#ajax-servers input" ).change(function() {
let id = $(this).attr('id').split('-');
updateServer(id[1])
});
$( "#ajax-servers select" ).on('selectmenuchange',function() {
let id = $(this).attr('id').split('-');
updateServer(id[1])
});
$( "#scan_server" ).change(function() {
if ($('#scan_server').is(':checked')) {
$('.services_for_scan').hide();
} else {
$('.services_for_scan').show();
}
});
});
function addServer(dialog_id) {
toastr.clear()
let valid = true;
let servername = $('#new-server-add').val();
let ip = $('#new-ip').val();
let server_group = $('#new-server-group-add').val();
let cred = $('#credentials').val();
let scan_server = 0;
let type_ip = 0;
let enable = 0;
let haproxy = 0;
let nginx = 0;
let apache = 0;
let firewall = 0;
let add_to_smon = 0;
if ($('#scan_server').is(':checked')) {
scan_server = '1';
}
if ($('#typeip').is(':checked')) {
type_ip = '1';
}
if ($('#enable').is(':checked')) {
enable = '1';
}
if ($('#haproxy').is(':checked')) {
haproxy = '1';
}
if ($('#nginx').is(':checked')) {
nginx = '1';
}
if ($('#apache').is(':checked')) {
apache = '1';
}
if ($('#firewall').is(':checked')) {
firewall = '1';
}
if ($('#add_to_smon').is(':checked')) {
add_to_smon = '1';
}
let allFields = $([]).add($('#new-server-add')).add($('#new-ip')).add($('#new-port'))
allFields.removeClass("ui-state-error");
valid = valid && checkLength($('#new-server-add'), "Hostname", 1);
valid = valid && checkLength($('#new-ip'), "IP", 1);
valid = valid && checkLength($('#new-port'), "Port", 1);
if (cred == null) {
toastr.error('First select credentials');
return false;
}
if (server_group === '------') {
toastr.error('First select a group');
return false;
}
if (server_group === undefined || server_group === null) {
server_group = $('#new-sshgroup').val();
}
if (valid) {
let json_data = {
"name": servername,
"ip": ip,
"port": $('#new-port').val(),
"group": server_group,
"type_ip": type_ip,
"haproxy": haproxy,
'nginx': nginx,
"apache": apache,
"firewall": firewall,
"add_to_smon": add_to_smon,
"enable": enable,
"slave": $('#slavefor').val(),
"cred": cred,
"desc": $('#desc').val(),
"protected": 0
}
$.ajax({
url: "/app/server",
type: "POST",
data: JSON.stringify(json_data),
contentType: "application/json; charset=utf-8",
success: function (data) {
if (data.status === 'failed') {
toastr.error(data.error);
} else {
common_ajax_action_after_success(dialog_id, 'newserver', 'ajax-servers', data.data);
$("input[type=submit], button").button();
$("input[type=checkbox]").checkboxradio();
$(".controlgroup").controlgroup();
$("select").selectmenu();
let id = data.id;
$('select:regex(id, git-server)').append('<option value=' + id + '>' + servername + '</option>').selectmenu("refresh");
$('select:regex(id, backup-server)').append('<option value=' + ip + '>' + servername + '</option>').selectmenu("refresh");
$('select:regex(id, haproxy_exp_addserv)').append('<option value=' +ip + '>' + servername + '</option>').selectmenu("refresh");
$('select:regex(id, nginx_exp_addserv)').append('<option value=' + ip + '>' + servername + '</option>').selectmenu("refresh");
$('select:regex(id, apache_exp_addserv)').append('<option value=' + ip + '>' + servername + '</option>').selectmenu("refresh");
$('select:regex(id, node_exp_addserv)').append('<option value=' + ip + '>' + servername + '</option>').selectmenu("refresh");
$('select:regex(id, geoipserv)').append('<option value=' + ip + '>' + servername + '</option>').selectmenu("refresh");
$('select:regex(id, haproxyaddserv)').append('<option value=' + ip + '>' + servername + '</option>').selectmenu("refresh");
$('select:regex(id, nginxaddserv)').append('<option value=' + ip + '>' + servername + '</option>').selectmenu("refresh");
$('select:regex(id, apacheaddserv)').append('<option value=' + ip + '>' + servername + '</option>').selectmenu("refresh");
after_server_creating(servername, ip, scan_server);
}
}
});
}
}
function after_server_creating(servername, ip, scan_server) {
let json_data = {
"name": servername,
"ip": ip,
"scan_server": scan_server
}
$.ajax({
url: "/app/server",
data: JSON.stringify(json_data),
contentType: "application/json; charset=utf-8",
type: "PATCH",
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data.indexOf('You should install lshw on the server') != '-1') {
toastr.error(data);
} else if (data.indexOf('error:') != '-1') {
toastr.error(data);
}
}
});
}
function updateServer(id) {
toastr.clear();
let type_ip = 0;
let enable = 0;
let firewall = 0;
let protected_serv = 0;
if ($('#typeip-' + id).is(':checked')) {
type_ip = '1';
}
if ($('#enable-' + id).is(':checked')) {
enable = '1';
}
if ($('#firewall-' + id).is(':checked')) {
firewall = '1';
}
if ($('#protected-' + id).is(':checked')) {
protected_serv = '1';
}
let group = $('#servergroup-' + id + ' option:selected').val();
if (group === undefined || group === null) {
group = $('#new-sshgroup').val();
}
let json_data = {
"name": $('#hostname-' + id).val(),
"port": $('#port-' + id).val(),
"group": group,
"type_ip": type_ip,
"firewall": firewall,
"enable": enable,
"slave": $('#slavefor-' + id + ' option:selected').val(),
"cred": $('#credentials-' + id + ' option:selected').val(),
"id": id,
"desc": $('#desc-' + id).val(),
"protected": protected_serv
}
$.ajax({
url: "/app/server",
type: 'PUT',
contentType: "application/json; charset=utf-8",
data: JSON.stringify(json_data),
success: function (data) {
if (data.status === 'failed') {
toastr.error(data.error);
} else {
toastr.clear();
$("#server-" + id).addClass("update", 1000);
setTimeout(function () {
$("#server-" + id).removeClass("update");
}, 2500);
}
}
});
}
function confirmDeleteServer(id) {
$( "#dialog-confirm" ).dialog({
resizable: false,
height: "auto",
width: 400,
modal: true,
title: delete_word + " " + $('#hostname-' + id).val() + "?",
buttons: [{
text: delete_word,
click: function () {
$(this).dialog("close");
removeServer(id);
}
},{
text: cancel_word,
click: function () {
$(this).dialog("close");
}
}]
});
}
function cloneServer(id) {
$( "#add-server-button" ).trigger( "click" );
if ($('#enable-'+id).is(':checked')) {
$('#enable').prop('checked', true)
} else {
$('#enable').prop('checked', false)
}
if ($('#typeip-'+id).is(':checked')) {
$('#typeip').prop('checked', true)
} else {
$('#typeip').prop('checked', false)
}
if ($('#haproxy-'+id).is(':checked')) {
$('#haproxy').prop('checked', true)
} else {
$('#haproxy').prop('checked', false)
}
if ($('#nginx-'+id).is(':checked')) {
$('#nginx').prop('checked', true)
} else {
$('#nginx').prop('checked', false)
}
$('#enable').checkboxradio("refresh");
$('#typeip').checkboxradio("refresh");
$('#haproxy').checkboxradio("refresh");
$('#nginx').checkboxradio("refresh");
$('#new-server-add').val($('#hostname-'+id).val())
$('#new-ip').val($('#ip-'+id).val())
$('#new-port').val($('#port-'+id).val())
$('#desc').val($('#desc-'+id).val())
$('#slavefor').val($('#slavefor-'+id+' option:selected').val()).change()
$('#slavefor').selectmenu("refresh");
$('#credentials').val($('#credentials-'+id+' option:selected').val()).change()
$('#credentials').selectmenu("refresh");
if (cur_url[0].indexOf('admin') != '-1') {
$('#new-server-group-add').val($('#servergroup-'+id+' option:selected').val()).change()
$('#new-server-group-add').selectmenu("refresh");
}
}
function removeServer(id) {
$("#server-" + id).css("background-color", "#f2dede");
$.ajax({
url: "/app/server",
type: "DELETE",
data: JSON.stringify({'id': id}),
contentType: "application/json; charset=utf-8",
success: function (data) {
if (data.status === 'failed') {
toastr.error(data.error);
} else {
$("#server-" + id).remove();
}
}
});
}
function viewFirewallRules(ip) {
$.ajax({
url: "/app/server/firewall/" + ip,
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data.indexOf('danger') != '-1' || data.indexOf('unique') != '-1' || data.indexOf('error: ') != '-1') {
toastr.error(data);
} else {
toastr.clear();
$("#firewall_rules_body").html(data);
$("#firewall_rules" ).dialog({
resizable: false,
height: "auto",
width: 860,
modal: true,
title: "Firewall rules",
buttons: {
Close: function() {
$( this ).dialog( "close" );
$("#firewall_rules_body").html('');
}
}
});
}
}
} );
}
function updateServerInfo(ip, id) {
$.ajax({
url: "/app/server/system_info/update/" + ip + "/" + id,
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data.indexOf('error:') != '-1' || data.indexOf('error_code') != '-1') {
toastr.error(data);
} else {
$("#server-info").html(data);
$('#server-info').show();
$.getScript(awesome);
}
}
});
}
function showServerInfo(id, ip) {
let server_info = translate_div.attr('data-server_info');
$.ajax({
url: "/app/server/system_info/get/" + ip + "/" +id,
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data.indexOf('error:') != '-1' || data.indexOf('error_code') != '-1') {
toastr.error(data);
} else {
$("#server-info").html(data);
$("#dialog-server-info").dialog({
resizable: false,
height: "auto",
width: 1000,
modal: true,
title: server_info + " (" + ip + ")",
buttons: [{
text: close_word,
click: function () {
$(this).dialog("close");
}
}]
});
$.getScript(awesome);
}
}
});
}
function serverIsUp(server_ip, server_id) {
let cur_url = window.location.href.split('/').pop();
if (cur_url.split('#')[1] == 'servers') {
$.ajax({
url: "/app/server/check/server/" + server_ip,
success: function (data) {
data = data.replace(/^\s+|\s+$/g, '');
if (data.indexOf('up') != '-1') {
$('#server_status-' + server_id).removeClass('serverNone');
$('#server_status-' + server_id).removeClass('serverDown');
$('#server_status-' + server_id).addClass('serverUp');
$('#server_status-' + server_id).attr('title', 'Server is reachable');
} else if (data.indexOf('down') != '-1') {
$('#server_status-' + server_id).removeClass('serverNone');
$('#server_status-' + server_id).removeClass('serverUp');
$('#server_status-' + server_id).addClass('serverDown');
$('#server_status-' + server_id).attr('title', 'Server is unreachable');
} else {
$('#server_status-' + server_id).removeClass('serverDown');
$('#server_status-' + server_id).removeClass('serverUp');
$('#server_status-' + server_id).addClass('serverNone');
$('#server_status-' + server_id).attr('title', 'Cannot get server status');
}
}
});
}
}
function openChangeServerServiceDialog(server_id) {
let user_groups_word = translate_div.attr('data-user_groups');
let hostname = $('#hostname-' + server_id).val();
$.ajax({
url: "/app/server/services/" + server_id,
success: function (data) {
$("#groups-roles").html(data);
$("#groups-roles").dialog({
resizable: false,
height: "auto",
width: 700,
modal: true,
title: user_groups_word + ' ' + hostname,
buttons: [{
text: save_word,
click: function () {
changeServerServices(server_id);
$(this).dialog("close");
}
}, {
text: cancel_word,
click: function () {
$(this).dialog("close");
}
}]
});
}
});
}
function addServiceToServer(service_id) {
let service_name = $('#add_service-'+service_id).attr('data-service_name');
let length_tr = $('#checked_services tbody tr').length;
let tr_class = 'odd';
if (length_tr % 2 != 0) {
tr_class = 'even';
}
let html_tag = '<tr class="'+tr_class+'" id="remove_service-'+service_id+'" data-service_name="'+service_name+'">' +
'<td class="padding20" style="width: 100%;">'+service_name+'</td>' +
'<td><span class="add_user_group" onclick="removeServiceFromUser('+service_id+')" title="'+delete_word+' '+service_word+'">-</span></td></tr>';
$('#add_service-'+service_id).remove();
$("#checked_services tbody").append(html_tag);
}
function removeServiceFromServer(service_id) {
let service_name = $('#remove_service-'+service_id).attr('data-service_name');
let length_tr = $('#all_services tbody tr').length;
let tr_class = 'odd';
if (length_tr % 2 != 0) {
tr_class = 'even';
}
let html_tag = '<tr class="'+tr_class+'" id="add_service-'+service_id+'" data-service_name="'+service_name+'">' +
'<td class="padding20" style="width: 100%;">'+service_name+'</td>' +
'<td><span class="add_user_group" onclick="addServiceToUser('+service_id+')" title="'+add_word+' '+service_word+'">+</span></td></tr>';
$('#remove_service-'+service_id).remove();
$("#all_services tbody").append(html_tag);
}
function changeServerServices(server_id) {
let jsonData = {};
$('#checked_services tbody tr').each(function () {
let this_id = $(this).attr('id').split('-')[1];
jsonData[this_id] = 1
});
$('#all_services tbody tr').each(function () {
let this_id = $(this).attr('id').split('-')[1];
jsonData[this_id] = 0
});
$.ajax({
url: "/app/server/services/" + server_id,
data: {
jsonDatas: JSON.stringify(jsonData),
changeServerServicesServer: $('#hostname-' + server_id).val(),
},
type: "POST",
success: function (data) {
if (data.indexOf('error:') != '-1' || data.indexOf('Failed') != '-1') {
toastr.error(data);
} else {
$("#server-" + server_id).addClass("update", 1000);
setTimeout(function () {
$("#server-" + server_id).removeClass("update");
}, 2500);
}
}
});
}

View File

@ -118,7 +118,6 @@ function updateSSH(id) {
ssh_enable = '1';
}
let group = $('#sshgroup-' + id).val();
console.log('group' + group)
if (group === undefined || group === null) {
group = $('#new-sshgroup').val();
}

View File

@ -18,4 +18,4 @@ const script = `${scriptPath}/script.js`;
const overview = `${scriptPath}/overview.js`;
const configShow = `${scriptPath}/configshow.js`;
const awesome = `${scriptPath}/fontawesome.min.js`;
const ha = `${scriptPath}/js/ha.js`;
const ha = `${scriptPath}/ha.js`;

View File

@ -3,11 +3,13 @@
{% block h2 %}{{lang.words.admin_area|title()}}{% endblock %}
{% block content %}
{% from 'include/input_macros.html' import input, select, copy_to_clipboard, checkbox %}
<script src="{{ url_for('static', filename='js/admin/common.js') }}"></script>
<script src="{{ url_for('static', filename='js/admin/group.js') }}"></script>
<script src="{{ url_for('static', filename='js/admin/server.js') }}"></script>
<script src="{{ url_for('static', filename='js/admin/ssh.js') }}"></script>
<script src="{{ url_for('static', filename='js/users.js') }}"></script>
<script src="{{ url_for('static', filename='js/admin/user.js') }}"></script>
<script src="{{ url_for('static', filename='js/backup.js') }}"></script>
<script src="/app/static/js/fontawesome.min.js"></script>
<script src="{{ url_for('static', filename='js/fontawesome.min.js') }}"></script>
{% include 'include/del_confirm.html' %}
<div id="tabs">
<ul id="admin-tabs">

View File

@ -3,7 +3,6 @@
{% block h2 %} Checker {{ lang.words.settings }} {% endblock %}
{% block content %}
{% from 'include/input_macros.html' import input, select, copy_to_clipboard, checkbox %}
<script src="/app/static/js/users.js"></script>
<script src="/app/static/js/checker.js"></script>
<script src="/app/static/js/fontawesome.min.js"></script>
<div id="checker"></div>

View File

@ -3,7 +3,6 @@
{% block h2 %}{{ lang.ha_page.has }} {% endblock %}
{% block content %}
{% from 'include/input_macros.html' import input, checkbox, copy_to_clipboard %}
<script src="/app/static/js/users.js"></script>
<script src="/app/static/js/ha.js"></script>
<script src="/app/static/js/overview.js"></script>
<link href="{{ url_for('static', filename='css/servers.css') }}" rel="stylesheet"/>

View File

@ -61,8 +61,6 @@
{% endfor %}
</select>
</td>
{% else %}
<input type="hidden" id="servergroup-{{server.0}}" name="servergroup-{{server.0}}" value="{{ group }}" />
{% endif %}
<td class="checkbox">
{% set id = 'enable-' + server.0|string() %}
@ -134,7 +132,7 @@
<td>
{% set id = 'desc-' + server.0|string() %}
{% if server.11 is not none %}
{{ input(id, value=server.11, size='20') }}
{{ input(id, value=server.11.replace("'", ''), size='20') }}
{% else %}
{{ input(id, size='20') }}
{% endif %}

View File

@ -4,7 +4,7 @@
<span title="It's just name alias. This alias will be use in 'Servers' page for choose credentials">{{lang.words.name|title()}}</span>
</td>
<td class="first-collumn help_cursor" style="width: 25%;" id="ssh-key-enabled-td">
<span title="If it is enabled, the key will be used, if turned off - the password. Do not forget to download the keys to all servers or install the sudo without a password">
<span title="If it is enabled, the key will be used, if turned off - the password. Do not forget to download the keys to all servers and set up the sudo without a password">
SSH {{lang.words.key}}
</span>
</td>

View File

@ -3,7 +3,7 @@
{% block h2 %}{{lang.menu_links.logs.h2}} {{service_name}}{% endblock %}
{% block content %}
{% from 'include/input_macros.html' import input, checkbox %}
<script src="/app/static/js/users.js"></script>
<script src="/app/static/js/admin/common.js"></script>
<input type="hidden" id="service" value="{{service}}" />
<table class="overview">
<tr class="overviewHead">

View File

@ -3,7 +3,7 @@
{% block h2 %}{{lang.words.internal|title()}} {{lang.words.logs}}{% endblock %}
{% block content %}
{% from 'include/input_macros.html' import input, checkbox %}
<script src="/app/static/js/users.js"></script>
<script src="/app/static/js/admin/common.js"></script>
<input type="hidden" id="service" value="{{service}}" />
<table class="overview">
<tr class="overviewHead">

View File

@ -4,7 +4,6 @@
{% from 'include/input_macros.html' import input, checkbox, select %}
{% block content %}
<script src="/app/static/js/smon.js"></script>
<script src="/app/static/js/users.js"></script>
<script src="/app/static/js/fontawesome.min.js"></script>
<script src="/app/static/js/jquery.timeago.js" type="text/javascript"></script>
<link href="{{ url_for('static', filename='css/servers.css') }}" rel="stylesheet"/>