mirror of https://github.com/Aidaho12/haproxy-wi
v8.0: Remove redundant requirement files and update VIP handling
Removed outdated Debian, EL7, EL8, and EL9 requirement files. Improved various VIP handling and validation functionalities, including changes to VIP endpoints and associated JavaScript functions. Minor enhancements and bug fixes across multiple modules and views.pull/399/head
parent
9148a31143
commit
0391dff9eb
|
@ -1,5 +1,6 @@
|
||||||
from app.modules.db.db_model import connect, HaCluster, HaClusterVirt, HaClusterVip, HaClusterService, HaClusterSlave, Server, HaClusterRouter
|
from app.modules.db.db_model import connect, HaCluster, HaClusterVirt, HaClusterVip, HaClusterService, HaClusterSlave, Server, HaClusterRouter
|
||||||
from app.modules.db.common import out_error
|
from app.modules.db.common import out_error
|
||||||
|
from app.modules.roxywi.exception import RoxywiResourceNotFound
|
||||||
|
|
||||||
|
|
||||||
def select_clusters(group_id: int):
|
def select_clusters(group_id: int):
|
||||||
|
@ -26,6 +27,13 @@ def select_cluster(cluster_id: int):
|
||||||
out_error(e)
|
out_error(e)
|
||||||
|
|
||||||
|
|
||||||
|
def get_cluster(cluster_id: int):
|
||||||
|
try:
|
||||||
|
return HaCluster.get(HaCluster.id == cluster_id)
|
||||||
|
except Exception as e:
|
||||||
|
out_error(e)
|
||||||
|
|
||||||
|
|
||||||
def select_cluster_name(cluster_id: int) -> str:
|
def select_cluster_name(cluster_id: int) -> str:
|
||||||
try:
|
try:
|
||||||
return HaCluster.get(HaCluster.id == cluster_id).name
|
return HaCluster.get(HaCluster.id == cluster_id).name
|
||||||
|
@ -54,6 +62,13 @@ def select_cluster_vip(cluster_id: int, router_id: int) -> HaClusterVip:
|
||||||
out_error(e)
|
out_error(e)
|
||||||
|
|
||||||
|
|
||||||
|
def select_cluster_vip_by_vip_id(cluster_id: int, vip_id: int) -> HaClusterVip:
|
||||||
|
try:
|
||||||
|
return HaClusterVip.get((HaClusterVip.cluster_id == cluster_id) & (HaClusterVip.id == vip_id))
|
||||||
|
except Exception as e:
|
||||||
|
out_error(e)
|
||||||
|
|
||||||
|
|
||||||
def select_clusters_vip_id(cluster_id: int, router_id):
|
def select_clusters_vip_id(cluster_id: int, router_id):
|
||||||
try:
|
try:
|
||||||
return HaClusterVip.get((HaClusterVip.cluster_id == cluster_id) & (HaClusterVip.router_id == router_id)).id
|
return HaClusterVip.get((HaClusterVip.cluster_id == cluster_id) & (HaClusterVip.router_id == router_id)).id
|
||||||
|
@ -75,6 +90,15 @@ def insert_cluster_services(cluster_id: int, service_id: int):
|
||||||
out_error(e)
|
out_error(e)
|
||||||
|
|
||||||
|
|
||||||
|
def select_count_cluster_slaves(cluster_id: int) -> int:
|
||||||
|
try:
|
||||||
|
return HaClusterSlave.select().where(HaClusterSlave.cluster_id == cluster_id).count()
|
||||||
|
except HaClusterSlave.DoesNotExist:
|
||||||
|
raise RoxywiResourceNotFound
|
||||||
|
except Exception as e:
|
||||||
|
out_error(e)
|
||||||
|
|
||||||
|
|
||||||
def select_cluster_master_slaves(cluster_id: int, group_id: int, router_id: int):
|
def select_cluster_master_slaves(cluster_id: int, group_id: int, router_id: int):
|
||||||
conn = connect()
|
conn = connect()
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
|
@ -149,6 +173,8 @@ def get_router_id(cluster_id: int, default_router=0) -> int:
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
return HaClusterRouter.get((HaClusterRouter.cluster_id == cluster_id) & (HaClusterRouter.default == default_router)).id
|
return HaClusterRouter.get((HaClusterRouter.cluster_id == cluster_id) & (HaClusterRouter.default == default_router)).id
|
||||||
|
except HaClusterRouter.DoesNotExist:
|
||||||
|
raise RoxywiResourceNotFound
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
out_error(e)
|
out_error(e)
|
||||||
|
|
||||||
|
@ -160,21 +186,22 @@ def get_router(router_id: int) -> HaClusterRouter:
|
||||||
out_error(e)
|
out_error(e)
|
||||||
|
|
||||||
|
|
||||||
def create_ha_router(cluster_id: int) -> int:
|
def create_ha_router(cluster_id: int, default: int = 0) -> int:
|
||||||
"""
|
"""
|
||||||
Create HA Router
|
Create HA Router
|
||||||
|
|
||||||
This method is used to create a HA (High Availability) router for a given cluster.
|
This method is used to create a HA (High Availability) router for a given cluster.
|
||||||
|
|
||||||
:param cluster_id: The ID of the cluster for which the HA router needs to be created.
|
:param default:
|
||||||
:return: The ID of the created HA router.
|
:param cluster_id: The ID of the cluster for which the HA router needs to be created.
|
||||||
:rtype: int
|
:return: The ID of the created HA router.
|
||||||
|
:rtype: int
|
||||||
|
|
||||||
:raises Exception: If an error occurs while creating the HA router.
|
:raises Exception: If an error occurs while creating the HA router.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
last_id = HaClusterRouter.insert(cluster_id=cluster_id).execute()
|
last_id = HaClusterRouter.insert(cluster_id=cluster_id, default=default).on_conflict_ignore().execute()
|
||||||
return last_id
|
return last_id
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
out_error(e)
|
out_error(e)
|
||||||
|
@ -256,15 +283,6 @@ def select_cluster_services(cluster_id: int):
|
||||||
out_error(e)
|
out_error(e)
|
||||||
|
|
||||||
|
|
||||||
def update_server_master(master, slave):
|
|
||||||
try:
|
|
||||||
master_id = Server.get(Server.ip == master).server_id
|
|
||||||
except Exception as e:
|
|
||||||
out_error(e)
|
|
||||||
|
|
||||||
update_master_server_by_slave_ip(master_id, slave)
|
|
||||||
|
|
||||||
|
|
||||||
def update_master_server_by_slave_ip(master_id: int, slave_ip: str) -> None:
|
def update_master_server_by_slave_ip(master_id: int, slave_ip: str) -> None:
|
||||||
try:
|
try:
|
||||||
Server.update(master=master_id).where(Server.ip == slave_ip).execute()
|
Server.update(master=master_id).where(Server.ip == slave_ip).execute()
|
||||||
|
|
|
@ -150,24 +150,17 @@ def select_service_id_by_slug(service_slug: str) -> int:
|
||||||
|
|
||||||
|
|
||||||
def select_services():
|
def select_services():
|
||||||
query = Services.select()
|
|
||||||
try:
|
try:
|
||||||
query_res = query.execute()
|
return Services.select().execute()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
out_error(e)
|
out_error(e)
|
||||||
return
|
|
||||||
else:
|
|
||||||
return query_res
|
|
||||||
|
|
||||||
|
|
||||||
def select_service(slug: str) -> object:
|
def select_service(slug: str) -> Services:
|
||||||
try:
|
try:
|
||||||
query_res = Services.get(Services.slug == slug)
|
return Services.get(Services.slug == slug)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
out_error(e)
|
out_error(e)
|
||||||
return 'there is no service'
|
|
||||||
else:
|
|
||||||
return query_res
|
|
||||||
|
|
||||||
|
|
||||||
def update_keepalived(serv):
|
def update_keepalived(serv):
|
||||||
|
@ -179,11 +172,9 @@ def update_keepalived(serv):
|
||||||
|
|
||||||
def select_apache(serv):
|
def select_apache(serv):
|
||||||
try:
|
try:
|
||||||
apache = Server.get(Server.ip == serv).apache
|
return Server.get(Server.ip == serv).apache
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
out_error(e)
|
out_error(e)
|
||||||
else:
|
|
||||||
return apache
|
|
||||||
|
|
||||||
|
|
||||||
def update_apache(serv: str) -> None:
|
def update_apache(serv: str) -> None:
|
||||||
|
@ -195,11 +186,9 @@ def update_apache(serv: str) -> None:
|
||||||
|
|
||||||
def select_nginx(serv):
|
def select_nginx(serv):
|
||||||
try:
|
try:
|
||||||
query_res = Server.get(Server.ip == serv).nginx
|
return Server.get(Server.ip == serv).nginx
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
out_error(e)
|
out_error(e)
|
||||||
else:
|
|
||||||
return query_res
|
|
||||||
|
|
||||||
|
|
||||||
def update_nginx(serv: str) -> None:
|
def update_nginx(serv: str) -> None:
|
||||||
|
|
|
@ -79,6 +79,9 @@ class UdpListenerRequest(BaseModel):
|
||||||
lb_algo: Literal['rr', 'wrr', 'lc', 'wlc', 'sh', 'dh', 'wlc', 'lblc']
|
lb_algo: Literal['rr', 'wrr', 'lc', 'wlc', 'sh', 'dh', 'wlc', 'lblc']
|
||||||
check_enabled: Optional[bool] = 1
|
check_enabled: Optional[bool] = 1
|
||||||
reconfigure: Optional[bool] = 0
|
reconfigure: Optional[bool] = 0
|
||||||
|
delay_loop: Optional[int] = 10
|
||||||
|
delay_before_retry: Optional[int] = 10
|
||||||
|
retry: Optional[int] = 3
|
||||||
|
|
||||||
|
|
||||||
class UserPost(BaseModel):
|
class UserPost(BaseModel):
|
||||||
|
@ -144,23 +147,23 @@ class CredUploadRequest(BaseModel):
|
||||||
class HAClusterServer(BaseModel):
|
class HAClusterServer(BaseModel):
|
||||||
eth: EscapedString
|
eth: EscapedString
|
||||||
id: int
|
id: int
|
||||||
ip: Union[IPvAnyAddress, DomainName]
|
|
||||||
name: EscapedString
|
|
||||||
master: Optional[bool] = 1
|
master: Optional[bool] = 1
|
||||||
|
|
||||||
|
|
||||||
|
class HAClusterServersRequest(BaseModel):
|
||||||
|
servers: List[HAClusterServer]
|
||||||
|
|
||||||
|
|
||||||
class HAClusterService(BaseModel):
|
class HAClusterService(BaseModel):
|
||||||
enabled: Optional[bool] = 0
|
enabled: Optional[bool] = 0
|
||||||
docker: Optional[bool] = 0
|
docker: Optional[bool] = 0
|
||||||
|
|
||||||
|
|
||||||
class HAClusterVIP(BaseModel):
|
class HAClusterVIP(BaseModel):
|
||||||
name: EscapedString
|
|
||||||
use_src: Optional[bool] = 1
|
use_src: Optional[bool] = 1
|
||||||
vip: IPvAnyAddress
|
vip: IPvAnyAddress
|
||||||
return_master: Optional[bool] = 1
|
return_master: Optional[bool] = 1
|
||||||
virt_server: Optional[bool] = 1
|
virt_server: Optional[bool] = 1
|
||||||
router_id: Optional[int] = None
|
|
||||||
servers: List[HAClusterServer]
|
servers: List[HAClusterServer]
|
||||||
|
|
||||||
|
|
||||||
|
@ -168,16 +171,16 @@ class HAClusterRequest(BaseModel):
|
||||||
name: EscapedString
|
name: EscapedString
|
||||||
description: Optional[EscapedString] = None
|
description: Optional[EscapedString] = None
|
||||||
return_master: Optional[bool] = 1
|
return_master: Optional[bool] = 1
|
||||||
servers: List[HAClusterServer]
|
servers: Optional[List[HAClusterServer]] = None
|
||||||
services: Dict[str, HAClusterService]
|
services: Dict[str, HAClusterService]
|
||||||
syn_flood: Optional[bool] = 1
|
syn_flood: Optional[bool] = 1
|
||||||
use_src: Optional[bool] = 1
|
use_src: Optional[bool] = 1
|
||||||
vip: IPvAnyAddress
|
vip: Optional[IPvAnyAddress] = None
|
||||||
virt_server: Optional[bool] = 1
|
virt_server: Optional[bool] = 1
|
||||||
|
|
||||||
|
|
||||||
class ConfigFileNameQuery(BaseModel):
|
class ConfigFileNameQuery(BaseModel):
|
||||||
file_name: Optional[str] = None
|
file_path: Optional[str] = None
|
||||||
version: Optional[str] = None
|
version: Optional[str] = None
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,15 +4,16 @@ import app.modules.db.server as server_sql
|
||||||
import app.modules.db.ha_cluster as ha_sql
|
import app.modules.db.ha_cluster as ha_sql
|
||||||
import app.modules.db.service as service_sql
|
import app.modules.db.service as service_sql
|
||||||
from app.modules.db.db_model import HaCluster, HaClusterRouter, HaClusterVip, HaClusterVirt
|
from app.modules.db.db_model import HaCluster, HaClusterRouter, HaClusterVip, HaClusterVirt
|
||||||
import app.modules.server.server as server_mod
|
|
||||||
import app.modules.roxywi.common as roxywi_common
|
import app.modules.roxywi.common as roxywi_common
|
||||||
from app.modules.server.ssh import return_ssh_keys_path
|
from app.modules.roxywi.class_models import HAClusterRequest, HAClusterVIP, HAClusterServersRequest
|
||||||
from app.modules.roxywi.class_models import HAClusterRequest, HAClusterVIP
|
from app.modules.roxywi.exception import RoxywiResourceNotFound
|
||||||
|
|
||||||
|
|
||||||
def _get_servers_dict(cluster: Union[HAClusterRequest, HAClusterVIP]) -> dict:
|
def _get_servers_dict(cluster: Union[HAClusterRequest, HAClusterVIP, HAClusterServersRequest]) -> Union[dict, None]:
|
||||||
for i, k in cluster.model_dump(mode='json').items():
|
for i, k in cluster.model_dump(mode='json').items():
|
||||||
if i == 'servers':
|
if i == 'servers':
|
||||||
|
if k is None:
|
||||||
|
return None
|
||||||
servers = k
|
servers = k
|
||||||
return servers
|
return servers
|
||||||
|
|
||||||
|
@ -25,7 +26,6 @@ def _get_services_dict(cluster: HAClusterRequest) -> dict:
|
||||||
|
|
||||||
|
|
||||||
def create_cluster(cluster: HAClusterRequest, group_id: int) -> int:
|
def create_cluster(cluster: HAClusterRequest, group_id: int) -> int:
|
||||||
master_ip = None
|
|
||||||
servers = _get_servers_dict(cluster)
|
servers = _get_servers_dict(cluster)
|
||||||
services = _get_services_dict(cluster)
|
services = _get_services_dict(cluster)
|
||||||
|
|
||||||
|
@ -35,39 +35,25 @@ def create_cluster(cluster: HAClusterRequest, group_id: int) -> int:
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise Exception(f'error: Cannot create new HA cluster: {e}')
|
raise Exception(f'error: Cannot create new HA cluster: {e}')
|
||||||
|
|
||||||
try:
|
if not servers is None:
|
||||||
router_id = HaClusterRouter.insert(cluster_id=cluster_id, default=1).on_conflict_ignore().execute()
|
|
||||||
except Exception as e:
|
|
||||||
raise Exception(f'error: Cannon create router: {e}')
|
|
||||||
|
|
||||||
try:
|
|
||||||
vip_id = HaClusterVip.insert(cluster_id=cluster_id, router_id=router_id, vip=cluster.vip, return_master=cluster.return_master).execute()
|
|
||||||
roxywi_common.logging(cluster_id, f'New vip {cluster.vip} has been created and added to the cluster', keep_history=1, roxywi=1, service='HA cluster')
|
|
||||||
except Exception as e:
|
|
||||||
raise Exception(f'error: Cannon add VIP: {e}')
|
|
||||||
|
|
||||||
|
|
||||||
for value in servers:
|
|
||||||
if value['master']:
|
|
||||||
master_ip = value['ip']
|
|
||||||
|
|
||||||
for value in servers:
|
|
||||||
if value['master']:
|
|
||||||
continue
|
|
||||||
try:
|
try:
|
||||||
ha_sql.update_server_master(master_ip, value['ip'])
|
router_id = ha_sql.create_ha_router(cluster_id, default=1)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise Exception(f'error: Cannot update master on slave {value["ip"]: {e}}')
|
raise Exception(f'error: Cannon create router: {e}')
|
||||||
|
|
||||||
for value in servers:
|
_create_or_update_master_slaves_servers(cluster_id, servers, router_id, True)
|
||||||
slave_id = value['id']
|
|
||||||
if value['master']:
|
if cluster.vip:
|
||||||
slave_id = server_sql.select_server_id_by_ip(master_ip)
|
try:
|
||||||
try:
|
vip_id = HaClusterVip.insert(cluster_id=cluster_id, router_id=router_id, vip=cluster.vip,
|
||||||
ha_sql.insert_or_update_slave(cluster_id, slave_id, value['eth'], value['master'], router_id)
|
return_master=cluster.return_master).execute()
|
||||||
roxywi_common.logging(cluster_id, f'New server {value["ip"]} has been added to the cluster', keep_history=1, roxywi=1, service='HA cluster')
|
roxywi_common.logging(cluster_id, f'New vip {cluster.vip} has been created and added to the cluster',
|
||||||
except Exception as e:
|
keep_history=1, roxywi=1, service='HA cluster')
|
||||||
raise Exception(f'error: Cannot update slave server {value["ip"]}: {e}')
|
except Exception as e:
|
||||||
|
raise Exception(f'error: Cannon add VIP: {e}')
|
||||||
|
|
||||||
|
if cluster.virt_server and not servers is None:
|
||||||
|
add_or_update_virt(cluster, servers, cluster_id, vip_id, group_id)
|
||||||
|
|
||||||
for service, value in services.items():
|
for service, value in services.items():
|
||||||
if not value['enabled']:
|
if not value['enabled']:
|
||||||
|
@ -79,9 +65,6 @@ def create_cluster(cluster: HAClusterRequest, group_id: int) -> int:
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise Exception(f'error: Cannot add service {service}: {e}')
|
raise Exception(f'error: Cannot add service {service}: {e}')
|
||||||
|
|
||||||
if cluster.virt_server:
|
|
||||||
add_or_update_virt(cluster, servers, cluster_id, vip_id, group_id)
|
|
||||||
|
|
||||||
return int(cluster_id)
|
return int(cluster_id)
|
||||||
|
|
||||||
|
|
||||||
|
@ -89,25 +72,26 @@ def update_cluster(cluster: HAClusterRequest, cluster_id: int, group_id: int) ->
|
||||||
servers = _get_servers_dict(cluster)
|
servers = _get_servers_dict(cluster)
|
||||||
services = _get_services_dict(cluster)
|
services = _get_services_dict(cluster)
|
||||||
|
|
||||||
try:
|
|
||||||
router_id = ha_sql.get_router_id(cluster_id, default_router=1)
|
|
||||||
except Exception as e:
|
|
||||||
raise Exception(f'error: Cannot get router: {e}')
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
ha_sql.update_cluster(cluster_id, cluster.name, cluster.description, cluster.syn_flood)
|
ha_sql.update_cluster(cluster_id, cluster.name, cluster.description, cluster.syn_flood)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise Exception(f'error: Cannot update HA cluster: {e}')
|
raise Exception(f'error: Cannot update HA cluster: {e}')
|
||||||
|
|
||||||
try:
|
if servers:
|
||||||
update_slaves(servers, cluster_id, router_id)
|
try:
|
||||||
except Exception as e:
|
router_id = ha_sql.get_router_id(cluster_id, default_router=1)
|
||||||
raise Exception(e)
|
except Exception as e:
|
||||||
|
raise Exception(f'error: Cannot get router: {e}')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
update_vip(cluster_id, router_id, cluster, group_id)
|
update_slaves(servers, cluster_id, router_id)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise Exception(e)
|
raise Exception(e)
|
||||||
|
|
||||||
|
try:
|
||||||
|
update_vip(cluster_id, router_id, cluster, group_id)
|
||||||
|
except Exception as e:
|
||||||
|
raise Exception(e)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
ha_sql.delete_cluster_services(cluster_id)
|
ha_sql.delete_cluster_services(cluster_id)
|
||||||
|
@ -126,7 +110,7 @@ def update_cluster(cluster: HAClusterRequest, cluster_id: int, group_id: int) ->
|
||||||
roxywi_common.logging(cluster_id, f'Cluster {cluster.name} has been updated', keep_history=1, roxywi=1, service='HA cluster')
|
roxywi_common.logging(cluster_id, f'Cluster {cluster.name} has been updated', keep_history=1, roxywi=1, service='HA cluster')
|
||||||
|
|
||||||
|
|
||||||
def delete_cluster(cluster_id: int) -> str:
|
def delete_cluster(cluster_id: int) -> None:
|
||||||
router_id = ha_sql.get_router_id(cluster_id, default_router=1)
|
router_id = ha_sql.get_router_id(cluster_id, default_router=1)
|
||||||
slaves = ha_sql.select_cluster_slaves(cluster_id, router_id)
|
slaves = ha_sql.select_cluster_slaves(cluster_id, router_id)
|
||||||
|
|
||||||
|
@ -137,11 +121,12 @@ def delete_cluster(cluster_id: int) -> str:
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise Exception(f'error: Cannot update master on slave {slave_ip}: {e}')
|
raise Exception(f'error: Cannot update master on slave {slave_ip}: {e}')
|
||||||
|
|
||||||
HaCluster.delete().where(HaCluster.id == cluster_id).execute()
|
try:
|
||||||
|
HaCluster.delete().where(HaCluster.id == cluster_id).execute()
|
||||||
|
except HaCluster.DoesNotExist:
|
||||||
|
raise RoxywiResourceNotFound
|
||||||
roxywi_common.logging(cluster_id, 'Cluster has been deleted', roxywi=1, service='HA cluster')
|
roxywi_common.logging(cluster_id, 'Cluster has been deleted', roxywi=1, service='HA cluster')
|
||||||
|
|
||||||
return 'ok'
|
|
||||||
|
|
||||||
|
|
||||||
def update_vip(cluster_id: int, router_id: int, cluster: Union[HAClusterRequest, HAClusterVIP], group_id: int) -> None:
|
def update_vip(cluster_id: int, router_id: int, cluster: Union[HAClusterRequest, HAClusterVIP], group_id: int) -> None:
|
||||||
vip_id = ha_sql.select_clusters_vip_id(cluster_id, router_id)
|
vip_id = ha_sql.select_clusters_vip_id(cluster_id, router_id)
|
||||||
|
@ -156,8 +141,10 @@ def update_vip(cluster_id: int, router_id: int, cluster: Union[HAClusterRequest,
|
||||||
try:
|
try:
|
||||||
ha_sql.update_slave(cluster_id, value['id'], value['eth'], value['master'], router_id)
|
ha_sql.update_slave(cluster_id, value['id'], value['eth'], value['master'], router_id)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise Exception(f'error: Cannot add server {value["ip"]}: {e}')
|
s = server_sql.get_server_by_id(value['id'])
|
||||||
|
raise Exception(f'error: Cannot add server {s.hostname}: {e}')
|
||||||
|
|
||||||
|
print('cluster.virt_server',cluster.virt_server)
|
||||||
if cluster.virt_server:
|
if cluster.virt_server:
|
||||||
add_or_update_virt(cluster, servers, cluster_id, vip_id, group_id)
|
add_or_update_virt(cluster, servers, cluster_id, vip_id, group_id)
|
||||||
else:
|
else:
|
||||||
|
@ -171,14 +158,30 @@ def update_vip(cluster_id: int, router_id: int, cluster: Union[HAClusterRequest,
|
||||||
roxywi_common.logging(cluster_id, f'Cluster VIP {cluster.vip} has been updated', keep_history=1, roxywi=1, service='HA cluster')
|
roxywi_common.logging(cluster_id, f'Cluster VIP {cluster.vip} has been updated', keep_history=1, roxywi=1, service='HA cluster')
|
||||||
|
|
||||||
|
|
||||||
def insert_vip(cluster_id: int, cluster: HAClusterVIP, group_id: int) -> None:
|
def insert_vip(cluster_id: int, cluster: HAClusterVIP, group_id: int) -> int:
|
||||||
vip = cluster.vip
|
try:
|
||||||
servers = _get_servers_dict(cluster)
|
slaves_count = ha_sql.select_count_cluster_slaves(cluster_id)
|
||||||
|
if slaves_count == 0:
|
||||||
|
try:
|
||||||
|
router_id = ha_sql.create_ha_router(cluster_id, default=1)
|
||||||
|
except Exception as e:
|
||||||
|
raise Exception(f'error: Cannon create a new default router: {e}')
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
router_id = ha_sql.create_ha_router(cluster_id)
|
||||||
|
except Exception as e:
|
||||||
|
raise Exception(f'error: Cannot create new router: {e}')
|
||||||
|
except Exception as e:
|
||||||
|
raise e
|
||||||
|
|
||||||
try:
|
try:
|
||||||
router_id = ha_sql.create_ha_router(cluster_id)
|
vip = cluster.vip
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise Exception(f'error: Cannot create new router: {e}')
|
raise Exception(f'Cannot get VIP: {e}')
|
||||||
|
try:
|
||||||
|
servers = _get_servers_dict(cluster)
|
||||||
|
except Exception as e:
|
||||||
|
raise Exception(f'Cannot get servers: {e}')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
vip_id = HaClusterVip.insert(cluster_id=cluster_id, router_id=router_id, vip=vip, return_master=cluster.return_master).execute()
|
vip_id = HaClusterVip.insert(cluster_id=cluster_id, router_id=router_id, vip=vip, return_master=cluster.return_master).execute()
|
||||||
|
@ -189,33 +192,27 @@ def insert_vip(cluster_id: int, cluster: HAClusterVIP, group_id: int) -> None:
|
||||||
try:
|
try:
|
||||||
ha_sql.insert_or_update_slave(cluster_id, value['id'], value['eth'], value['master'], router_id)
|
ha_sql.insert_or_update_slave(cluster_id, value['id'], value['eth'], value['master'], router_id)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise Exception(f'error: Cannot add server {value["ip"]}: {e}')
|
s = server_sql.get_server_by_id(value['id'])
|
||||||
|
raise Exception(f'error: Cannot add server {s.hostname}: {e}')
|
||||||
|
|
||||||
if cluster.virt_server:
|
if cluster.virt_server:
|
||||||
add_or_update_virt(cluster, servers, cluster_id, vip_id, group_id)
|
add_or_update_virt(cluster, servers, cluster_id, vip_id, group_id)
|
||||||
|
|
||||||
roxywi_common.logging(cluster_id, f'New cluster VIP: {vip} has been created', keep_history=1, roxywi=1, service='HA cluster')
|
roxywi_common.logging(cluster_id, f'New cluster VIP: {vip} has been created', keep_history=1, roxywi=1, service='HA cluster')
|
||||||
|
return vip_id
|
||||||
|
|
||||||
|
|
||||||
def update_slaves(servers: dict, cluster_id: int, router_id: int) -> None:
|
def update_slaves(servers: dict, cluster_id: int, router_id: int) -> None:
|
||||||
master_ip = None
|
|
||||||
all_routers_in_cluster = HaClusterRouter.select(HaClusterRouter.id).where(HaClusterRouter.cluster_id == cluster_id).execute()
|
all_routers_in_cluster = HaClusterRouter.select(HaClusterRouter.id).where(HaClusterRouter.cluster_id == cluster_id).execute()
|
||||||
server_ids_from_db = ha_sql.select_cluster_slaves(cluster_id, router_id)
|
server_ids_from_db = ha_sql.select_cluster_slaves(cluster_id, router_id)
|
||||||
server_ids = []
|
server_ids = []
|
||||||
server_ids_from_json = []
|
server_ids_from_json = []
|
||||||
|
|
||||||
for value in servers:
|
|
||||||
if value['master']:
|
|
||||||
master_ip = value['ip']
|
|
||||||
|
|
||||||
for server in server_ids_from_db:
|
for server in server_ids_from_db:
|
||||||
server_ids.append(server[0])
|
server_ids.append(server[0])
|
||||||
|
|
||||||
for value in servers:
|
for value in servers:
|
||||||
slave_id = value['id']
|
server_ids_from_json.append(int(value['id']))
|
||||||
if value['master']:
|
|
||||||
slave_id = server_sql.select_server_id_by_ip(master_ip)
|
|
||||||
server_ids_from_json.append(int(slave_id))
|
|
||||||
|
|
||||||
server_ids_for_deletion = set(server_ids) - set(server_ids_from_json)
|
server_ids_for_deletion = set(server_ids) - set(server_ids_from_json)
|
||||||
server_ids_for_adding = set(server_ids_from_json) - set(server_ids)
|
server_ids_for_adding = set(server_ids_from_json) - set(server_ids)
|
||||||
|
@ -228,7 +225,7 @@ def update_slaves(servers: dict, cluster_id: int, router_id: int) -> None:
|
||||||
try:
|
try:
|
||||||
ha_sql.insert_or_update_slave(cluster_id, slave_id, value['eth'], value['master'], router)
|
ha_sql.insert_or_update_slave(cluster_id, slave_id, value['eth'], value['master'], router)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise Exception(f'error: Cannot add new slave {value["name"]}: {e}')
|
raise Exception(f'error: Cannot add new slave {value["ip"]}: {e}')
|
||||||
|
|
||||||
for o_s in server_ids_for_deletion:
|
for o_s in server_ids_for_deletion:
|
||||||
ha_sql.delete_master_from_slave(o_s)
|
ha_sql.delete_master_from_slave(o_s)
|
||||||
|
@ -238,34 +235,19 @@ def update_slaves(servers: dict, cluster_id: int, router_id: int) -> None:
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise Exception(f'error: Cannot recreate slaves server: {e}')
|
raise Exception(f'error: Cannot recreate slaves server: {e}')
|
||||||
|
|
||||||
for value in servers:
|
_create_or_update_master_slaves_servers(cluster_id, servers, router_id)
|
||||||
if value['master']:
|
|
||||||
continue
|
|
||||||
try:
|
|
||||||
ha_sql.update_server_master(master_ip, value['ip'])
|
|
||||||
except Exception as e:
|
|
||||||
raise Exception(f'error: Cannot update master on slave {value["ip"]}: {e}')
|
|
||||||
|
|
||||||
for value in servers:
|
|
||||||
slave_id = value['id']
|
|
||||||
if value['master']:
|
|
||||||
slave_id = server_sql.select_server_id_by_ip(master_ip)
|
|
||||||
try:
|
|
||||||
ha_sql.insert_or_update_slave(cluster_id, slave_id, value['eth'], value['master'], router_id)
|
|
||||||
except Exception as e:
|
|
||||||
raise Exception(f'error: Cannot update server {value["ip"]}: {e}')
|
|
||||||
|
|
||||||
|
|
||||||
def add_or_update_virt(cluster: Union[HAClusterRequest, HAClusterVIP], servers: dict, cluster_id: int, vip_id: int, group_id: int) -> None:
|
def add_or_update_virt(cluster: Union[HAClusterRequest, HAClusterVIP], servers: dict, cluster_id: int, vip_id: int, group_id: int) -> None:
|
||||||
haproxy = 0
|
haproxy = 0
|
||||||
nginx = 0
|
nginx = 0
|
||||||
apache = 0
|
apache = 0
|
||||||
master_ip = None
|
master_id = None
|
||||||
vip = str(cluster.vip)
|
vip = str(cluster.vip)
|
||||||
|
|
||||||
for value in servers:
|
for value in servers:
|
||||||
if value['master']:
|
if value['master']:
|
||||||
master_ip = value['ip']
|
master_id = value['id']
|
||||||
|
|
||||||
if ha_sql.check_ha_virt(vip_id):
|
if ha_sql.check_ha_virt(vip_id):
|
||||||
try:
|
try:
|
||||||
|
@ -280,15 +262,34 @@ def add_or_update_virt(cluster: Union[HAClusterRequest, HAClusterVIP], servers:
|
||||||
nginx = 1 if service.service_id == '2' else 0
|
nginx = 1 if service.service_id == '2' else 0
|
||||||
apache = 1 if service.service_id == '4' else 0
|
apache = 1 if service.service_id == '4' else 0
|
||||||
try:
|
try:
|
||||||
cred_id = ha_sql.get_cred_id_by_server_ip(master_ip)
|
server = server_sql.get_server_by_id(master_id)
|
||||||
firewall = 1 if server_mod.is_service_active(master_ip, 'firewalld') else 0
|
c = ha_sql.get_cluster(cluster_id)
|
||||||
ssh_settings = return_ssh_keys_path(master_ip)
|
|
||||||
virt_id = server_sql.add_server(
|
virt_id = server_sql.add_server(
|
||||||
f'{vip}-VIP', vip, group_id, '1', '1', '0', cred_id, ssh_settings['port'],
|
f'{vip}-VIP', vip, group_id, '1', '1', '0', server.cred_id, server.port,
|
||||||
f'VRRP IP for {cluster.name} cluster', haproxy, nginx, apache, firewall
|
f'VRRP IP for {c.name} cluster', haproxy, nginx, apache, server.firewall_enable
|
||||||
)
|
)
|
||||||
HaClusterVirt.insert(cluster_id=cluster_id, virt_id=virt_id, vip_id=vip_id).execute()
|
HaClusterVirt.insert(cluster_id=cluster_id, virt_id=virt_id, vip_id=vip_id).execute()
|
||||||
roxywi_common.logging(cluster_id, f'New cluster virtual server for VIP: {vip} has been created', keep_history=1, roxywi=1,
|
roxywi_common.logging(cluster_id, f'New cluster virtual server for VIP: {vip} has been created', keep_history=1, roxywi=1,
|
||||||
service='HA cluster')
|
service='HA cluster')
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
roxywi_common.logging(cluster_id, f'error: Cannot create new cluster virtual server for VIP: {vip}: {e}', roxywi=1, service='HA cluster')
|
roxywi_common.logging(cluster_id, f'error: Cannot create new cluster virtual server for VIP: {vip}: {e}', roxywi=1, service='HA cluster')
|
||||||
|
|
||||||
|
|
||||||
|
def _create_or_update_master_slaves_servers(cluster_id: int, servers: dict, router_id: int, create: bool = False) -> None:
|
||||||
|
for server in servers:
|
||||||
|
if server['master']:
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
ha_sql.update_master_server_by_slave_ip(server['id'], server['ip'])
|
||||||
|
except Exception as e:
|
||||||
|
raise Exception(f'error: Cannot update master on slave {server["ip"]: {e}}')
|
||||||
|
|
||||||
|
for server in servers:
|
||||||
|
try:
|
||||||
|
ha_sql.insert_or_update_slave(cluster_id, server['id'], server['eth'], server['master'], router_id)
|
||||||
|
if create:
|
||||||
|
s = server_sql.get_server_by_id(server['id'])
|
||||||
|
roxywi_common.logging(cluster_id, f'New server {s.hostname} has been added to the cluster', keep_history=1,
|
||||||
|
roxywi=1, service='HA cluster')
|
||||||
|
except Exception as e:
|
||||||
|
raise Exception(f'error: Cannot update slave server {server["ip"]}: {e}')
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from flask import render_template, g, request
|
from flask import render_template, g, request
|
||||||
from flask_jwt_extended import jwt_required
|
from flask_jwt_extended import jwt_required
|
||||||
|
|
||||||
|
from app.modules.roxywi.exception import RoxywiResourceNotFound
|
||||||
from app.routes.ha import bp
|
from app.routes.ha import bp
|
||||||
from app.middleware import get_user_params, check_services
|
from app.middleware import get_user_params, check_services
|
||||||
import app.modules.db.ha_cluster as ha_sql
|
import app.modules.db.ha_cluster as ha_sql
|
||||||
|
@ -25,11 +26,18 @@ def before_request():
|
||||||
@check_services
|
@check_services
|
||||||
@get_user_params()
|
@get_user_params()
|
||||||
def get_ha_cluster(service, cluster_id):
|
def get_ha_cluster(service, cluster_id):
|
||||||
router_id = ha_sql.get_router_id(cluster_id, default_router=1)
|
try:
|
||||||
|
router_id = ha_sql.get_router_id(cluster_id, default_router=1)
|
||||||
|
except RoxywiResourceNotFound:
|
||||||
|
router_id = None
|
||||||
|
if router_id:
|
||||||
|
slaves = ha_sql.select_cluster_slaves(cluster_id, router_id)
|
||||||
|
else:
|
||||||
|
slaves = {}
|
||||||
kwargs = {
|
kwargs = {
|
||||||
'servers': roxywi_common.get_dick_permit(virt=1),
|
'servers': roxywi_common.get_dick_permit(virt=1),
|
||||||
'clusters': ha_sql.select_cluster(cluster_id),
|
'clusters': ha_sql.select_cluster(cluster_id),
|
||||||
'slaves': ha_sql.select_cluster_slaves(cluster_id, router_id),
|
'slaves': slaves,
|
||||||
'virts': ha_sql.select_clusters_virts(),
|
'virts': ha_sql.select_clusters_virts(),
|
||||||
'vips': ha_sql.select_cluster_vips(cluster_id),
|
'vips': ha_sql.select_cluster_vips(cluster_id),
|
||||||
'cluster_services': ha_sql.select_cluster_services(cluster_id),
|
'cluster_services': ha_sql.select_cluster_services(cluster_id),
|
||||||
|
@ -103,15 +111,17 @@ def show_ha_cluster(service, cluster_id):
|
||||||
return render_template('service.html', **kwargs)
|
return render_template('service.html', **kwargs)
|
||||||
|
|
||||||
|
|
||||||
@bp.route('/<service>/slaves/<int:cluster_id>', methods=['GET', 'POST'])
|
@bp.route('/<service>/slaves/<int:cluster_id>/<int:vip_id>', methods=['GET', 'POST'])
|
||||||
@check_services
|
@check_services
|
||||||
@get_user_params()
|
@get_user_params()
|
||||||
def get_slaves(service, cluster_id):
|
def get_slaves(service, cluster_id, vip_id):
|
||||||
lang = g.user_params['lang']
|
lang = g.user_params['lang']
|
||||||
if request.method == 'GET':
|
if request.method == 'GET':
|
||||||
router_id = ha_sql.get_router_id(cluster_id, default_router=1)
|
router_id = ha_sql.get_router_id(cluster_id, default_router=1)
|
||||||
else:
|
else:
|
||||||
router_id = int(request.form.get('router_id'))
|
# router_id = int(request.form.get('router_id'))
|
||||||
|
vip = ha_sql.select_cluster_vip_by_vip_id(cluster_id, vip_id)
|
||||||
|
router_id = vip.router_id
|
||||||
slaves = ha_sql.select_cluster_slaves(cluster_id, router_id)
|
slaves = ha_sql.select_cluster_slaves(cluster_id, router_id)
|
||||||
|
|
||||||
return render_template('ajax/ha/add_vip_slaves.html', lang=lang, slaves=slaves)
|
return render_template('ajax/ha/add_vip_slaves.html', lang=lang, slaves=slaves)
|
||||||
|
|
|
@ -186,7 +186,7 @@ pre {
|
||||||
padding-top: 11px;
|
padding-top: 11px;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
width: 450px;
|
width: 460px;
|
||||||
float: left;
|
float: left;
|
||||||
margin-left: 71%;
|
margin-left: 71%;
|
||||||
margin-top: -50px;
|
margin-top: -50px;
|
||||||
|
|
|
@ -116,11 +116,11 @@ function createHaClusterStep1(edited=false, cluster_id=0, clean=true) {
|
||||||
if (edited && clean) {
|
if (edited && clean) {
|
||||||
let master_name = $('#master-server-'+cluster_id).text();
|
let master_name = $('#master-server-'+cluster_id).text();
|
||||||
let master_ip = $('#master-ip-'+cluster_id).text();
|
let master_ip = $('#master-ip-'+cluster_id).text();
|
||||||
|
let master_id = $('#master-id-'+cluster_id).text();
|
||||||
$("#ha-cluster-master option").not(master_name).each(function (index) {
|
$("#ha-cluster-master option").not(master_name).each(function (index) {
|
||||||
$(this).prop('disabled', true);
|
$(this).prop('disabled', true);
|
||||||
});
|
});
|
||||||
$('#ha-cluster-master').append('<option value="' + master_ip + '" selected="selected">' + master_name + '</option>').selectmenu("refresh");
|
$('#ha-cluster-master').append('<option value="' + master_ip + '" selected="selected" data-id="'+master_id+'">' + master_name + '</option>').selectmenu("refresh");
|
||||||
$('#ha-cluster-master').selectmenu("refresh");
|
|
||||||
get_keepalived_ver($('#cur_master_ver'), master_ip);
|
get_keepalived_ver($('#cur_master_ver'), master_ip);
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: api_prefix + "/ha/cluster/" + cluster_id,
|
url: api_prefix + "/ha/cluster/" + cluster_id,
|
||||||
|
@ -500,14 +500,14 @@ function increaseProgressValue(progress_step) {
|
||||||
}
|
}
|
||||||
$(progress_id).css('width', new_progress+'%');
|
$(progress_id).css('width', new_progress+'%');
|
||||||
}
|
}
|
||||||
function add_vip_ha_cluster(cluster_id, cluster_name, router_id='', vip='', edited=0) {
|
function add_vip_ha_cluster(cluster_id, cluster_name, vip_id='', vip='', edited=0) {
|
||||||
let save_word = translate_div.attr('data-save');
|
let save_word = translate_div.attr('data-save');
|
||||||
let tabel_title = $("#add-vip-table").attr('title');
|
let tabel_title = $("#add-vip-table").attr('title');
|
||||||
let buttons = [];
|
let buttons = [];
|
||||||
let req_method = 'GET';
|
let req_method = 'GET';
|
||||||
if (edited) {
|
if (edited) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: api_prefix + "/ha/cluster/" + cluster_id + "/vip/" + router_id,
|
url: api_prefix + "/ha/cluster/" + cluster_id + "/vip/" + vip_id,
|
||||||
type: "GET",
|
type: "GET",
|
||||||
async: false,
|
async: false,
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
|
@ -544,7 +544,7 @@ function add_vip_ha_cluster(cluster_id, cluster_name, router_id='', vip='', edit
|
||||||
if (!validateSlaves(jsonData)) {
|
if (!validateSlaves(jsonData)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
saveVip(jsonData, cluster_id, $(this), cluster_name, edited, router_id, vip);
|
saveVip(jsonData, cluster_id, $(this), edited, vip_id);
|
||||||
toastr.clear();
|
toastr.clear();
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
|
@ -555,7 +555,7 @@ function add_vip_ha_cluster(cluster_id, cluster_name, router_id='', vip='', edit
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
jsonData = createJsonVip('#vip_servers div span');
|
jsonData = createJsonVip('#vip_servers div span');
|
||||||
saveVip(jsonData, cluster_id, $(this), cluster_name, edited, router_id, vip, true);
|
saveVip(jsonData, cluster_id, $(this), edited, vip_id, true);
|
||||||
toastr.clear();
|
toastr.clear();
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
|
@ -578,7 +578,7 @@ function add_vip_ha_cluster(cluster_id, cluster_name, router_id='', vip='', edit
|
||||||
if (!validateSlaves(jsonData)) {
|
if (!validateSlaves(jsonData)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
saveVip(jsonData, cluster_id, $(this), cluster_name, edited, router_id, vip);
|
saveVip(jsonData, cluster_id, $(this), edited, vip_id);
|
||||||
toastr.clear();
|
toastr.clear();
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
|
@ -591,10 +591,7 @@ function add_vip_ha_cluster(cluster_id, cluster_name, router_id='', vip='', edit
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: "/ha/cluster/slaves/" + cluster_id,
|
url: "/ha/cluster/slaves/" + cluster_id + "/" + vip_id,
|
||||||
data: {
|
|
||||||
router_id: router_id,
|
|
||||||
},
|
|
||||||
type: req_method,
|
type: req_method,
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
if (data.indexOf('error:') != '-1') {
|
if (data.indexOf('error:') != '-1') {
|
||||||
|
@ -627,7 +624,7 @@ function add_vip_ha_cluster(cluster_id, cluster_name, router_id='', vip='', edit
|
||||||
});
|
});
|
||||||
dialog_div.dialog('open');
|
dialog_div.dialog('open');
|
||||||
}
|
}
|
||||||
function saveVip(jsonData, cluster_id, dialog_id, cluster_name, edited, router_id='', vip='', deleted=false) {
|
function saveVip(jsonData, cluster_id, dialog_id, edited, vip_id='', deleted=false) {
|
||||||
let req_type = 'POST'
|
let req_type = 'POST'
|
||||||
let return_master = 0
|
let return_master = 0
|
||||||
let virt_server = 0
|
let virt_server = 0
|
||||||
|
@ -645,15 +642,14 @@ function saveVip(jsonData, cluster_id, dialog_id, cluster_name, edited, router_i
|
||||||
jsonData['return_master'] = return_master;
|
jsonData['return_master'] = return_master;
|
||||||
jsonData['virt_server'] = virt_server;
|
jsonData['virt_server'] = virt_server;
|
||||||
jsonData['use_src'] = use_src;
|
jsonData['use_src'] = use_src;
|
||||||
jsonData['name'] = cluster_name;
|
|
||||||
let url = api_prefix + "/ha/cluster/" + cluster_id + "/vip";
|
let url = api_prefix + "/ha/cluster/" + cluster_id + "/vip";
|
||||||
if (edited) {
|
if (edited) {
|
||||||
req_type = 'PUT';
|
req_type = 'PUT';
|
||||||
jsonData['router_id'] = router_id;
|
url = api_prefix + "/ha/cluster/" + cluster_id + "/vip/" + vip_id;
|
||||||
}
|
}
|
||||||
if (deleted) {
|
if (deleted) {
|
||||||
req_type = 'DELETE';
|
req_type = 'DELETE';
|
||||||
url = api_prefix + "/ha/cluster/" + router_id + "/vip"
|
url = api_prefix + "/ha/cluster/" + cluster_id + "/vip/" + vip_id;
|
||||||
}
|
}
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: url,
|
url: url,
|
||||||
|
@ -759,18 +755,18 @@ function createJsonCluster(div_id) {
|
||||||
let jsonData = {};
|
let jsonData = {};
|
||||||
jsonData = {'servers': []};
|
jsonData = {'servers': []};
|
||||||
jsonData['servers'].push({
|
jsonData['servers'].push({
|
||||||
'id': 1,
|
'id': $('#ha-cluster-master option:selected').attr('data-id'),
|
||||||
'eth': $('#ha-cluster-master-interface').val(),
|
'eth': $('#ha-cluster-master-interface').val(),
|
||||||
'ip': $('#ha-cluster-master option:selected').val(),
|
// 'ip': $('#ha-cluster-master option:selected').val(),
|
||||||
'name': $('#ha-cluster-master option:selected').text(),
|
// 'name': $('#ha-cluster-master option:selected').text(),
|
||||||
'master': 1
|
'master': 1
|
||||||
});
|
});
|
||||||
$(div_id).each(function () {
|
$(div_id).each(function () {
|
||||||
let this_id = $(this).attr('id').split('-')[1];
|
let this_id = $(this).attr('id').split('-')[1];
|
||||||
let eth = $('#slave_int-' + this_id).val();
|
let eth = $('#slave_int-' + this_id).val();
|
||||||
let ip = $('#slave_int_div-' + this_id).attr('data-ip');
|
// let ip = $('#slave_int_div-' + this_id).attr('data-ip');
|
||||||
let name = $('#slave_int_div-' + this_id).parent().text().replace('\n','').replace('\t','').trim();
|
// let name = $('#slave_int_div-' + this_id).parent().text().replace('\n','').replace('\t','').trim();
|
||||||
jsonData['servers'].push({'id': this_id, 'eth': eth, 'ip': ip, 'name': name, 'master': 0});
|
jsonData['servers'].push({'id': this_id, 'eth': eth, 'master': 0});
|
||||||
});
|
});
|
||||||
return jsonData;
|
return jsonData;
|
||||||
}
|
}
|
||||||
|
@ -780,21 +776,22 @@ function createJsonVip(div_id) {
|
||||||
$(div_id).each(function () {
|
$(div_id).each(function () {
|
||||||
let this_id = $(this).attr('id').split('-')[1];
|
let this_id = $(this).attr('id').split('-')[1];
|
||||||
let eth1 = $('#slave_int-' + this_id).val();
|
let eth1 = $('#slave_int-' + this_id).val();
|
||||||
let ip1 = $('#slave_int_div-' + this_id).attr('data-ip');
|
// let ip1 = $('#slave_int_div-' + this_id).attr('data-ip');
|
||||||
let name1 = $('#slave_int_div-' + this_id).parent().text().replace('\n','').replace('\t','').trim();
|
// let name1 = $('#slave_int_div-' + this_id).parent().text().replace('\n','').replace('\t','').trim();
|
||||||
let eth = $('#master_int-' + this_id).val();
|
let eth = $('#master_int-' + this_id).val();
|
||||||
let ip = $('#master_int_div-' + this_id).attr('data-ip');
|
// let ip = $('#master_int_div-' + this_id).attr('data-ip');
|
||||||
let name = $('#master_int_div-' + this_id).parent().text().replace('\n','').replace('\t','').trim();
|
// let name = $('#master_int_div-' + this_id).parent().text().replace('\n','').replace('\t','').trim();
|
||||||
if (eth) {
|
if (eth) {
|
||||||
jsonData['servers'].push({'id': this_id, 'eth': eth, 'ip': ip, 'name': name, 'master': 1});
|
jsonData['servers'].push({'id': this_id, 'eth': eth, 'master': 1});
|
||||||
} else {
|
} else {
|
||||||
jsonData['servers'].push({'id': this_id,'eth': eth1, 'ip': ip1, 'name': name1, 'master': 0});
|
jsonData['servers'].push({'id': this_id,'eth': eth1, 'master': 0});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return jsonData;
|
return jsonData;
|
||||||
}
|
}
|
||||||
function validateSlaves(jsonData) {
|
function validateSlaves(jsonData) {
|
||||||
|
console.log(jsonData)
|
||||||
if (Object.keys(jsonData['servers']).length === 1) {
|
if (Object.keys(jsonData['servers']).length === 1) {
|
||||||
toastr.error('error: There is must be at least one slave server');
|
toastr.error('error: There is must be at least one slave server');
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
{% if slave.31 %}
|
{% if slave.31 %}
|
||||||
Master name: {{ copy_to_clipboard(id='master-server-'+cluster.id|string(), value=slave.1) }}<br>
|
Master name: {{ copy_to_clipboard(id='master-server-'+cluster.id|string(), value=slave.1) }}<br>
|
||||||
Master IP: {{ copy_to_clipboard(id='master-ip-'+cluster.id|string(), value=slave.2) }}<br>
|
Master IP: {{ copy_to_clipboard(id='master-ip-'+cluster.id|string(), value=slave.2) }}<br>
|
||||||
|
<span style="display: none;" id="master-id-{{ cluster.id }}">{{ slave.0 }}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{{lang.words.slaves|title()}}:
|
{{lang.words.slaves|title()}}:
|
||||||
|
@ -46,7 +47,7 @@
|
||||||
<span id="cluster-vip">
|
<span id="cluster-vip">
|
||||||
{%- for vip in vips %}
|
{%- for vip in vips %}
|
||||||
{% if g.user_params['role'] <= 2 %}
|
{% if g.user_params['role'] <= 2 %}
|
||||||
<a style="cursor: pointer;" onclick="add_vip_ha_cluster('{{vip.cluster_id}}', '{{cluster.name}}', '{{vip.router_id}}', '{{vip.vip}}', 1)" title="{{lang.words.edit|title()}} VIP">{{vip.vip}}</a>
|
<a style="cursor: pointer;" onclick="add_vip_ha_cluster('{{vip.cluster_id}}', '{{cluster.name}}', '{{vip.id}}', '{{vip.vip}}', 1)" title="{{lang.words.edit|title()}} VIP">{{vip.vip}}</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
{{vip.vip}}
|
{{vip.vip}}
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<td>
|
<td>
|
||||||
<select autofocus required name="backup-server" id="backup-server">
|
<select autofocus required name="backup-server" id="backup-server">
|
||||||
<option disabled>------</option>
|
<option disabled>------</option>
|
||||||
{% for s in servers %}}
|
{% for s in servers %}
|
||||||
<option value="{{ s.2 }}">{{ s.1 }}</option>
|
<option value="{{ s.2 }}">{{ s.1 }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
|
|
|
@ -359,7 +359,9 @@
|
||||||
<select id="git-service" required>
|
<select id="git-service" required>
|
||||||
<option disabled selected>------</option>
|
<option disabled selected>------</option>
|
||||||
{% for s in services %}
|
{% for s in services %}
|
||||||
|
{% if s.service_id in (1, 2, 3, 4) %}
|
||||||
<option value="{{s.service_id}}">{{s.service}}</option>
|
<option value="{{s.service_id}}">{{s.service}}</option>
|
||||||
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -9,9 +9,7 @@ import app.modules.roxywi.common as roxywi_common
|
||||||
import app.modules.common.common as common
|
import app.modules.common.common as common
|
||||||
import app.modules.service.ha_cluster as ha_cluster
|
import app.modules.service.ha_cluster as ha_cluster
|
||||||
from app.middleware import get_user_params, page_for_admin, check_group, check_services
|
from app.middleware import get_user_params, page_for_admin, check_group, check_services
|
||||||
from app.modules.roxywi.class_models import (
|
from app.modules.roxywi.class_models import BaseResponse, IdResponse, HAClusterRequest, HAClusterVIP
|
||||||
BaseResponse, IdResponse, HAClusterRequest, HAClusterVIP
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class HAView(MethodView):
|
class HAView(MethodView):
|
||||||
|
@ -128,6 +126,9 @@ class HAView(MethodView):
|
||||||
name: body
|
name: body
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
- services
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
servers:
|
servers:
|
||||||
|
@ -140,8 +141,8 @@ class HAView(MethodView):
|
||||||
type: 'string'
|
type: 'string'
|
||||||
master:
|
master:
|
||||||
type: 'integer'
|
type: 'integer'
|
||||||
name:
|
id:
|
||||||
type: 'string'
|
type: 'integer'
|
||||||
name:
|
name:
|
||||||
type: string
|
type: string
|
||||||
description:
|
description:
|
||||||
|
@ -203,6 +204,9 @@ class HAView(MethodView):
|
||||||
name: body
|
name: body
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
- services
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
servers:
|
servers:
|
||||||
|
@ -215,8 +219,8 @@ class HAView(MethodView):
|
||||||
type: 'string'
|
type: 'string'
|
||||||
master:
|
master:
|
||||||
type: 'integer'
|
type: 'integer'
|
||||||
name:
|
id:
|
||||||
type: 'string'
|
type: 'integer'
|
||||||
name:
|
name:
|
||||||
type: string
|
type: string
|
||||||
description:
|
description:
|
||||||
|
@ -240,8 +244,6 @@ class HAView(MethodView):
|
||||||
type: string
|
type: string
|
||||||
docker:
|
docker:
|
||||||
type: integer
|
type: integer
|
||||||
router_id:
|
|
||||||
type: string
|
|
||||||
responses:
|
responses:
|
||||||
201:
|
201:
|
||||||
description: HA cluster updated successfully
|
description: HA cluster updated successfully
|
||||||
|
@ -299,7 +301,7 @@ class HAVIPView(MethodView):
|
||||||
self.group_id = g.user_params['group_id']
|
self.group_id = g.user_params['group_id']
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get(service: str, cluster_id: int, router_id: int):
|
def get(service: str, cluster_id: int, vip_id: int):
|
||||||
"""
|
"""
|
||||||
This endpoint retrieves information about the specified VIP.
|
This endpoint retrieves information about the specified VIP.
|
||||||
---
|
---
|
||||||
|
@ -317,8 +319,8 @@ class HAVIPView(MethodView):
|
||||||
required: true
|
required: true
|
||||||
type: 'integer'
|
type: 'integer'
|
||||||
- in: 'path'
|
- in: 'path'
|
||||||
name: 'router_id'
|
name: 'vip_id'
|
||||||
description: 'ID of the Router to retrieve'
|
description: 'ID of the VIP to retrieve'
|
||||||
required: true
|
required: true
|
||||||
type: 'integer'
|
type: 'integer'
|
||||||
responses:
|
responses:
|
||||||
|
@ -328,29 +330,13 @@ class HAVIPView(MethodView):
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
cluster_id:
|
cluster_id:
|
||||||
type: 'object'
|
type: 'integer'
|
||||||
properties:
|
|
||||||
description:
|
|
||||||
type: 'string'
|
|
||||||
group_id:
|
|
||||||
type: 'integer'
|
|
||||||
id:
|
|
||||||
type: 'integer'
|
|
||||||
name:
|
|
||||||
type: 'string'
|
|
||||||
pos:
|
|
||||||
type: 'integer'
|
|
||||||
syn_flood:
|
|
||||||
type: 'integer'
|
|
||||||
id:
|
id:
|
||||||
type: 'integer'
|
type: 'integer'
|
||||||
return_master:
|
return_master:
|
||||||
type: 'integer'
|
type: 'integer'
|
||||||
router_id:
|
router_id:
|
||||||
type: 'object'
|
type: 'integer'
|
||||||
properties:
|
|
||||||
id:
|
|
||||||
type: 'integer'
|
|
||||||
use_src:
|
use_src:
|
||||||
type: 'integer'
|
type: 'integer'
|
||||||
vip:
|
vip:
|
||||||
|
@ -359,8 +345,8 @@ class HAVIPView(MethodView):
|
||||||
description: Unexpected error
|
description: Unexpected error
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
vip = ha_sql.select_cluster_vip(cluster_id, router_id)
|
vip = ha_sql.select_cluster_vip_by_vip_id(cluster_id, vip_id)
|
||||||
settings = model_to_dict(vip)
|
settings = model_to_dict(vip, recurse=False)
|
||||||
is_virt = ha_sql.check_ha_virt(vip.id)
|
is_virt = ha_sql.check_ha_virt(vip.id)
|
||||||
settings.setdefault('virt_server', is_virt)
|
settings.setdefault('virt_server', is_virt)
|
||||||
return jsonify(settings)
|
return jsonify(settings)
|
||||||
|
@ -389,37 +375,29 @@ class HAVIPView(MethodView):
|
||||||
name: body
|
name: body
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
|
required:
|
||||||
|
- servers
|
||||||
|
- vip
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
servers:
|
servers:
|
||||||
type: object
|
type: 'array'
|
||||||
additionalProperties:
|
description: Must be at least 2 servers. One of them must be master = 1
|
||||||
type: object
|
items:
|
||||||
|
type: 'object'
|
||||||
properties:
|
properties:
|
||||||
eth:
|
id:
|
||||||
type: string
|
type: 'integer'
|
||||||
ip:
|
|
||||||
type: string
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
master:
|
master:
|
||||||
type: integer
|
type: 'integer'
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
description:
|
|
||||||
type: string
|
|
||||||
vip:
|
vip:
|
||||||
type: string
|
type: string
|
||||||
virt_server:
|
virt_server:
|
||||||
type: integer
|
type: integer
|
||||||
return_master:
|
return_master:
|
||||||
type: string
|
|
||||||
syn_flood:
|
|
||||||
type: integer
|
type: integer
|
||||||
use_src:
|
use_src:
|
||||||
type: integer
|
type: integer
|
||||||
router_id:
|
|
||||||
type: string
|
|
||||||
responses:
|
responses:
|
||||||
201:
|
201:
|
||||||
description: VIP created successfully
|
description: VIP created successfully
|
||||||
|
@ -431,14 +409,14 @@ class HAVIPView(MethodView):
|
||||||
description: Unexpected error
|
description: Unexpected error
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
ha_cluster.insert_vip(cluster_id, body, self.group_id)
|
vip_id = ha_cluster.insert_vip(cluster_id, body, self.group_id)
|
||||||
return BaseResponse().model_dump(mode='json'), 201
|
return IdResponse(id=vip_id).model_dump(mode='json'), 201
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot create VIP')
|
return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot create VIP')
|
||||||
|
|
||||||
|
|
||||||
@validate(body=HAClusterVIP)
|
@validate(body=HAClusterVIP)
|
||||||
def put(self, service: str, cluster_id: int, body: HAClusterVIP):
|
def put(self, service: str, cluster_id: int, vip_id: int, body: HAClusterVIP):
|
||||||
"""
|
"""
|
||||||
This endpoint allows to update a VIP for HA cluster.
|
This endpoint allows to update a VIP for HA cluster.
|
||||||
---
|
---
|
||||||
|
@ -455,41 +433,38 @@ class HAVIPView(MethodView):
|
||||||
description: 'ID of the HA cluster to update'
|
description: 'ID of the HA cluster to update'
|
||||||
required: true
|
required: true
|
||||||
type: 'integer'
|
type: 'integer'
|
||||||
|
- in: 'path'
|
||||||
|
name: 'vip_id'
|
||||||
|
description: 'ID of the VIP to update'
|
||||||
|
required: true
|
||||||
|
type: 'integer'
|
||||||
- in: body
|
- in: body
|
||||||
name: body
|
name: body
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
|
required:
|
||||||
|
- servers
|
||||||
|
- vip
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
servers:
|
servers:
|
||||||
type: object
|
type: 'array'
|
||||||
additionalProperties:
|
description: Must be at least 2 servers. One of them must be master = 1
|
||||||
type: object
|
items:
|
||||||
|
type: 'object'
|
||||||
properties:
|
properties:
|
||||||
eth:
|
id:
|
||||||
type: string
|
type: 'integer'
|
||||||
ip:
|
|
||||||
type: string
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
master:
|
master:
|
||||||
type: integer
|
type: 'integer'
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
description:
|
|
||||||
type: string
|
|
||||||
vip:
|
vip:
|
||||||
type: string
|
type: string
|
||||||
virt_server:
|
virt_server:
|
||||||
type: integer
|
type: integer
|
||||||
return_master:
|
return_master:
|
||||||
type: string
|
type: string
|
||||||
syn_flood:
|
|
||||||
type: integer
|
|
||||||
use_src:
|
use_src:
|
||||||
type: integer
|
type: integer
|
||||||
router_id:
|
|
||||||
type: string
|
|
||||||
responses:
|
responses:
|
||||||
201:
|
201:
|
||||||
description: VIP updated successfully
|
description: VIP updated successfully
|
||||||
|
@ -500,14 +475,15 @@ class HAVIPView(MethodView):
|
||||||
default:
|
default:
|
||||||
description: Unexpected error
|
description: Unexpected error
|
||||||
"""
|
"""
|
||||||
|
vip = ha_sql.select_cluster_vip_by_vip_id(cluster_id, vip_id)
|
||||||
try:
|
try:
|
||||||
ha_cluster.update_vip(cluster_id, body.router_id, body, self.group_id)
|
ha_cluster.update_vip(cluster_id, vip.router_id, body, self.group_id)
|
||||||
return BaseResponse().model_dump(mode='json'), 201
|
return BaseResponse().model_dump(mode='json'), 201
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot update VIP')
|
return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot update VIP')
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def delete(service: str, router_id: int):
|
def delete(service: str, cluster_id: int, vip_id: int):
|
||||||
"""
|
"""
|
||||||
Delete a VIP
|
Delete a VIP
|
||||||
---
|
---
|
||||||
|
@ -520,7 +496,12 @@ class HAVIPView(MethodView):
|
||||||
required: true
|
required: true
|
||||||
type: 'string'
|
type: 'string'
|
||||||
- in: 'path'
|
- in: 'path'
|
||||||
name: 'router_id'
|
name: 'cluster_id'
|
||||||
|
description: 'ID of the HA cluster to delete VIP from'
|
||||||
|
required: true
|
||||||
|
type: 'integer'
|
||||||
|
- in: 'path'
|
||||||
|
name: 'vip_id'
|
||||||
description: 'ID of the VIP to delete'
|
description: 'ID of the VIP to delete'
|
||||||
required: true
|
required: true
|
||||||
type: 'integer'
|
type: 'integer'
|
||||||
|
@ -532,11 +513,12 @@ class HAVIPView(MethodView):
|
||||||
404:
|
404:
|
||||||
description: VIP not found
|
description: VIP not found
|
||||||
"""
|
"""
|
||||||
router = ha_sql.get_router(router_id)
|
vip = ha_sql.select_cluster_vip_by_vip_id(cluster_id, vip_id)
|
||||||
|
router = ha_sql.get_router(vip.router_id)
|
||||||
if router.default == 1:
|
if router.default == 1:
|
||||||
return roxywi_common.handler_exceptions_for_json_data(Exception(''), 'You cannot delete default VIP')
|
return roxywi_common.handler_exceptions_for_json_data(Exception(''), 'You cannot delete default VIP')
|
||||||
try:
|
try:
|
||||||
ha_sql.delete_ha_router(router_id)
|
ha_sql.delete_ha_router(vip.router_id)
|
||||||
return BaseResponse().model_dump(mode='json'), 204
|
return BaseResponse().model_dump(mode='json'), 204
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot delete VIP')
|
return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot delete VIP')
|
||||||
|
@ -592,10 +574,7 @@ class HAVIPsView(MethodView):
|
||||||
return_master:
|
return_master:
|
||||||
type: 'integer'
|
type: 'integer'
|
||||||
router_id:
|
router_id:
|
||||||
type: 'object'
|
type: 'integer'
|
||||||
properties:
|
|
||||||
id:
|
|
||||||
type: 'integer'
|
|
||||||
use_src:
|
use_src:
|
||||||
type: 'integer'
|
type: 'integer'
|
||||||
vip:
|
vip:
|
||||||
|
@ -604,5 +583,5 @@ class HAVIPsView(MethodView):
|
||||||
description: Unexpected error
|
description: Unexpected error
|
||||||
"""
|
"""
|
||||||
vips = ha_sql.select_cluster_vips(cluster_id)
|
vips = ha_sql.select_cluster_vips(cluster_id)
|
||||||
vips = [model_to_dict(vip) for vip in vips]
|
vips = [model_to_dict(vip, recurse=False) for vip in vips]
|
||||||
return jsonify(vips)
|
return jsonify(vips)
|
||||||
|
|
|
@ -85,6 +85,14 @@ class BackupView(MethodView):
|
||||||
description: The configuration for backup service
|
description: The configuration for backup service
|
||||||
schema:
|
schema:
|
||||||
type: 'object'
|
type: 'object'
|
||||||
|
required:
|
||||||
|
- cred_id
|
||||||
|
- rhost
|
||||||
|
- rpath
|
||||||
|
- server
|
||||||
|
- rserver
|
||||||
|
- time
|
||||||
|
- type
|
||||||
properties:
|
properties:
|
||||||
server:
|
server:
|
||||||
type: 'string'
|
type: 'string'
|
||||||
|
@ -92,15 +100,19 @@ class BackupView(MethodView):
|
||||||
rserver:
|
rserver:
|
||||||
type: 'string'
|
type: 'string'
|
||||||
description: 'The remote server where backup files should be stored'
|
description: 'The remote server where backup files should be stored'
|
||||||
|
example: 10.0.0.1
|
||||||
rpath:
|
rpath:
|
||||||
type: 'string'
|
type: 'string'
|
||||||
description: 'The path on the remote server where backup files should be stored'
|
description: 'The path on the remote server where backup files should be stored'
|
||||||
|
example: /var/backup/
|
||||||
type:
|
type:
|
||||||
type: 'string'
|
type: 'string'
|
||||||
description: 'Type of the operation'
|
description: 'Type of the operation'
|
||||||
|
enum: [backup, synchronization]
|
||||||
time:
|
time:
|
||||||
type: 'string'
|
type: 'string'
|
||||||
description: 'The timing for the backup task'
|
description: 'The timing for the backup task'
|
||||||
|
enum: [hourly, daily, weekly, monthly]
|
||||||
cred_id:
|
cred_id:
|
||||||
type: 'string'
|
type: 'string'
|
||||||
description: 'Credentials ID for the backup task'
|
description: 'Credentials ID for the backup task'
|
||||||
|
@ -137,6 +149,14 @@ class BackupView(MethodView):
|
||||||
description: The configuration for backup service
|
description: The configuration for backup service
|
||||||
schema:
|
schema:
|
||||||
type: 'object'
|
type: 'object'
|
||||||
|
required:
|
||||||
|
- cred_id
|
||||||
|
- rhost
|
||||||
|
- rpath
|
||||||
|
- server
|
||||||
|
- rserver
|
||||||
|
- time
|
||||||
|
- type
|
||||||
properties:
|
properties:
|
||||||
server:
|
server:
|
||||||
type: 'string'
|
type: 'string'
|
||||||
|
@ -144,15 +164,19 @@ class BackupView(MethodView):
|
||||||
rserver:
|
rserver:
|
||||||
type: 'string'
|
type: 'string'
|
||||||
description: 'The remote server where backup files should be stored'
|
description: 'The remote server where backup files should be stored'
|
||||||
|
example: 10.0.0.1
|
||||||
rpath:
|
rpath:
|
||||||
type: 'string'
|
type: 'string'
|
||||||
description: 'The path on the remote server where backup files should be stored'
|
description: 'The path on the remote server where backup files should be stored'
|
||||||
|
example: /var/backup/
|
||||||
type:
|
type:
|
||||||
type: 'string'
|
type: 'string'
|
||||||
description: 'Type of the operation'
|
description: 'Type of the operation'
|
||||||
|
enum: [backup, synchronization]
|
||||||
time:
|
time:
|
||||||
type: 'string'
|
type: 'string'
|
||||||
description: 'The timing for the backup task'
|
description: 'The timing for the backup task'
|
||||||
|
enum: [hourly, daily, weekly, monthly]
|
||||||
cred_id:
|
cred_id:
|
||||||
type: 'string'
|
type: 'string'
|
||||||
description: 'Credentials ID for the backup task'
|
description: 'Credentials ID for the backup task'
|
||||||
|
@ -282,6 +306,13 @@ class S3BackupView(MethodView):
|
||||||
description: The configuration for S3 backup service
|
description: The configuration for S3 backup service
|
||||||
schema:
|
schema:
|
||||||
type: 'object'
|
type: 'object'
|
||||||
|
required:
|
||||||
|
- s3_server
|
||||||
|
- server
|
||||||
|
- bucket
|
||||||
|
- secret_key
|
||||||
|
- access_key
|
||||||
|
- time
|
||||||
properties:
|
properties:
|
||||||
s3_server:
|
s3_server:
|
||||||
type: 'string'
|
type: 'string'
|
||||||
|
@ -301,6 +332,7 @@ class S3BackupView(MethodView):
|
||||||
time:
|
time:
|
||||||
type: 'string'
|
type: 'string'
|
||||||
description: 'The timing for the S3 backup task'
|
description: 'The timing for the S3 backup task'
|
||||||
|
enum: [hourly, daily, weekly, monthly]
|
||||||
description:
|
description:
|
||||||
type: 'string'
|
type: 'string'
|
||||||
description: 'Description for the S3 backup configuration'
|
description: 'Description for the S3 backup configuration'
|
||||||
|
@ -428,25 +460,37 @@ class GitBackupView(MethodView):
|
||||||
description: The configuration for Git backup service
|
description: The configuration for Git backup service
|
||||||
schema:
|
schema:
|
||||||
type: 'object'
|
type: 'object'
|
||||||
|
required:
|
||||||
|
- cred_id
|
||||||
|
- server_id
|
||||||
|
- service_id
|
||||||
|
- init
|
||||||
|
- repo
|
||||||
|
- branch
|
||||||
|
- time
|
||||||
properties:
|
properties:
|
||||||
server_id:
|
server_id:
|
||||||
type: 'integer'
|
type: 'integer'
|
||||||
description: 'The ID of the server to backed up'
|
description: 'The ID of the server to backed up'
|
||||||
service_id:
|
service_id:
|
||||||
type: 'integer'
|
type: 'integer'
|
||||||
description: 'Service ID'
|
description: 'Service ID: 1: HAProxy, 2: NGINX, 3: Keepalived, 4: Apache'
|
||||||
|
example: 1
|
||||||
init:
|
init:
|
||||||
type: 'integer'
|
type: 'integer'
|
||||||
description: 'Indicates whether to initialize the repository'
|
description: 'Indicates whether to initialize the repository'
|
||||||
repo:
|
repo:
|
||||||
type: 'string'
|
type: 'string'
|
||||||
description: 'The repository from where to fetch the data for backup'
|
description: 'The repository from where to fetch the data for backup'
|
||||||
|
example: git@github.com:Example/haproxy_configs
|
||||||
branch:
|
branch:
|
||||||
type: 'string'
|
type: 'string'
|
||||||
description: 'The branch to pull for backup'
|
description: 'The branch to pull for backup'
|
||||||
|
example: 'master'
|
||||||
time:
|
time:
|
||||||
type: 'string'
|
type: 'string'
|
||||||
description: 'The timing for the Git backup task'
|
description: 'The timing for the Git backup task'
|
||||||
|
enum: [hourly, daily, weekly, monthly]
|
||||||
cred_id:
|
cred_id:
|
||||||
type: 'integer'
|
type: 'integer'
|
||||||
description: 'The ID of the credentials to be used for backup'
|
description: 'The ID of the credentials to be used for backup'
|
||||||
|
|
|
@ -274,10 +274,10 @@ class ServiceConfigView(MethodView):
|
||||||
required: true
|
required: true
|
||||||
description: The ID or IP of the server
|
description: The ID or IP of the server
|
||||||
- in: query
|
- in: query
|
||||||
name: file_name
|
name: file_path
|
||||||
type: 'string'
|
type: 'string'
|
||||||
required: false
|
required: false
|
||||||
description: The full path to the configuration file (used only for nginx and apache, replace "/" with 92)
|
description: The full path to the configuration file
|
||||||
- in: query
|
- in: query
|
||||||
name: version
|
name: version
|
||||||
type: 'string'
|
type: 'string'
|
||||||
|
@ -289,10 +289,10 @@ class ServiceConfigView(MethodView):
|
||||||
default:
|
default:
|
||||||
description: Unexpected error
|
description: Unexpected error
|
||||||
"""
|
"""
|
||||||
if service in ('nginx', 'apache') and (query.file_name is None and query.version is None):
|
if service in ('nginx', 'apache') and (query.file_path is None and query.version is None):
|
||||||
return ErrorResponse(error=f'There is must be "file_name" as query parameter for {service.title()}')
|
return ErrorResponse(error=f'There is must be "file_name" as query parameter for {service.title()}')
|
||||||
if query.file_name:
|
if query.file_path:
|
||||||
query.file_name = query.file_name.replace('/', '92')
|
query.file_path = query.file_path.replace('/', '92')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
server_ip = SupportClass(False).return_server_ip_or_id(server_id)
|
server_ip = SupportClass(False).return_server_ip_or_id(server_id)
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
configparser>=3.5.0
|
|
||||||
pytz>=2017.3
|
|
||||||
tzlocal==2.0.0
|
|
||||||
pyTelegramBotAPI>=3.6.3
|
|
||||||
slack-sdk>=3.4.0
|
|
||||||
distro>=1.2.0
|
|
||||||
retry>=0.9.2
|
|
||||||
psutil>=5.9.1
|
|
||||||
pdpyras>=4.5.2
|
|
||||||
Werkzeug==2.2.3
|
|
||||||
Flask==2.2.5
|
|
||||||
Flask-Login==0.6.2
|
|
||||||
Flask-APScheduler==1.13.0
|
|
||||||
Flask-Caching==2.1.0
|
|
||||||
python3-nmap<=1.5.1
|
|
||||||
aio-pika>=7.1.0
|
|
||||||
pika>=1.2.0
|
|
||||||
websockets>=9.0
|
|
||||||
ansible-core>=2.11.12
|
|
||||||
ansible-runner==2.3.2
|
|
||||||
python-whois>=0.8.0
|
|
||||||
requests==2.27.1
|
|
||||||
netaddr>=0.10.1
|
|
|
@ -1,23 +0,0 @@
|
||||||
pyTelegramBotAPI==3.6.3
|
|
||||||
networkx==2.1
|
|
||||||
matplotlib==2.1.2
|
|
||||||
paramiko-ng>=2.5.0
|
|
||||||
slack-sdk>=3.4.0
|
|
||||||
peewee>=3.14.10
|
|
||||||
PyMySQL>=1.0.2
|
|
||||||
retry>=0.9.2
|
|
||||||
pdpyras>=4.5.2
|
|
||||||
tzlocal==2.0.0
|
|
||||||
Werkzeug==2.0.3
|
|
||||||
Flask==2.0.3
|
|
||||||
Flask-APScheduler==1.12.4
|
|
||||||
Flask-Caching==1.10.1
|
|
||||||
Flask-Login==0.5.0
|
|
||||||
python3-nmap<=1.5.1
|
|
||||||
aio-pika>=7.1.0
|
|
||||||
pika>=1.2.0
|
|
||||||
websockets>=9.0
|
|
||||||
ansible-core>=2.11.12
|
|
||||||
ansible-runner==2.3.1
|
|
||||||
python-whois>=0.8.0
|
|
||||||
netaddr>=0.10.1
|
|
|
@ -1,24 +0,0 @@
|
||||||
configparser==3.5.0
|
|
||||||
pyTelegramBotAPI==3.6.3
|
|
||||||
networkx>=3.3
|
|
||||||
matplotlib>=2.1.2
|
|
||||||
slack-sdk>=3.4.0
|
|
||||||
peewee>=3.14.10
|
|
||||||
PyMySQL>=1.0.2
|
|
||||||
bottle>=0.12.18
|
|
||||||
retry>=0.9.2
|
|
||||||
tzlocal==2.0.0
|
|
||||||
pdpyras>=4.5.2
|
|
||||||
Werkzeug>=2.0.3
|
|
||||||
Flask>=2.0.3
|
|
||||||
Flask-APScheduler>=1.12.4
|
|
||||||
Flask-Caching>=1.10.1
|
|
||||||
Flask-Login>=0.5.0
|
|
||||||
python3-nmap<=1.5.1
|
|
||||||
aio-pika>=7.1.0
|
|
||||||
pika>=1.2.0
|
|
||||||
websockets>=9.0
|
|
||||||
ansible-core>=2.11.12
|
|
||||||
ansible-runner==2.3.1
|
|
||||||
python-whois>=0.8.0
|
|
||||||
netaddr>=0.10.1
|
|
|
@ -1,25 +0,0 @@
|
||||||
configparser>=3.5.0
|
|
||||||
pyTelegramBotAPI>=3.6.3
|
|
||||||
networkx>=2.1
|
|
||||||
matplotlib>=2.1.2
|
|
||||||
slack-sdk>=3.4.0
|
|
||||||
peewee>=3.14.10
|
|
||||||
PyMySQL>=1.0.2
|
|
||||||
bottle>=0.12.18
|
|
||||||
retry>=0.9.2
|
|
||||||
pdpyras>=4.5.2
|
|
||||||
Werkzeug==2.2.3
|
|
||||||
Flask==2.2.5
|
|
||||||
Flask-Login==0.6.2
|
|
||||||
Flask-APScheduler==1.13.0
|
|
||||||
Flask-Caching==2.1.0
|
|
||||||
python3-nmap<=1.5.1
|
|
||||||
aio-pika>=7.1.0
|
|
||||||
pika>=1.2.0
|
|
||||||
websockets>=9.0
|
|
||||||
tzlocal==2.0.0
|
|
||||||
ansible-core>=2.11.12
|
|
||||||
ansible-runner==2.3.1
|
|
||||||
python-whois>=0.8.0
|
|
||||||
requests==2.27.1
|
|
||||||
netaddr>=0.10.1
|
|
Loading…
Reference in New Issue