diff --git a/api/api.py b/api/api.py index bc49ab8e..e58f33ac 100644 --- a/api/api.py +++ b/api/api.py @@ -91,7 +91,10 @@ def index(): 'keepalived//action/restart': 'restart Keepalived service by id or hostname or ip. METHOD: GET', 'keepalived//config': 'get Keepalived config from a server by id or hostname or ip. METHOD: GET', 'keepalived//config': 'upload Keepalived config to a server by id or hostname or ip. Headers: action: save/reload/restart. Body must consist a whole Keepalived config. METHOD: POST', - 'ha/create': 'Create HA cluster. Body be JSON body: master_ip: str, slave_ip: str, vrrp_ip: str, master_eth: str, slave_eth: str, virt_server: int, haproxy: int, nginx: int, syn_flood: int, return_to_master: int. METHOD: POST', + 'ha': 'HA clusters list. METHOD: GET', + 'ha': 'Create HA cluster. Body must be JSON: name: str, desc: str, cluster_id: 0, router_id: "", vip: str, servers: {server_id: dict:{eth: str, ip: str, name: str, master: int}}, service: dict: {{haproxy: int, docker: int}, {nginx: int, docker: int}}, virt_server: int, syn_flood: int, return_to_master: int. METHOD: POST', + 'ha': 'Edit HA cluster. Body must be JSON: name: str, desc: str, cluster_id: int, router_id: "", vip: str, servers: {server_id: dict:{eth: str, ip: str, name: str, master: int}}, service: dict: {{haproxy: int, docker: int}, {nginx: int, docker: int}}, virt_server: int, syn_flood: int, return_to_master: int. METHOD: PUT', + 'ha': 'Delete HA cluster. Body must be JSON: cluster_id: int. METHOD: DELETE', } return dict(help=data) @@ -243,11 +246,18 @@ def add_acl(haproxy_id): return api_funct.add_acl(haproxy_id) -@route('/ha/create', method=['POST']) +@route('/ha', method=['GET', 'POST', 'PUT', 'DELETE']) def create_ha(): - if not check_login(required_service=3): + if not check_login(required_service=5): return dict(error=_error_auth) - return api_funct.install_keepalived() + if request.method == 'POST': + return api_funct.create_ha_cluster() + elif request.method == 'PUT': + return api_funct.update_cluster() + elif request.method == 'DELETE': + return api_funct.delete_ha_cluster() + elif request.method == 'GET': + return api_funct.cluster_list() @route('//', method=['GET']) diff --git a/api/api_funct.py b/api/api_funct.py index b7254d91..24ebe496 100644 --- a/api/api_funct.py +++ b/api/api_funct.py @@ -18,6 +18,7 @@ import modules.roxywi.user as roxywi_user import modules.roxywi.common as roxywi_common import modules.service.common as service_common import modules.service.installation as service_mod +import modules.service.ha_cluster as ha_cluster get_config_var = roxy_wi_tools.GetConfigVar() @@ -828,67 +829,96 @@ def create_server(): return dict(data) -def install_keepalived(): - body = request.body.getvalue().decode('utf-8') - json_loads = json.loads(body) - master = json_loads['master_ip'] - slave = json_loads['slave_ip'] - vrrp_ip = json_loads['vrrp_ip'] - eth = json_loads['master_eth'] - eth_slave = json_loads['slave_eth'] - haproxy = int(json_loads['haproxy']) - nginx = int(json_loads['nginx']) - virt_server = int(json_loads['virt_server']) - syn_flood = int(json_loads['syn_flood']) - return_to_master = int(json_loads['return_to_master']) - router_id = random.randint(1, 255) - data = {'status': dict()} - data['status'][master] = dict() - data['status'][slave] = dict() - - try: - service_mod.keepalived_master_install(master, eth, eth_slave, vrrp_ip, virt_server, syn_flood, return_to_master, - haproxy, nginx, router_id, 1) - except Exception as e: - data['status'][master]['keepalived'] = f'error: {e}' - else: - data['status'][master]['keepalived'] = 'done' - - try: - service_mod.keepalived_slave_install(master, slave, eth, eth_slave, vrrp_ip, syn_flood, haproxy, nginx, router_id, 1) - except Exception as e: - data['status'][slave]['keepalived'] = f'error: {e}' - else: - data['status'][slave]['keepalived'] = 'done' - - if haproxy: - try: - service_mod.install_haproxy(master, 1) - except Exception as e: - data['status'][master]['haproxy'] = f'error: {e}' - else: - data['status'][master]['haproxy'] = 'done' - - try: - service_mod.install_haproxy(slave, 1) - except Exception as e: - data['status'][slave]['haproxy'] = f'error: {e}' - else: - data['status'][slave]['haproxy'] = 'done' - - if nginx: - try: - service_mod.install_service(master, 'nginx', '0', 1) - except Exception as e: - data['status'][master]['nginx'] = f'error: {e}' - else: - data['status'][master]['nginx'] = 'done' - - try: - service_mod.install_service(slave, 'nginx', '0', 1) - except Exception as e: - data['status'][slave]['nginx'] = f'error: {e}' - else: - data['status'][slave]['nginx'] = 'done' +def cluster_list(): + token = request.headers.get('token') + login, group_id, role_id = sql.get_username_groupid_from_api_token(token) + clusters = sql.select_clusters(group_id) + data = {} + for cluster in clusters: + data.setdefault(cluster.id, cluster.name) return dict(data) + + +def create_ha_cluster(): + token = request.headers.get('token') + body = request.body.getvalue().decode('utf-8') + json_loads = json.loads(body) + login, group_id, role_id = sql.get_username_groupid_from_api_token(token) + data = {'status': dict()} + + try: + ha_cluster.create_cluster(json_loads, group_id) + except Exception as e: + data['status'] = f'error: Cannot create HA cluster: {e}' + return data['status'] + try: + service_mod.install_service('keepalived', body) + except Exception as e: + data['status'].setdefault('keepalived', f'error: {e}') + else: + data['status'].setdefault('keepalived', 'done') + + if json_loads['services']['haproxy']['enabled']: + try: + service_mod.install_service('haproxy', body) + except Exception as e: + data['status'].setdefault('haproxy', f'error: {e}') + else: + data['status'].setdefault('haproxy', 'done') + + if json_loads['services']['nginx']['enabled']: + try: + service_mod.install_service('nginx', body) + except Exception as e: + data['status'].setdefault('nginx', f'error: {e}') + else: + data['status'].setdefault('nginx', 'done') + + return dict(data) + + +def update_cluster(): + token = request.headers.get('token') + body = request.body.getvalue().decode('utf-8') + json_loads = json.loads(body) + login, group_id, role_id = sql.get_username_groupid_from_api_token(token) + data = {'status': dict()} + + try: + ha_cluster.update_cluster(json_loads, group_id) + except Exception as e: + data['status'] = f'error: Cannot create HA cluster: {e}' + return data['status'] + + if json_loads['services']['haproxy']['enabled']: + try: + service_mod.install_service('haproxy', body) + except Exception as e: + data['status'].setdefault('haproxy', f'error: {e}') + else: + data['status'].setdefault('haproxy', 'done') + + if json_loads['services']['nginx']['enabled']: + try: + service_mod.install_service('nginx', body) + except Exception as e: + data['status'].setdefault('nginx', f'error: {e}') + else: + data['status'].setdefault('nginx', 'done') + + return dict(data) + + +def delete_ha_cluster(): + body = request.body.getvalue().decode('utf-8') + json_loads = json.loads(body) + cluster_id = json_loads['cluster_id'] + data = {'status': dict()} + try: + ha_cluster.delete_cluster(cluster_id) + except Exception as e: + data['status'] = f'error: {e}' + else: + data['status'] = 'done' + return dict(data) diff --git a/app/modules/service/ha_cluster.py b/app/modules/service/ha_cluster.py index c9173ccc..c5d4d5f2 100644 --- a/app/modules/service/ha_cluster.py +++ b/app/modules/service/ha_cluster.py @@ -111,8 +111,9 @@ def update_cluster(cluster: object, group_id: int) -> str: def delete_cluster(cluster_id: int) -> str: + router_id = sql.get_router_id(cluster_id, default_router=1) + slaves = sql.select_cluster_slaves(cluster_id, router_id) HaCluster.delete().where(HaCluster.id == cluster_id).execute() - slaves = sql.select_cluster_slaves(cluster_id) for slave in slaves: slave_ip = sql.select_server_ip_by_id(slave.server_id) diff --git a/app/modules/service/installation.py b/app/modules/service/installation.py index dbba5c0f..f11fc413 100644 --- a/app/modules/service/installation.py +++ b/app/modules/service/installation.py @@ -184,7 +184,6 @@ def grafana_install(): def generate_kp_inv(json_data: json, install_service) -> object: - json_data = json.loads(json_data) inv = {"server": {"hosts": {}}} server_ips = [] cluster_id = int(json_data['cluster_id']) @@ -224,7 +223,6 @@ def generate_kp_inv(json_data: json, install_service) -> object: def generate_haproxy_inv(json_data: json, install_service: str) -> object: - json_data = json.loads(json_data) inv = {"server": {"hosts": {}}} slaves = [] server_ips = [] @@ -276,7 +274,6 @@ def generate_haproxy_inv(json_data: json, install_service: str) -> object: def generate_service_inv(json_data: json, install_service: str) -> object: - json_data = json.loads(json_data) inv = {"server": {"hosts": {}}} server_ips = [] stats_user = sql.get_setting(f'{install_service}_stats_user') @@ -384,7 +381,6 @@ def run_ansible(inv: object, server_ips: str, ansible_role: str) -> object: def service_actions_after_install(server_ips: str, service: str, json_data) -> None: is_docker = None - json_data = json.loads(json_data) update_functions = { 'haproxy': sql.update_haproxy, 'nginx': sql.update_nginx, @@ -405,3 +401,24 @@ def service_actions_after_install(server_ips: str, service: str, json_data) -> N if is_docker == '1' and service != 'keepalived': sql.insert_or_update_service_setting(server_id, service, 'dockerized', '1') sql.insert_or_update_service_setting(server_id, service, 'restart', '1') + + +def install_service(service: str, json_data: object) -> object: + try: + json_data = json.loads(json_data) + except Exception as e: + raise Exception(f'error: Cannot parse JSON: {e}') + + generate_functions = { + 'haproxy': generate_haproxy_inv, + 'nginx': generate_service_inv, + 'apache': generate_service_inv, + 'keepalived': generate_kp_inv, + } + + try: + inv, server_ips = generate_functions[service](json_data, service) + service_actions_after_install(server_ips, service, json_data) + return run_ansible(inv, server_ips, service), 201 + except Exception as e: + raise Exception(f'error: Cannot install {service}: {e}') diff --git a/app/routes/install/routes.py b/app/routes/install/routes.py index 11b503cf..4b65723b 100644 --- a/app/routes/install/routes.py +++ b/app/routes/install/routes.py @@ -39,19 +39,7 @@ def install_monitoring(): @check_services def install_service(service): json_data = request.form.get('jsonData') - generate_functions = { - 'haproxy': service_mod.generate_haproxy_inv, - 'nginx': service_mod.generate_service_inv, - 'apache': service_mod.generate_service_inv, - 'keepalived': service_mod.generate_kp_inv, - } - - try: - inv, server_ips = generate_functions[service](json_data, service) - service_mod.service_actions_after_install(server_ips, service, json_data) - return service_mod.run_ansible(inv, server_ips, service), 201 - except Exception as e: - return str(e) + service_mod.install_service(service, json_data) @bp.route('//version/')