#!/usr/bin/python
# -*- coding: UTF-8 -*-
# Copyright (c) Huawei Technologies Co., Ltd. 2022-2023. All rights reserved.
import traceback
import functools
from json.decoder import JSONDecodeError

import utils.common.log as logger
from utils.common.exception import HCCIException
from plugins.DistributedStorage.common.constants import Constant
from plugins.DistributedStorage.common.rest_client import RestClient
from plugins.DistributedStorage.common.response_parse import ResponseParse
from plugins.DistributedStorage.utils.common.deploy_constant import DeployConstant


def singleton_with_ip(cls):
    _instance = {}

    @functools.wraps(cls)
    def _singleton(*args, **kwargs):
        float_ip = args[0].get("float_ip")
        if float_ip not in _instance:
            _instance_node = dict()
            _instance_node[cls] = cls(*args, **kwargs)
            _instance[float_ip] = _instance_node
        else:
            if cls not in _instance.get(float_ip):
                try:
                    _instance[float_ip][cls] = cls(*args, **kwargs)
                except KeyError as e:
                    logger.error('Key not exist.Detail:%s' % str(e))
                    raise e
        try:
            _instance_float_ip_cls = _instance[float_ip][cls]
        except KeyError as e:
            logger.error('Key not exist.Detail:%s' % str(e))
            raise e
        return _instance_float_ip_cls
    return _singleton


@singleton_with_ip
class UpgradeOperate(object):
    def __init__(self, fs_info=None, float_ip=None):
        self.float_ip = fs_info.get("float_ip") if fs_info else float_ip
        self.port = DeployConstant.PORT
        self.rest_client = RestClient(self.float_ip, self.port)
        self.sys_esn = None
        self.https = "https://"

    def try_login(self, username, password):
        ret_result, ret_data = self.get_session()
        logger.info("current session(%s, %s)" % (ret_result, ret_data))
        if ret_result.get("code") != 0:
            return self.login(username, password)
        for resp in ret_data:
            if resp["status"] != '1':
                return self.login(username, password)
        return 200, 0, ""

    def login(self, username, password):
        res = []
        try:
            res = self.rest_client.login(username, password)
        except Exception as e:
            logger.error(traceback.format_exc())
            logger.error(str(res))
            raise HCCIException(621001, str(e)) from e
        result = ResponseParse(res)
        status_code, error_code, error_des = result.get_res_code()
        if status_code == 200 and error_code == 0:
            token = result.get_login_token()
            self.sys_esn = result.get_system_esn()
            self.rest_client.set_cookie(token)
        return status_code, error_code, error_des

    def logout(self):
        res = []
        uri = '/api/v2/aa/sessions?is_timeout=false'
        url = self.https + self.float_ip + ":" + self.port + uri
        try:
            res = self.rest_client.normal_request(url, 'delete')
        except Exception as exc:
            logger.error(traceback.format_exc())
            logger.error(str(res))
            logger.error("logout failed, exc: {}".format(exc))
            return {"code": "-1"}, {}
        result = ResponseParse(res)
        _, ret_result, ret_data = result.get_rsp_data()
        return ret_result, ret_data

    def get_session(self):
        res = []
        uri = '/api/v2/aa/current_session'
        url = self.https + self.float_ip + ":" + self.port + uri
        res = []
        try:
            res = self.rest_client.normal_request(url, 'get')
        except Exception as exc:
            logger.error(traceback.format_exc())
            logger.error(str(res))
            logger.error("get_session failed, exc: {}".format(exc))
            return {"code": "-1"}, {}
        result = ResponseParse(res)
        _, ret_result, ret_data = result.get_rsp_data()
        return ret_result, ret_data

    def package_validaty(self, package_name, package_size):
        res = []
        uri = "/api/v2/upgrade/upgrade_package_validaty"
        url = self.https + self.float_ip + ":" + self.port + uri
        data = {
            "package_name": package_name,
            "package_size": package_size
            }
        try:
            res = self.rest_client.normal_request(url, 'post', data)
        except Exception as e:
            logger.error(str(res))
            logger.error(traceback.format_exc())
            raise HCCIException(621004, str(e)) from e
        try:
            logger.info(res.json())
        except JSONDecodeError as e:
            logger.error(str(res))
            raise HCCIException(621004, "Response is not json type, details: {}".format(str(res))) from e
        result = ResponseParse(res)
        _, ret_result, ret_data = result.get_rsp_data()
        return ret_result, ret_data

    def get_upg_mode(self):
        res = []
        uri = "/api/v2/upgrade/upgrade_mode"
        url = self.https + self.float_ip + ":" + self.port + uri
        try:
            res = self.rest_client.normal_request(url, 'get')
        except Exception as e:
            logger.error(str(res))
            logger.error(traceback.format_exc())
            raise HCCIException(621004, str(e)) from e
        try:
            logger.info(res.json())
        except JSONDecodeError as e:
            logger.error(str(res))
            raise HCCIException(621004, "Response is not json type: {}".format(str(res))) from e
        result = ResponseParse(res)
        _, ret_result, ret_data = result.get_rsp_data()
        return ret_result, ret_data

    def set_upg_mode(self, mode="2"):
        res = []
        uri = "/api/v2/upgrade/upgrade_mode"
        url = self.https + self.float_ip + ":" + self.port + uri
        data = {
            "upgrade_mode": mode
            }
        try:
            res = self.rest_client.normal_request(url, 'put', data)
        except Exception as e:
            logger.error(traceback.format_exc())
            logger.error(str(res))
            raise HCCIException(621004, str(e)) from e
        try:
            logger.info(res.json())
        except JSONDecodeError as e:
            logger.error(str(res))
            raise HCCIException(621004, "Response is not json type: %s" % str(res)) from e
        result = ResponseParse(res)
        _, ret_result, ret_data = result.get_rsp_data()
        return ret_result, ret_data

    def upload_upg_pkg(self, pkg_path):
        res = []
        uri = "/api/v2/upgrade/upgrade_packages"
        url = self.https + self.float_ip + ":" + self.port + uri
        try:
            res = self.rest_client.upload_tar_request_stream(url, 'post', pkg_path)
        except Exception as e:
            logger.error(traceback.format_exc())
            logger.error(str(res))
            raise HCCIException(621004, str(e)) from e
        try:
            logger.info(res.json())
        except JSONDecodeError as e:
            logger.error(str(res))
            raise HCCIException(621004, "Response is not json type: %s" % str(res)) from e
        result = ResponseParse(res)
        _, ret_result, ret_data = result.get_rsp_data()
        return ret_result, ret_data

    def pre_check(self):
        res = []
        uri = "/api/v2/upgrade/precheck"
        url = self.https + self.float_ip + ":" + self.port + uri
        data = {}
        try:
            res = self.rest_client.normal_request(url, 'post', data)
        except Exception as e:
            logger.error(traceback.format_exc())
            logger.error(str(res))
            raise HCCIException(621004, str(e)) from e
        try:
            logger.info(res.json())
        except JSONDecodeError as e:
            logger.error(str(res))
            raise HCCIException(621004, "Response is not json type: %s" % str(res)) from e
        result = ResponseParse(res)
        _, ret_result, ret_data = result.get_rsp_data()
        return ret_result, ret_data

    def get_pre_check_status(self):
        res = []
        uri = "/api/v2/upgrade/precheck_status"
        url = self.https + self.float_ip + ":" + self.port + uri
        try:
            res = self.rest_client.normal_request(url, 'get')
        except Exception as e:
            logger.error(traceback.format_exc())
            logger.error(str(res))
            raise HCCIException(621004, str(e)) from e
        try:
            logger.info(res.json())
        except JSONDecodeError as e:
            logger.error(str(res))
            raise HCCIException(621004, "Response is not json type: %s" % str(res)) from e
        result = ResponseParse(res)
        _, ret_result, ret_data = result.get_rsp_data()
        return ret_result, ret_data

    def upgrade_task(self):
        res = []
        uri = "/api/v2/upgrade/upgrade_task"
        url = self.https + self.float_ip + ":" + self.port + uri
        data = {}
        try:
            res = self.rest_client.normal_request(url, 'post', data)
        except Exception as e:
            logger.error(traceback.format_exc())
            logger.error(str(res))
            raise HCCIException(621004, str(e)) from e
        try:
            logger.info(res.json())
        except JSONDecodeError as e:
            logger.error(str(res))
            raise HCCIException(621004, "Response is not json type: %s" % str(res)) from e
        result = ResponseParse(res)
        _, ret_result, ret_data = result.get_rsp_data()
        return ret_result, ret_data

    def get_upgrade_task(self):
        res = []
        uri = "/api/v2/upgrade/task"
        url = self.https + self.float_ip + ":" + self.port + uri
        try:
            res = self.rest_client.normal_request(url, 'get')
        except Exception as e:
            logger.error(traceback.format_exc())
            logger.error(str(res))
            raise HCCIException(621004, str(e)) from e
        try:
            logger.info(res.json())
        except JSONDecodeError as e:
            logger.error(str(res))
            raise HCCIException(621004, "Response is not json type: %s" % str(res)) from e
        result = ResponseParse(res)
        _, ret_result, ret_data = result.get_rsp_data()
        return ret_result, ret_data

    def get_upgrade_status(self, error_code=621004):
        res = []
        uri = "/api/v2/upgrade/upgrade_status"
        url = self.https + self.float_ip + ":" + self.port + uri
        try:
            res = self.rest_client.normal_request(url, 'get')
        except Exception as e:
            logger.error(traceback.format_exc())
            logger.error(str(res))
            raise HCCIException(error_code, str(e)) from e
        try:
            logger.info(res.json())
        except JSONDecodeError as e:
            logger.error(str(res))
            raise HCCIException(error_code, "Response is not json type: %s" % str(res)) from e
        result = ResponseParse(res)
        _, ret_result, ret_data = result.get_rsp_data()
        return ret_result, ret_data

    def post_check(self):
        res = []
        uri = "/api/v2/upgrade/postcheck"
        url = self.https + self.float_ip + ":" + self.port + uri
        data = {}
        try:
            res = self.rest_client.normal_request(url, 'post', data)
        except Exception as e:
            logger.error(traceback.format_exc())
            logger.error(str(res))
            raise HCCIException(621004, str(e)) from e
        try:
            logger.info(res.json())
        except JSONDecodeError as e:
            logger.error(str(res))
            raise HCCIException(621004, "Response is not json type: %s" % str(res)) from e
        result = ResponseParse(res)
        _, ret_result, ret_data = result.get_rsp_data()
        return ret_result, ret_data

    def get_post_check_result(self):
        res = []
        uri = "/api/v2/deploy_manager/micro_service_postcheck_result"
        url = self.https + self.float_ip + ":" + self.port + uri
        try:
            res = self.rest_client.normal_request(url, 'get')
        except Exception as e:
            logger.error(traceback.format_exc())
            logger.error(str(res))
            raise HCCIException(621004, str(e)) from e
        try:
            logger.info(res.json())
        except JSONDecodeError as e:
            logger.error(str(res))
            raise HCCIException(621004, "Response is not json type: %s" % str(res)) from e
        result = ResponseParse(res)
        _, ret_result, ret_data = result.get_rsp_data()
        return ret_result, ret_data

    def retry_upgrade_task(self):
        res = []
        uri = "/api/v2/upgrade/upgrade_retry_task"
        url = self.https + self.float_ip + ":" + self.port + uri
        data = {}
        try:
            res = self.rest_client.normal_request(url, 'post', data)
        except Exception as e:
            logger.error(traceback.format_exc())
            logger.error(str(res))
            raise HCCIException(621004, str(e)) from e
        try:
            logger.info(res.json())
        except JSONDecodeError as e:
            logger.error(str(res))
            raise HCCIException(621004, "Response is not json type: %s" % str(res)) from e
        result = ResponseParse(res)
        _, ret_result, ret_data = result.get_rsp_data()
        return ret_result, ret_data

    def rollback_upgrade_task(self):
        res = []
        uri = "/api/v2/upgrade/rollback_task"
        url = self.https + self.float_ip + ":" + self.port + uri
        data = {}
        try:
            res = self.rest_client.normal_request(url, 'post', data)
        except Exception as e:
            logger.error(traceback.format_exc())
            logger.error(str(res))
            raise HCCIException(621004, str(e)) from e
        try:
            logger.info(res.json())
        except JSONDecodeError as e:
            logger.error(str(res))
            raise HCCIException(621004, "Response is not json type: %s" % str(res)) from e
        result = ResponseParse(res)
        _, ret_result, ret_data = result.get_rsp_data()
        return ret_result, ret_data

    def upgrade_confirm(self):
        res = []
        uri = "/api/v2/upgrade/upgrade_confirm"
        url = self.https + self.float_ip + ":" + self.port + uri
        data = {}
        try:
            res = self.rest_client.normal_request(url, 'post', data)
        except Exception as e:
            logger.error(traceback.format_exc())
            logger.error(str(res))
            raise HCCIException(621004, str(e)) from e
        try:
            logger.info(res.json())
        except JSONDecodeError as e:
            logger.error(str(res))
            raise HCCIException(621004, "Response is not json type: %s" % str(res)) from e
        result = ResponseParse(res)
        _, ret_result, ret_data = result.get_rsp_data()
        return ret_result, ret_data

    def get_alarm(self, alarm_filter):
        res = []
        uri = Constant.GET_ALARM_URL + "?filter=" + alarm_filter
        url = self.https + self.float_ip + ":" + self.port + uri
        try:
            res = self.rest_client.normal_request(url, 'get')
        except Exception as e:
            logger.error(traceback.format_exc())
            logger.error(str(res))
            raise HCCIException(621004, str(e)) from e
        try:
            logger.info(res.json())
        except JSONDecodeError as e:
            logger.error(str(res))
            raise HCCIException(621004, "Response is not json type: %s" % str(res)) from e
        result = ResponseParse(res)
        _, ret_result, ret_data = result.get_rsp_data()
        return ret_result, ret_data

    def get_alarm_count(self, alarm_filter=None):
        res = []
        if not alarm_filter:
            uri = Constant.GET_ALARM_COUNT_URL
        else:
            uri = Constant.GET_ALARM_COUNT_URL + "?filter=" + alarm_filter
        url = self.https + self.float_ip + ":" + self.port + uri
        try:
            res = self.rest_client.normal_request(url, 'get')
        except Exception as e:
            logger.error(traceback.format_exc())
            logger.error(str(res))
            raise HCCIException(621004, str(e)) from e
        try:
            logger.info(res.json())
        except JSONDecodeError as e:
            logger.error(str(res))
            raise HCCIException(621004, "Response is not json type: %s" % str(res)) from e
        result = ResponseParse(res)
        _, ret_result, ret_data = result.get_rsp_data()
        return ret_result, ret_data

    def get_storage_pool(self):
        res = []
        uri = "/dsware/service/v1.3/storagePool"
        url = self.https + self.float_ip + ":" + self.port + uri
        try:
            res = self.rest_client.normal_request(url, 'get')
        except Exception as e:
            logger.error(traceback.format_exc())
            logger.error(str(res))
            raise HCCIException(621004, str(e)) from e
        try:
            logger.info(res.json())
        except JSONDecodeError as e:
            logger.error(str(res))
            raise HCCIException(621004, "Response is not json type: %s" % str(res)) from e
        result = ResponseParse(res)
        _, ret_result, ret_data = result.get_result_data()
        return ret_result, ret_data

    def get_node_disk(self, pool_id):
        res = []
        uri = "/dsware/service/cluster/storagepool/queryNodeDiskInfo" \
              "?poolId={}".format(pool_id)
        url = self.https + self.float_ip + ":" + self.port + uri
        try:
            res = self.rest_client.normal_request(url, 'get')
        except Exception as e:
            logger.error(str(res))
            logger.error(traceback.format_exc())
            raise HCCIException(621004, str(e)) from e
        try:
            logger.info(res.json())
        except JSONDecodeError as e:
            logger.error(str(res))
            raise HCCIException(621004, "Response is not json type, details: %s" % str(res)) from e
        result = ResponseParse(res)
        _, ret_result, ret_data = result.get_result_data()
        return ret_result, ret_data

    def start_inspection(self, nodes_list, inspections_list):
        res = []
        uri = "/api/v2/cluster/inspection"
        url = self.https + self.float_ip + ":" + self.port + uri
        data = {"items": inspections_list, "nodes": nodes_list}
        try:
            res = self.rest_client.normal_request(url, 'post', data)
        except Exception as e:
            logger.error(traceback.format_exc())
            logger.error(str(res))
            raise HCCIException(621004, str(e)) from e
        try:
            logger.info(res.json())
        except JSONDecodeError as e:
            logger.error(str(res))
            raise HCCIException(621004, "Response is not json type: {}".format(str(res))) from e
        result = ResponseParse(res)
        _, ret_result, ret_data = result.get_rsp_data()
        return ret_result, ret_data

    def get_inspection_status(self, task_id, inspections_list):
        res = []
        uri = "/api/v2/cluster/inspection/"
        url = self.https + self.float_ip + ":" + self.port + uri + task_id
        data = {
            "items": inspections_list
            }
        try:
            res = self.rest_client.normal_request(url, 'post', data)
        except Exception as e:
            logger.error(traceback.format_exc())
            logger.error(str(res))
            raise HCCIException(621004, str(e)) from e
        try:
            logger.info(res.json())
        except JSONDecodeError as e:
            logger.error(str(res))
            raise HCCIException(621004, "Response is not json type:%s" % str(res)) from e
        result = ResponseParse(res)
        _, ret_result, ret_data = result.get_rsp_data()
        return ret_result, ret_data

    def get_disk(self):
        res = []
        uri = "/dsware/service/v1.3/server/list"
        url = self.https + self.float_ip + ":" + self.port + uri
        try:
            res = self.rest_client.normal_request(url, 'get')
        except Exception as e:
            logger.error(traceback.format_exc())
            logger.error(str(res))
            raise HCCIException(621004, str(e)) from e
        try:
            logger.info(res.json())
        except JSONDecodeError as e:
            logger.error(str(res))
            raise HCCIException(621004, "Response is not json type:%s" % str(res)) from e
        result = ResponseParse(res)
        _, ret_result, ret_data = result.get_result_data()
        return ret_result, ret_data

    def get_servers(self):
        res = []
        uri = "/api/v2/cluster/servers"
        url = self.https + self.float_ip + ":" + self.port + uri
        try:
            res = self.rest_client.normal_request(url, 'get')
        except Exception as e:
            logger.error(traceback.format_exc())
            logger.error(str(res))
            raise HCCIException(621004, str(e)) from e
        try:
            logger.info(res.json())
        except JSONDecodeError as e:
            logger.error(str(res))
            raise HCCIException(621004, "Response is not json type: %s" % str(res)) from e
        result = ResponseParse(res)
        _, ret_result, ret_data = result.get_rsp_data()
        return ret_result, ret_data

    def get_pmi_resource(self, res_file):
        res = []
        uri = "/api/v2/cluster/resource_files?resource_type=inspection"
        url = self.https + self.float_ip + ":" + self.port + uri
        try:
            res = self.rest_client.download_request(url, res_file)
        except Exception as e:
            logger.error(traceback.format_exc())
            logger.error(str(res))
            raise HCCIException(621004, str(e)) from e
        result = ResponseParse(res)
        _, ret_result, ret_data = result.get_download_data()
        return ret_result, ret_data

    def get_product(self):
        res = []
        url = self.https + self.float_ip + ":" + self.port + Constant.PRODUCT_URL
        try:
            res = self.rest_client.normal_request(url, 'get')
        except Exception as e:
            logger.error(traceback.format_exc())
            logger.error(str(res))
            raise HCCIException(621004, str(e)) from e
        try:
            logger.info(res.json())
        except JSONDecodeError as e:
            logger.error(str(res))
            raise HCCIException(621004, "Response is not json type: {}".format(str(res))) from e
        result = ResponseParse(res)
        _, ret_result, ret_data = result.get_rsp_data()
        return ret_result, ret_data

    def download_inspection_result(self, task_id, res_file, item_id, node_ip):
        res = []
        uri = Constant.DOWNLOAD_INSPECTION_URL + task_id + "?item_id=" + item_id + "&node_ip=" + node_ip
        url = self.https + self.float_ip + ":" + self.port + uri
        try:
            res = self.rest_client.download_request(url, res_file)
        except JSONDecodeError as e:
            raise HCCIException(621004, "Response is not json type: %s" % str(res)) from e
        except Exception as e:
            logger.error(traceback.format_exc())
            raise HCCIException(621004, str(e)) from e
        result = ResponseParse(res)
        _, ret_result, ret_data = result.get_download_data()
        return ret_result, ret_data

    def get_upgrade_packages(self):
        res = []
        uri = "/api/v2/upgrade/upgrade_packages"
        url = self.https + self.float_ip + ":" + self.port + uri
        try:
            res = self.rest_client.normal_request(url, 'get')
        except Exception as e:
            logger.error(traceback.format_exc())
            logger.error(str(res))
            raise HCCIException(621004, str(e)) from e
        try:
            logger.info(res.json())
        except JSONDecodeError as e:
            logger.error(str(res))
            raise HCCIException(621004, "Response is not json type: %s" % str(res)) from e
        result = ResponseParse(res)
        _, ret_result, ret_data = result.get_rsp_data()
        return ret_result, ret_data

    def get_esn(self):
        res = []
        uri = "/api/v2/common/esn"
        url = self.https + self.float_ip + ":" + self.port + uri
        try:
            res = self.rest_client.normal_request(url, 'get')
        except Exception as e:
            logger.error(traceback.format_exc())
            logger.error(str(res))
            raise HCCIException(621004, str(e)) from e
        try:
            logger.info(res.json())
        except JSONDecodeError as e:
            logger.error(str(res))
            raise HCCIException(621004, "Response is not json type: %s" % str(res)) from e
        result = ResponseParse(res)
        _, ret_result, ret_data = result.get_rsp_data()
        return ret_result, ret_data

    def get_version(self):
        res = []
        uri = "/api/v2/cluster/product"
        url = self.https + self.float_ip + ":" + self.port + uri
        try:
            res = self.rest_client.normal_request(url, 'get')
        except Exception as e:
            logger.error(traceback.format_exc())
            logger.error(str(res))
            raise HCCIException(621004, str(e)) from e
        try:
            logger.info(res.json())
        except JSONDecodeError as e:
            logger.error("Response is not json type, details:{}".format(e))
            raise HCCIException(621004, "Response is not json type: %s" % str(res)) from e
        result = ResponseParse(res)
        _, ret_result, ret_data = result.get_rsp_data()
        return ret_result, ret_data

    def do_self_upgrade(self):
        res = []
        uri = "/api/v2/cluster/self_upgrade"
        url = self.https + self.float_ip + ":" + self.port + uri
        try:
            res = self.rest_client.normal_request(url, 'post')
        except Exception as e:
            logger.error(traceback.format_exc())
            logger.error(str(res))
            raise HCCIException(621004, str(e)) from e
        try:
            logger.info(res.json())
        except JSONDecodeError as e:
            logger.error(str(res))
            raise HCCIException(621004, "Response is not json type: %s" % str(res)) from e
        result = ResponseParse(res)
        _, ret_result, ret_data = result.get_rsp_data()
        return ret_result, ret_data

    def query_task_progress(self, task_name):
        res = []
        uri = "/api/v2/cluster/progress"
        url = self.https + self.float_ip + ":" + self.port + uri + "?task_name=" + task_name
        try:
            res = self.rest_client.normal_request(url, 'get')
        except Exception as e:
            logger.error(traceback.format_exc())
            logger.error(str(res))
            raise HCCIException(621004, str(e)) from e
        try:
            logger.info(res.json())
        except JSONDecodeError as e:
            logger.error(str(res))
            raise HCCIException(621004, "Response is not json type: %s" % str(res)) from e
        result = ResponseParse(res)
        _, ret_result, ret_data = result.get_rsp_data()
        return ret_result, ret_data

    def enable_os_sandbox(self, node_ips):
        res = []
        uri = "/api/v2/cluster/sandbox"
        url = self.https + self.float_ip + ":" + self.port + uri
        body = {'start': {'node_ips': node_ips}}
        try:
            res = self.rest_client.normal_request(url, 'post', body)
        except Exception as e:
            logger.error(traceback.format_exc())
            logger.error(str(res))
            raise HCCIException(621004, str(e)) from e
        try:
            resp = res.json()
        except JSONDecodeError as e:
            logger.error(str(res))
            raise HCCIException(621004, "Response is not json type: %s" % str(res)) from e
        result, data = resp.get('result'), resp.get('data')
        if result.get('code') != 0:
            err_msg = 'Failed to enable sandbox configuration info, details: {}'.format(resp)
            logger.error(err_msg)
            raise Exception(err_msg)
        return data

    def disable_os_sandbox(self, node_info):
        res = []
        uri = "/api/v2/cluster/sandbox"
        url = self.https + self.float_ip + ":" + self.port + uri
        body = {'stop': node_info}
        try:
            res = self.rest_client.normal_request(url, 'post', body)
        except Exception as e:
            logger.error(traceback.format_exc())
            logger.error(str(res))
            raise HCCIException(621004, str(e)) from e
        try:
            resp = res.json()
        except JSONDecodeError as e:
            logger.error(str(res))
            raise HCCIException(621004, "Response is not json type: %s" % str(res)) from e
        result, data = resp.get('result'), resp.get('data')
        if result.get('code') != 0:
            err_msg = 'Failed to enable sandbox configuration info, details: {}'.format(resp)
            logger.error(err_msg)
            raise Exception(err_msg)
        return data
