mirror of https://github.com/Aidaho12/haproxy-wi
parent
07cdbbfab5
commit
7d47e94160
|
@ -36,6 +36,7 @@ from app.routes.user import bp as user_bp
|
|||
from app.routes.server import bp as server_bp
|
||||
from app.routes.admin import bp as admin_bp
|
||||
from app.routes.ha import bp as ha_bp
|
||||
from app.routes.udp import bp as udp_bp
|
||||
|
||||
app.register_blueprint(main_bp)
|
||||
app.register_blueprint(overview_bp)
|
||||
|
@ -55,6 +56,7 @@ app.register_blueprint(user_bp, url_prefix='/user')
|
|||
app.register_blueprint(server_bp, url_prefix='/server')
|
||||
app.register_blueprint(admin_bp, url_prefix='/admin')
|
||||
app.register_blueprint(ha_bp, url_prefix='/ha')
|
||||
app.register_blueprint(udp_bp)
|
||||
|
||||
from app import login
|
||||
from app import jobs
|
||||
|
|
|
@ -15,6 +15,7 @@ def default_values():
|
|||
apache_dir = 'httpd'
|
||||
data_source = [
|
||||
{'param': 'time_zone', 'value': 'UTC', 'section': 'main', 'desc': 'Time Zone', 'group': '1'},
|
||||
{'param': 'license', 'value': '', 'section': 'main', 'desc': 'License key', 'group': '1'},
|
||||
{'param': 'proxy', 'value': '', 'section': 'main', 'desc': 'IP address and port of the proxy server. Use proto://ip:port', 'group': '1'},
|
||||
{'param': 'session_ttl', 'value': '5', 'section': 'main', 'desc': 'TTL for a user session (in days)', 'group': '1'},
|
||||
{'param': 'token_ttl', 'value': '5', 'section': 'main', 'desc': 'TTL for a user token (in days)', 'group': '1'},
|
||||
|
@ -154,6 +155,7 @@ def default_values():
|
|||
{'service_id': 3, 'service': 'Keepalived', 'slug': 'keepalived'},
|
||||
{'service_id': 4, 'service': 'Apache', 'slug': 'apache'},
|
||||
{'service_id': 5, 'service': 'HA cluster', 'slug': 'cluster'},
|
||||
{'service_id': 6, 'service': 'UDP balancing', 'slug': 'udp'},
|
||||
]
|
||||
|
||||
try:
|
||||
|
@ -465,85 +467,6 @@ def update_db_v_4_3_0():
|
|||
print("An error occurred:", e)
|
||||
|
||||
|
||||
def update_db_v_6_3_4():
|
||||
cursor = conn.cursor()
|
||||
sql = list()
|
||||
sql.append("alter table smon add column ssl_expire_warning_alert integer default 0")
|
||||
sql.append("alter table smon add column ssl_expire_critical_alert integer default 0")
|
||||
for i in sql:
|
||||
try:
|
||||
cursor.execute(i)
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
print('Updating... DB has been updated to version 6.3.4.0')
|
||||
|
||||
|
||||
def update_db_v_6_3_5():
|
||||
cursor = conn.cursor()
|
||||
sql = list()
|
||||
sql.append("ALTER TABLE `action_history` ADD COLUMN server_ip varchar(64);")
|
||||
sql.append("ALTER TABLE `action_history` ADD COLUMN hostname varchar(64);")
|
||||
for i in sql:
|
||||
try:
|
||||
cursor.execute(i)
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
print("Updating... DB has been updated to version 6.3.5.0")
|
||||
|
||||
|
||||
def update_db_v_6_3_6():
|
||||
cursor = conn.cursor()
|
||||
sql = list()
|
||||
sql.append("ALTER TABLE `user_groups` ADD COLUMN user_role_id integer;")
|
||||
if mysql_enable == '1':
|
||||
sql.append("update user_groups u_g inner join user as u on u_g.user_id = u.id inner join role as r on r.name = u.role set user_role_id = r.id where u_g.user_role_id is NULL;")
|
||||
sql.append("update user u inner join role as r on r.name = u.role set u.role = r.id;")
|
||||
else:
|
||||
sql.append("update user_groups as u_g set user_role_id = (select r.id from role as r inner join user as u on u.role = r.name where u_g.user_id = u.id) where user_role_id is null;")
|
||||
sql.append("update user as u set role = (select r.id from role as r where r.name = u.role);")
|
||||
for i in sql:
|
||||
try:
|
||||
cursor.execute(i)
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
print("Updating... DB has been updated to version 6.3.6.0")
|
||||
|
||||
|
||||
def update_db_v_6_3_8():
|
||||
cursor = conn.cursor()
|
||||
sql = """
|
||||
ALTER TABLE `smon` ADD COLUMN ssl_expire_date varchar(64);
|
||||
"""
|
||||
try:
|
||||
cursor.execute(sql)
|
||||
except Exception as e:
|
||||
if e.args[0] == 'duplicate column name: ssl_expire_date' or str(e) == '(1060, "Duplicate column name \'ssl_expire_date\'")':
|
||||
print('Updating... DB has been updated to version 6.3.8')
|
||||
else:
|
||||
print("An error occurred:", e)
|
||||
else:
|
||||
print("Updating... DB has been updated to version 6.3.8")
|
||||
|
||||
|
||||
def update_db_v_6_3_9():
|
||||
cursor = conn.cursor()
|
||||
sql = """
|
||||
ALTER TABLE `checker_setting` ADD COLUMN pd_id integer default 0;
|
||||
"""
|
||||
try:
|
||||
cursor.execute(sql)
|
||||
except Exception as e:
|
||||
if e.args[0] == 'duplicate column name: pd_id' or str(e) == '(1060, "Duplicate column name \'pd_id\'")':
|
||||
print('Updating... DB has been updated to version 6.3.9')
|
||||
else:
|
||||
print("An error occurred:", e)
|
||||
else:
|
||||
print("Updating... DB has been updated to version 6.3.9")
|
||||
|
||||
|
||||
def update_db_v_6_3_11():
|
||||
cursor = conn.cursor()
|
||||
sql = """
|
||||
|
@ -755,7 +678,7 @@ def update_db_v_7_2_3():
|
|||
|
||||
def update_ver():
|
||||
try:
|
||||
Version.update(version='7.2.6.0').execute()
|
||||
Version.update(version='7.3.0.0').execute()
|
||||
except Exception:
|
||||
print('Cannot update version')
|
||||
|
||||
|
@ -773,11 +696,6 @@ def update_all():
|
|||
if check_ver() is None:
|
||||
update_db_v_3_4_5_22()
|
||||
update_db_v_4_3_0()
|
||||
update_db_v_6_3_4()
|
||||
update_db_v_6_3_5()
|
||||
update_db_v_6_3_6()
|
||||
update_db_v_6_3_8()
|
||||
update_db_v_6_3_9()
|
||||
update_db_v_6_3_11()
|
||||
update_db_v_6_3_13()
|
||||
update_db_v_6_3_13_1()
|
||||
|
|
|
@ -24,7 +24,7 @@ def check_login():
|
|||
return redirect(login_url('login_page', next_url=request.url))
|
||||
|
||||
try:
|
||||
roxywi_auth.check_login(user_params['user_uuid'], user_params['token'])
|
||||
roxywi_auth.check_login(user_params['user_uuid'])
|
||||
except Exception:
|
||||
return redirect(login_url('login_page', next_url=request.url))
|
||||
|
||||
|
@ -69,13 +69,13 @@ def login_page():
|
|||
if user.ldap_user == 1:
|
||||
if login in user.username:
|
||||
if roxywi_auth.check_in_ldap(login, password):
|
||||
user_uuid, user_token = roxywi_auth.create_uuid_and_token(login)
|
||||
user_uuid = roxywi_auth.create_uuid_and_token(login)
|
||||
return roxywi_auth.do_login(user_uuid, str(user.groups), user, next_url)
|
||||
|
||||
else:
|
||||
hashed_password = roxy_wi_tools.Tools.get_hash(password)
|
||||
if login in user.username and hashed_password == user.password:
|
||||
user_uuid, user_token = roxywi_auth.create_uuid_and_token(login)
|
||||
user_uuid = roxywi_auth.create_uuid_and_token(login)
|
||||
return roxywi_auth.do_login(user_uuid, str(user.groups), user, next_url)
|
||||
else:
|
||||
return 'ban', 200
|
||||
|
|
|
@ -10,7 +10,7 @@ def check_services(fn):
|
|||
@wraps(fn)
|
||||
def decorated_view(*args, **kwargs):
|
||||
service = kwargs['service']
|
||||
if service not in ('haproxy', 'nginx', 'apache', 'keepalived', 'cluster', 'waf'):
|
||||
if service not in ('haproxy', 'nginx', 'apache', 'keepalived', 'cluster', 'waf', 'udp'):
|
||||
abort(405, 'Wrong service')
|
||||
if not roxywi_auth.is_access_permit_to_service(service):
|
||||
abort(403, f'You do not have needed permissions to access to {service.title()} service')
|
||||
|
|
|
@ -235,7 +235,7 @@ def upload_and_restart(server_ip: str, cfg: str, just_save: str, service: str, *
|
|||
except Exception as e:
|
||||
roxywi_common.logging('Roxy-WI server', str(e), roxywi=1)
|
||||
|
||||
# If master then save version of config in a new way
|
||||
# If master then save a version of config in a new way
|
||||
if not kwargs.get('slave') and service != 'waf':
|
||||
_create_config_version(server_id, server_ip, service, config_path, kwargs.get('login'), cfg, kwargs.get('oldcfg'), tmp_file)
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ class User(BaseModel, UserMixin):
|
|||
groups = CharField()
|
||||
ldap_user = IntegerField(constraints=[SQL('DEFAULT "0"')])
|
||||
activeuser = IntegerField(constraints=[SQL('DEFAULT "1"')])
|
||||
user_services = CharField(constraints=[SQL('DEFAULT "1 2 3 4 5"')])
|
||||
user_services = CharField(constraints=[SQL('DEFAULT "1 2 3 4 5 6"')])
|
||||
last_login_date = DateTimeField(constraints=[SQL('DEFAULT "0000-00-00 00:00:00"')])
|
||||
last_login_ip = CharField(null=True)
|
||||
|
||||
|
@ -153,16 +153,6 @@ class UUID(BaseModel):
|
|||
primary_key = False
|
||||
|
||||
|
||||
class Token(BaseModel):
|
||||
user_id = IntegerField()
|
||||
token = CharField()
|
||||
exp = DateTimeField(default=datetime.now)
|
||||
|
||||
class Meta:
|
||||
table_name = 'token'
|
||||
primary_key = False
|
||||
|
||||
|
||||
class ApiToken(BaseModel):
|
||||
token = CharField()
|
||||
user_name = CharField()
|
||||
|
@ -765,15 +755,36 @@ class HaClusterService(BaseModel):
|
|||
constraints = [SQL('UNIQUE (cluster_id, service_id)')]
|
||||
|
||||
|
||||
class UDPBalancer(BaseModel):
|
||||
id = AutoField()
|
||||
name = CharField()
|
||||
cluster_id = IntegerField(null=True)
|
||||
server_id = IntegerField(null=True)
|
||||
vip = CharField()
|
||||
port = IntegerField()
|
||||
group_id = ForeignKeyField(Groups)
|
||||
config = CharField()
|
||||
desc = CharField()
|
||||
lb_algo = CharField(constraints=[SQL('DEFAULT "rr"')])
|
||||
check_enabled = IntegerField(constraints=[SQL('DEFAULT "1"')])
|
||||
delay_loop = IntegerField(constraints=[SQL('DEFAULT "10"')])
|
||||
delay_before_retry = IntegerField(constraints=[SQL('DEFAULT "10"')])
|
||||
retry = IntegerField(constraints=[SQL('DEFAULT "3"')])
|
||||
|
||||
class Meta:
|
||||
table_name = 'udp_balancers'
|
||||
constraints = [SQL('UNIQUE (vip, port)')]
|
||||
|
||||
|
||||
def create_tables():
|
||||
conn = connect()
|
||||
with conn:
|
||||
conn.create_tables(
|
||||
[User, Server, Role, Telegram, Slack, UUID, Token, ApiToken, Groups, UserGroups, ConfigVersion, Setting,
|
||||
[User, Server, Role, Telegram, Slack, UUID, ApiToken, Groups, UserGroups, ConfigVersion, Setting,
|
||||
Cred, Backup, Metrics, WafMetrics, Version, Option, SavedServer, Waf, ActionHistory, PortScannerSettings,
|
||||
PortScannerPorts, PortScannerHistory, ServiceSetting, MetricsHttpStatus, SMON, WafRules, Alerts, GeoipCodes,
|
||||
NginxMetrics, SystemInfo, Services, UserName, GitSetting, CheckerSetting, ApacheMetrics, WafNginx, ServiceStatus,
|
||||
KeepaliveRestart, PD, SmonHistory, SmonAgent, SmonTcpCheck, SmonHttpCheck, SmonPingCheck, SmonDnsCheck, S3Backup, RoxyTool,
|
||||
SmonStatusPage, SmonStatusPageCheck, HaCluster, HaClusterSlave, HaClusterVip, HaClusterVirt, HaClusterService,
|
||||
HaClusterRouter, MM]
|
||||
HaClusterRouter, MM, UDPBalancer]
|
||||
)
|
||||
|
|
|
@ -44,6 +44,13 @@ def get_hostname_by_server_ip(server_ip):
|
|||
return hostname.hostname
|
||||
|
||||
|
||||
def get_server_by_id(server_id):
|
||||
try:
|
||||
return Server.get(Server.server_id == server_id)
|
||||
except Exception as e:
|
||||
return out_error(e)
|
||||
|
||||
|
||||
def select_server_by_name(name):
|
||||
try:
|
||||
ip = Server.get(Server.hostname == name)
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
from app.modules.db.db_model import mysql_enable, connect, Server, UDPBalancer
|
||||
from app.modules.db.common import out_error
|
||||
|
||||
|
||||
def select_listeners(group_id: int) -> UDPBalancer:
|
||||
try:
|
||||
return UDPBalancer.select().where(UDPBalancer.group_id == group_id).execute()
|
||||
except Exception as e:
|
||||
out_error(e)
|
||||
|
||||
|
||||
def insert_listener(**kwargs) -> int:
|
||||
try:
|
||||
return UDPBalancer.insert(**kwargs).execute()
|
||||
except Exception as e:
|
||||
out_error(e)
|
||||
|
||||
|
||||
def update_listener(listener_id: int, **kwargs) -> int:
|
||||
try:
|
||||
return UDPBalancer.update(**kwargs).where(UDPBalancer.id == listener_id).execute()
|
||||
except Exception as e:
|
||||
out_error(e)
|
||||
|
||||
|
||||
def get_listener(listener_id: int) -> UDPBalancer:
|
||||
try:
|
||||
return UDPBalancer.get(UDPBalancer.id == listener_id)
|
||||
except Exception as e:
|
||||
out_error(e)
|
||||
|
||||
|
||||
def delete_listener(listener_id: int) -> None:
|
||||
try:
|
||||
UDPBalancer.delete().where(UDPBalancer.id == listener_id).execute()
|
||||
except Exception as e:
|
||||
out_error(e)
|
|
@ -1,6 +1,6 @@
|
|||
from peewee import Case, JOIN
|
||||
|
||||
from app.modules.db.db_model import User, UserGroups, Groups, UUID, Token, ApiToken
|
||||
from app.modules.db.db_model import User, UserGroups, Groups, UUID, ApiToken
|
||||
from app.modules.db.sql import get_setting
|
||||
from app.modules.db.common import out_error
|
||||
import app.modules.roxy_wi_tools as roxy_wi_tools
|
||||
|
@ -190,21 +190,15 @@ def select_users_roles():
|
|||
return query_res
|
||||
|
||||
|
||||
def update_last_act_user(uuid: str, token: str, ip: str) -> None:
|
||||
def update_last_act_user(uuid: str,ip: str) -> None:
|
||||
get_date = roxy_wi_tools.GetDate(get_setting('time_zone'))
|
||||
session_ttl = get_setting('session_ttl')
|
||||
token_ttl = get_setting('token_ttl')
|
||||
cur_date_session = get_date.return_date('regular', timedelta=session_ttl)
|
||||
cur_date_token = get_date.return_date('regular', timedelta=token_ttl)
|
||||
cur_date = get_date.return_date('regular')
|
||||
user_id = get_user_id_by_uuid(uuid)
|
||||
query = UUID.update(exp=cur_date_session).where(UUID.uuid == uuid)
|
||||
query1 = Token.update(exp=cur_date_token).where(Token.token == token)
|
||||
query2 = User.update(last_login_date=cur_date, last_login_ip=ip).where(User.user_id == user_id)
|
||||
try:
|
||||
query.execute()
|
||||
query1.execute()
|
||||
query2.execute()
|
||||
UUID.update(exp=cur_date_session).where(UUID.uuid == uuid).execute()
|
||||
User.update(last_login_date=cur_date, last_login_ip=ip).where(User.user_id == user_id).execute()
|
||||
except Exception as e:
|
||||
out_error(e)
|
||||
|
||||
|
@ -281,18 +275,6 @@ def write_user_uuid(login, user_uuid):
|
|||
out_error(e)
|
||||
|
||||
|
||||
def write_user_token(login, user_token):
|
||||
token_ttl = get_setting('token_ttl')
|
||||
user_id = get_user_id_by_username(login)
|
||||
get_date = roxy_wi_tools.GetDate()
|
||||
cur_date = get_date.return_date('regular', timedelta=token_ttl)
|
||||
|
||||
try:
|
||||
Token.insert(user_id=user_id, token=user_token, exp=cur_date).execute()
|
||||
except Exception as e:
|
||||
out_error(e)
|
||||
|
||||
|
||||
def select_user_services(user_id):
|
||||
try:
|
||||
query_res = User.get(User.user_id == user_id).user_services
|
||||
|
@ -405,28 +387,11 @@ def get_username_group_id_from_api_token(token):
|
|||
return user_name.user_name, user_name.user_group_id, user_name.user_role
|
||||
|
||||
|
||||
def get_token(uuid):
|
||||
query = Token.select().join(UUID, on=(Token.user_id == UUID.user_id)).where(UUID.uuid == uuid).limit(1)
|
||||
try:
|
||||
query_res = query.execute()
|
||||
except Exception as e:
|
||||
out_error(e)
|
||||
else:
|
||||
try:
|
||||
for i in query_res:
|
||||
return i.token
|
||||
except Exception:
|
||||
return ''
|
||||
|
||||
|
||||
def delete_old_uuid():
|
||||
get_date = roxy_wi_tools.GetDate()
|
||||
cur_date = get_date.return_date('regular')
|
||||
query = UUID.delete().where((UUID.exp < cur_date) | (UUID.exp.is_null(True)))
|
||||
query1 = Token.delete().where((Token.exp < cur_date) | (Token.exp.is_null(True)))
|
||||
try:
|
||||
query.execute()
|
||||
query1.execute()
|
||||
UUID.delete().where((UUID.exp < cur_date) | (UUID.exp.is_null(True))).execute()
|
||||
except Exception as e:
|
||||
out_error(e)
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import app.modules.db.service as service_sql
|
|||
import app.modules.roxywi.common as roxywi_common
|
||||
|
||||
|
||||
def check_login(user_uuid, token) -> str:
|
||||
def check_login(user_uuid) -> str:
|
||||
if user_uuid is None:
|
||||
return 'login_page'
|
||||
|
||||
|
@ -24,7 +24,7 @@ def check_login(user_uuid, token) -> str:
|
|||
except Exception:
|
||||
ip = ''
|
||||
|
||||
user_sql.update_last_act_user(user_uuid, token, ip)
|
||||
user_sql.update_last_act_user(user_uuid, ip)
|
||||
|
||||
return 'ok'
|
||||
return 'login_page'
|
||||
|
@ -106,11 +106,9 @@ def check_in_ldap(user, password):
|
|||
|
||||
def create_uuid_and_token(login: str):
|
||||
user_uuid = str(uuid.uuid4())
|
||||
user_token = str(uuid.uuid4())
|
||||
user_sql.write_user_uuid(login, user_uuid)
|
||||
user_sql.write_user_token(login, user_token)
|
||||
|
||||
return user_uuid, user_token
|
||||
return user_uuid
|
||||
|
||||
|
||||
def do_login(user_uuid: str, user_group: str, user: str, next_url: str):
|
||||
|
|
|
@ -5,6 +5,7 @@ from typing import Any
|
|||
from flask import request
|
||||
|
||||
from app.modules.db.sql import get_setting
|
||||
import app.modules.db.udp as udp_sql
|
||||
import app.modules.db.roxy as roxy_sql
|
||||
import app.modules.db.user as user_sql
|
||||
import app.modules.db.group as group_sql
|
||||
|
@ -37,18 +38,10 @@ def get_user_group(**kwargs) -> int:
|
|||
return user_group
|
||||
|
||||
|
||||
def check_user_group_for_flask(**kwargs):
|
||||
if kwargs.get('token') is not None:
|
||||
return True
|
||||
|
||||
if kwargs.get('user_uuid'):
|
||||
group_id = kwargs.get('user_group_id')
|
||||
user_uuid = kwargs.get('user_uuid')
|
||||
user_id = user_sql.get_user_id_by_uuid(user_uuid)
|
||||
else:
|
||||
user_uuid = request.cookies.get('uuid')
|
||||
group_id = request.cookies.get('group')
|
||||
user_id = user_sql.get_user_id_by_uuid(user_uuid)
|
||||
def check_user_group_for_flask():
|
||||
user_uuid = request.cookies.get('uuid')
|
||||
group_id = request.cookies.get('group')
|
||||
user_id = user_sql.get_user_id_by_uuid(user_uuid)
|
||||
|
||||
if user_sql.check_user_group(user_id, group_id):
|
||||
return True
|
||||
|
@ -163,25 +156,32 @@ def keep_action_history(service: str, action: str, server_ip: str, login: str, u
|
|||
user_ip = 'localhost'
|
||||
|
||||
if service == 'HA cluster':
|
||||
cluster_id = server_ip
|
||||
cluster_name = ha_sql.select_cluster_name(int(cluster_id))
|
||||
history_sql.insert_action_history(service, action, int(cluster_id), user_id, user_ip, cluster_id, cluster_name)
|
||||
try:
|
||||
server_id = server_ip
|
||||
hostname = ha_sql.select_cluster_name(int(server_id))
|
||||
except Exception as e:
|
||||
logging('Roxy-WI server', f'Cannot get info about cluster {server_ip} for history: {e}', roxywi=1)
|
||||
elif service == 'UDP Listener':
|
||||
try:
|
||||
server_id = int(server_ip)
|
||||
listener = udp_sql.get_listener(server_id)
|
||||
hostname = listener.name
|
||||
except Exception as e:
|
||||
logging('Roxy-WI server', f'Cannot get info about Listener {server_ip} for history: {e}', roxywi=1)
|
||||
else:
|
||||
try:
|
||||
server_id = server_sql.select_server_id_by_ip(server_ip=server_ip)
|
||||
hostname = server_sql.get_hostname_by_server_ip(server_ip)
|
||||
|
||||
history_sql.insert_action_history(service, action, server_id, user_id, user_ip, server_ip, hostname)
|
||||
except Exception as e:
|
||||
logging('Roxy-WI server', f'Cannot save a history: {e}', roxywi=1)
|
||||
logging('Roxy-WI server', f'Cannot get info about {server_ip} for history: {e}', roxywi=1)
|
||||
|
||||
try:
|
||||
history_sql.insert_action_history(service, action, server_id, user_id, user_ip, server_ip, hostname)
|
||||
except Exception as e:
|
||||
logging('Roxy-WI server', f'Cannot save a history: {e}', roxywi=1)
|
||||
|
||||
|
||||
def get_dick_permit(**kwargs):
|
||||
if kwargs.get('token'):
|
||||
token = kwargs.get('token')
|
||||
else:
|
||||
token = ''
|
||||
|
||||
if not kwargs.get('group_id'):
|
||||
try:
|
||||
group_id = get_user_group(id=1)
|
||||
|
@ -190,7 +190,7 @@ def get_dick_permit(**kwargs):
|
|||
else:
|
||||
group_id = kwargs.pop('group_id')
|
||||
|
||||
if check_user_group_for_flask(token=token):
|
||||
if check_user_group_for_flask():
|
||||
try:
|
||||
servers = server_sql.get_dick_permit(group_id, **kwargs)
|
||||
except Exception as e:
|
||||
|
@ -236,11 +236,6 @@ def get_users_params(**kwargs):
|
|||
except Exception as e:
|
||||
raise Exception(f'error: Cannot get user services {e}')
|
||||
|
||||
try:
|
||||
token = user_sql.get_token(user_uuid)
|
||||
except Exception as e:
|
||||
raise Exception(f'error: Cannot get user token {e}')
|
||||
|
||||
if kwargs.get('virt') and kwargs.get('service') == 'haproxy':
|
||||
servers = get_dick_permit(virt=1, haproxy=1)
|
||||
elif kwargs.get('virt'):
|
||||
|
@ -258,7 +253,6 @@ def get_users_params(**kwargs):
|
|||
'user': user,
|
||||
'user_uuid': user_uuid,
|
||||
'role': role,
|
||||
'token': token,
|
||||
'servers': servers,
|
||||
'user_services': user_services,
|
||||
'lang': user_lang,
|
||||
|
|
|
@ -6,6 +6,7 @@ import requests
|
|||
from requests.adapters import HTTPAdapter
|
||||
from requests.packages.urllib3.util.retry import Retry
|
||||
|
||||
import app.modules.db.sql as sql
|
||||
import app.modules.db.roxy as roxy_sql
|
||||
import app.modules.common.common as common
|
||||
import app.modules.roxywi.common as roxywi_common
|
||||
|
@ -72,21 +73,20 @@ def check_new_version(service):
|
|||
|
||||
|
||||
def update_user_status() -> None:
|
||||
user_license = sql.get_setting('license')
|
||||
proxy_dict = common.return_proxy_dict()
|
||||
user_name = roxy_sql.select_user_name()
|
||||
retry_strategy = Retry(
|
||||
total=3,
|
||||
status_forcelist=[429, 500, 502, 503, 504],
|
||||
method_whitelist=["HEAD", "GET", "OPTIONS"]
|
||||
status_forcelist=[429, 500, 502, 503, 504]
|
||||
)
|
||||
adapter = HTTPAdapter(max_retries=retry_strategy)
|
||||
roxy_wi_get_plan = requests.Session()
|
||||
roxy_wi_get_plan.mount("https://", adapter)
|
||||
roxy_wi_get_plan = requests.get(f'https://roxy-wi.org/user-name/{user_name}', timeout=5, proxies=proxy_dict)
|
||||
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)
|
||||
try:
|
||||
status = roxy_wi_get_plan.content.decode(encoding='UTF-8')
|
||||
status = status.split(' ')
|
||||
roxy_sql.update_user_status(status[0], status[1].strip(), status[2].strip())
|
||||
status = roxy_wi_get_plan.json()
|
||||
roxy_sql.update_user_status(status['status'], status['plan'], status['method'])
|
||||
except Exception as e:
|
||||
roxywi_common.logging('Roxy-WI server', f'error: Cannot get user status {e}', roxywi=1)
|
||||
|
||||
|
@ -111,12 +111,24 @@ def update_plan():
|
|||
if distro.id() == 'ubuntu':
|
||||
path_to_repo = '/etc/apt/auth.conf.d/roxy-wi.conf'
|
||||
cmd = "grep login /etc/apt/auth.conf.d/roxy-wi.conf |awk '{print $2}'"
|
||||
cmd2 = "grep password /etc/apt/auth.conf.d/roxy-wi.conf |awk '{print $2}'"
|
||||
else:
|
||||
path_to_repo = '/etc/yum.repos.d/roxy-wi.repo'
|
||||
cmd = "grep base /etc/yum.repos.d/roxy-wi.repo |grep -v '#' |awk -F\":\" '{print $2}'|awk -F\"/\" '{print $3}'"
|
||||
cmd2 = "grep base /etc/yum.repos.d/roxy-wi.repo |grep -v '#' |awk -F\":\" '{print $3}'|awk -F\"@\" '{print $1}'"
|
||||
if os.path.exists(path_to_repo):
|
||||
get_user_name, stderr = server_mod.subprocess_execute(cmd)
|
||||
user_name = get_user_name[0]
|
||||
cur_license = sql.get_setting('license')
|
||||
if not cur_license:
|
||||
get_license, stderr = server_mod.subprocess_execute(cmd2)
|
||||
user_license = get_license[0]
|
||||
|
||||
if user_license:
|
||||
try:
|
||||
sql.update_setting('license', user_license, 1)
|
||||
except Exception as e:
|
||||
roxywi_common.logging('Roxy-WI server', f'error: Cannot update license {e}', roxywi=1)
|
||||
else:
|
||||
user_name = 'git'
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import app.modules.db.sql as sql
|
|||
import app.modules.db.ha_cluster as ha_sql
|
||||
import app.modules.db.server as server_sql
|
||||
import app.modules.db.service as service_sql
|
||||
import app.modules.service.udp as udp_mod
|
||||
import app.modules.service.common as service_common
|
||||
import app.modules.common.common as common
|
||||
import app.modules.server.server as server_mod
|
||||
|
@ -34,6 +35,27 @@ def show_installation_output(error: str, output: list, service: str, rc=0):
|
|||
return True
|
||||
|
||||
|
||||
def generate_udp_inv(listener_id: int, action: str) -> object:
|
||||
inv = {"server": {"hosts": {}}}
|
||||
server_ips = []
|
||||
listener = udp_mod.get_listener_config(listener_id)
|
||||
if listener['cluster_id']:
|
||||
server_ips = udp_mod.get_slaves_for_udp_listener(listener['cluster_id'], listener['vip'])
|
||||
elif listener['server_id']:
|
||||
server = server_sql.get_server_by_id(listener['server_id'])
|
||||
server_ips.append(server.ip)
|
||||
|
||||
for server_ip in server_ips:
|
||||
inv['server']['hosts'][server_ip] = {
|
||||
'action': action,
|
||||
"vip": listener['vip'],
|
||||
"port": listener['port'],
|
||||
"id": listener['id'],
|
||||
"config": listener['config'],
|
||||
}
|
||||
return inv, server_ips
|
||||
|
||||
|
||||
def generate_geoip_inv(server_ip: str, installed_service: str, geoip_update: int) -> object:
|
||||
inv = {"server": {"hosts": {}}}
|
||||
server_ips = []
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
import json
|
||||
|
||||
from playhouse.shortcuts import model_to_dict
|
||||
|
||||
import app.modules.db.udp as udp_sql
|
||||
import app.modules.db.server as server_sql
|
||||
import app.modules.db.ha_cluster as ha_sql
|
||||
import app.modules.common.common as common
|
||||
import app.modules.server.server as server_mod
|
||||
import app.modules.roxywi.common as roxywi_common
|
||||
|
||||
|
||||
def create_listener(json_data: json) -> int:
|
||||
listener = _validate_form(json_data)
|
||||
listener_id = udp_sql.insert_listener(**listener)
|
||||
roxywi_common.logging(listener_id, f'UDP listener {listener["name"]} has been created', keep_history=1, roxywi=1, service='UDP Listener')
|
||||
return listener_id
|
||||
|
||||
|
||||
def update_listener(json_data: json) -> str:
|
||||
listener = _validate_form(json_data)
|
||||
listener_id = json_data['listener_id']
|
||||
udp_sql.update_listener(listener_id, **listener)
|
||||
roxywi_common.logging(listener_id, f'UDP listener {listener["name"]} has been updated', keep_history=1, roxywi=1, service='UDP Listener')
|
||||
return 'ok'
|
||||
|
||||
|
||||
def _validate_form(json_data: json) -> dict:
|
||||
returned_data = {}
|
||||
if not isinstance(json_data, dict):
|
||||
raise ValueError("error: Invalid form data")
|
||||
returned_data['name'] = common.checkAjaxInput(json_data['new-listener-name'])
|
||||
returned_data['desc'] = common.checkAjaxInput(json_data['new-listener-desc'])
|
||||
try:
|
||||
returned_data['port'] = int(json_data['new-listener-port'])
|
||||
except Exception:
|
||||
raise ValueError("error: Invalid port number")
|
||||
returned_data['group_id'] = int(json_data['group_id'])
|
||||
returned_data['config'] = {}
|
||||
for k, v in json_data.items():
|
||||
if k == 'servers':
|
||||
_validate_backend_servers(v)
|
||||
for server, value in v.items():
|
||||
server_ip = common.is_ip_or_dns(server)
|
||||
returned_data['config'][server_ip] = {}
|
||||
returned_data['config'][server_ip]['port'] = int(value['port'])
|
||||
returned_data['config'][server_ip]['weight'] = int(value['weight'])
|
||||
if json_data['new-listener-type'] == 'server':
|
||||
returned_data['server_id'] = int(json_data['serv'])
|
||||
try:
|
||||
returned_data['vip'] = common.is_ip_or_dns(json_data['new-udp-ip'])
|
||||
except ValueError:
|
||||
raise ValueError("error: Cannot parse Server and IP")
|
||||
else:
|
||||
try:
|
||||
cluster_id = int(json_data['ha-cluster'])
|
||||
returned_data['cluster_id'] = cluster_id
|
||||
except ValueError:
|
||||
raise ValueError("error: Cannot parse Cluster ID")
|
||||
returned_data['vip'] = common.is_ip_or_dns(json_data['new-udp-vip'])
|
||||
|
||||
return returned_data
|
||||
|
||||
|
||||
def _validate_backend_servers(serves: dict):
|
||||
if not isinstance(serves, dict):
|
||||
raise ValueError("error: Invalid backend servers data")
|
||||
if len(serves) == 0:
|
||||
raise ValueError("error: Empty backend servers")
|
||||
for server, value in serves.items():
|
||||
server = common.is_ip_or_dns(server)
|
||||
if server == '':
|
||||
raise ValueError("error: Cannot parse backend server IP")
|
||||
try:
|
||||
port = int(value['port'])
|
||||
except ValueError:
|
||||
raise ValueError(f"error: Invalid port for backend server {server}")
|
||||
if port > 65535 or port < 1:
|
||||
raise Exception(f'error: Port must be 1-65535 for backend server {server}')
|
||||
try:
|
||||
weight = int(value['weight'])
|
||||
except ValueError:
|
||||
raise ValueError(f"error: Invalid weight for backend server {server}")
|
||||
if weight > 65535 or weight < 1:
|
||||
raise Exception(f'error: Weight must be 1-65535 for backend server {server}')
|
||||
|
||||
|
||||
def get_listener_config(listener_id: int) -> dict:
|
||||
listener = udp_sql.get_listener(listener_id)
|
||||
listener_json = model_to_dict(listener)
|
||||
listener_json['config'] = eval(listener_json['config'])
|
||||
return listener_json
|
||||
|
||||
|
||||
def get_slaves_for_udp_listener(cluster_id: int, vip: str) -> list:
|
||||
servers = []
|
||||
vips = ha_sql.select_cluster_vips(cluster_id)
|
||||
for v in vips:
|
||||
if v.vip == vip:
|
||||
router_id = v.router_id
|
||||
break
|
||||
else:
|
||||
raise ValueError("error: Cannot find VIP")
|
||||
slaves = ha_sql.select_cluster_slaves(cluster_id, router_id)
|
||||
for slave in slaves:
|
||||
servers.append(slave[2])
|
||||
return servers
|
||||
|
||||
|
||||
def listener_actions(listener_id: int, action: str, group_id: int) -> str:
|
||||
if action not in ('start', 'stop', 'restart'):
|
||||
raise ValueError("error: Invalid action")
|
||||
servers = []
|
||||
listener = udp_sql.get_listener(listener_id)
|
||||
if int(listener.group_id.group_id) != group_id:
|
||||
raise ValueError("error: Invalid group")
|
||||
if listener.cluster_id:
|
||||
get_slaves_for_udp_listener(listener.cluster_id, listener.vip)
|
||||
elif listener.server_id:
|
||||
server = server_sql.get_server_by_id(listener.server_id)
|
||||
servers.append(server.ip)
|
||||
if len(servers) < 1:
|
||||
raise ValueError("error: Cannot find server")
|
||||
cmd = f'sudo systemctl {action} keepalived-udp-{listener_id}.service'
|
||||
print(cmd)
|
||||
for server_ip in servers:
|
||||
try:
|
||||
server_mod.ssh_command(server_ip, cmd)
|
||||
roxywi_common.logging(listener.id, f'UDP listener {listener.name} has been {action} on {server_ip}', keep_history=1, roxywi=1, service='UDP Listener')
|
||||
except Exception as e:
|
||||
roxywi_common.handle_exceptions(e, 'Roxy-WI server', f'Cannot {action} for UDP balancer {listener.name}', roxywi=1)
|
||||
return 'ok'
|
|
@ -12,7 +12,6 @@ import app.modules.common.common as common
|
|||
import app.modules.roxywi.auth as roxywi_auth
|
||||
import app.modules.roxywi.common as roxywi_common
|
||||
import app.modules.roxy_wi_tools as roxy_wi_tools
|
||||
import app.modules.server.server as server_mod
|
||||
|
||||
get_config = roxy_wi_tools.GetConfigVar()
|
||||
|
||||
|
@ -670,11 +669,3 @@ def add_nginx_upstream():
|
|||
return add_mod.save_nginx_config(config_add, server_ip, config_name)
|
||||
except Exception as e:
|
||||
return str(e)
|
||||
|
||||
|
||||
@bp.route('/show/ip/<server_ip>')
|
||||
def show_ip(server_ip):
|
||||
server_ip = common.is_ip_or_dns(server_ip)
|
||||
commands = 'sudo hostname -I | tr " " "\\n"|sed "/^$/d"'
|
||||
|
||||
return server_mod.ssh_command(server_ip, commands, ip="1")
|
||||
|
|
|
@ -255,3 +255,14 @@ def ha_vip(service, cluster_id):
|
|||
return 'ok'
|
||||
except Exception as e:
|
||||
return f'error: Cannot delete VIP: {e}'
|
||||
|
||||
|
||||
@bp.route('/<service>/<int:cluster_id>/vips', methods=['GET'])
|
||||
@check_services
|
||||
@get_user_params()
|
||||
def get_vips(service, cluster_id):
|
||||
from playhouse.shortcuts import model_to_dict
|
||||
if request.method == 'GET':
|
||||
vips = ha_sql.select_cluster_vips(cluster_id)
|
||||
vips = [model_to_dict(vip) for vip in vips]
|
||||
return jsonify(vips)
|
||||
|
|
|
@ -137,3 +137,14 @@ def check_geoip(service, server_ip):
|
|||
service_dir = common.return_nice_path(sql.get_setting(f'{service}_dir'))
|
||||
cmd = f"ls {service_dir}geoip/"
|
||||
return server_mod.ssh_command(server_ip, cmd)
|
||||
|
||||
|
||||
@bp.post('/udp')
|
||||
def install_udp():
|
||||
listener_id = int(request.form.get('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
|
||||
except Exception as e:
|
||||
return f'{e}'
|
||||
|
||||
|
|
|
@ -55,6 +55,24 @@ def show_if(server_ip):
|
|||
return server_mod.ssh_command(server_ip, command)
|
||||
|
||||
|
||||
@bp.route('/show/ip/<server_ip>')
|
||||
def show_ip_by_id(server_ip):
|
||||
server_ip = common.is_ip_or_dns(server_ip)
|
||||
if server_ip == '':
|
||||
raise Exception('error: Cannot find server ip')
|
||||
commands = 'sudo hostname -I | tr " " "\\n"|sed "/^$/d"'
|
||||
|
||||
return server_mod.ssh_command(server_ip, commands, ip="1")
|
||||
|
||||
|
||||
@bp.route('/show/ip/<int:server_id>')
|
||||
def show_ip(server_id):
|
||||
server_ip = server_sql.get_server_by_id(server_id)
|
||||
commands = 'sudo hostname -I | tr " " "\\n"|sed "/^$/d"'
|
||||
|
||||
return server_mod.ssh_command(server_ip.ip, commands, ip="1")
|
||||
|
||||
|
||||
@bp.post('/create')
|
||||
@get_user_params()
|
||||
def create_server():
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
from flask import Blueprint
|
||||
|
||||
bp = Blueprint('udp', __name__)
|
||||
|
||||
from app.routes.udp import routes
|
|
@ -0,0 +1,105 @@
|
|||
from flask import render_template, request, g, jsonify
|
||||
from flask_login import login_required
|
||||
|
||||
from app.routes.udp import bp
|
||||
import app.modules.db.udp as udp_sql
|
||||
import app.modules.db.server as server_sql
|
||||
import app.modules.db.ha_cluster as ha_sql
|
||||
import app.modules.common.common as common
|
||||
import app.modules.roxywi.auth as roxywi_auth
|
||||
import app.modules.roxywi.common as roxywi_common
|
||||
import app.modules.service.udp as udp_mod
|
||||
import app.modules.service.installation as service_mod
|
||||
from app.middleware import get_user_params, check_services
|
||||
|
||||
|
||||
@bp.before_request
|
||||
@login_required
|
||||
def before_request():
|
||||
""" Protect all the admin endpoints. """
|
||||
pass
|
||||
|
||||
|
||||
@bp.route('/<service>/listener', methods=['GET', 'POST', 'PUT', 'DELETE'])
|
||||
@check_services
|
||||
@get_user_params()
|
||||
def listener_funct(service):
|
||||
if request.method != 'GET':
|
||||
roxywi_auth.page_for_admin(level=2)
|
||||
if request.method == 'GET':
|
||||
kwargs = {
|
||||
'listeners': udp_sql.select_listeners(g.user_params['group_id']),
|
||||
'lang': g.user_params['lang'],
|
||||
'clusters': ha_sql.select_clusters(g.user_params['group_id']),
|
||||
'is_needed_tool': common.is_tool('ansible'),
|
||||
'user_subscription': roxywi_common.return_user_subscription()
|
||||
}
|
||||
return render_template('udp/listeners.html', **kwargs)
|
||||
elif request.method == 'POST':
|
||||
json_data = request.get_json()
|
||||
json_data['group_id'] = g.user_params['group_id']
|
||||
try:
|
||||
listener_id = udp_mod.create_listener(json_data)
|
||||
return jsonify({'status': 'created', 'listener_id': listener_id})
|
||||
except Exception as e:
|
||||
return jsonify({'status': 'failed', 'error': str(e)})
|
||||
elif request.method == 'PUT':
|
||||
json_data = request.get_json()
|
||||
json_data['group_id'] = g.user_params['group_id']
|
||||
try:
|
||||
udp_mod.update_listener(json_data)
|
||||
return jsonify({'status': 'updated'}), 201
|
||||
except Exception as e:
|
||||
return jsonify({'status': 'failed', 'error': str(e)})
|
||||
elif request.method == 'DELETE':
|
||||
kwargs = request.get_json()
|
||||
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
|
||||
except Exception as e:
|
||||
return jsonify({'status': 'failed', 'error': str(e)})
|
||||
try:
|
||||
udp_sql.delete_listener(listener_id)
|
||||
return jsonify({'status': 'deleted'}), 201
|
||||
except Exception as e:
|
||||
return jsonify({'status': 'failed', 'error': str(e)})
|
||||
|
||||
|
||||
@bp.get('/<service>/listener/<int:listener_id>')
|
||||
@check_services
|
||||
@get_user_params()
|
||||
def get_listener(service, listener_id):
|
||||
listener = udp_sql.get_listener(listener_id)
|
||||
cluster = dict()
|
||||
server = dict()
|
||||
if listener.cluster_id:
|
||||
cluster = ha_sql.select_cluster(listener.cluster_id)
|
||||
elif listener.server_id:
|
||||
server = server_sql.get_server_by_id(listener.server_id)
|
||||
kwargs = {
|
||||
'clusters': cluster,
|
||||
'listener': listener,
|
||||
'server': server,
|
||||
'lang': g.user_params['lang'],
|
||||
}
|
||||
return render_template('udp/listener.html', **kwargs)
|
||||
|
||||
|
||||
@bp.get('/<service>/listener/<int:listener_id>/settings')
|
||||
@check_services
|
||||
@get_user_params()
|
||||
def get_listener_settings(service, listener_id):
|
||||
listener_config = udp_mod.get_listener_config(listener_id)
|
||||
return jsonify(listener_config)
|
||||
|
||||
|
||||
@bp.get('/<service>/listener/<int:listener_id>/<action>')
|
||||
@check_services
|
||||
@get_user_params()
|
||||
def action_with_listener(service, listener_id, action):
|
||||
try:
|
||||
udp_mod.listener_actions(listener_id, action, g.user_params['group_id'])
|
||||
return jsonify({'status': 'done'})
|
||||
except Exception as e:
|
||||
return jsonify({'status': 'failed', 'error': str(e)})
|
|
@ -32,10 +32,9 @@ def create_user():
|
|||
page = common.checkAjaxInput(request.form.get('page'))
|
||||
activeuser = common.checkAjaxInput(request.form.get('activeuser'))
|
||||
group = common.checkAjaxInput(request.form.get('newgroupuser'))
|
||||
token = common.checkAjaxInput(request.form.get('token'))
|
||||
lang = roxywi_common.get_user_lang_for_flask()
|
||||
|
||||
if not roxywi_common.check_user_group_for_flask(token=token):
|
||||
if not roxywi_common.check_user_group_for_flask():
|
||||
return 'error: Wrong group'
|
||||
if page == 'servers':
|
||||
if roxywi_auth.is_admin(level=2, role_id=role):
|
||||
|
|
|
@ -4,12 +4,17 @@ $UDPServerRun 514
|
|||
module(load="builtin:omfile")
|
||||
|
||||
|
||||
if $programname startswith 'haproxy' then {
|
||||
if $syslogseverity == 6 then
|
||||
action(type="omfile" file="/var/log/haproxy/access.log")
|
||||
if $syslogseverity <= 3 then
|
||||
action(type="omfile" file="/var/log/haproxy/error.log")
|
||||
if $syslogseverity <= 5 then
|
||||
action(type="omfile" file="/var/log/haproxy/status.log")
|
||||
stop
|
||||
if ($programname startswith 'haproxy' and $inputname == 'imudp') then {
|
||||
if $syslogseverity == 6 then {
|
||||
action(type="omfile" file="/var/log/haproxy/access.log")
|
||||
stop
|
||||
}
|
||||
if $syslogseverity <= 3 then {
|
||||
action(type="omfile" file="/var/log/haproxy/error.log")
|
||||
stop
|
||||
}
|
||||
if $syslogseverity <= 5 then {
|
||||
action(type="omfile" file="/var/log/haproxy/status.log"])
|
||||
stop
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
- name: "UDP balancer"
|
||||
hosts: all
|
||||
become: yes
|
||||
become_method: sudo
|
||||
gather_facts: yes
|
||||
roles:
|
||||
- role: udp
|
||||
environment:
|
||||
http_proxy: "{{PROXY}}"
|
||||
https_proxy: "{{PROXY}}"
|
|
@ -0,0 +1,2 @@
|
|||
keepalived_path_logs: "/var/log/keepalived-udp"
|
||||
service_dir: "/etc/keepalived"
|
|
@ -0,0 +1,4 @@
|
|||
- name: Restart rsyslog
|
||||
ansible.builtin.service:
|
||||
name: rsyslog
|
||||
state: restarted
|
|
@ -0,0 +1,104 @@
|
|||
---
|
||||
- name: check if Keepalived is installed
|
||||
package_facts:
|
||||
manager: "auto"
|
||||
|
||||
- name: Creates log directory
|
||||
file:
|
||||
path: "{{keepalived_path_logs}}"
|
||||
state: directory
|
||||
|
||||
- name: Creates UDP check directory
|
||||
file:
|
||||
path: "{{service_dir}}/checks"
|
||||
state: directory
|
||||
|
||||
- name: Copy UDP check file
|
||||
template:
|
||||
src: udp_check.sh.j2
|
||||
dest: "{{service_dir}}/checks/udp_check.sh"
|
||||
mode: 0755
|
||||
|
||||
- name: Copy keepalived configuration for rsyslog
|
||||
template:
|
||||
src: rsyslog.conf.j2
|
||||
dest: /etc/rsyslog.d/51-keepalived-udp.conf
|
||||
mode: 0644
|
||||
notify: Restart rsyslog
|
||||
|
||||
- name: Copy keepalived configuration for logrotate
|
||||
template:
|
||||
src: logrotate.conf.j2
|
||||
dest: /etc/logrotate.d/keepalived-udp
|
||||
mode: 0644
|
||||
|
||||
- name: Install the latest version of Keepalived
|
||||
package:
|
||||
name:
|
||||
- keepalived
|
||||
- ipvsadm
|
||||
- iptables
|
||||
state: present
|
||||
when: "'keepalived' not in ansible_facts.packages"
|
||||
environment:
|
||||
http_proxy: "{{PROXY}}"
|
||||
https_proxy: "{{PROXY}}"
|
||||
|
||||
- name: Copy keepalived configuration in place.
|
||||
template:
|
||||
src: keepalived-udp.conf.j2
|
||||
dest: "{{ service_dir }}/keepalived-udp-{{ id }}.conf"
|
||||
mode: 0644
|
||||
|
||||
- name: Copy keepalived UPD service file in place.
|
||||
template:
|
||||
src: keepalived.service.j2
|
||||
dest: "/etc/systemd/system/keepalived-udp-{{ id }}.service"
|
||||
mode: 0644
|
||||
|
||||
- name: Copy iptables restore service file in place.
|
||||
template:
|
||||
src: iptables-restore.service.j2
|
||||
dest: /etc/systemd/system/iptables-restore.service
|
||||
mode: 0644
|
||||
|
||||
- name: Enable and start service keepalived
|
||||
service:
|
||||
name: "keepalived-udp-{{ id }}"
|
||||
daemon_reload: yes
|
||||
state: restarted
|
||||
enabled: yes
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Enable and start service iptables-restore
|
||||
service:
|
||||
name: iptables-restore
|
||||
daemon_reload: yes
|
||||
state: restarted
|
||||
enabled: yes
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Enable sysctl parameters
|
||||
sysctl:
|
||||
name: "{{ item }}"
|
||||
value: '1'
|
||||
sysctl_set: yes
|
||||
state: present
|
||||
reload: yes
|
||||
with_items: ["net.ipv4.ip_forward", "net.ipv4.conf.all.arp_ignore", "net.ipv4.ip_nonlocal_bind", "net.ipv6.ip_nonlocal_bind"]
|
||||
|
||||
- name: Enable arp_ignore
|
||||
sysctl:
|
||||
name: net.ipv4.conf.all.arp_announce
|
||||
value: '2'
|
||||
sysctl_set: yes
|
||||
state: present
|
||||
reload: yes
|
||||
|
||||
- name: Create NAT in iptables
|
||||
command: "/sbin/iptables -t nat -A POSTROUTING -m ipvs --vaddr {{ vip }} -j MASQUERADE"
|
||||
|
||||
- name: Save current state of the firewall in system file
|
||||
community.general.iptables_state:
|
||||
state: saved
|
||||
path: /etc/sysconfig/iptables
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
- include_tasks: "{{ action }}.yml"
|
|
@ -0,0 +1,29 @@
|
|||
---
|
||||
- name: Delete NAT in iptables
|
||||
shell: "/sbin/iptables -t nat -D POSTROUTING -m ipvs --vaddr {{ vip }} -j MASQUERADE"
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Save current state of the firewall in system file
|
||||
community.general.iptables_state:
|
||||
state: saved
|
||||
path: /etc/sysconfig/iptables
|
||||
|
||||
- name: Delete keepalived configuration in place.
|
||||
file:
|
||||
path: "{{ service_dir }}/keepalived-udp-{{ id }}.conf"
|
||||
state: absent
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Disable and start service keepalived
|
||||
service:
|
||||
name: "keepalived-udp-{{ id }}"
|
||||
daemon_reload: yes
|
||||
state: stopped
|
||||
enabled: no
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Delete keepalived UPD service file.
|
||||
file:
|
||||
path: "/etc/systemd/system/keepalived-udp-{{ id }}.service"
|
||||
state: absent
|
||||
ignore_errors: yes
|
|
@ -0,0 +1,13 @@
|
|||
# {{ ansible_managed }}
|
||||
|
||||
[Unit]
|
||||
Description=Restore iptables rules
|
||||
Before=network-pre.target
|
||||
Conflicts=shutdown.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/sbin/iptables-restore /etc/sysconfig/iptables
|
||||
|
||||
[Install]
|
||||
WantedBy=basic.target
|
|
@ -0,0 +1,19 @@
|
|||
virtual_server {{ vip }} {{ port }} {
|
||||
lb_algo rr
|
||||
lb_kind NAT
|
||||
protocol UDP
|
||||
delay_loop 10
|
||||
delay_before_retry 10
|
||||
retry 3
|
||||
|
||||
|
||||
{% for server, value in config.items() %}
|
||||
real_server {{ server }} {{ value.port }} {
|
||||
weight {{ value.weight }}
|
||||
MISC_CHECK {
|
||||
misc_path "{{ service_dir }}/checks/udp_check.sh {{ server }} {{ value.port }}"
|
||||
misc_timeout 5
|
||||
}
|
||||
}
|
||||
{% endfor %}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
[Unit]
|
||||
Description=LVS and VRRP High Availability Monitor
|
||||
After=network-online.target syslog.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
SELinuxContext=system_u:system_r:keepalived_t:s0
|
||||
Type=forking
|
||||
PIDFile=/var/run/keepalived-udp-{{ id }}.pid
|
||||
KillMode=process
|
||||
ExecStart=/usr/sbin/keepalived --log-facility=1 -f /etc/keepalived/keepalived-udp-{{ id }}.conf -p /var/run/keepalived-udp-{{ id }}.pid -r /var/run/keepalived-udp-vrrp-{{ id }}.pid -c /var/run/keepalived-udp-check-{{ id }}.pid
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
|
||||
StandardOutput=syslog
|
||||
StandardError=syslog
|
||||
SyslogIdentifier=roxy-wi-udp
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
|
@ -0,0 +1,10 @@
|
|||
{{ keepalived_path_logs }}/*.log {
|
||||
daily
|
||||
rotate 10
|
||||
missingok
|
||||
notifempty
|
||||
create 0644 root root
|
||||
dateext
|
||||
sharedscripts
|
||||
copytruncate
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
$ModLoad imudp
|
||||
$UDPServerAddress 127.0.0.1
|
||||
$UDPServerRun 514
|
||||
module(load="builtin:omfile")
|
||||
|
||||
if $programname startswith 'Keepalived_healthcheckers' then {
|
||||
if $syslogseverity == 6 then
|
||||
action(type="omfile" file="{{ keepalived_path_logs }}/status.log")
|
||||
stop
|
||||
if $syslogseverity <= 3 then
|
||||
action(type="omfile" file="{{ keepalived_path_logs }}/error.log")
|
||||
stop
|
||||
if $syslogseverity <= 5 then
|
||||
action(type="omfile" file="{{ keepalived_path_logs }}/status.log")
|
||||
stop
|
||||
}
|
||||
|
||||
if $programname startswith 'keepalived' then {
|
||||
if $syslogseverity == 6 then
|
||||
action(type="omfile" file="{{ keepalived_path_logs }}/status.log")
|
||||
stop
|
||||
if $syslogseverity <= 3 then
|
||||
action(type="omfile" file="{{ keepalived_path_logs }}/error.log")
|
||||
stop
|
||||
if $syslogseverity <= 5 then
|
||||
action(type="omfile" file="{{ keepalived_path_logs }}/status.log")
|
||||
stop
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
|
||||
nc_cmd=`which nc`
|
||||
|
||||
nc_flavor=$($nc_cmd --version 2>&1 | grep -o nmap)
|
||||
case "$nc_flavor" in
|
||||
nmap)
|
||||
nc_flavor_opts="-i1"
|
||||
;;
|
||||
*) # default, probably openbsd
|
||||
nc_flavor_opts="-w1"
|
||||
;;
|
||||
esac
|
||||
|
||||
$nc_cmd -uzv $nc_flavor_opts $1 $2 > /dev/null
|
||||
exit $?
|
|
@ -471,3 +471,8 @@
|
|||
font-family: "Font Awesome 5 Regular";
|
||||
content: "\f086";
|
||||
}
|
||||
.balance::before {
|
||||
display: none;
|
||||
font-family: "Font Awesome 5 Solid";
|
||||
content: "\f516";
|
||||
}
|
||||
|
|
|
@ -264,7 +264,7 @@ $( function() {
|
|||
request.term = 1
|
||||
}
|
||||
$.ajax({
|
||||
url: "/app/add/show/ip/" + $("#serv").val(),
|
||||
url: "/app/server/show/ip/" + $("#serv").val(),
|
||||
success: function (data) {
|
||||
data = data.replace(/\s+/g, ' ');
|
||||
response(data.split(" "));
|
||||
|
@ -284,7 +284,7 @@ $( function() {
|
|||
request.term = 1
|
||||
}
|
||||
$.ajax({
|
||||
url: "/app/add/show/ip/" + $("#serv2").val(),
|
||||
url: "/app/server/show/ip/" + $("#serv2").val(),
|
||||
success: function (data) {
|
||||
data = data.replace(/\s+/g, ' ');
|
||||
response(data.split(" "));
|
||||
|
@ -2059,7 +2059,6 @@ function make_actions_for_adding_header(section_id) {
|
|||
$.getScript("/app/static/js/overview.js");
|
||||
$( "select" ).selectmenu();
|
||||
$('[name=headers_method]').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> ' +
|
||||
|
@ -2084,7 +2083,7 @@ function make_actions_for_adding_bind(section_id) {
|
|||
request.term = 1
|
||||
}
|
||||
$.ajax({
|
||||
url: "/app/add/show/ip/" + $("#" + serv).val(),
|
||||
url: "/app/server/show/ip/" + $("#" + serv).val(),
|
||||
success: function (data) {
|
||||
data = data.replace(/\s+/g, ' ');
|
||||
response(data.split(" "));
|
||||
|
@ -2099,17 +2098,17 @@ function make_actions_for_adding_bind(section_id) {
|
|||
});
|
||||
}
|
||||
function makeid(length) {
|
||||
var result = '';
|
||||
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
var charactersLength = characters.length;
|
||||
for ( var i = 0; i < length; i++ ) {
|
||||
let result = '';
|
||||
let characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let charactersLength = characters.length;
|
||||
for ( let i = 0; i < length; i++ ) {
|
||||
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function showUserlists() {
|
||||
var serv = $("#existing_userlist_serv option:selected").val();
|
||||
var select_id = $("#existing_userlist_serv");
|
||||
let serv = $("#existing_userlist_serv option:selected").val();
|
||||
let select_id = $("#existing_userlist_serv");
|
||||
if (!checkIsServerFiled(select_id)) return false;
|
||||
$.ajax({
|
||||
url: "/app/add/haproxy/userlist/" + serv,
|
||||
|
|
|
@ -1,9 +1,3 @@
|
|||
function ValidateIPaddress(ipaddress) {
|
||||
if (/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(ipaddress)) {
|
||||
return (true)
|
||||
}
|
||||
return (false)
|
||||
}
|
||||
$( function() {
|
||||
$("select").selectmenu({
|
||||
width: 180
|
||||
|
@ -244,9 +238,7 @@ function createHaClusterStep1(edited=false, cluster_id=0, clean=true) {
|
|||
dialog_div.dialog('open');
|
||||
}
|
||||
function createHaClusterStep2(edited=false, cluster_id=0, jsonData='') {
|
||||
var add_word = $('#translate').attr('data-next');
|
||||
var cancel_word = $('#translate').attr('data-cancel');
|
||||
var next_word = $('#translate').attr('data-next');
|
||||
var back_word = $('#translate').attr('data-back');
|
||||
var save_word = $('#translate').attr('data-save');
|
||||
var apply_word = $('#translate').attr('data-apply');
|
||||
|
|
|
@ -175,8 +175,7 @@ function installService(service) {
|
|||
showErrorStatus(nice_names[service], $(select_id + ' option:selected').text());
|
||||
},
|
||||
data: {
|
||||
jsonData: JSON.stringify(jsonData),
|
||||
token: $('#token').val()
|
||||
jsonData: JSON.stringify(jsonData)
|
||||
},
|
||||
type: "POST",
|
||||
success: function (data) {
|
||||
|
@ -232,10 +231,6 @@ function showExporterVersion(exporter) {
|
|||
var nice_names = {'haproxy': 'HAProxy', 'nginx': 'NGINX', 'apache': 'Apache', 'node': 'Node', 'keepalived': 'Keepalived'};
|
||||
$.ajax({
|
||||
url: "/app/install/exporter/"+ exporter +"/version/" + $('#' + exporter + '_exp_addserv option:selected').val(),
|
||||
// data: {
|
||||
// token: $('#token').val()
|
||||
// },
|
||||
// type: "POST",
|
||||
success: function (data) {
|
||||
data = data.replace(/^\s+|\s+$/g, '');
|
||||
if (data.indexOf('error:') != '-1') {
|
||||
|
@ -252,10 +247,6 @@ function showExporterVersion(exporter) {
|
|||
function showServiceVersion(service) {
|
||||
$.ajax({
|
||||
url: "/app/install/" + service + "/version/" + $('#' + service + 'addserv option:selected').val(),
|
||||
// data: {
|
||||
// token: $('#token').val()
|
||||
// },
|
||||
// type: "POST",
|
||||
success: function (data) {
|
||||
data = data.replace(/^\s+|\s+$/g, '');
|
||||
if (data.indexOf('error: ') != '-1') {
|
||||
|
|
|
@ -0,0 +1,472 @@
|
|||
var cancel_word = $('#translate').attr('data-cancel');
|
||||
$( function() {
|
||||
$( "#ha-cluster" ).on('selectmenuchange',function() {
|
||||
let cluster_id = $( "#ha-cluster option:selected" ).val();
|
||||
if (cluster_id != '------') {
|
||||
getHAClusterVIPS(cluster_id);
|
||||
} else {
|
||||
clearUdpVip();
|
||||
}
|
||||
});
|
||||
$("#new-udp-ip").autocomplete({
|
||||
source: function (request, response) {
|
||||
if (!checkIsServerFiled('#serv')) return false;
|
||||
if (request.term == "") {
|
||||
request.term = 1
|
||||
}
|
||||
$.ajax({
|
||||
url: "/app/server/show/ip/" + $("#serv").val(),
|
||||
success: function (data) {
|
||||
data = data.replace(/\s+/g, ' ');
|
||||
response(data.split(" "));
|
||||
}
|
||||
});
|
||||
},
|
||||
appendTo: "#create-udp-step-2",
|
||||
autoFocus: true,
|
||||
minLength: -1,
|
||||
select: function (event, ui) {
|
||||
$('#new-listener-port').focus();
|
||||
}
|
||||
});
|
||||
});
|
||||
function getHAClusterVIPS(cluster_id) {
|
||||
$.ajax({
|
||||
url: `/app/ha/cluster/${cluster_id}/vips`,
|
||||
async: false,
|
||||
contentType: "application/json; charset=utf-8",
|
||||
success: function (data) {
|
||||
if (data.status === 'failed') {
|
||||
toastr.error(data.error);
|
||||
return false;
|
||||
} else {
|
||||
clearUdpVip();
|
||||
$('#new-udp-vip').append('<option value="------" selected>------</option>')
|
||||
data.forEach(function (obj) {
|
||||
console.log(obj.vip);
|
||||
$('#new-udp-vip').append('<option value="' + obj.id + '">' + obj.vip + '</option>')
|
||||
});
|
||||
$('#new-udp-vip').selectmenu("refresh");
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
function createUDPListener(edited=false, listener_id=0, clean=true) {
|
||||
let next_word = $('#translate').attr('data-next');
|
||||
let tabel_title = $("#create-udp-step-1-overview").attr('title');
|
||||
clearListenerDialog();
|
||||
if (edited) {
|
||||
tabel_title = $("#create-udp-step-1-overview").attr('data-edit');
|
||||
}
|
||||
if (edited && clean) {
|
||||
let place = $('#listener-type-'+ listener_id).val();
|
||||
if (place === 'cluster') {
|
||||
$('.new-udp-ha-cluster-tr').show();
|
||||
$('.new-udp-servers-tr').hide();
|
||||
} else {
|
||||
$('.new-udp-ha-cluster-tr').hide();
|
||||
$('.new-udp-servers-tr').show();
|
||||
}
|
||||
$.ajax({
|
||||
url: `/app/udp/listener/${listener_id}/settings`,
|
||||
type: "GET",
|
||||
async: false,
|
||||
contentType: "application/json; charset=utf-8",
|
||||
success: function (data) {
|
||||
$('#new-listener-name').val(data.name.replaceAll("'", ""));
|
||||
$('#new-listener-type').val(place);
|
||||
$('#new-listener-port').val(data.port);
|
||||
$('#new-listener-desc').val(data.desc.replaceAll("'", ""));
|
||||
if (place === 'cluster') {
|
||||
$.when(getHAClusterVIPS(data.cluster_id)).done(function () {
|
||||
$("#new-udp-vip option").filter(function () {
|
||||
return $(this).text() == data.vip;
|
||||
}).attr('selected', true);
|
||||
$("#new-udp-vip").selectmenu('refresh');
|
||||
});
|
||||
$("#ha-cluster").val(data.cluster_id).change();
|
||||
$("#ha-cluster").attr('disabled', 'disabled');
|
||||
$("#ha-cluster").selectmenu('refresh');
|
||||
} else {
|
||||
$("#serv").val(data.server_id).change();
|
||||
$("#serv").attr('disabled', 'disabled');
|
||||
$("#serv").selectmenu('refresh');
|
||||
$('#new-udp-ip').val(data.vip);
|
||||
}
|
||||
$('#new-udp-servers-td').empty();
|
||||
$('#new-udp-servers-td').append('<a class="link add-server" title="Add backend server" onclick="createBackendServer()"></a>');
|
||||
for(let server in data.config) {
|
||||
createBackendServer(server, data.config[server]['port'], data.config[server]['weight']);
|
||||
}
|
||||
}
|
||||
});
|
||||
createUDPListenerStep2(edited, listener_id, place);
|
||||
return false;
|
||||
}
|
||||
let dialog_div = $("#create-udp-step-1").dialog({
|
||||
autoOpen: false,
|
||||
resizable: false,
|
||||
height: "auto",
|
||||
width: 630,
|
||||
modal: true,
|
||||
title: tabel_title,
|
||||
show: {
|
||||
effect: "fade",
|
||||
duration: 200
|
||||
},
|
||||
hide: {
|
||||
effect: "fade",
|
||||
duration: 200
|
||||
},
|
||||
buttons: [{
|
||||
text: next_word,
|
||||
click: function () {
|
||||
if ($('#new-udp-type option:selected').val().indexOf('--') != '-1') {
|
||||
toastr.error('error: Select Listener type');
|
||||
return false;
|
||||
}
|
||||
let place = '';
|
||||
if ($('#new-udp-type option:selected').val() == 'cluster') {
|
||||
$('.new-udp-ha-cluster-tr').show();
|
||||
$('.new-udp-servers-tr').hide();
|
||||
place = 'cluster';
|
||||
} else {
|
||||
$('.new-udp-ha-cluster-tr').hide();
|
||||
$('.new-udp-servers-tr').show();
|
||||
place = 'server';
|
||||
}
|
||||
$('#new-listener-type').val(place);
|
||||
createUDPListenerStep2(edited, listener_id, place);
|
||||
$(this).dialog("close");
|
||||
toastr.clear();
|
||||
}
|
||||
}, {
|
||||
text: cancel_word,
|
||||
click: function () {
|
||||
$(this).dialog("close");
|
||||
clearListenerDialog(edited);
|
||||
}
|
||||
}]
|
||||
});
|
||||
dialog_div.dialog('open');
|
||||
}
|
||||
function createUDPListenerStep2(edited, listener_id, place) {
|
||||
let save_word = $('#translate').attr('data-save');
|
||||
let apply_word = $('#translate').attr('data-apply');
|
||||
let back_word = $('#translate').attr('data-back');
|
||||
let tabel_title = $("#create-udp-step-2-overview").attr('title');
|
||||
if (edited) {
|
||||
tabel_title = $("#create-udp-step-1-overview").attr('data-edit');
|
||||
}
|
||||
let dialog_div = $("#create-udp-step-2").dialog({
|
||||
autoOpen: false,
|
||||
resizable: false,
|
||||
height: "auto",
|
||||
width: 630,
|
||||
modal: true,
|
||||
title: tabel_title,
|
||||
show: {
|
||||
effect: "fade",
|
||||
duration: 200
|
||||
},
|
||||
hide: {
|
||||
effect: "fade",
|
||||
duration: 200
|
||||
},
|
||||
buttons: [{
|
||||
text: save_word,
|
||||
click: function () {
|
||||
if (!validateUDPListenerForm(place)) {
|
||||
return false;
|
||||
}
|
||||
jsonData = getFormData($("#create_udp_listener"));
|
||||
saveUdpListener(jsonData, $(this), listener_id, edited);
|
||||
}
|
||||
}, {
|
||||
text: apply_word,
|
||||
click: function () {
|
||||
jsonData = getFormData($("#create_udp_listener"));
|
||||
saveUdpListener(jsonData, $(this), listener_id, edited, 1);
|
||||
}
|
||||
}, {
|
||||
text: back_word,
|
||||
click: function () {
|
||||
$(this).dialog("close");
|
||||
createUDPListener(edited, listener_id, false);
|
||||
}
|
||||
}, {
|
||||
text: cancel_word,
|
||||
click: function () {
|
||||
$(this).dialog("close");
|
||||
clearListenerDialog(edited);
|
||||
}
|
||||
}]
|
||||
});
|
||||
dialog_div.dialog('open');
|
||||
}
|
||||
function validateUDPListenerForm(place) {
|
||||
if ($('#new-listener-name').val() == '') {
|
||||
toastr.error('error: Fill in the Name field');
|
||||
return false;
|
||||
}
|
||||
if ($('#new-listener-port').val() == '') {
|
||||
toastr.error('error: Fill in the Port field');
|
||||
return false;
|
||||
}
|
||||
if (place == 'server') {
|
||||
if ($('#new-udp-ip').val() == '') {
|
||||
toastr.error('error: Fill in the IP field');
|
||||
return false;
|
||||
}
|
||||
if (!ValidateIPaddress($('#new-udp-ip').val())) {
|
||||
toastr.error('error: Wrong IP');
|
||||
return false;
|
||||
}
|
||||
if ($('#serv option:selected').val().indexOf('--') != '-1') {
|
||||
toastr.error('error: Select a server');
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if ($('#ha-cluster option:selected').val().indexOf('--') != '-1') {
|
||||
toastr.error('error: Select a HA cluster');
|
||||
return false;
|
||||
}
|
||||
if ($('#new-udp-ha-ports').val() == '') {
|
||||
toastr.error('error: Fill in the Port field');
|
||||
return false;
|
||||
}
|
||||
if ($('#new-udp-ha-weight').val() == '') {
|
||||
toastr.error('error: Fill in the Weight field');
|
||||
return false;
|
||||
}
|
||||
if ($('#new-udp-vip option:selected').val().indexOf('--') != '-1') {
|
||||
toastr.error('error: Select the VIP address');
|
||||
return false;
|
||||
}
|
||||
if (!ValidateIPaddress($('#new-udp-vip option:selected').text())) {
|
||||
toastr.error('error: Wrong VIP');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function getFormData($form) {
|
||||
$("#serv").attr('disabled', false);
|
||||
$("#serv").selectmenu('refresh');
|
||||
let unindexed_array = $form.serializeArray();
|
||||
let indexed_array = {};
|
||||
indexed_array['servers'] = {};
|
||||
console.log(unindexed_array)
|
||||
|
||||
$.map(unindexed_array, function (n, i) {
|
||||
indexed_array[n['name']] = n['value'];
|
||||
});
|
||||
$('.servers').each(function () {
|
||||
let ip = $(this).children("input[name='new-udp-server']").val();
|
||||
if (ip === undefined || ip === '') {
|
||||
return;
|
||||
}
|
||||
let port = $(this).children("input[name='new-udp-port']").val();
|
||||
let weight = $(this).children("input[name='new-udp-weight']").val();
|
||||
indexed_array['servers'][ip] = {port, weight};
|
||||
});
|
||||
indexed_array['ha-cluster'] = $('#ha-cluster').val();
|
||||
indexed_array['new-udp-router_id'] = $('#new-udp-vip').val();
|
||||
indexed_array['new-udp-vip'] = $('#new-udp-vip option:selected').text();
|
||||
$("#serv").attr('disabled', 'disabled');
|
||||
$("#serv").selectmenu('refresh');
|
||||
return indexed_array;
|
||||
}
|
||||
function saveUdpListener(jsonData, dialog_id, listener_id=0, edited=0, reconfigure=0) {
|
||||
let req_method = 'POST';
|
||||
if (edited) {
|
||||
req_method = 'PUT';
|
||||
jsonData['listener_id'] = listener_id;
|
||||
}
|
||||
$.ajax({
|
||||
url: "/app/udp/listener",
|
||||
type: req_method,
|
||||
data: JSON.stringify(jsonData),
|
||||
contentType: "application/json; charset=utf-8",
|
||||
success: function (data) {
|
||||
if (data.status === 'failed') {
|
||||
toastr.error(data.error);
|
||||
} else {
|
||||
if (edited) {
|
||||
getUDPListener(listener_id);
|
||||
$("#listener-" + listener_id).addClass("update", 1000);
|
||||
setTimeout(function () {
|
||||
$("#listener-" + listener_id).removeClass("update");
|
||||
}, 2500);
|
||||
} else {
|
||||
listener_id = data.listener_id;
|
||||
getUDPListener(data.listener_id, true);
|
||||
}
|
||||
if (reconfigure) {
|
||||
NProgress.start();
|
||||
$.when(Reconfigure(listener_id)).done(function () {
|
||||
dialog_id.dialog("close");
|
||||
NProgress.done();
|
||||
});
|
||||
} else {
|
||||
dialog_id.dialog("close");
|
||||
}
|
||||
toastr.success('Listener ' + data.status);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function Reconfigure(listener_id) {
|
||||
return $.ajax({
|
||||
url: "/app/install/udp",
|
||||
data: {listener_id: listener_id},
|
||||
async: false,
|
||||
type: "POST",
|
||||
success: function (data) {
|
||||
if (data.status === 'failed') {
|
||||
toastr.error(data.error);
|
||||
} else {
|
||||
parseAnsibleJsonOutput(data, 'UDP listener', '');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function getUDPListener(listener_id, new_listener=false) {
|
||||
$.ajax({
|
||||
url: "/app/udp/listener/" + listener_id,
|
||||
success: function (data) {
|
||||
data = data.replace(/^\s+|\s+$/g, '');
|
||||
if (data.indexOf('error:') != '-1') {
|
||||
toastr.error(data);
|
||||
} else {
|
||||
if (new_listener) {
|
||||
$('.up-pannel').append(data);
|
||||
} else {
|
||||
$('#listener-' + listener_id).replaceWith(data);
|
||||
}
|
||||
$('#listener-'+listener_id).removeClass('animated-background');
|
||||
}
|
||||
}
|
||||
});
|
||||
$.getScript("/app/static/js/fontawesome.min.js");
|
||||
}
|
||||
function confirmDeleteListener(listener_id) {
|
||||
let delete_word = $('#translate').attr('data-delete');
|
||||
$("#dialog-confirm").dialog({
|
||||
resizable: false,
|
||||
height: "auto",
|
||||
width: 400,
|
||||
modal: true,
|
||||
title: delete_word + " " + $('#listener-name-' + listener_id).text() + "?",
|
||||
buttons: [{
|
||||
text: delete_word,
|
||||
click: function () {
|
||||
$(this).dialog("close");
|
||||
deleteListener(listener_id);
|
||||
}
|
||||
}, {
|
||||
text: cancel_word,
|
||||
click: function () {
|
||||
$(this).dialog("close");
|
||||
}
|
||||
}]
|
||||
});
|
||||
}
|
||||
function deleteListener(listener_id) {
|
||||
let jsonData = {'listener_id': listener_id}
|
||||
$.ajax({
|
||||
url: "/app/udp/listener",
|
||||
type: "DELETE",
|
||||
data: JSON.stringify(jsonData),
|
||||
contentType: "application/json; charset=utf-8",
|
||||
success: function (data) {
|
||||
if (data.status === 'failed') {
|
||||
toastr.error(data.error);
|
||||
} else {
|
||||
$('#listener-' + listener_id).remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function clearListenerDialog(edited=0) {
|
||||
$('#new-listener-name').val('');
|
||||
$('#new-listener-desc').val('');
|
||||
$('#ha-cluster-master-interface').val('');
|
||||
$('#new-udp-ip').val('');
|
||||
$('#vrrp-ip').prop("readonly", false);
|
||||
$('#new-listener-port').val('');
|
||||
$("#ha-cluster").attr('disabled', false);
|
||||
$("#serv").attr('disabled', false);
|
||||
clearUdpVip()
|
||||
$('#new-udp-servers-td').empty();
|
||||
$('#new-udp-servers-td').append('<a class="link add-server" title="Add backend server" onclick="createBackendServer()"></a>');
|
||||
createBackendServer();
|
||||
let selects = ['new-udp-type', 'ha-cluster', 'new-udp-vip', 'serv']
|
||||
for (let select of selects) {
|
||||
unselectSelectMenu(select);
|
||||
}
|
||||
}
|
||||
function unselectSelectMenu(select_id) {
|
||||
$('#' + select_id + ' option').attr('selected', false);
|
||||
$('#' + select_id + ' option:first').attr('selected', 'selected');
|
||||
$('#' + select_id).selectmenu("refresh");
|
||||
}
|
||||
function clearUdpVip() {
|
||||
$('#new-udp-vip').selectmenu( "destroy" );
|
||||
$('#new-udp-vip').empty();
|
||||
$('#new-udp-vip').selectmenu();
|
||||
}
|
||||
function confirmUdpBalancerAction(action, listener_id) {
|
||||
let action_word = $('#translate').attr('data-'+action);
|
||||
console.log('#litener-name-'+listener_id);
|
||||
let l_name = $('#listener-name-'+listener_id).text();
|
||||
$( "#dialog-confirm" ).dialog({
|
||||
resizable: false,
|
||||
height: "auto",
|
||||
width: 400,
|
||||
modal: true,
|
||||
title: action_word + " " + l_name + "?",
|
||||
buttons: [{
|
||||
text: action_word,
|
||||
click: function () {
|
||||
$(this).dialog("close");
|
||||
ajaxActionListener(action, listener_id);
|
||||
}
|
||||
}, {
|
||||
text: cancel_word,
|
||||
click: function() {
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
}]
|
||||
});
|
||||
}
|
||||
function ajaxActionListener(action, listener_id) {
|
||||
$.ajax({
|
||||
url: `/app/udp/listener/${listener_id}/${action}`,
|
||||
type: "GET",
|
||||
contentType: "application/json; charset=utf-8",
|
||||
success: function (data) {
|
||||
if (data.status === 'failed') {
|
||||
toastr.error(data.error);
|
||||
return false;
|
||||
} else {
|
||||
toastr.success(`Listener has been ${action}ed`);
|
||||
getUDPListener(listener_id);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function createBackendServer(server='', port='', weight='1') {
|
||||
let server_word = $('#translate').attr('data-server');
|
||||
let port_word = $('#translate').attr('data-port');
|
||||
let weight_word = $('#translate').attr('data-weight');
|
||||
let delete_word = $('#translate').attr('data-delete');
|
||||
$('<div class="servers">' +
|
||||
server_word+': <input name="new-udp-server" value="' + server + '" class="form-control" placeholder="10.0.0.1">' +
|
||||
port_word + ': <input name="new-udp-port" value="' + port + '" type="number" class="form-control" placeholder="443" style="width: 50px">' +
|
||||
weight_word + ': <input name="new-udp-weight" value="' + weight + '" type="number" class="form-control" style="width: 30px">' +
|
||||
'<span class="minus minus-style" title="'+delete_word+' '+server_word+'" onclick="$(this).parent().remove()"></span>' +
|
||||
'</div>').insertBefore('.add-server');
|
||||
$.getScript("/app/static/js/fontawesome.min.js");
|
||||
}
|
|
@ -19,12 +19,12 @@
|
|||
data-raw="{{lang.words.raw|title()}}" data-resp_time="{{lang.smon_page.desc.resp_time}}" data-next="{{lang.words.next|title()}}" data-back="{{lang.words.back|title()}}"
|
||||
data-installing="{{lang.words.installing|title()}}" data-creating="{{lang.words.creating|title()}}" data-roxywi_timeout="{{lang.ha_page.roxywi_timeout}}"
|
||||
data-check_apache_log="{{lang.ha_page.check_apache_log}}" data-was_installed="{{lang.ha_page.was_installed}}" data-start_enter="{{lang.ha_page.start_enter}}"
|
||||
data-apply="{{lang.words.apply|title()}}" data-reconfigure="{{lang.words.reconfigure|title()}}" />
|
||||
data-apply="{{lang.words.apply|title()}}" data-reconfigure="{{lang.words.reconfigure|title()}}" data-server="{{lang.words.server|title()}}" data-port="{{lang.words.port}}"
|
||||
data-weight="{{lang.words.weight}}" />
|
||||
{% include 'include/main_head.html' %}
|
||||
</head>
|
||||
<body>
|
||||
{% if g.user_params['user'] %}
|
||||
<input type="hidden" id="token" value="{{ g.user_params['token'] }}">
|
||||
<script>show_version();</script>
|
||||
{% include 'include/main_menu.html' %}
|
||||
<div class="container">
|
||||
|
|
|
@ -43,8 +43,8 @@
|
|||
{{set.param}}
|
||||
</td>
|
||||
<td class="addOption">
|
||||
{% if set.param in ('ldap_password', 'haproxy_stats_password', 'nginx_stats_password', 'apache_stats_password', 'rabbitmq_password', 'mail_smtp_password') %}
|
||||
{% if set.value is none %}
|
||||
{% if set.param in ('ldap_password', 'haproxy_stats_password', 'nginx_stats_password', 'apache_stats_password', 'rabbitmq_password', 'mail_smtp_password', 'license') %}
|
||||
{% if set.value == '' or set.value is none %}
|
||||
{{ input(set.param, size='25', type='password', style='width: 210px;') }}
|
||||
{% else %}
|
||||
{{ input(set.param, size='25', type='password', style='width: 210px;', placeholder='******') }}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<label for="{{id}}" title="{{title}}" class="{{id}}" style="{{style}}" data-help="{{title}}">{{desc}}</label><input name="{{name}}" type="checkbox" id="{{id}}" value="{{value|e}}" {{checked}} {{disabled}} />
|
||||
{%- endmacro %}
|
||||
|
||||
{%- macro select(id, values, name='', required='', first='', class='', selected='', title='', disabled='true', is_servers='') -%}
|
||||
{%- macro select(id, values, name='', required='', first='', class='', selected='', title='', disabled='true', is_servers='', by_id='') -%}
|
||||
{% if name == '' %}
|
||||
{% set name = id %}
|
||||
{% endif %}
|
||||
|
@ -35,11 +35,19 @@
|
|||
{% endif %}
|
||||
{% if is_servers %}
|
||||
{% for value in values %}
|
||||
{% if value.2 == selected|string() %}
|
||||
<option value="{{value.2}}" selected>{{value.1}}</option>
|
||||
{% else %}
|
||||
<option value="{{ value.2 }}">{{ value.1 }}</option>
|
||||
{% endif %}
|
||||
{% if by_id %}
|
||||
{% if value.0 == selected|string() %}
|
||||
<option value="{{value.0}}" selected>{{value.1}}</option>
|
||||
{% else %}
|
||||
<option value="{{ value.0 }}">{{ value.1 }}</option>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if value.2 == selected|string() %}
|
||||
<option value="{{value.2}}" selected>{{value.1}}</option>
|
||||
{% else %}
|
||||
<option value="{{ value.2 }}">{{ value.1 }}</option>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% for v, des in values.items() %}
|
||||
|
|
|
@ -69,6 +69,11 @@
|
|||
</ul>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if '6' in g.user_params['user_services'] %}
|
||||
{% if g.user_params['role'] <= 2 %}
|
||||
<li><a href="{{ url_for('udp.listener_funct', service='udp') }}" title="{{lang.menu_links.udp.title}}" class="balance {% if request.url_rule.endpoint == 'udp.listener_funct' %} menu-active{% endif %}">{{lang.menu_links.udp.title}}</a></li>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if '3' in g.user_params['user_services'] %}
|
||||
{% if g.user_params['role'] <= 2 %}
|
||||
<li class="p_menu">
|
||||
|
|
|
@ -115,6 +115,9 @@
|
|||
},
|
||||
"history": {
|
||||
"title": "History of"
|
||||
},
|
||||
"udp": {
|
||||
"title": "UDP balancers"
|
||||
}
|
||||
}
|
||||
%}
|
||||
|
@ -170,6 +173,7 @@
|
|||
},
|
||||
"main": {
|
||||
"time_zone": "Time Zone",
|
||||
"license": "License key",
|
||||
"proxy": "IP address and port of the proxy server. Use proto://ip:port",
|
||||
"session_ttl": "TTL for a user session (in days)",
|
||||
"token_ttl": "TTL for a user token (in days)",
|
||||
|
@ -508,6 +512,12 @@
|
|||
"save_apply": "<b>Save</b> - means saving the HA cluster settings for Roxy-WI, without changing the component settings on the cluster members. <br /> <b>Apply</b> - recreate the HA cluster configuration on the cluster member servers and install additional services.",
|
||||
}
|
||||
%}
|
||||
{% set udp_page = {
|
||||
"save_apply": "<b>Save</b> - means saving the UDP listener settings for Roxy-WI, without changing the component settings on the cluster members or standalone server. <br /> <b>Apply</b> - recreate the UDP listener configuration on the cluster member servers or standalone server.",
|
||||
"listener_ip": "IP for binding UDP Listener. Start typing",
|
||||
"listener_port": "Port for binding UDP Listener",
|
||||
}
|
||||
%}
|
||||
{% set nettools_page = {
|
||||
"ip_or_name": "Enter IP or Name",
|
||||
"dns_name": "Enter a DNS name",
|
||||
|
@ -928,5 +938,9 @@
|
|||
"agent": "agent",
|
||||
"agent2": "agent",
|
||||
"reconfigure": "reconfigure",
|
||||
"listener": "listener",
|
||||
"listeners": "listeners",
|
||||
"weight": "weight",
|
||||
"where": "where",
|
||||
}
|
||||
%}
|
||||
|
|
|
@ -115,6 +115,9 @@
|
|||
},
|
||||
"history": {
|
||||
"title": "Historique de"
|
||||
},
|
||||
"udp": {
|
||||
"title": "Équilibreurs UDP"
|
||||
}
|
||||
}
|
||||
%}
|
||||
|
@ -170,6 +173,7 @@
|
|||
},
|
||||
"main": {
|
||||
"time_zone": "Fuseau horaire",
|
||||
"license": "Clé de licence",
|
||||
"proxy": "Adresse IP et port du proxy server. format proto://ip:port",
|
||||
"session_ttl": "TTL pour la session utilisateur (en jours)",
|
||||
"token_ttl": "TTL pour le jeton de l\'utilisateur (en jours)",
|
||||
|
@ -508,6 +512,12 @@
|
|||
"save_apply": "<b>Enregistrer</b> - signifie enregistrer les paramètres du cluster HA pour Roxy-WI, sans modifier les paramètres des composants sur les membres du cluster. <br /> <b>Appliquer </b>: recréez la configuration du cluster HA sur les serveurs membres du cluster et installez des services supplémentaires.",
|
||||
}
|
||||
%}
|
||||
{% set udp_page = {
|
||||
"save_apply": "<b>Enregistrer</b> - signifie enregistrer les paramètres du Écouteur UDP pour Roxy-WI, sans modifier les paramètres des composants sur les membres du cluster ou serveur autonome. <br /> <b>Appliquer </b>: recréez la configuration du Écouteur UDP sur les serveurs membres du cluster et installez des services supplémentaires ou serveur autonome.",
|
||||
"listener_ip": "IP pour lier l’écouteur UDP. Commencer à écrire",
|
||||
"listener_port": "Port pour lier l'écouteur UDP",
|
||||
}
|
||||
%}
|
||||
{% set nettools_page = {
|
||||
"ip_or_name": "Entrez l'adresse IP ou le nom",
|
||||
"dns_name": "Entrez un nom DNS",
|
||||
|
@ -928,5 +938,9 @@
|
|||
"agent": "agent",
|
||||
"agent2": "agent",
|
||||
"reconfigure": "reconfigurer",
|
||||
"listener": "auditeur",
|
||||
"listeners": "les auditeurs",
|
||||
"weight": "poids",
|
||||
"where": "où",
|
||||
}
|
||||
%}
|
||||
|
|
|
@ -115,6 +115,9 @@
|
|||
},
|
||||
"history": {
|
||||
"title": "Histórico de"
|
||||
},
|
||||
"udp": {
|
||||
"title": "Balanceadores UDP"
|
||||
}
|
||||
}
|
||||
%}
|
||||
|
@ -170,6 +173,7 @@
|
|||
},
|
||||
"main": {
|
||||
"time_zone": "Fuso horário.",
|
||||
"license": "Chave de licença",
|
||||
"proxy": "Endereço e porta de prowy. Utiliza proto://ip:port",
|
||||
"session_ttl": "TTL de sessão de usuario (em dias)",
|
||||
"token_ttl": "TTL de token de usuario (em dias)",
|
||||
|
@ -508,6 +512,12 @@
|
|||
"save_apply": "<b>Salvar</b> - significa salvar as configurações do cluster HA para Roxy-WI, sem alterar as configurações do componente nos membros do cluster. <br /> <b>Aplicar</b> – recrie a configuração do cluster HA nos servidores membros do cluster e instale serviços adicionais.",
|
||||
}
|
||||
%}
|
||||
{% set udp_page = {
|
||||
"save_apply": "<b>Salvar</b> - significa salvar as configurações do Ouvinte UDP para Roxy-WI, sem alterar as configurações do componente nos membros do cluster ou servidor independente. <br /> <b>Aplicar</b> – recrie a configuração do Ouvinte UDP nos servidores membros do cluster e instale serviços adicionais ou servidor independente.",
|
||||
"listener_ip": "IP para vincular o ouvinte UDP. Começe a digitar",
|
||||
"listener_port": "Porta para ligação do ouvinte UDP",
|
||||
}
|
||||
%}
|
||||
{% set nettools_page = {
|
||||
"ip_or_name": "Digite IP ou nome",
|
||||
"dns_name": "Insira um nome DNS",
|
||||
|
@ -928,5 +938,9 @@
|
|||
"agent": "agente",
|
||||
"agent2": "agente",
|
||||
"reconfigure": "reconfigurar",
|
||||
"listener": "ouvinte",
|
||||
"listeners": "ouvintes",
|
||||
"weight": "peso",
|
||||
"where": "onde",
|
||||
}
|
||||
%}
|
||||
|
|
|
@ -115,6 +115,9 @@
|
|||
},
|
||||
"history": {
|
||||
"title": "История"
|
||||
},
|
||||
"udp": {
|
||||
"title": "UDP балансировщики"
|
||||
}
|
||||
}
|
||||
%}
|
||||
|
@ -170,6 +173,7 @@
|
|||
},
|
||||
"main": {
|
||||
"time_zone": "Временная зона",
|
||||
"license": "Лицензионный ключ",
|
||||
"proxy": "IP-адрес и порт прокси сервера. Формат: proto://ip:port",
|
||||
"session_ttl": "Время жизни пользовательских сессий (в днях)",
|
||||
"token_ttl": "Время жизни пользовательских токенов (в днях)",
|
||||
|
@ -508,6 +512,12 @@
|
|||
"save_apply": "<b>Сохранить</b> - подразумевает сохранение настроек HА кластера для Roxy-WI, без изменения настроек компонентов на участниках кластера. <br /> <b>Применить</b> - пересоздать конфигурацию HА кластера на серверах участниках кластера и установит дополнительные сервисы."
|
||||
}
|
||||
%}
|
||||
{% set udp_page = {
|
||||
"save_apply": "<b>Сохранить</b> - подразумевает сохранение настроек UDP слушателя для Roxy-WI, без изменения настроек компонентов на участниках кластера или standalone сервера. <br /> <b>Применить</b> - пересоздать конфигурацию HА кластера на серверах участниках кластера и установит дополнительные сервисы или standalone сервера.",
|
||||
"listener_ip": "IP для привязки UDP Listener. Начните печатать",
|
||||
"listener_port": "Порт для привязки UDP Listener",
|
||||
}
|
||||
%}
|
||||
{% set nettools_page = {
|
||||
"ip_or_name": "Введите IP или доменное имя",
|
||||
"dns_name": "Введите доменное имя",
|
||||
|
@ -928,5 +938,9 @@
|
|||
"agent": "агент",
|
||||
"agent2": "агента",
|
||||
"reconfigure": "переконфигурировать",
|
||||
"listener": "слушатель",
|
||||
"listeners": "слушатели",
|
||||
"weight": "вес",
|
||||
"where": "где",
|
||||
}
|
||||
%}
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
{% import 'languages/'+lang|default('en')+'.html' as lang %}
|
||||
{% from 'include/input_macros.html' import input, checkbox, copy_to_clipboard %}
|
||||
<div id="listener-{{listener.id}}" class="div-server-hapwi">
|
||||
<div class="server-name">
|
||||
<span id="listener-name-{{listener.id}}">{{listener.name|replace("'", "")}}</span>
|
||||
<span id="listener-desc-{{listener.id}}">{% if listener.desc != '' %} ({{listener.desc|replace("'", "")}}) {% endif %}</span>
|
||||
<span class="server-action">
|
||||
{% if g.user_params['role'] <= 3 %}
|
||||
<span class="service-start" onclick="confirmUdpBalancerAction('start', '{{listener.id}}')"></span>
|
||||
<span class="service-reload" onclick="confirmUdpBalancerAction('restart', '{{listener.id}}')"></span>
|
||||
<span class="service-stop" onclick="confirmUdpBalancerAction('stop', '{{listener.id}}')"></span>
|
||||
<a class="edit" onclick="createUDPListener(true, '{{listener.id}}')"></a>
|
||||
<a class="delete" onclick="confirmDeleteListener('{{listener.id}}')"></a>
|
||||
{% endif %}
|
||||
{# <a href="{{ url_for('main.service_history', service='cluster', server_ip=listener.id) }}" title="{{lang.words.view|title()}} {{lang.words.history3}} {{listener.name}}" class="history" style="margin: 0 5px 0 10px;"></a>#}
|
||||
</span>
|
||||
</div>
|
||||
<div class="server-desc">
|
||||
{% if listener.cluster_id %}
|
||||
{% for cluster in clusters %}
|
||||
{% if listener.cluster_id == cluster.id %}
|
||||
{{ input('listener-type-'+listener.id|string(), value='cluster', type='hidden') }}
|
||||
<b>{{lang.words.cluster|title}} {{ lang.words.name }}</b>:
|
||||
<a href="/app/ha/cluster/{{ cluster.id }}" title="{{lang.words.open|title()}} {{lang.words.cluster|replace("'", "")}}"> {{ cluster.name }}</a>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<b>VIP</b>:
|
||||
{% else %}
|
||||
{{ input('listener-type-'+listener.id|string(), value='server', type='hidden') }}
|
||||
<b>{{ lang.words.server|title() }}</b>: {{ server.hostname }}
|
||||
<b>IP</b>:
|
||||
{% endif %}
|
||||
{{ copy_to_clipboard(value=listener.vip) }}<br />
|
||||
<b>{{lang.words.port|title()}}</b>: {{ listener.port }} <br />
|
||||
<b>{{ lang.words.backend|title() }} {{ lang.words.servers }}</b>: <br />
|
||||
{% set config = listener.config|string_to_dict %}
|
||||
{% for c, v in config.items() %}
|
||||
{{ lang.words.server|title() }}: {{ copy_to_clipboard(value=c) }}, {{ lang.words.port }}: {{ v.port }}, {{ lang.words.weight }}: {{ v.weight }} <br />
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,141 @@
|
|||
{% extends "base.html" %}
|
||||
{% block title %}{{ lang.menu_links.udp.title }} {% endblock %}
|
||||
{% block h2 %}{{ lang.menu_links.udp.title }} {% endblock %}
|
||||
{% block content %}
|
||||
{% from 'include/input_macros.html' import input, checkbox, copy_to_clipboard, select %}
|
||||
<script src="/app/static/js/install.js"></script>
|
||||
<script src="/app/static/js/udp.js"></script>
|
||||
<link href="{{ url_for('static', filename='css/servers.css') }}" rel="stylesheet"/>
|
||||
<link href="{{ url_for('static', filename='css/smon.css') }}" rel="stylesheet">
|
||||
<link href="{{ url_for('static', filename='css/ha.css') }}" rel="stylesheet">
|
||||
{% if user_subscription.user_status == 0 or user_subscription.user_plan == 'user' %}
|
||||
{% include 'include/no_sub.html' %}
|
||||
{% elif not is_needed_tool %}
|
||||
<div style="text-align: center;">
|
||||
<h3>{{lang.admin_page.desc.no_ansible}} Ansible</h3>.
|
||||
<img src="{{ url_for('static', filename='images/no_servers.png')}}" alt="There is no server">
|
||||
<h4>
|
||||
{{lang.words.read|title()}} <a href="https://roxy-wi.org/installation#ansible" title="{{lang.words.install|title()}} Ansible" target="_blank">here</a> {{lang.phrases.how_to_install}} Ansible.
|
||||
</h4>
|
||||
</div>
|
||||
{% else %}
|
||||
{% if g.user_params['role'] <= 3 %}
|
||||
<div class="add-button add-button-big" title="{{lang.words.create|title()}} UDP {{ lang.words.listener }}" onclick="createUDPListener();">+ {{lang.words.create|title()}} UDP {{ lang.words.listener }}</div>
|
||||
{% endif %}
|
||||
<div class="up-pannel" class="sortable">
|
||||
{% for listener in listeners %}
|
||||
<div id="listener-{{listener.id}}" class="div-server-hapwi animated-background"></div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div id="create-udp-step-1" style="display: none;">
|
||||
<table class="overview" id="create-udp-step-1-overview"
|
||||
title="{{lang.words.create|title()}} UDP {{ lang.words.listener }}"
|
||||
data-edit="{{lang.words.edit|title()}} UDP {{ lang.words.listener }}">
|
||||
<tr>
|
||||
<td class="padding20" style="width: 37%">
|
||||
{{lang.words.select|title()}} {{ lang.words.where }} {{ lang.words.create }} {{ lang.words.an }} UDP {{ lang.words.listener }}
|
||||
</td>
|
||||
<td>
|
||||
{% set values = {'cluster': 'HA Cluster', 'server': 'Standalone' } %}
|
||||
{{ select('new-udp-type', values=values) }}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div id="create-udp-step-2" style="display: none;">
|
||||
<form action="" id="create_udp_listener">
|
||||
<table class="overview" id="create-udp-step-2-overview"
|
||||
title="{{lang.words.create|title()}} UDP {{ lang.words.listener }}"
|
||||
data-edit="{{lang.words.edit|title()}} UDP {{ lang.words.listener }}">
|
||||
{% include 'include/tr_validate_tips.html' %}
|
||||
<tr>
|
||||
<td class="padding20" style="width: 37%">
|
||||
{{lang.words.name|title()}}
|
||||
<span class="need-field">*</span>
|
||||
</td>
|
||||
<td>
|
||||
{{ input('new-listener-name', autofocus='autofocus') }}
|
||||
{{ input('new-listener-type', type='hidden', value='server') }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="new-udp-ha-cluster-tr">
|
||||
<td class="padding20">
|
||||
{{lang.ha_page.ha}} {{lang.words.cluster}}
|
||||
<span class="need-field">*</span>
|
||||
</td>
|
||||
<td>
|
||||
<select id="ha-cluster">
|
||||
<option value="------" selected>------</option>
|
||||
{% for cluster in clusters %}
|
||||
<option value="{{ cluster.id }}">{{ cluster.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="new-udp-ha-cluster-tr">
|
||||
<td class="padding20">
|
||||
VIP
|
||||
<span class="need-field">*</span>
|
||||
</td>
|
||||
<td>
|
||||
<select id="new-udp-vip"></select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="new-udp-servers-tr">
|
||||
<td class="padding20">
|
||||
{{lang.words.server|title()}}
|
||||
<span class="need-field">*</span>
|
||||
</td>
|
||||
<td>
|
||||
{{ select('serv', values=g.user_params['servers'], is_servers='true', by_id='true') }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="new-udp-servers-tr">
|
||||
<td class="padding20">
|
||||
IP
|
||||
<span class="need-field">*</span>
|
||||
</td>
|
||||
<td>{{ input('new-udp-ip', title=lang.udp_page.listener_ip) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="padding20">
|
||||
{{lang.words.port|title()}}
|
||||
<span class="need-field">*</span>
|
||||
</td>
|
||||
<td>
|
||||
{{ input('new-listener-port', type='number', title=lang.udp_page.listener_port) }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="padding20">
|
||||
{{lang.words.backend|title()}} {{lang.words.servers|title()}}
|
||||
<span class="need-field">*</span>
|
||||
</td>
|
||||
<td id="new-udp-servers-td">
|
||||
<a class="link add-server" id="frontend_add_acl" title="{{lang.words.add|title()}} ACL" style="cursor: pointer; display: none;"></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="padding20">
|
||||
{{lang.words.desc|title()}}
|
||||
</td>
|
||||
<td>
|
||||
{{ input('new-listener-desc', autofocus='autofocus') }}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="alert alert-warning">
|
||||
{{lang.udp_page.save_apply|safe}}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div id="dialog-confirm" style="display: none;">
|
||||
<p><span class="ui-icon ui-icon-alert" style="float:left; margin:3px 12px 20px 0;"></span>{{lang.phrases.are_you_sure}}</p>
|
||||
</div>
|
||||
<script>
|
||||
{% for listener in listeners %}
|
||||
getUDPListener('{{listener.id}}');
|
||||
{% endfor %}
|
||||
</script>
|
||||
{% endif %}
|
||||
{% endblock %}
|
Loading…
Reference in New Issue