Pavel Loginov 2022-02-16 10:46:30 +03:00
parent 009d983f83
commit 96fcc74127
15 changed files with 460 additions and 123 deletions

View File

@ -1,6 +1,7 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import sys
import funct
import sql
import http.cookies
@ -61,7 +62,7 @@ if (
elif form.getvalue('mode') is not None:
haproxy_dir = sql.get_setting('haproxy_dir')
port = form.getvalue('port')
port = form.getlist('port')
bind = ""
ip = ""
force_close = form.getvalue('force_close')
@ -74,6 +75,9 @@ elif form.getvalue('mode') is not None:
backend = ""
acl = ""
servers_split = ""
new_listener = form.getvalue('listener')
new_frontend = form.getvalue('frontend')
new_backend = form.getvalue('new_backend')
if form.getvalue('balance') is not None:
balance = " balance " + form.getvalue('balance') + "\n"
@ -85,17 +89,20 @@ elif form.getvalue('mode') is not None:
balance += " " + health_check + "\n"
if form.getvalue('ip') is not None:
ip = form.getvalue('ip')
ip = form.getlist('ip')
if form.getvalue('listener') is not None:
name = "listen " + form.getvalue('listener')
end_name = form.getvalue('listener')
elif form.getvalue('frontend') is not None:
name = "frontend " + form.getvalue('frontend')
end_name = form.getvalue('frontend')
elif form.getvalue('new_backend') is not None:
name = "backend " + form.getvalue('new_backend')
end_name = form.getvalue('new_backend')
if new_listener is not None:
name = "listen " + new_listener
end_name = new_listener
elif new_frontend is not None:
name = "frontend " + new_frontend
end_name = new_frontend
elif new_backend is not None:
name = "backend " + new_backend
end_name = new_backend
else:
print('error: The name cannot be empty')
sys.exit()
if form.getvalue('backends') is not None:
backend = " default_backend " + form.getvalue('backends') + "\n"
@ -113,10 +120,25 @@ elif form.getvalue('mode') is not None:
else:
ssl_check = " ssl verify"
if not ip and port is not None:
bind = " bind *:" + port + " " + ssl + "\n"
elif port is not None:
bind = " bind " + ip + ":" + port + " " + ssl + "\n"
if ip or port:
if type(port) is list:
i = 0
for p in port:
if ip[i] == 'IsEmptY':
if ip[i] == 'IsEmptY' and port[i] == 'IsEmptY':
i += 1
continue
else:
port_value = port[i]
bind += " bind *:" + port_value + " " + ssl + "\n"
else:
if port[i] == 'IsEmptY':
print('error: IP cannot be bind without a port')
sys.exit()
else:
port_value = port[i]
bind += " bind " + ip[i] + ":" + port_value + " " + ssl + "\n"
i += 1
if form.getvalue('default-check') == "1":
if form.getvalue('check-servers') == "1":
@ -246,6 +268,7 @@ elif form.getvalue('mode') is not None:
send_proxy = form.getlist('send_proxy')
backup = form.getlist('backup')
server_maxconn = form.getlist('server_maxconn')
port_check = form.getvalue('port_check')
i = 0
for server in servers:
if form.getvalue('template') is None:
@ -270,12 +293,18 @@ elif form.getvalue('mode') is not None:
except Exception:
maxconn_val = '200'
servers_split += " server {0} {0}:{1} maxconn {5}{2} {3} {4} \n".format(server,
try:
port_check_val = port_check[i]
except Exception:
port_check_val = port
servers_split += " server {0} {0}:{1}{2} port {6} maxconn {5} {3} {4} \n".format(server,
server_port[i],
check,
send_proxy_param,
backup_param,
maxconn_val)
maxconn_val,
port_check_val)
else:
servers_split += " server-template {0} {1} {2}:{3} {4} \n".format(form.getvalue('prefix'),
form.getvalue('template-number'),

View File

@ -858,17 +858,6 @@ def update_db_v_5_3_2_2(**kwargs):
print("Updating... DB has been updated to version 5.3.2")
def update_db_v_5_4_0(**kwargs):
query = Setting.update(value='/etc/nginx/conf.d').where(Setting.param == 'nginx_dir')
try:
query.execute()
except Exception as e:
print("An error occurred:", e)
else:
if kwargs.get('silent') != 1:
print("Updating... DB has been updated to version 5.4.0")
def update_db_v_5_4_01(**kwargs):
query = Setting.update(value='/etc/nginx/nginx.conf').where(Setting.param == 'nginx_config_path')
try:
@ -877,7 +866,7 @@ def update_db_v_5_4_01(**kwargs):
print("An error occurred:", e)
else:
if kwargs.get('silent') != 1:
print("Updating... DB has been updated to version 5.4.0-1")
print("Updating... DB has been updated to version 5.4.0")
def update_db_v_5_4_02(**kwargs):
@ -888,11 +877,26 @@ def update_db_v_5_4_02(**kwargs):
print("An error occurred:", e)
else:
if kwargs.get('silent') != 1:
print("Updating... DB has been updated to version 5.4.0-2")
print("Updating... DB has been updated to version 5.4.0-1")
def update_db_v_5_4_2(**kwargs):
cursor = conn.cursor()
sql = """ALTER TABLE `smon` ADD COLUMN slack_channel_id integer DEFAULT '0';"""
try:
cursor.execute(sql)
except Exception as e:
if kwargs.get('silent') != 1:
if str(e) == 'duplicate column name: slack_channel_id' or str(e) == '(1060, "Duplicate column name \'slack_channel_id\'")':
print('Updating... DB has been updated to version 5.4.2')
else:
print("An error occurred:", e)
else:
print("Updating... DB has been updated to version 5.4.2")
def update_ver():
query = Version.update(version='5.4.1.0')
query = Version.update(version='5.4.2.0')
try:
query.execute()
except:
@ -928,9 +932,9 @@ def update_all():
update_db_v_5_3_1()
update_db_v_5_3_2()
update_db_v_5_3_2_2()
update_db_v_5_4_0()
update_db_v_5_4_01()
update_db_v_5_4_02()
update_db_v_5_4_2()
update_ver()
@ -963,9 +967,9 @@ def update_all_silent():
update_db_v_5_3_1(silent=1)
update_db_v_5_3_2(silent=1)
update_db_v_5_3_2_2(silent=1)
update_db_v_5_4_0(silent=1)
update_db_v_5_4_01(silent=1)
update_db_v_5_4_02(silent=1)
update_db_v_5_4_2(silent=1)
update_ver()

View File

@ -13,7 +13,7 @@ if mysql_enable == '1':
conn = MySQLDatabase(mysql_db, user=mysql_user, password=mysql_password, host=mysql_host, port=int(mysql_port))
else:
db = "/var/www/haproxy-wi/app/roxy-wi.db"
conn = SqliteDatabase(db, pragmas={'timeout': 10000})
conn = SqliteDatabase(db, pragmas={'timeout': 1000})
class BaseModel(Model):
@ -30,7 +30,7 @@ class User(BaseModel):
groups = CharField()
ldap_user = IntegerField(constraints=[SQL('DEFAULT "0"')])
activeuser = IntegerField(constraints=[SQL('DEFAULT "1"')])
user_services = CharField(constraints=[SQL('DEFAULT "1 2 3"')])
user_services = CharField(constraints=[SQL('DEFAULT "1 2 3 4"')])
last_login_date = DateTimeField(constraints=[SQL('DEFAULT "0000-00-00 00:00:00"')])
last_login_ip = CharField(null=True)
@ -385,6 +385,7 @@ class SMON(BaseModel):
body_status = IntegerField(constraints=[SQL('DEFAULT 1')])
telegram_channel_id = IntegerField(null=True)
user_group = IntegerField()
slack_channel_id = IntegerField(null=True)
class Meta:
table_name = 'smon'

View File

@ -900,7 +900,9 @@ def upload(server_ip, path, file, **kwargs):
def upload_and_restart(server_ip, cfg, **kwargs):
import sql
error = ''
service_name = ''
container_name = ''
reload_or_restart_command = ''
server_id = sql.select_server_id_by_ip(server_ip=server_ip)
if kwargs.get("nginx"):
@ -1000,9 +1002,8 @@ def upload_and_restart(server_ip, cfg, **kwargs):
if not kwargs.get('slave'):
diff = ''
old_cfg = kwargs.get('oldcfg')
if not old_cfg:
if old_cfg is None:
old_cfg = tmp_file + '.old'
print(old_cfg)
try:
get_config(server_ip, old_cfg, service=service, config_file_name=config_path)
except Exception:
@ -1380,7 +1381,7 @@ def get_files(dir=get_config_var('configs', 'haproxy_save_configs_dir'), format=
file = set()
return_files = set()
i = 0
for files in sorted(glob.glob(os.path.join(dir, '*.'+format))):
for files in sorted(glob.glob(os.path.join(dir, '*.'+format+'*'))):
if format == 'log':
file += [(i, files.split('/')[5])]
else:
@ -1398,6 +1399,8 @@ def get_files(dir=get_config_var('configs', 'haproxy_save_configs_dir'), format=
def get_remote_files(server_ip: str, config_dir: str, file_format: str):
if 'nginx' not in config_dir:
return 'error: The path must contain the name of the service. Check it in Roxy-WI settings'
if config_dir[-1] != '/':
config_dir += '/'
commands = ['ls ' + config_dir + '*.' + file_format]
@ -1806,6 +1809,6 @@ def get_system_info(server_ip: str) -> bool:
else:
return False
def string_to_dict(dict_string):
def string_to_dict(dict_string) -> dict:
from ast import literal_eval
return literal_eval(dict_string)

View File

@ -1192,12 +1192,15 @@ if act == 'configShowFiles':
except:
config_file_name = ''
return_files = funct.get_remote_files(serv, nginx_config_dir, 'conf')
if 'error: ' in return_files:
print(return_files)
sys.exit()
return_files += ' ' + sql.get_setting('nginx_config_path')
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('templates/'), autoescape=True)
template = env.get_template('ajax/show_configs_files.html')
template = template.render(serv=serv, return_files=return_files, config_file_name=config_file_name)
template = template.render(serv=serv, return_files=return_files, config_file_name=config_file_name, path_dir=nginx_config_dir)
print(template)
if form.getvalue('master'):
@ -2028,6 +2031,9 @@ if form.getvalue('updateuser') is not None:
if form.getvalue('updatepassowrd') is not None:
password = form.getvalue('updatepassowrd')
if form.getvalue('uuid'):
user_id = sql.get_user_id_by_uuid(form.getvalue('uuid'))
else:
user_id = form.getvalue('id')
user = sql.select_users(id=user_id)
for u in user:
@ -2483,6 +2489,7 @@ if form.getvalue('newsmon') is not None:
group = form.getvalue('newsmongroup')
desc = form.getvalue('newsmondescription')
telegram = form.getvalue('newsmontelegram')
slack = form.getvalue('newsmonslack')
try:
port = int(port)
@ -2499,14 +2506,15 @@ if form.getvalue('newsmon') is not None:
print('SMON error: Cannot be HTTP with 443 port')
sys.exit()
last_id = sql.insert_smon(server, port, enable, http, uri, body, group, desc, telegram, user_group)
last_id = sql.insert_smon(server, port, enable, http, uri, body, group, desc, telegram, slack, user_group)
if last_id:
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('templates'), autoescape=True)
template = env.get_template('ajax/show_new_smon.html')
template = template.render(
smon=sql.select_smon_by_id(last_id),
telegrams=sql.get_user_telegram_by_group(user_group))
telegrams=sql.get_user_telegram_by_group(user_group),
slacks=sql.get_user_slack_by_group(user_group))
print(template)
funct.logging('SMON', ' Has been add a new server ' + server + ' to SMON ', haproxywi=1, login=1)
@ -2538,6 +2546,7 @@ if form.getvalue('updateSmonIp') is not None:
http = form.getvalue('updateSmonHttp')
body = form.getvalue('updateSmonBody')
telegram = form.getvalue('updateSmonTelegram')
slack = form.getvalue('updateSmonSlack')
group = form.getvalue('updateSmonGroup')
desc = form.getvalue('updateSmonDesc')
@ -2557,7 +2566,7 @@ if form.getvalue('updateSmonIp') is not None:
sys.exit()
if sql.update_smon(smon_id, ip, port, body, telegram, group, desc, en):
if sql.update_smon(smon_id, ip, port, body, telegram, slack, group, desc, en):
print("Ok")
funct.logging('SMON', ' Has been update the server ' + ip + ' to SMON ', haproxywi=1, login=1)

View File

@ -49,6 +49,7 @@ template = template.render(h2=1, title=title,
user=user,
group=user_group,
telegrams=sql.get_user_telegram_by_group(user_group),
slacks=sql.get_user_slack_by_group(user_group),
smon=smon,
smon_status=smon_status,
smon_error=stderr,

View File

@ -780,7 +780,7 @@ def get_dick_permit(**kwargs):
if funct.check_user_group(token=token):
cursor = conn.cursor()
if grp == '1' and not only_group:
sql = """ select * from servers where {} {} {} {} {} order by pos""" .format(disable, type_ip, nginx, keepalived, ip)
sql = """ select * from servers where {} {} {} {} {} {} order by pos""" .format(disable, type_ip, nginx, haproxy, keepalived, ip)
else:
sql = """ select * from servers where groups = '{group}' and ({disable}) {type_ip} {ip} {haproxy} {nginx} {keepalived} order by pos
""".format(group=grp, disable=disable, type_ip=type_ip, ip=ip, haproxy=haproxy, nginx=nginx, keepalived=keepalived)
@ -1874,7 +1874,7 @@ def select_keepalived_alert(**kwargs):
def select_keep_alive():
query = Server.select(Server.ip).where(Server.active == 1)
query = Server.select(Server.ip, Server.groups).where(Server.active == 1)
try:
query_res = query.execute()
except Exception as e:
@ -1884,7 +1884,7 @@ def select_keep_alive():
def select_nginx_keep_alive():
query = Server.select(Server.ip).where(Server.nginx_active == 1)
query = Server.select(Server.ip, Server.groups).where(Server.nginx_active == 1)
try:
query_res = query.execute()
except Exception as e:
@ -1894,7 +1894,7 @@ def select_nginx_keep_alive():
def select_keepalived_keep_alive():
query = Server.select(Server.ip).where(Server.keepalived_active == 1)
query = Server.select(Server.ip, Server.port, Server.groups).where(Server.keepalived_active == 1)
try:
query_res = query.execute()
except Exception as e:
@ -1973,7 +1973,6 @@ 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
@ -1996,7 +1995,7 @@ def check_token_exists(token):
return False
def insert_smon(server, port, enable, proto, uri, body, group, desc, telegram, user_group):
def insert_smon(server, port, enable, proto, uri, body, group, desc, telegram, slack, user_group):
try:
http = proto+':'+uri
except:
@ -2004,7 +2003,7 @@ def insert_smon(server, port, enable, proto, uri, body, group, desc, telegram, u
try:
last_id = SMON.insert(ip=server, port=port, en=enable, desc=desc, group=group, http=http, body=body,
telegram_channel_id=telegram, user_group=user_group, status='3').execute()
telegram_channel_id=telegram, slack_channel_id=slack, user_group=user_group, status='3').execute()
except Exception as e:
out_error(e)
return False
@ -2029,11 +2028,11 @@ def select_smon(user_group, **kwargs):
http = kwargs.get('proto')+':'+kwargs.get('uri')
except:
http = ''
sql = """select id, ip, port, en, http, body, telegram_channel_id, `desc`, `group`, user_group from smon
sql = """select id, ip, port, en, http, body, telegram_channel_id, `desc`, `group`, user_group, slack_channel_id from smon
where ip='%s' and port='%s' and http='%s' and body='%s' %s
""" % (kwargs.get('ip'), kwargs.get('port'), http, body, user_group)
elif kwargs.get('action') == 'add':
sql = """select id, ip, port, en, http, body, telegram_channel_id, `desc`, `group`, user_group from smon
sql = """select id, ip, port, en, http, body, telegram_channel_id, `desc`, `group`, user_group, slack_channel_id from smon
%s order by `group`""" % user_group
else:
sql = """select * from `smon` %s """ % user_group
@ -2048,8 +2047,7 @@ def select_smon(user_group, **kwargs):
def select_smon_by_id(last_id):
cursor = conn.cursor()
sql = """select id, ip, port, en, http, body, telegram_channel_id, `desc`, `group`, user_group
sql = """select id, ip, port, en, http, body, telegram_channel_id, `desc`, `group`, user_group, slack_channel_id
from `smon` where id = {} """.format(last_id)
try:
@ -2073,9 +2071,9 @@ def delete_smon(smon_id, user_group):
return True
def update_smon(smon_id, ip, port, body, telegram, group, desc, en):
def update_smon(smon_id, ip, port, body, telegram, slack, group, desc, en):
funct.check_user_group()
query = (SMON.update(ip=ip, port=port, body=body, telegram_channel_id=telegram, group=group, desc=desc, en=en)
query = (SMON.update(ip=ip, port=port, body=body, telegram_channel_id=telegram, slack_channel_id=slack, group=group, desc=desc, en=en)
.where(SMON.id == smon_id))
try:
query.execute()
@ -2110,14 +2108,14 @@ def alerts_history(service, user_group, **kwargs):
def select_en_service():
cursor = conn.cursor()
sql = """ select ip, port, telegram_channel_id, id, user_group from smon where en = 1"""
query = SMON.select().where(SMON.en == 1)
try:
cursor.execute(sql)
query_res = query.execute()
except Exception as e:
out_error(e)
else:
return cursor.fetchall()
return query_res
def select_status(smon_id):
@ -2285,6 +2283,20 @@ def select_alerts(user_group):
return cursor.fetchall()
def select_all_alerts_for_all():
cursor = conn.cursor()
if mysql_enable == '1':
sql = """ select level, message, `date`, user_group from alerts where `date` <= (now()+ INTERVAL 10 second) """
else:
sql = """ select level, message, `date`, user_group from alerts where `date` >= datetime('now', '-10 second', 'localtime') and `date` <= datetime('now', 'localtime') ; """
try:
cursor.execute(sql)
except Exception as e:
out_error(e)
else:
return cursor.fetchall()
def is_cloud():
cursor = conn.cursor()
sql = """ select * from cloud_uuid """
@ -3019,3 +3031,13 @@ def is_system_info(server_id):
return False
else:
return True
def select_os_info(server_id):
try:
query_res = SystemInfo.get(SystemInfo.server_id == server_id).os_info
except Exception as e:
out_error(e)
return
else:
return query_res

View File

@ -71,10 +71,13 @@
<td class="addName">IP and Port:</td>
<td class="addOption">
{{ input('ip', placeholder="Any", size='15') }}<b>:</b>
{{ input('listen-port', name='port', type="number", title="Port for bind listen", placeholder="8080", size='5', required='required') }}
{{ input('listen-port', name='port', title="Port for bind listen", placeholder="8080", size='5', required='required') }}
<div id="listener_bind" style="display: none"></div>
<a class="link add-server" id="add_bind_listener" title="Bind one more IP-port pair"></a>
<div class="tooltip tooltipTop">
If the IP-address for the listener is empty, it will listen on all IP addresses. <br />
Start typing IP or press down button. If you are using <b>VRRP, leave the IP field blank</b>. If you assign a VRRP IP, the slave server will not start
If the IP-address for the listener is empty, it will listen on all IP addresses.
Start typing IP or press down button. Click on + to add multiple IP-port pairs. If you are using VRRP,
leave the IP field blank. If you assign a VRRP IP, the slave server will not start.
</div>
</td>
</tr>
@ -137,7 +140,7 @@
{{ select('listener_acl_then', name='acl_then', values=values, first='Choose action', class='force_close', disabled=false) }}
<b class="padding10">value</b>
{{ input('listener_acl_then_value', name='acl_then_value', title="Required if \'then\' is \'Use backend\' or \'Redirect\', \'Return\', or \'Set-header\'") }}
<span class="minus minus-style" onclick="delete_acl_rule('listener_acl_rule')" title="Delete this rule"></span>
<span class="minus minus-style" onclick="deleteId('listener_acl_rule')" title="Delete this rule"></span>
</p>
</div>
<span>
@ -227,14 +230,14 @@
{% include 'include/add_servers.html' %}
<br>
<br>
{{ checkbox('template-listen', name='template', title='Use server-template instead servers list', value='template', desc='Server-template') }}
{{ checkbox('template-listen', name='template', title='Сreate the list of servers from the template', value='template', desc='Server-template') }}
</td>
</tr>
<tr class="advance">
<td class="addName">Check:</td>
<td class="addOption">
<div>
<label for="controlgroup-listen-show" style="margin-top: 5px;" title="Change default check">Custom check params</label>
<label for="controlgroup-listen-show" style="margin-top: 5px;" title="Set custom check parameters">Custom check params</label>
<input type="checkbox" id="controlgroup-listen-show" name="default-check" value="1">
<span class="tooltip tooltipTop"> Default params: inter 2000 rise 2 fall 5</span>
</div>
@ -275,7 +278,7 @@
<a class="ui-button ui-widget ui-corner-all" title="Add Listen" onclick="addProxy('add-listener')">Add Listen</a>
</td>
<td class="addButton">
<a class="ui-button ui-widget ui-corner-all" title="Generate config and show it" onclick="generateConfig('add-listener')">Generate config</a>
<a class="ui-button ui-widget ui-corner-all" title="Generate and display config" onclick="generateConfig('add-listener')">Generate config</a>
</td>
</tr>
</table>
@ -320,10 +323,13 @@
<td class="addName">IP and Port:</td>
<td class="addOption">
<input type="text" name="ip" id="ip1" size="15" placeholder="Any" class="form-control"><b>:</b>
<input type="number" name="port" required title="Port for bind frontend" placeholder="8080" class="form-control">
<input type="text" name="port" size="5" required title="Port for bind frontend" placeholder="8080" class="form-control">
<div id="frontend_bind" style="display: none"></div>
<a class="link add-server" id="add_bind_frontend" title="Bind one more IP-port pair"></a>
<div class="tooltip tooltipTop">
If the IP-address for the frontend is empty, it will listen on all IP addresses. <br />
Start typing IP or press down button. If you are using <b>VRRP, leave the IP field blank</b>. If you assign a VRRP IP, the slave server will not start
If the IP-address for the listener is empty, it will listen on all IP addresses.
Start typing IP or press down button. Click on + to add multiple IP-port pairs. If you are using VRRP,
leave the IP field blank. If you assign a VRRP IP, the slave server will not start.
</div>
</td>
</tr>
@ -366,7 +372,7 @@
{{ select('frontend_acl_then', name='acl_then', values=values, first='Choose action', class='force_close', disabled=false) }}
<b class="padding10">value</b>
{{ input('frontend_acl_then_value', name='acl_then_value', title="Required if \'then\' is \'Use backend\' or \'Redirect\', \'Return\', or \'Set-header\'") }}
<span class="minus minus-style" onclick="delete_acl_rule('frontend_acl_rule')" title="Delete this rule"></span>
<span class="minus minus-style" onclick="deleteId('frontend_acl_rule')" title="Delete this rule"></span>
</p>
</div>
<span>
@ -451,7 +457,7 @@
<a class="ui-button ui-widget ui-corner-all" title="Add Frontend" onclick="addProxy('add-frontend')">Add Frontend</a>
</td>
<td class="addButton">
<a class="ui-button ui-widget ui-corner-all" title="Generate config and show it" onclick="generateConfig('add-frontend')">Generate config</a>
<a class="ui-button ui-widget ui-corner-all" title="Generate and display config" onclick="generateConfig('add-frontend')">Generate config</a>
</td>
</tr>
</table>
@ -542,7 +548,7 @@
{{ select('backend_acl_then', name='acl_then', values=values, first='Choose action', class='force_close', disabled=false) }}
<b class="padding10">value</b>
{{ input('backend_acl_then_value', name='acl_then_value', title="Required if \'then\' is \'Use backend\', \'Redirect\', \'Return\', or \'Set-header\'") }}
<span class="minus minus-style" onclick="delete_acl_rule('backend_acl_rule')" title="Delete this rule"></span>
<span class="minus minus-style" onclick="deleteId('backend_acl_rule')" title="Delete this rule"></span>
</p>
</div>
<span>
@ -611,14 +617,14 @@
{% include 'include/add_servers.html' %}
<br>
<br>
{{ checkbox('template-backend', name='template', title='Use server-template instead servers list', value='template', desc='Server-template') }}
{{ checkbox('template-backend', name='template', title='Create the list of servers from the template', value='template', desc='Server-template') }}
</td>
</tr>
<tr class="advance">
<td class="addName">Check:</td>
<td class="addOption">
<div>
<label for="controlgroup-backend-show" style="margin-top: 5px;" title="Change default check">Custom check params</label>
<label for="controlgroup-backend-show" style="margin-top: 5px;" title="Set custom check parameters">Custom check params</label>
<input type="checkbox" id="controlgroup-backend-show" name="default-check">
<span class="tooltip tooltipTop"> Default params: inter 2000 rise 2 fall 5</span>
</div>
@ -659,7 +665,7 @@
<a class="ui-button ui-widget ui-corner-all" title="Add Backend" onclick="addProxy('add-backend')">Add Backend</a>
</td>
<td class="addButton">
<a class="ui-button ui-widget ui-corner-all" title="Generate config and show it" onclick="generateConfig('add-backend')">Generate config</a>
<a class="ui-button ui-widget ui-corner-all" title="Generate and display config" onclick="generateConfig('add-backend')">Generate config</a>
</td>
</tr>
</table>
@ -900,7 +906,7 @@
<td class="addOption">
<span id="userlist-users">
{{ input('userlist-user', required='required', title="Username", placeholder="user_name") }}
{{ input('userlist-password', required='required', title="User password. By default it insecure-password", placeholder="password") }}
{{ input('userlist-password', required='required', title="User password. By default, it insecure-password", placeholder="password") }}
{{ input('userlist-user-group', title="User`s group", placeholder="user`s group") }}
</span>
<span>
@ -914,7 +920,7 @@
<a class="ui-button ui-widget ui-corner-all" title="Add Userlist" onclick="addProxy('add-userlist')">Add Userlist</a>
</td>
<td class="addButton">
<a class="ui-button ui-widget ui-corner-all" title="Generate config and show it" onclick="generateConfig('add-userlist')">Generate config</a>
<a class="ui-button ui-widget ui-corner-all" title="Generate and display config" onclick="generateConfig('add-userlist')">Generate config</a>
</td>
</tr>
</table>
@ -954,7 +960,7 @@
</div>
</div>
<div id="peers">
<form name="add-userlist" id="add-peers" action="/app/add.py" method="post">
<form name="add-peers" id="add-peers" action="/app/add.py" method="post">
<table>
<caption><h3>Add Peer</h3></caption>
<tr>
@ -1000,7 +1006,7 @@
<a class="ui-button ui-widget ui-corner-all" title="Add Userlist" onclick="addProxy('add-peers')">Add Peer</a>
</td>
<td class="addButton">
<a class="ui-button ui-widget ui-corner-all" title="Generate config and show it" onclick="generateConfig('add-peers')">Generate config</a>
<a class="ui-button ui-widget ui-corner-all" title="Generate and display config" onclick="generateConfig('add-peers')">Generate config</a>
</td>
</tr>
</table>
@ -1099,7 +1105,6 @@
<input type="hidden" id="group" value="{{ group }}">
</div>
</div>
{% include 'include/del_confirm.html' %}
<script>
$( function() {
$( ".force_close" ).selectmenu({

View File

@ -267,10 +267,12 @@
</select>
</td>
</tr>
<tr id="show-user-settings-group"></tr>
</table>
</div>
<div id="current-user-groups-dialog" style="display: none;">
<div id="current-user-groups-form"></div>
</div>
{% include 'include/change_pass_form.html' %}
</body>
</html>

View File

@ -7,18 +7,21 @@
<input name="prefix" class="prefix form-control" title="servers prefix" size="3" placeholder="web" style="display: none;">
<input name="template-number" class="prefix form-control" title="servers num" value="3" type="number" style="width: 35px; display: none;">
<input name="servers" required title="Backend IP" size=14 placeholder="xxx.xxx.xxx.xxx" class="form-control">:
<input name="server_port" required title="Backend port" size=3 placeholder="yyy" class="form-control add_server_number" type="number">
<input name="server_maxconn" required title="Maxconn. Default 200" size=5 value="200" class="form-control add_server_number" type="number">
<input name="server_port" required title="Backend port" size=8 placeholder="yyy" class="form-control add_server_number" type="number">
<span name="port_check_text">port check:</span> <input name="port_check" required title="Port for checking" size=8 class="form-control add_server_number" type="number">
<span name="maxconn_name">maxconn:</span> <input name="server_maxconn" required title="Maxconn. Default 200" size=8 value="200" class="form-control add_server_number" type="number">
<span class="send_proxy"></span>
<br />
<input name="servers" title="Backend IP" size=14 placeholder="xxx.xxx.xxx.xxx" class="form-control second-server"><span class="second-server">:</span>
<input name="server_port" title="Backend port" size=8 placeholder="yyy" class="form-control second-server add_server_number" type="number">
<span name="port_check_text">port check:</span> <input name="port_check" required title="Port for checking" size=8 class="form-control add_server_number" type="number">
<span name="maxconn_name">maxconn:</span> <input name="server_maxconn" required title="Maxconn. Default 200" size=8 value="200" class="form-control add_server_number" type="number">
<span class="send_proxy"></span>
<br />
<input name="servers" title="Backend IP" size=14 placeholder="xxx.xxx.xxx.xxx" class="form-control second-server"><span class="second-server">:</span>
<input name="server_port" title="Backend port" size=3 placeholder="yyy" class="form-control second-server add_server_number" type="number">
<input name="server_maxconn" title="Maxconn. Default 200" size=5 value="200" class="form-control add_server_number" type="number">
<span class="send_proxy"></span>
<br />
<input name="servers" title="Backend IP" size=14 placeholder="xxx.xxx.xxx.xxx" class="form-control second-server"><span class="second-server">:</span>
<input name="server_port" title="Backend port" size=3 placeholder="yyy" class="form-control second-server add_server_number" type="number">
<input name="server_maxconn" required title="Maxconn. Default 200" size=5 value="200" class="form-control add_server_number" type="number">
<span name="port_check_text">port check:</span> <input name="port_check" required title="Port for checking" size=8 class="form-control add_server_number" type="number">
<span name="maxconn_name">maxconn:</span> <input name="server_maxconn" required title="Maxconn. Default 200" size=8 value="200" class="form-control add_server_number" type="number">
<span class="send_proxy"></span>
</span>
<span>

View File

@ -49,6 +49,18 @@
{% endfor %}
</select>
</td>
<td>
<select id="smon-slack-{{s.0}}">
<option value="0">Disabled</option>
{% for t in slacks %}
{% if s.10|int() == t.id|int() %}
<option value="{{t.id}}" selected>{{t.chanel_name}}</option>
{% else %}
<option value="{{t.id}}">{{t.chanel_name}}</option>
{% endif %}
{% endfor %}
</select>
</td>
<td>
{% set id = 'smon-group-' + s.0|string() %}
{% if s.8 is not none %}
@ -77,6 +89,9 @@
$("#smon-telegram-{{s.0}}" ).selectmenu({
width: 170
});
$("#smon-slack-{{s.0}}" ).selectmenu({
width: 170
});
$("#smon-proto-{{s.0}}" ).selectmenu({
width: 78
});

View File

@ -50,6 +50,7 @@
<th style="width: 15%;">URI</th>
<th style="width: 20%;">Body</th>
<th style="width: 15%;">Telegram</th>
<th style="width: 15%;">Slack</th>
<th style="width: 10%;">Group</th>
<th style="width: 100%;">Description</th>
<th></th>
@ -124,6 +125,17 @@
</select>
</td>
</tr>
<tr>
<td class="padding20">Slack</td>
<td>
<select id="new-smon-slack">
<option value="0">Disabled</option>
{% for t in slacks %}
<option value="{{t.id}}">{{t.chanel_name}}</option>
{% endfor %}
</select>
</td>
</tr>
<tr>
<td class="padding20">Group</td>
<td>{{ input('new-smon-group') }}</td>

View File

@ -259,6 +259,7 @@ $( function() {
$( "#ip" ).autocomplete({
source: function( request, response ) {
if(!checkIsServerFiled('#serv')) return false;
if ( request.term == "" ) {
request.term = 1
}
@ -283,13 +284,14 @@ $( function() {
});
$( "#ip1" ).autocomplete({
source: function( request, response ) {
if(!checkIsServerFiled('#serv2')) return false;
if ( request.term == "" ) {
request.term = 1
}
$.ajax( {
url: "options.py",
data: {
ip: request.term,
show_ip: request.term,
serv: $("#serv2").val(),
token: $('#token').val()
},
@ -302,11 +304,12 @@ $( function() {
autoFocus: true,
minLength: -1,
select: function( event, ui ) {
$(this).next().next().focus();
$('#frontend-port').focus();
}
});
$( "#backends" ).autocomplete({
source: function( request, response ) {
if(!checkIsServerFiled('#serv2')) return false;
if ( request.term == "" ) {
request.term = 1
}
@ -748,6 +751,9 @@ $( function() {
$( ".backend_server" ).hide( "fast" );
$( ".send_proxy" ).hide( "fast" );
$( "input[name=server_maxconn]" ).hide( "fast" );
$( "input[name=port_check]" ).hide( "fast" );
$( "[name=maxconn_name]" ).hide( "fast" );
$( "[name=port_check_text]" ).hide( "fast" );
$( ".prefix" ).attr('required',true);
} else {
$( ".prefix" ).hide( "fast" );
@ -756,6 +762,9 @@ $( function() {
$( ".backend_server" ).show( "fast" )
$( ".send_proxy" ).show( "fast" )
$( "input[name=server_maxconn]" ).show( "fast" );
$( "input[name=port_check]" ).show( "fast" );
$( "[name=maxconn_name]" ).show( "fast" );
$( "[name=port_check_text]" ).show( "fast" );
}
});
var location = window.location.href;
@ -870,6 +879,7 @@ $( function() {
$( "#path-cert-listen" ).autocomplete({
source: function( request, response ) {
if(!checkIsServerFiled('#serv2')) return false;
$.ajax( {
url: "options.py",
data: {
@ -888,6 +898,7 @@ $( function() {
});
$( "#path-cert-frontend" ).autocomplete({
source: function( request, response ) {
if(!checkIsServerFiled('#serv2')) return false;
$.ajax( {
url: "options.py",
data: {
@ -905,6 +916,9 @@ $( function() {
minLength: -1
});
$( "#ssl_key_upload" ).click(function() {
if(!checkIsServerFiled('#serv4')) return false;
if(!checkIsServerFiled('#ssl_name', 'Enter the Certificate name')) return false;
if(!checkIsServerFiled('#ssl_cert', 'Paste the contents of the certificate file')) return false;
$.ajax( {
url: "options.py",
data: {
@ -927,6 +941,7 @@ $( function() {
} );
});
$('#ssl_key_view').click(function() {
if(!checkIsServerFiled('#serv5')) return false;
$.ajax( {
url: "options.py",
data: {
@ -999,12 +1014,20 @@ $( function() {
toastr.error('Wrong e-mail format');
}
});
var add_server_var = '<br /><input name="servers" title="Backend IP" size=14 placeholder="xxx.xxx.xxx.xxx" class="form-control second-server">: ' +
var add_server_var = '<br /><input name="servers" title="Backend IP" size=14 placeholder="xxx.xxx.xxx.xxx" class="form-control second-server" style="margin: 2px 0 4px 0;">: ' +
'<input name="server_port" required title="Backend port" size=3 placeholder="yyy" class="form-control second-server add_server_number" type="number"> ' +
'<input name="server_maxconn" required title="Maxconn. Default 200" size=5 value="200" class="form-control add_server_number" type="number">'
'port check: <input name="port_check" required title="Maxconn. Default 200" size=5 value="200" class="form-control add_server_number" type="number">' +
' maxconn: <input name="server_maxconn" required title="Maxconn. Default 200" size=5 value="200" class="form-control add_server_number" type="number">'
$('[name=add-server-input]').click(function() {
$("[name=add_servers]").append(add_server_var);
changePortCheckFromServerPort();
});
$('[name=port]').on('input', function (){
var iNum = parseInt($('[name=port]').val());
$('[name=port_check]').val(iNum);
$('[name=server_port]').val(iNum);
});
changePortCheckFromServerPort();
var add_userlist_var = '<br /><input name="userlist-user" title="User name" placeholder="user_name" class="form-control"> <input name="userlist-password" required title="User password. By default it insecure-password" placeholder="password" class="form-control"> <input name="userlist-user-group" title="User`s group" placeholder="user`s group" class="form-control">'
$('#add-userlist-user').click(function() {
$('#userlist-users').append(add_userlist_var);
@ -1229,6 +1252,14 @@ $( function() {
$("#backend_add_acl").click(function(){
make_actions_for_adding_acl_rule('#backend_acl');
});
$("#add_bind_listener").click(function(){
make_actions_for_adding_bind('#listener_bind');
$( "#listener_bind" ).show();
});
$("#add_bind_frontend").click(function(){
make_actions_for_adding_bind('#frontend_bind');
$( "#frontend_bind" ).show();
});
$( "#serv" ).on('selectmenuchange',function() {
$('#name').focus();
});
@ -1243,6 +1274,7 @@ $( function() {
});
});
function resetProxySettings() {
$('[name=ip]').val('');
$('[name=port]').val('');
$('[name=server_port]').val('');
$('input:checkbox').prop( "checked", false );
@ -1422,6 +1454,7 @@ function updateSavedServer(id) {
} );
}
function view_ssl(id) {
if(!checkIsServerFiled('#serv5')) return false;
$.ajax( {
url: "options.py",
data: {
@ -1456,6 +1489,7 @@ function view_ssl(id) {
} );
}
function deleteSsl(id) {
if(!checkIsServerFiled('#serv5')) return false;;
$.ajax( {
url: "options.py",
data: {
@ -1658,6 +1692,24 @@ function deleteList(list, color) {
}
function generateConfig(form_name) {
var frm = $('#'+form_name);
if (form_name == 'add-listener') {
serv = '#serv'
name_id = '#name'
} else if (form_name == 'add-frontend') {
serv = '#serv2'
name_id = '#new_frontend'
} else if (form_name == 'add-backend') {
serv = '#serv3'
name_id = '#new_backend'
} else if (form_name == 'add-userlist') {
serv = '#userlist_serv'
name_id = '#new_userlist'
} else {
serv = '#peers_serv'
name_id = '#peers-name'
}
if(!checkIsServerFiled(serv)) return false;
if(!checkIsServerFiled(name_id, 'The name cannot be empty')) return false;
var input = $("<input>")
.attr("name", "generateconfig").val("1").attr("type", "hidden").attr("id", "generateconfig");
$('#'+form_name +' input[name=acl_then_value]').each(function(){
@ -1665,12 +1717,26 @@ function generateConfig(form_name) {
$(this).val('IsEmptY')
}
});
$('#'+form_name +' input[name=ip]').each(function(){
if (!$(this).val()){
$(this).val('IsEmptY')
}
});
$('#'+form_name +' input[name=port]').each(function(){
if (!$(this).val()){
$(this).val('IsEmptY')
}
});
frm.append(input);
$.ajax({
url: frm.attr('action'),
data: frm.serialize(),
type: frm.attr('method'),
success: function (data) {
if (data.indexOf('error: ') != '-1' || data.indexOf('Fatal') != '-1') {
toastr.clear();
toastr.error(data);
} else {
$('#dialog-confirm-body').text(data);
$("#dialog-confirm-cert").dialog({
resizable: false,
@ -1685,6 +1751,7 @@ function generateConfig(form_name) {
}
});
}
}
});
$("#generateconfig").remove();
$('#'+form_name +' input[name=acl_then_value]').each(function(){
@ -1692,14 +1759,52 @@ function generateConfig(form_name) {
$(this).val('')
}
});
$('#'+form_name +' input[name=ip]').each(function(){
if ($(this).val() == 'IsEmptY'){
$(this).val('')
}
});
$('#'+form_name +' input[name=port]').each(function(){
if ($(this).val() == 'IsEmptY'){
$(this).val('')
}
});
}
function addProxy(form_name) {
var frm = $('#'+form_name);
if (form_name == 'add-listener') {
serv = '#serv'
name_id = '#name'
} else if (form_name == 'add-frontend') {
serv = '#serv2'
name_id = '#new_frontend'
} else if (form_name == 'add-backend') {
serv = '#serv3'
name_id = '#new_backend'
} else if (form_name == 'add-userlist') {
serv = '#userlist_serv'
name_id = '#new_userlist'
} else {
serv = '#peers_serv'
name_id = '#peers-name'
}
if(!checkIsServerFiled(serv)) return false;
if(!checkIsServerFiled(name_id, 'The name cannot be empty')) return false;
$('#'+form_name +' input[name=acl_then_value]').each(function(){
if ($(this).val().length === 0){
$(this).val('IsEmptY')
}
});
$('#'+form_name +' input[name=ip]').each(function(){
if ($(this).val().length === 0){
$(this).val('IsEmptY')
}
});
$('#'+form_name +' input[name=port]').each(function(){
if ($(this).val().length === 0){
$(this).val('IsEmptY')
}
});
$.ajax({
url: frm.attr('action'),
data: frm.serialize(),
@ -1714,7 +1819,7 @@ function addProxy(form_name) {
toastr.error('error: Proxy cannot be empty');
} else {
toastr.clear();
toastr.success('Section: ' + data + 'has been added. Do not forget to restart the server');
toastr.success('Section: <b>' + data + '</b> has been added. Do not forget to restart the server');
var ip = frm.find('select[name=serv]').val();
localStorage.setItem('restart', ip);
resetProxySettings();
@ -1726,6 +1831,16 @@ function addProxy(form_name) {
$(this).val('')
}
});
$('#'+form_name +' input[name=ip]').each(function(){
if ($(this).val() == 'IsEmptY'){
$(this).val('')
}
});
$('#'+form_name +' input[name=port]').each(function(){
if ($(this).val() == 'IsEmptY'){
$(this).val('')
}
});
}
function confirmDeleting(deleting_thing, id, dialog_id, color) {
$( "#dialog-confirm" ).dialog({
@ -1752,8 +1867,14 @@ function confirmDeleting(deleting_thing, id, dialog_id, color) {
}
});
}
function delete_acl_rule(id) {
function deleteId(id) {
$('#'+id).remove();
if ($('#listener_bind > p').length == 0) {
$('#listener_bind').hide();
}
if ($('#frontend_bind > p').length == 0) {
$('#frontend_bind').hide();
}
}
var acl_option = '<p id="new_acl_p" style="border-bottom: 1px solid #ddd; padding-bottom: 10px;">\n' +
'<b class="padding10">if</b>\n' +
@ -1784,7 +1905,7 @@ var acl_option = '<p id="new_acl_p" style="border-bottom: 1px solid #ddd; paddin
function make_actions_for_adding_acl_rule(section_id) {
var random_id = makeid(3);
$(section_id).append(acl_option);
$('#new_acl_rule_minus').attr('onclick', 'delete_acl_rule(\''+random_id+'\')');
$('#new_acl_rule_minus').attr('onclick', 'deleteId(\''+random_id+'\')');
$('#new_acl_rule_minus').attr('id', '');
$('#new_acl_p').attr('id', random_id);
$('#new_acl_rule_minus').attr('id', '');
@ -1793,6 +1914,48 @@ function make_actions_for_adding_acl_rule(section_id) {
$('[name=acl_if]').selectmenu({width: 180});
$('[name=acl_then]').selectmenu({width: 180});
}
var bind_option = '<p id="new_bind_p"><input type="text" name="ip" size="15" placeholder="Any" class="form-control ui-autocomplete-input" autocomplete="off">' +
'<b>:</b> ' +
'<input type="text" name="port" size="5" style="" required="" placeholder="8080" title="Port for bind listen" class="form-control" autocomplete="off"> ' +
'<span class="minus minus-style" id="new_bind_minus" title="Remove the IP-port pair"></span>'
function make_actions_for_adding_bind(section_id) {
var random_id = makeid(3);
$(section_id).append(bind_option);
$('#new_bind_minus').attr('onclick', 'deleteId(\''+random_id+'\')');
$('#new_bind_minus').attr('id', '');
$('#new_bind_p').attr('id', random_id);
$('#new_bind_minus').attr('id', '');
$.getScript("/inc/fontawesome.min.js");
$( "select" ).selectmenu();
var serv = 'serv2'
if(section_id == '#listener_bind') {
serv = 'serv'
}
$( "#"+random_id + " > input[name=ip]").autocomplete({
source: function( request, response ) {
if ( request.term == "" ) {
request.term = 1
}
$.ajax( {
url: "options.py",
data: {
show_ip: request.term,
serv: $("#"+serv).val(),
token: $('#token').val()
},
success: function( data ) {
data = data.replace(/\s+/g,' ');
response(data.split(" "));
}
} );
},
autoFocus: true,
minLength: -1,
select: function( event, ui ) {
$( "#"+random_id + " > input[name=port]").focus();
}
});
}
function makeid(length) {
var result = '';
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
@ -1830,3 +1993,16 @@ function showUserlists() {
});
}
}
function changePortCheckFromServerPort() {
$('[name=server_port]').on('input', function (){
var iNum = parseInt($($(this)).val());
$($(this)).next().val(iNum);
});
}
function checkIsServerFiled(select_id, message = 'Choose the server first') {
if ($(select_id).val() == null || $(select_id).val() == '') {
toastr.warning(message);
return false;
}
return true;
}

View File

@ -325,7 +325,7 @@ function showLog() {
},
type: "POST",
success: function( data ) {
if (data.indexOf('error:') != '-1' && data.indexOf('Internal error:') == '-1') {
if (data.indexOf('Internal error:') == '-1') {
toastr.error(data);
} else {
toastr.clear();
@ -611,9 +611,6 @@ function viewLogs() {
},
type: "POST",
success: function( data ) {
if (data.indexOf('error: ') != '-1') {
toastr.error(data);
} else {
$("#ajax").html(data);
window.history.pushState("View logs", "View logs", cur_url[0] + "?type=" + type +
"&viewlogs=" + viewlogs +
@ -625,7 +622,6 @@ function viewLogs() {
'&hour1=' + hour1 +
'&minut1=' + minut1);
}
}
} );
}
}
@ -873,7 +869,8 @@ $( function() {
saveUserSettings();
$( this ).dialog( "close" );
},
Cancel: function () {
'Change password': function() {
changePassword();
$( this ).dialog( "close" );
},
Logout: function() {
@ -904,7 +901,7 @@ $( function() {
if (data.indexOf('danger') != '-1') {
$("#ajax").html(data);
} else {
$('#show-user-settings-table').append(data);
$('#show-user-settings-group').html(data);
$( "select" ).selectmenu();
}
}
@ -1246,3 +1243,58 @@ async function waitConsumer() {
}
}
setInterval(waitConsumer, 20000);
function changePassword() {
$( "#user-change-password-table" ).dialog({
autoOpen: true,
resizable: false,
height: "auto",
width: 600,
modal: true,
title: "Change password",
show: {
effect: "fade",
duration: 200
},
hide: {
effect: "fade",
duration: 200
},
buttons: {
"Change": function() {
changeUserPasswordItOwn($(this));
},
Cancel: function() {
$( this ).dialog( "close" );
$('#missmatchpass').hide();
}
}
});
}
function changeUserPasswordItOwn(d) {
var pass = $('#change-password').val();
var pass2 = $('#change2-password').val();
if(pass != pass2) {
$('#missmatchpass').show();
} else {
$('#missmatchpass').hide();
toastr.clear();
$.ajax( {
url: "options.py",
data: {
updatepassowrd: pass,
uuid: Cookies.get('uuid'),
token: $('#token').val()
},
type: "POST",
success: function( data ) {
data = data.replace(/\s+/g,' ');
if (data.indexOf('error:') != '-1') {
toastr.error(data);
} else {
toastr.clear();
d.dialog( "close" );
}
}
} );
}
}

View File

@ -88,6 +88,7 @@ function addNewSmonServer(dialog_id) {
newsmongroup: $('#new-smon-group').val(),
newsmondescription: $('#new-smon-description').val(),
newsmontelegram: $('#new-smon-telegram').val(),
newsmonslack: $('#new-smon-slack').val(),
token: $('#token').val()
},
type: "POST",
@ -159,6 +160,7 @@ function updateSmon(id) {
updateSmonHttp: $('#smon-proto1-'+id).text(),
updateSmonBody: $('#smon-body-'+id).text(),
updateSmonTelegram: $('#smon-telegram-'+id).val(),
updateSmonSlack: $('#smon-slack-'+id).val(),
updateSmonGroup: $('#smon-group-'+id).val(),
updateSmonDesc: $('#smon-desc-'+id).val(),
id: id,
@ -192,7 +194,8 @@ function cloneSmom(id) {
$('#new-smon-group').val($('#smon-group-'+id).val());
$('#new-smon-description').val($('#smon-desc-'+id).val())
$('#new-smon-telegram').val($('#smon-telegram-'+id+' option:selected').val()).change()
$('#new-smon-telegram').selectmenu("refresh");
$('#new-smon-slack').val($('#smon-slack-'+id+' option:selected').val()).change()
$('#new-smon-slack').selectmenu("refresh");
}
$( function() {
$('#add-smon-button').click(function() {