#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) Huawei Technologies Co., Ltd. 2022-2023. All rights reserved.
import os
import re

from IPy import IP

import utils.common.log as logger
import utils.constant.constant as constant
from utils.common.exception import HCCIException
from utils.constant.FCDConstant import HYGONLIST
from utils.Driver.CloudDC.OpenStack.Network.networkutils import ManageMentStorageData
from utils.Driver.CloudDC.OpenStack.compute.resource_tracker import ResourceTracker
from utils.Driver.CloudDC.OpenStack.get_host_info import GetHostInfo
from utils.PasswordManager.PasswordManager import FSPasswordManager
from utils.business.project_util import ProjectApi
from utils.client.FSPAuthClient import FSPAuthClient, OpenstackAuthClient
from utils.common.OpenStackNodeManager import OpenStackNodeManager
from utils.common.fic_common import GetConfig
from utils.constant.FCDConstant import BMC_ROLE_INFO, get_compute_dpdk_hosts
from utils.constant.FCDConstant import REGION_CONTROL_HA_SITE as region_site
from utils.constant.constant import REFCOMPONENTCONSTANT
from utils.taskcenter.install_os_lib import InstallOs
from utils.business.project_condition_utils import get_project_condition_boolean
from plugins.DistributedStorage.utils.common.deploy_constant import DeployConstant
from plugins.DistributedStorage.utils.config.device_check import DeviceResource
from plugins.ManageOne.scripts.utils.get_solution import get_solution


class ParamsGain(object):
    def __init__(self, project_id, pod_id, db):
        self.project_id = project_id
        self.pod_id = pod_id
        self.db = db
        webui_client = FSPAuthClient.get_cps_web_client(
            self.db, self.project_id, self.pod_id)
        self.cps_hosts = GetHostInfo(webui_client)
        self.ntp_bool = get_project_condition_boolean(
            self.project_id,
            '!('
            '(TenantStorFBReuse80&(ExpansionAZ_KVM|ExpansionAZ_BMS))'
            '|ExpansionPOD_CloudService'
            '|ExpansionMgmtRes_ServiceNode'
            '|ExpansionScale_CloudServiceNode'
            ')')

    @staticmethod
    def get_vm_params(expand_fusionstorage_args):
        expand_fusionstorage_args["create_vm_task_id"] = "DistributedStorageBusinessStorage"
        expand_fusionstorage_args["create_vm_subtask_id"] = "FS800_BSD_CreateFSMVM"
        expand_fusionstorage_args["create_vm_dsware_name"] = "dsware-server2"
        expand_fusionstorage_args["create_vm_service_name"] = "DistributedStorageBusiness"
        expand_fusionstorage_args["create_vm_fsm_scale"] = "business_fsm_scale"

    @staticmethod
    def get_role_resource(exp_fs_args, vbs_list):
        controller_osd_bmc_list = [vbs.get('bmc_ip') for vbs in vbs_list]
        vbs_cpu = 4
        vbs_memory = 7
        exp_fs_args['vbs_cpu'] = vbs_cpu
        exp_fs_args['vbs_memory'] = vbs_memory
        exp_fs_args['vbs_bmc_ip_list'] = list(controller_osd_bmc_list)

    @staticmethod
    def get_vm_params_when_manage_converge(manage_converge_args):
        if manage_converge_args["scene"] == "RegionConHA" and manage_converge_args["mode"] == "ha_standy":
            manage_converge_args["create_vm_subtask_id"] = "FS800_MCD_SetB_CreateFSMVM"
            manage_converge_args["create_vm_dsware_name"] = "dsware-server2"
        else:
            manage_converge_args["create_vm_subtask_id"] = "FS800_MCD_SetA_CreateFSMVM"
            manage_converge_args["create_vm_dsware_name"] = "dsware-server1"
        manage_converge_args["create_vm_task_id"] = "DistributedStorageManageStorage"
        manage_converge_args["create_vm_service_name"] = "DistributedStorageManage"
        manage_converge_args["create_vm_fsm_scale"] = "manage_fsm_scale"

    @staticmethod
    def get_osd_node_memory_and_cpu(cache_capacity, cache_type, osd_cpu, primary_capacity, storage_slot):
        device_resource = DeviceResource()
        if cache_type == 'none':
            osd_cpu = 12
            osd_memory = device_resource.get_fsa_memory_800(
                storage_slot, cache_capacity, primary_capacity, is_none_cache=True, condition='manageFB')
        else:
            osd_memory = device_resource.get_fsa_memory_800(
                storage_slot, cache_capacity, primary_capacity, is_none_cache=False, condition='manageFB')
        return osd_cpu, osd_memory

    @staticmethod
    def cloud_service_not_osd_node(osd_role, unit):
        return unit["bmc_role"] == constant.BMCROLE.CLOUD_SERVICE_NODE and osd_role not in unit["ref_component"]

    @staticmethod
    def cloud_service_osd_node(osd_role, unit):
        return unit["bmc_role"] == constant.BMCROLE.CLOUD_SERVICE_NODE and osd_role in unit["ref_component"]

    @staticmethod
    def get_pkg_path(pkg_type):
        conf_obj = GetConfig(path='/platforms/conf/platform.ini')
        default_path = conf_obj.get_item('common', 'software_pkg_path')
        if not default_path:
            default_path = '/home/pkg'

        pkg_name_like = None
        is_type = True
        if pkg_type == 'uvp':
            pkg_name_like = DeployConstant.STORAGE_PACKAGES_PATTERN[4]["OceanStor-Pacific_8.1.*_UVP.tar.gz"]
        elif pkg_type == 'fs':
            pkg_name_like = DeployConstant.STORAGE_PACKAGES_PATTERN[5]["OceanStor-Pacific_8.1.*.tar.gz"]
        else:
            logger.error("No such type")
            is_type = False

        if is_type:
            items = os.listdir(default_path)
            pkg_name = None
            for names in items:
                if len(re.findall(pkg_name_like, names)) > 0:
                    pkg_name = names
                    break
            if not pkg_name:
                err_msg = "The install package of %s is not exist." % pkg_name_like
                logger.error(err_msg)
                raise Exception(err_msg)
            pkg_path = default_path + '/' + pkg_name
        else:
            pkg_path = None
        return pkg_path

    @staticmethod
    def get_pacific_pkg_path(pkg_type):
        conf_obj = GetConfig(path='/platforms/conf/platform.ini')
        default_path = conf_obj.get_item('common', 'software_pkg_path')
        if not default_path:
            default_path = '/home/pkg'

        is_type = True
        pkg_name_like = None
        if pkg_type == 'uvp':
            pkg_name_like = DeployConstant.STORAGE_PACKAGES_PATTERN[4]["OceanStor-Pacific_8.1.*_UVP.tar.gz"]
        elif pkg_type == 'fs':
            pkg_name_like = DeployConstant.STORAGE_PACKAGES_PATTERN[5]["OceanStor-Pacific_8.1.*.tar.gz"]
        else:
            logger.error("No such type")
            is_type = False

        if is_type:
            items = os.listdir(default_path)
            pkg_name = None
            for names in items:
                if len(re.findall(pkg_name_like, names)) > 0:
                    pkg_name = names
                    break
            if not pkg_name:
                err_msg = "The install package of %s is not exist." % pkg_name_like
                logger.error(err_msg)
                raise Exception(err_msg)
            pkg_path = default_path + '/' + pkg_name
        else:
            pkg_path = None
        return pkg_path

    @staticmethod
    def expand_iscsi_info(node_list, all_node_data):
        for node in node_list:
            for node_data in all_node_data:
                if node.get('bmc_ip') == node_data.get('bmc_ip'):
                    node["iscsi_business_plane_ip"] = node_data.get("iscsi_business_plane_ip")

    @staticmethod
    def get_node_extension_info(node_list, all_node_data):
        for node in node_list:
            for node_data in all_node_data:
                if node.get('bmc_ip') == node_data.get('bmc_ip'):
                    node['model'] = node_data.get('equipment_model')
                    node['cabinet'] = node_data.get('rack_id')
                    node['site'] = node_data.get('site', '')

    @staticmethod
    def get_arb_network_config(fs_args, net_infos):
        fs_arb_netmask = fs_args.get("fs_arb_netmask")
        fs_arb_vlan = fs_args.get("fs_arb_vlan")
        if fs_arb_netmask and fs_arb_vlan:
            arbitration_net = {
                "plane": ["replication_plane"],
                "type": "vlan_bond",
                "bond_name": "bond0", "ip_mask": fs_arb_netmask,
                "vlan_id": fs_arb_vlan, "vlan_name": "rep_arb",
                "ip_name": "arbitration_plane_ip"}
            net_infos["arbitration_net"] = arbitration_net

    @staticmethod
    def get_rep_netwrok_config(fs_args, net_infos):
        fs_rep1_netmask = fs_args.get("fs_rep1_netmask")
        fs_rep2_netmask = fs_args.get("fs_rep2_netmask")
        if fs_rep1_netmask and fs_rep2_netmask:
            rep1_bond_net = {
                "plane": ["replication_plane"], "index": "0",
                "type": "bond", "bond_mode": "1",
                "bond_name": "rep0", "ip_mask": fs_rep1_netmask,
                "ip_name": "replication_plane_ip", "nic_pci": None,
                "dev_port": None}
            net_infos["rep1_bond_net"] = rep1_bond_net
            rep2_bond_net = {
                "plane": ["replication_plane"], "index": "1",
                "type": "bond", "bond_mode": "1",
                "bond_name": "rep1", "ip_mask": fs_rep2_netmask,
                "ip_name": "replication_plane_ip", "nic_pci": None,
                "dev_port": None}
            net_infos["rep2_bond_net"] = rep2_bond_net

    @staticmethod
    def get_package(pkg_regular):
        conf_obj = GetConfig(path='/platforms/conf/platform.ini')
        default_path = conf_obj.get_item('common', 'software_pkg_path')
        if not default_path:
            default_path = '/home/pkg'
        items = os.listdir(default_path)
        pkg_name = None
        for names in items:
            if len(re.findall(pkg_regular, names)) > 0:
                pkg_name = names
                break
        if not pkg_name:
            logger.error("The package %s is not exist." % pkg_regular)
            return default_path, ""
        return default_path, pkg_name

    @staticmethod
    def get_osd_node_bmc_info(nodes_info, osd_list):
        osd_bmc_infos = list()
        osd_om_and_bmc_ip = dict()
        for node in osd_list:
            osd_om_and_bmc_ip[node.get('bmc_ip')] = node.get('om_ip')

        for node in nodes_info:
            if node.get("bmc_ip") in osd_om_and_bmc_ip:
                node_bmc_ip = node.get('bmc_ip')
                node['om_ip'] = osd_om_and_bmc_ip.get(node_bmc_ip)
                osd_bmc_infos.append(node)

        bmc_ip_by_nodes_info = {bmc_info.get('bmc_ip') for bmc_info in osd_bmc_infos}
        bmc_ip_by_osd_list = {bmc_info.get('bmc_ip') for bmc_info in osd_list}
        if bmc_ip_by_osd_list.symmetric_difference(bmc_ip_by_nodes_info):
            logger.error('Failed to query the bmc information')
            raise HCCIException(626332, str(osd_om_and_bmc_ip), str(bmc_ip_by_nodes_info))
        logger.info('the bmc ip information: {}'.format(osd_om_and_bmc_ip))

        return osd_bmc_infos

    @staticmethod
    def get_osd_node_storage_slot(all_openstack_nodes, expansion_service_bool=False):
        def filter_osd_node(node_dic):
            return node_dic.get("bmc_role") in bmc_roles and osd_role in node_dic.get("ref_component")
        osd_role = 'osd'
        control_node_role_list = [constant.BMCROLE.FIRST_NODE, constant.BMCROLE.CONTROLLER_NODE,
                                  constant.BMCROLE.CLOUD_SERVICE_NODE]
        cloud_server_list = [constant.BMCROLE.CLOUD_SERVICE_NODE]
        bmc_roles = control_node_role_list if not expansion_service_bool else cloud_server_list
        storage_slots = [unit.get("primary_slot") for unit in all_openstack_nodes if filter_osd_node(unit)]
        max_slot_length = 0
        max_slot = ""
        for one_slot in storage_slots:
            slot_start = int(one_slot.split('-')[0])
            slot_end = int(one_slot.split('-')[1])
            if slot_end - slot_start + 1 > max_slot_length:
                max_slot_length = slot_end - slot_start + 1
                max_slot = one_slot
        logger.info("Get the max slots[%s]" % max_slot)
        return max_slot

    @staticmethod
    def get_control_node_info(all_openstack_nodes):
        def filter_control_nodes(node_info):
            return node_info.get("bmc_role") == constant.BMCROLE.FIRST_NODE or \
                   node_info.get("bmc_role") == constant.BMCROLE.CONTROLLER_NODE

        control_node_info = []
        for unit in all_openstack_nodes:
            if filter_control_nodes(unit):
                control_node_info.append(
                    [unit["cache_capacity"], unit["primary_capacity"], unit["cache_type"], unit['equipment_model']])
        return control_node_info

    def get_business_converge_args(self):
        """
        :return:
        business_converge_args:
            'float_ip浮动ip':
            'ha模式ha_mode':
            '路径install_path':
            'dm初始密码dm_init_pwd':
            'dm修改密码dm_update_pwd':
            'fsa节点列表fsa_list':
                          fsa1:
                              'bmc_ip': ,
                              'om_ip': ,
                              'hostname': ,
                              'root_passwd': ,
                              'user': ,
                              'passwd':,
                          fsa2: ...
            'osd节点列表osd_list':
                          osd1:
                              'bmc_ip': ,
                              'om_ip': ,
                              'hostname': ,
                              'root_passwd': ,
                              'user': ,
                              'passwd':
                         osd2:...
            'vbs节点列表vbs_list':
                         vbs1:
                             'bmc_ip': ,
                             'om_ip': ,
                             'hostname': ,
                             'root_passwd': ,
                              'user': ,
                              'passwd':,
                        vbs2:...
        """
        business_converge_args = dict()
        business_converge_args['az_id'] = self.get_az_id()
        self.get_fsm_pwd_info(business_converge_args)
        all_business_converge_args = self.db.get_all_data_with_key_value(self.pod_id, "DistributedStorageBusiness")
        business_converge_args['float_ip'] = all_business_converge_args.get('FSMOMFloatingIP02', 'unKnown')
        business_converge_args['ha_mode'] = DeployConstant.HA_MODE
        business_converge_args['backend_name'] = self.db.get_user_input_cloud_param_by_key(
            self.project_id, "business_backendstorage_name")

        all_node_data, fsa_list, osd_list, vbs_list = self.get_node_info_when_business_converge(business_converge_args)
        # 安装角色
        self.get_role_source_when_business_converge(all_node_data, business_converge_args, osd_list, vbs_list)

        # 配置存储网络
        frontend_storage_network_list = self.get_business_compute_node_storage_network()
        business_converge_args['frontend_storage_network_list'] = frontend_storage_network_list
        business_converge_args['backend_storage_network_list'] = frontend_storage_network_list

        # 创建客户端
        business_converge_args['iscsi_condition'] = get_project_condition_boolean(self.project_id, 'TenantStorFB_iSCSI')
        business_converge_args['vbs_client_list'] = fsa_list

        # 配置ntp服务
        business_converge_args['need_config_ntp_condition'] = self.ntp_bool
        business_converge_args['time_zone'] = self.db.get_user_input_cloud_param_by_key(self.project_id, "time_zone")
        # TC_Create_VM 新增参数
        business_converge_args["create_vm_task_id"] = "DistributedStorageBusinessStorage"
        business_converge_args["create_vm_subtask_id"] = "FS800_BCD_CreateFSMVM"
        business_converge_args["create_vm_dsware_name"] = "dsware-server2"
        business_converge_args["create_vm_service_name"] = "DistributedStorageBusiness"
        business_converge_args["create_vm_fsm_scale"] = "business_fsm_scale"

        # TC_Add_Node 新增參數
        business_converge_args["tc_add_node_role_for_osd"] = ['compute', 'storage']
        business_converge_args["tc_add_node_role_for_vbs"] = ['compute']

        # 获取注册dmk的登录信息
        business_converge_args.update(self.get_dmk_user_info())

        # 启用加密且使用外置密管场景，获取外置密管服务器信息
        if get_project_condition_boolean(self.project_id, "FsExternalEncrypted"):
            business_converge_args.update(self.get_external_kms_info())
        return business_converge_args

    def get_role_source_when_business_converge(self, all_node_data, business_converge_args, osd_list, vbs_list):
        controller_osd_bmc_list = [osd.get('bmc_ip') for osd in osd_list]
        osd_cpu = self.get_osd_cpu_when_business_converge(all_node_data)
        storage_slot = [unit["primary_slot"] for unit in all_node_data if self.osd_kvm_condition(unit)][0]
        cache_type = [unit["cache_type"] for unit in all_node_data if self.osd_kvm_condition(unit)][0]
        cache_capacity = [unit["cache_capacity"] for unit in all_node_data if self.osd_kvm_condition(unit)][0]
        storagepool_redundancy_policy = [unit["storagepool_redundancy_policy"]
                                         for unit in all_node_data
                                         if self.osd_kvm_condition(unit)][0]
        primary_capacity = [unit["primary_capacity"] for unit in all_node_data if self.osd_kvm_condition(unit)][0]
        total_ec_data_and_verify = self.get_total_ec_data_and_verify_fragments(
            all_node_data, storagepool_redundancy_policy)
        storage_slot = self.get_storage_slot_when_business_converge(storage_slot)
        # 是否部署复制组件
        deploy_rep = get_project_condition_boolean(
            self.project_id, "TenantStorFBHCI80&(CSHAStorage_TFB|CSDRStorage_TFB)&!DRStorage_TFB_Sep")
        # 是否是全闪无缓存场景
        is_none_cache = False
        if cache_type == 'none':
            cache_capacity = 0
            is_none_cache = True
        osd_memory = DeviceResource().get_fsa_memory_800(
            storage_slot, cache_capacity, primary_capacity,
            storagepool_redundancy_policy=storagepool_redundancy_policy,
            total_ec_data_and_verify=total_ec_data_and_verify,
            deploy_rep=deploy_rep,
            is_none_cache=is_none_cache)
        # 纯计算节点
        vbs_bmc_ip_list = set([vbs.get('bmc_ip') for vbs in vbs_list]).difference(set(controller_osd_bmc_list))
        business_converge_args['osd_cpu'] = osd_cpu
        business_converge_args['osd_memory'] = osd_memory
        business_converge_args['vbs_cpu'] = 4
        business_converge_args['vbs_memory'] = 7
        business_converge_args['vbs_osd_bmc_ip_list'] = list(controller_osd_bmc_list)
        business_converge_args['vbs_bmc_ip_list'] = list(vbs_bmc_ip_list)

    def get_storage_slot_when_business_converge(self, storage_slot):
        slot_start = int(storage_slot.split('-')[0])
        slot_end = int(storage_slot.split('-')[1])
        # 数据盘个数
        num = slot_end - slot_start + 1
        if num <= 12:
            storage_slot = '0-11'
        elif num <= 16:
            storage_slot = '0-15'
        elif num <= 24:
            storage_slot = '0-23'
        else:
            storage_slot = '0-35'
        return storage_slot

    def get_osd_cpu_when_business_converge(self, all_node_data):
        osd_cpu = 6
        # 全闪场景取cpu12
        if self.get_cache_type(all_node_data) == 'none':
            osd_cpu = 12
        # 超融合容灾场景，预留复制所需cpu
        if get_project_condition_boolean(
                self.project_id, "TenantStorFBHCI80&(CSHAStorage_TFB|CSDRStorage_TFB)&!DRStorage_TFB_Sep"):
            osd_cpu += 4
        return osd_cpu

    def get_node_info_when_business_converge(self, business_converge_args):
        x86_arm_compute_role_list = DeployConstant.X86_ARM_COMPUTE_NODE_ROLE_LIST
        # Type1场景下网络节点作为VBS节点,Type2/3无网络节点
        x86_arm_compute_role_list.extend(BMC_ROLE_INFO.DPDK_NET_ROLE_LIST)
        # 业务存储融合场景下与取白名单kvm、dpdk的bmc IP列表取交集
        tsfbhci_compute_bmc_ip_list = OpenStackNodeManager.get_bmc_ip_by_role_list(
            self.db, self.pod_id, x86_arm_compute_role_list)
        # 获取fsa、osd、vbs节点bmc IP
        fsa_bmc_list = OpenStackNodeManager.get_fsa_ip_list(self.db, self.pod_id, is_typeii=False, is_business=True)
        osd_bmc_list = OpenStackNodeManager.get_osd_ip_list(self.db, self.pod_id, is_typeii=False, is_business=True)
        vbs_bmc_list = OpenStackNodeManager.get_vbs_ip_list(self.db, self.pod_id, is_typeii=False, is_business=True)
        fsa_bmc_list_cmp = set(fsa_bmc_list).intersection(set(tsfbhci_compute_bmc_ip_list))
        osd_bmc_list_cmp = set(osd_bmc_list).intersection(set(tsfbhci_compute_bmc_ip_list))
        vbs_bmc_list_cmp = set(vbs_bmc_list).intersection(set(tsfbhci_compute_bmc_ip_list))
        # 通过bmc ip获取管理IP
        fsa_list = self.get_role_node_list(fsa_bmc_list_cmp)
        osd_list = self.get_role_node_list(osd_bmc_list_cmp)
        vbs_list = self.get_role_node_list(vbs_bmc_list_cmp)
        # 获取存储节点BMC info
        nodes_info = self.db.get_bmc_info_by_pod_id(self.pod_id)
        osd_bmc_infos = self.get_osd_node_bmc_info(nodes_info, osd_list)
        # 获取节点型号
        all_node_data = self.db.get_bmc_info_by_pod_id(pod_id=self.pod_id)
        self.get_node_extension_info(fsa_list, all_node_data)
        self.get_node_extension_info(osd_list, all_node_data)
        self.get_node_extension_info(vbs_list, all_node_data)
        business_converge_args['osd_bmc_infos'] = osd_bmc_infos
        business_converge_args['fsa_list'] = fsa_list
        business_converge_args['osd_list'] = osd_list
        business_converge_args['vbs_list'] = vbs_list
        ret = all_node_data, fsa_list, osd_list, vbs_list
        return ret

    def get_business_converge_expand_compute_args(self):
        """
        :return:
        business_converge_args:
            'float_ip浮动ip':
            'ha模式ha_mode':
            '路径install_path':
            'dm初始密码dm_init_pwd':
            'dm修改密码dm_update_pwd':
            'fsa节点列表fsa_list':
                          fsa1:
                              'bmc_ip': ,
                              'om_ip': ,
                              'hostname': ,
                              'root_passwd': ,
                              'user': ,
                              'passwd':,
                          fsa2: ...
            'osd节点列表osd_list':
                          osd1:
                              'bmc_ip': ,
                              'om_ip': ,
                              'hostname': ,
                              'root_passwd': ,
                              'user': ,
                              'passwd':
                         osd2:...
            'vbs节点列表vbs_list':
                         vbs1:
                             'bmc_ip': ,
                             'om_ip': ,
                             'hostname': ,
                             'root_passwd': ,
                              'user': ,
                              'passwd':,
                        vbs2:...
        """
        business_converge_expand_compute = dict()
        business_converge_expand_compute['float_ip'] = self.db.get_user_input_cloud_param_by_key(
            self.project_id, "reuse_fsm_float_ip")
        business_converge_expand_compute['dm_init_pwd'] = self.db.get_value_from_cloudparam(
            self.pod_id, "DistributedStorage", "DMPortalInitPassword")
        business_converge_expand_compute['dm_update_pwd'] = self.db.get_user_input_cloud_param_by_key(
            self.project_id, "reuse_fsm_admin_passwd")
        business_converge_expand_compute['need_config_ntp_condition'] = self.ntp_bool
        business_converge_expand_compute['time_zone'] = self.db.get_user_input_cloud_param_by_key(
            self.project_id, "time_zone")
        all_node_data = self.db.get_bmc_info_by_pod_id(pod_id=self.pod_id)
        fsa_list, osd_bmc_infos, osd_list, vbs_list = self.exp_business_converge_get_node_info(all_node_data)
        business_converge_expand_compute['fsa_list'] = fsa_list
        business_converge_expand_compute['osd_list'] = osd_list
        business_converge_expand_compute['vbs_list'] = vbs_list
        business_converge_expand_compute['osd_bmc_infos'] = osd_bmc_infos

        # 安装角色
        resource_dic = self.get_role_resource_when_business_converge(all_node_data, osd_list, vbs_list)
        business_converge_expand_compute.update(resource_dic)

        # 配置存储网络
        frontend_storage_network_list = self.get_business_compute_node_storage_network()
        business_converge_expand_compute['frontend_storage_network_list'] = frontend_storage_network_list
        business_converge_expand_compute['backend_storage_network_list'] = frontend_storage_network_list

        # 创建客户端
        business_converge_expand_compute['iscsi_condition'] = get_project_condition_boolean(
            self.project_id, 'TenantStorFB_iSCSI')
        business_converge_expand_compute['vbs_client_list'] = fsa_list

        # TC_Add_Node 新增参数
        business_converge_expand_compute["tc_add_node_role_for_osd"] = ['compute', 'storage']
        business_converge_expand_compute["tc_add_node_role_for_vbs"] = ['compute']
        return business_converge_expand_compute

    def get_role_resource_when_business_converge(self, all_node_data, osd_list, vbs_list):
        params_dict = dict()
        controller_osd_bmc_list = [osd.get('bmc_ip') for osd in osd_list]
        # 是否部署复制组件
        deploy_rep = get_project_condition_boolean(
            self.project_id, "TenantStorFBHCI80&(CSHAStorage_TFB|CSDRStorage_TFB)&!DRStorage_TFB_Sep")
        # 针对即是vbs，也是osd的节点，计算所需内存和cpu
        storage_slot_info = [unit["primary_slot"] for unit in all_node_data if self.osd_kvm_condition(unit)]
        if storage_slot_info:
            osd_cpu = 6
            # 全闪场景取cpu12
            if not self.get_cache_type(all_node_data):
                osd_cpu = 12
            # 超融合容灾场景，预留复制所需cpu
            if get_project_condition_boolean(
                    self.project_id, "TenantStorFBHCI80&(CSHAStorage_TFB|CSDRStorage_TFB)&!DRStorage_TFB_Sep"):
                osd_cpu += 4
            storage_slot = self.get_storage_slot(storage_slot_info)

            primary_capacity = [unit.get("primary_capacity") for unit in all_node_data][0]
            storage_pool_redundancy_policy = [unit.get("storagepool_redundancy_policy") for unit in all_node_data][0]
            total_ec_data_and_verify = self.get_total_ec_data_and_verify_fragments(
                all_node_data, storage_pool_redundancy_policy)

            # 是否是全闪无缓存场景
            cache_type = [unit.get("cache_type") for unit in all_node_data]
            is_none_cache = False
            if not cache_type:
                cache_capacity = 0
                is_none_cache = True
            else:
                cache_capacity = [unit.get("cache_capacity") for unit in all_node_data][0]

            osd_memory = DeviceResource().get_fsa_memory_800(
                storage_slot, cache_capacity, primary_capacity,
                storagepool_redundancy_policy=storage_pool_redundancy_policy,
                total_ec_data_and_verify=total_ec_data_and_verify,
                deploy_rep=deploy_rep,
                is_none_cache=is_none_cache)
            params_dict['osd_memory'] = osd_memory
            params_dict['osd_cpu'] = osd_cpu
        # 纯计算节点
        vbs_bmc_ip_list = {vbs.get('bmc_ip') for vbs in vbs_list}.difference(set(controller_osd_bmc_list))
        params_dict['vbs_cpu'] = 4
        params_dict['vbs_memory'] = 7
        params_dict['vbs_osd_bmc_ip_list'] = list(controller_osd_bmc_list)
        params_dict['vbs_bmc_ip_list'] = list(vbs_bmc_ip_list)
        return params_dict

    def get_storage_slot(self, storage_slot_info):
        storage_slot = storage_slot_info[0]
        slot_start, slot_end = storage_slot.split('-')
        # 数据盘个数
        num = int(slot_end) - int(slot_start) + 1
        if num <= 12:
            storage_slot = '0-11'
        elif num <= 16:
            storage_slot = '0-15'
        elif num <= 24:
            storage_slot = '0-23'
        else:
            storage_slot = '0-35'
        return storage_slot

    def exp_business_converge_get_node_info(self, all_node_data):
        x86_arm_compute_role_list = DeployConstant.X86_ARM_COMPUTE_NODE_ROLE_LIST
        # Type1场景下网络节点作为VBS节点,Type2/3无网络节点
        x86_arm_compute_role_list.extend(BMC_ROLE_INFO.DPDK_NET_ROLE_LIST)
        # 业务存储融合场景下与取白名单kvm、dpdk的bmc IP列表取交集
        tsfbhci_compute_bmc_ip_list = OpenStackNodeManager.get_bmc_ip_by_role_list(
            self.db, self.pod_id, x86_arm_compute_role_list)
        # 获取fsa、osd、vbs节点bmc IP
        fsa_bmc_list = OpenStackNodeManager.get_fsa_ip_list(self.db, self.pod_id, is_typeii=False, is_business=True)
        osd_bmc_list = OpenStackNodeManager.get_osd_ip_list(self.db, self.pod_id, is_typeii=False, is_business=True)
        vbs_bmc_list = OpenStackNodeManager.get_vbs_ip_list(self.db, self.pod_id, is_typeii=False, is_business=True)
        fsa_bmc_list_cmp = set(fsa_bmc_list).intersection(set(tsfbhci_compute_bmc_ip_list))
        osd_bmc_list_cmp = set(osd_bmc_list).intersection(set(tsfbhci_compute_bmc_ip_list))
        vbs_bmc_list_cmp = set(vbs_bmc_list).intersection(set(tsfbhci_compute_bmc_ip_list))
        # 通过bmc ip获取管理IP
        fsa_list = self.get_role_node_list(fsa_bmc_list_cmp)
        osd_list = self.get_role_node_list(osd_bmc_list_cmp)
        vbs_list = self.get_role_node_list(vbs_bmc_list_cmp)
        # 获取节点型号
        self.get_node_extension_info(fsa_list, all_node_data)
        self.get_node_extension_info(osd_list, all_node_data)
        self.get_node_extension_info(vbs_list, all_node_data)
        # 获取存储节点BMC info
        nodes_info = self.db.get_bmc_info_by_pod_id(self.pod_id)
        osd_bmc_infos = self.get_osd_node_bmc_info(nodes_info, osd_list)
        ret = fsa_list, osd_bmc_infos, osd_list, vbs_list
        return ret

    def get_business_separate_args(self):
        """
        :return:
        business_separate_args:
            'float_ip浮动ip':
            'ha模式ha_mode':
            '路径install_path':
            'dm初始密码dm_init_pwd':
            'dm修改密码dm_update_pwd':
            'fsa节点列表fsa_list':
                          fsa1:
                              'bmc_ip': ,
                              'om_ip': ,
                              'hostname': ,
                              'root_passwd': ,
                              'user': ,
                              'passwd':,
                          fsa2: ...
            'osd节点列表osd_list':
                          osd1:
                              'bmc_ip': ,
                              'om_ip': ,
                              'hostname': ,
                              'root_passwd': ,
                              'user': ,
                              'passwd':
                         osd2:...
            'vbs节点列表vbs_list':
                         vbs1:
                             'bmc_ip': ,
                             'om_ip': ,
                             'hostname': ,
                             'root_passwd': ,
                              'user': ,
                              'passwd':,
                        vbs2:...
        """
        business_separate_args = dict()
        business_separate_args['az_id'] = self.get_az_id()
        business_separate_args['backend_name'] = self.db.get_user_input_cloud_param_by_key(
            self.project_id, "business_backendstorage_name")
        self.get_fsm_params_when_business_sep(business_separate_args)
        business_separate_args.update(self.get_install_os_args())
        business_separate_args.update(self._get_constant_args())

        vbs_list = self.get_vbs_list_when_business_sep()
        business_separate_args['vbs_list'] = vbs_list
        osd_list, storage_bmc_list = self.get_osd_list_when_business_sep()
        business_separate_args['osd_list'] = osd_list
        business_separate_args['fsa_list'] = vbs_list + osd_list
        rep_list = self.get_rep_list_when_business_sep()
        business_separate_args['rep_list'] = rep_list
        # 获取存储节点BMC info
        nodes_info = self.db.get_install_os_list_info(self.pod_id)
        osd_bmc_infos = self.get_osd_node_bmc_info(nodes_info, osd_list)
        business_separate_args['osd_bmc_infos'] = osd_bmc_infos
        # 安装角色
        self.get_role_resource(business_separate_args, vbs_list)
        # 配置存储网络
        frontend_storage_network_list = self.get_frontend_storage_network_info()
        backend_storage_network_list = self.get_backend_storage_network_info(frontend_storage_network_list)
        business_separate_args['frontend_storage_network_list'] = frontend_storage_network_list
        business_separate_args['backend_storage_network_list'] = backend_storage_network_list
        # 创建客户端
        self.get_vbs_client_params_when_business_sep(business_separate_args, osd_list, storage_bmc_list, vbs_list)
        # 配置ntp服务，非扩容场景
        business_separate_args['need_config_ntp_condition'] = self.ntp_bool
        business_separate_args['time_zone'] = self.db.get_user_input_cloud_param_by_key(self.project_id, "time_zone")
        # TC_Create_VM 新增参数
        self.get_vm_params(business_separate_args)
        # TC_Add_Node 新增参数
        business_separate_args["tc_add_node_role_for_osd"] = ['storage']
        business_separate_args["tc_add_node_role_for_vbs"] = ['compute']
        # 获取注册dmk的登录信息
        business_separate_args.update(self.get_dmk_user_info())
        # 启用加密且使用外置密管场景，获取外置密管服务器信息
        if get_project_condition_boolean(
                self.project_id, "FsExternalEncrypted"):
            external_kms_info = self.get_external_kms_info()
            business_separate_args.update(external_kms_info)
        return business_separate_args

    def get_vbs_client_params_when_business_sep(self, business_separate_args, osd_list, storage_bmc_list, vbs_list):
        iscsi_condition = get_project_condition_boolean(self.project_id, 'TenantStorFB_iSCSI')
        business_separate_args['iscsi_condition'] = iscsi_condition
        business_separate_args['vbs_client_list'] = vbs_list
        if not vbs_list and iscsi_condition:
            logger.error("The vbs list is none")
            business_separate_args['vbs_client_list'] = osd_list
        if iscsi_condition:
            self.expand_iscsi_info(business_separate_args["osd_list"], storage_bmc_list)
            # 创建vbs客户端时不进行iscsi网络配置
        business_separate_args['iscsi_condition'] = None

    def get_fsm_params_when_business_sep(self, business_separate_args):
        business_separate_args['float_ip'] = self.get_fsm_float_ip_when_business_sep()
        business_separate_args['dm_init_pwd'] = self.db.get_value_from_cloudparam(
            self.pod_id, "DistributedStorage", "DMPortalInitPassword")
        if get_project_condition_boolean(
                self.project_id,
                '(TenantStorFBReuse80|TenantStorNewPool|TenantStorNewNode)&'
                '(ExpansionAZ_KVM|ExpansionAZ_BMS|ExpansionServiceStorage)'):
            business_separate_args['dm_update_pwd'] = self.db.get_user_input_cloud_param_by_key(
                self.project_id, "reuse_fsm_admin_passwd")
        else:
            business_separate_args['dm_update_pwd'] = self.db.get_value_from_cloudparam(
                self.pod_id, "DistributedStorage", "FSMPortalPassword")
            business_separate_args['fsadmin_pwd'] = self.db.get_value_from_cloudparam(
                self.pod_id, "DistributedStorage", "FSMfsdminPassword")
            business_separate_args['fsm_root_pwd'] = self.db.get_value_from_cloudparam(
                self.pod_id, "DistributedStorage", "FSMrootPassword")

            business_separate_args['ha_mode'] = DeployConstant.HA_MODE

    def get_rep_list_when_business_sep(self):
        rep_list = list()
        rep_bmc_list = self.db.get_install_os_list_info(self.pod_id, 'rep')
        for bmc in rep_bmc_list:
            rep_node = dict()
            rep_node['bmc_ip'] = bmc["bmc_ip"]
            rep_node['om_ip'] = bmc["manageIp"]
            rep_node['hostname'] = bmc["hostname"]
            rep_node['model'] = bmc.get('equipment_model')
            (root, rep_node['root_pwd'], rep_node['user'],
             rep_node['passwd']) = bmc["creuser"].split(',')
            rep_node['cabinet'] = bmc.get('rack_id')
            rep_list.append(rep_node)
        return rep_list

    def get_osd_list_when_business_sep(self):
        osd_list = list()
        storage_bmc_list = self.db.get_install_os_list_info(self.pod_id)
        for bmc in storage_bmc_list:
            # NFVI场景区分1.4和1.5
            if get_solution() and bmc["is_manage"]:
                continue
            else:
                osd_node = dict()
                osd_node['bmc_ip'] = bmc["bmc_ip"]
                osd_node['om_ip'] = bmc["manageIp"]
                osd_node['hostname'] = bmc["hostname"]
                osd_node['model'] = bmc.get('equipment_model')
                (root, osd_node['root_pwd'], osd_node['user'],
                 osd_node['passwd']) = bmc["creuser"].split(',')
                osd_node['cabinet'] = bmc.get('rack_id')
                osd_list.append(osd_node)
        return osd_list, storage_bmc_list

    def get_vbs_list_when_business_sep(self):
        x86_arm_compute_role_list = get_compute_dpdk_hosts()
        # 筛选适合的计算节点
        tsfb_compute_bmc_ip_list = OpenStackNodeManager.get_bmc_ip_by_role_list(
            self.db, self.pod_id, x86_arm_compute_role_list)
        vbs_bmc_list = OpenStackNodeManager.get_vbs_ip_list(self.db, self.pod_id, is_typeii=False, is_business=True)
        vbs_bmc_list_osd = [vbs['bmc_ip'] for vbs in self.db.get_install_os_list_info(self.pod_id, component='vbs')]
        vbs_bmc_list_cmp = set(vbs_bmc_list).intersection(set(tsfb_compute_bmc_ip_list)).union(set(vbs_bmc_list_osd))
        # 通过bmc ip获取管理IP
        vbs_list = self.get_role_node_list(vbs_bmc_list_cmp)
        # 获取节点型号
        all_node_data = self.db.get_bmc_info_by_pod_id(pod_id=self.pod_id)
        self.get_node_extension_info(vbs_list, all_node_data)
        return vbs_list

    def get_fsm_float_ip_when_business_sep(self):
        all_business_separate_args = self.db.get_all_data_with_key_value(self.pod_id, "DistributedStorageBusiness")
        if get_project_condition_boolean(
                self.project_id, 'TenantStorFB80&(ExpansionAZ_KVM|ExpansionPOD_KVM|ExpansionAZ_BMS|ExpansionPOD_BMS)'):
            float_ip = self.db.get_user_input_cloud_param_by_key(self.project_id, "expansion_new_fsm_float_ip")
        elif get_project_condition_boolean(
                self.project_id,
                '(TenantStorFBReuse80|TenantStorNewPool|TenantStorNewNode)&(ExpansionAZ_KVM|ExpansionServiceStorage)'):
            float_ip = self.db.get_user_input_cloud_param_by_key(self.project_id, "expansion_az_fsm_float_ip")
        elif get_project_condition_boolean(self.project_id, 'TenantStorFBReuse80&ExpansionAZ_BMS'):
            float_ip = self.db.get_user_input_cloud_param_by_key(self.project_id, "reuse_fsm_float_ip")
        else:
            float_ip = all_business_separate_args.get('FSMOMFloatingIP02', 'unKnown')
        return float_ip

    def get_business_separate_expand_compute_args(self):
        """
        :return:
        business_separate_args:
            'float_ip浮动ip':
            'ha模式ha_mode':
            '路径install_path':
            'dm初始密码dm_init_pwd':
            'dm修改密码dm_update_pwd':
            'fsa节点列表fsa_list':
                          fsa1:
                              'bmc_ip': ,
                              'om_ip': ,
                              'hostname': ,
                              'root_passwd': ,
                              'user': ,
                              'passwd':,
                          fsa2: ...
            'osd节点列表osd_list':
                          osd1:
                              'bmc_ip': ,
                              'om_ip': ,
                              'hostname': ,
                              'root_passwd': ,
                              'user': ,
                              'passwd':
                         osd2:...
            'vbs节点列表vbs_list':
                         vbs1:
                             'bmc_ip': ,
                             'om_ip': ,
                             'hostname': ,
                             'root_passwd': ,
                              'user': ,
                              'passwd':,
                        vbs2:...
        """
        business_separate_expand_compute_args = dict()
        business_separate_expand_compute_args['az_id'] = self.get_az_id()
        business_separate_expand_compute_args['float_ip'] = self.db.get_user_input_cloud_param_by_key(
            self.project_id, "reuse_fsm_float_ip")
        business_separate_expand_compute_args['dm_init_pwd'] = self.db.get_value_from_cloudparam(
            self.pod_id, "DistributedStorage", "DMPortalInitPassword")
        business_separate_expand_compute_args['dm_update_pwd'] = self.db.get_user_input_cloud_param_by_key(
            self.project_id, "reuse_fsm_admin_passwd")
        business_separate_expand_compute_args['need_config_ntp_condition'] = self.ntp_bool
        business_separate_expand_compute_args['time_zone'] = self.db.get_user_input_cloud_param_by_key(
            self.project_id, "time_zone")
        # 筛选适合的计算节点
        x86_arm_compute_role_list = get_compute_dpdk_hosts()
        tsfb_compute_bmc_ip_list = OpenStackNodeManager.get_bmc_ip_by_role_list(
            self.db, self.pod_id, x86_arm_compute_role_list)
        vbs_bmc_list = OpenStackNodeManager.get_vbs_ip_list(self.db, self.pod_id, is_typeii=False, is_business=True)
        vbs_bmc_list_cmp = set(vbs_bmc_list).intersection(set(tsfb_compute_bmc_ip_list))

        # 通过bmc ip获取管理IP
        vbs_list = self.get_role_node_list(vbs_bmc_list_cmp)
        # 获取节点型号
        all_node_data = self.db.get_bmc_info_by_pod_id(pod_id=self.pod_id)
        self.get_node_extension_info(vbs_list, all_node_data)

        business_separate_expand_compute_args['vbs_list'] = vbs_list
        business_separate_expand_compute_args['osd_list'] = list()
        business_separate_expand_compute_args['fsa_list'] = vbs_list
        storage_net_args = self.get_install_os_args()
        business_separate_expand_compute_args.update(storage_net_args)
        constant_args = self._get_constant_args()
        business_separate_expand_compute_args.update(constant_args)
        # 安装角色
        self.get_role_resource(business_separate_expand_compute_args, vbs_list)
        # 配置存储网络
        frontend_storage_network_list = self.get_frontend_storage_network_info()
        backend_storage_network_list = self.get_backend_storage_network_info(frontend_storage_network_list)
        business_separate_expand_compute_args['frontend_storage_network_list'] = frontend_storage_network_list
        business_separate_expand_compute_args['backend_storage_network_list'] = backend_storage_network_list
        # 创建客户端
        iscsi_condition = get_project_condition_boolean(self.project_id, 'TenantStorFB_iSCSI')
        business_separate_expand_compute_args['iscsi_condition'] = iscsi_condition
        business_separate_expand_compute_args['vbs_client_list'] = vbs_list
        if not vbs_list and iscsi_condition:
            business_separate_expand_compute_args['vbs_client_list'] = list()
        # TC_Add_Node 新增参数
        business_separate_expand_compute_args["tc_add_node_role_for_osd"] = ['storage']
        business_separate_expand_compute_args["tc_add_node_role_for_vbs"] = ['compute']
        return business_separate_expand_compute_args

    def get_business_separate_expand_fusionstorage_args(self):
        """
        ipsan扩分布式存储获取参数
        :return:
        business_separate_args:
                    'float_ip浮动ip':
            'ha模式ha_mode':
            '路径install_path':
            'dm初始密码dm_init_pwd':
            'dm修改密码dm_update_pwd':
            'fsa节点列表fsa_list':
                          fsa1:
                              'bmc_ip': ,
                              'om_ip': ,
                              'hostname': ,
                              'root_passwd': ,
                              'user': ,
                              'passwd':,
                          fsa2: ...
            'osd节点列表osd_list':
                          osd1:
                              'bmc_ip': ,
                              'om_ip': ,
                              'hostname': ,
                              'root_passwd': ,
                              'user': ,
                              'passwd':
                         osd2:...
            'vbs节点列表vbs_list':
                         vbs1:
                             'bmc_ip': ,
                             'om_ip': ,
                             'hostname': ,
                             'root_passwd': ,
                              'user': ,
                              'passwd':,
                        vbs2:...
        """
        expand_fusionstorage_args = dict()
        expand_fusionstorage_args['az_id'] = self.get_az_id()
        expand_fusionstorage_args['ha_mode'] = DeployConstant.HA_MODE
        expand_fusionstorage_args['float_ip'] = self.db.get_user_input_cloud_param_by_key(
            self.project_id, "expansion_fusionstorage_float_ip")
        self.get_fsm_pwd_info(expand_fusionstorage_args)
        expand_fusionstorage_args['backend_name'] = self.db.get_user_input_cloud_param_by_key(
            self.project_id, "business_backendstorage_name")
        az_name = self.db.get_user_input_cloud_param_by_key(self.project_id, "openstack_expansion_az")
        if not az_name:
            az_name = self.db.get_user_input_cloud_param_by_key(self.project_id, "openstack_region")
        expand_fusionstorage_args['az_name'] = az_name

        vbs_list, osd_list, storage_bmc_list = self.get_node_info_when_business_separate_exp_fs(
            az_name, expand_fusionstorage_args)

        storage_net_args = self.get_install_os_args()
        expand_fusionstorage_args.update(storage_net_args)
        constant_args = self._get_constant_args()
        expand_fusionstorage_args.update(constant_args)
        # 安装角色
        self.get_role_resource(expand_fusionstorage_args, vbs_list)
        # 配置存储网络
        frontend_storage_network_list = self.get_frontend_storage_network_info()
        backend_storage_network_list = self.get_backend_storage_network_info(frontend_storage_network_list)
        expand_fusionstorage_args['frontend_storage_network_list'] = frontend_storage_network_list
        expand_fusionstorage_args['backend_storage_network_list'] = backend_storage_network_list
        # 创建客户端
        self.get_vbs_client_params_when_business_separate_exp_fs(expand_fusionstorage_args, osd_list,
                                                                 storage_bmc_list, vbs_list)
        # 配置ntp服务
        expand_fusionstorage_args['need_config_ntp_condition'] = self.ntp_bool
        expand_fusionstorage_args['time_zone'] = self.db.get_user_input_cloud_param_by_key(self.project_id, "time_zone")
        # TC_Create_VM 新增参数
        self.get_vm_params(expand_fusionstorage_args)
        # TC_Add_Node 新增参数
        expand_fusionstorage_args["tc_add_node_role_for_osd"] = ['storage']
        expand_fusionstorage_args["tc_add_node_role_for_vbs"] = ['compute']
        # 获取注册dmk的登录信息
        dmk_info = self.get_dmk_user_info()
        expand_fusionstorage_args.update(dmk_info)
        # 启用加密且使用外置密管场景，获取外置密管服务器信息
        if get_project_condition_boolean(self.project_id, "FsExternalEncrypted"):
            external_kms_info = self.get_external_kms_info()
            expand_fusionstorage_args.update(external_kms_info)
        return expand_fusionstorage_args

    def get_fsm_pwd_info(self, fs_args):
        fs_args['dm_init_pwd'] = self.db.get_value_from_cloudparam(
            self.pod_id, "DistributedStorage", "DMPortalInitPassword")
        fs_args['dm_update_pwd'] = self.db.get_value_from_cloudparam(
            self.pod_id, "DistributedStorage", "FSMPortalPassword")
        fs_args['fsadmin_pwd'] = self.db.get_value_from_cloudparam(
            self.pod_id, "DistributedStorage", "FSMfsdminPassword")
        fs_args['fsm_root_pwd'] = self.db.get_value_from_cloudparam(
            self.pod_id, "DistributedStorage", "FSMrootPassword")

    def get_vbs_client_params_when_business_separate_exp_fs(self, expand_fusionstorage_args, osd_list,
                                                            storage_bmc_list, vbs_list):
        iscsi_condition = get_project_condition_boolean(self.project_id, 'TenantStorFB_iSCSI')
        expand_fusionstorage_args['iscsi_condition'] = iscsi_condition
        expand_fusionstorage_args['vbs_client_list'] = vbs_list
        if not vbs_list and iscsi_condition:
            logger.error("The vbs list is none")
            expand_fusionstorage_args['vbs_client_list'] = osd_list
        if iscsi_condition:
            self.expand_iscsi_info(expand_fusionstorage_args["osd_list"], storage_bmc_list)
        # 创建vbs客户端时不进行iscsi网络配置
        expand_fusionstorage_args['iscsi_condition'] = None

    def get_node_info_when_business_separate_exp_fs(self, az_name, expand_fusionstorage_args):
        webui_client = FSPAuthClient.get_cps_web_client(self.db, self.project_id, self.pod_id)
        nova_client = OpenstackAuthClient.get_compute_client(self.db, self.project_id, self.pod_id)
        resource_tracker = ResourceTracker(self.pod_id, webui_client, nova_client)
        host_id_list = resource_tracker.get_az_hosts_id(az_name)
        vbs_list = self.get_node_list_by_host_id(host_id_list)
        # 获取节点型号
        all_node_data = self.db.get_bmc_info_by_pod_id(pod_id=self.pod_id)
        self.get_node_extension_info(vbs_list, all_node_data)
        osd_list, storage_bmc_list = self.get_osd_list_when_business_sep()
        expand_fusionstorage_args['vbs_list'] = vbs_list
        expand_fusionstorage_args['osd_list'] = osd_list
        expand_fusionstorage_args['fsa_list'] = vbs_list + osd_list
        # 获取存储节点BMC info
        nodes_info = self.db.get_install_os_list_info(self.pod_id)
        osd_bmc_infos = self.get_osd_node_bmc_info(nodes_info, osd_list)
        expand_fusionstorage_args['osd_bmc_infos'] = osd_bmc_infos
        return vbs_list, osd_list, storage_bmc_list

    def get_business_separate_expand_fusionstorage_args_while_new_pool_or_new_node(self):
        """
        :return:
        business_separate_new_pool_or_node_args:
            'float_ip浮动ip':
            'ha模式ha_mode':
            '路径install_path':
            'dm初始密码dm_init_pwd':
            'dm修改密码dm_update_pwd':
            'fsa节点列表fsa_list':
                          fsa1:
                              'bmc_ip': ,
                              'om_ip': ,
                              'hostname': ,
                              'root_passwd': ,
                              'user': ,
                              'passwd':,
                          fsa2: ...
            'osd节点列表osd_list':
                          osd1:
                              'bmc_ip': ,
                              'om_ip': ,
                              'hostname': ,
                              'root_passwd': ,
                              'user': ,
                              'passwd':
                         osd2:...
            'vbs节点列表vbs_list':
                         vbs1:
                             'bmc_ip': ,
                             'om_ip': ,
                             'hostname': ,
                             'root_passwd': ,
                              'user': ,
                              'passwd':,
                        vbs2:...
        """
        business_separate_new_pool_or_node_args = dict()
        business_separate_new_pool_or_node_args['az_id'] = self.get_az_id()

        business_separate_new_pool_or_node_args['vbs_list'] = list()
        business_separate_new_pool_or_node_args['float_ip'] = \
            self.db.get_user_input_cloud_param_by_key(self.project_id, "expansion_az_fsm_float_ip")
        business_separate_new_pool_or_node_args['dm_init_pwd'] = \
            self.db.get_value_from_cloudparam(self.pod_id, "DistributedStorage", "DMPortalInitPassword")
        business_separate_new_pool_or_node_args['dm_update_pwd'] = \
            self.db.get_user_input_cloud_param_by_key(self.project_id, "reuse_fsm_admin_passwd")
        business_separate_new_pool_or_node_args['backend_name'] = \
            self.db.get_user_input_cloud_param_by_key(self.project_id, "business_backendstorage_name")
        business_separate_new_pool_or_node_args['time_zone'] = \
            self.db.get_user_input_cloud_param_by_key(self.project_id, "time_zone")
        business_separate_new_pool_or_node_args['fsm_root_pwd'] = \
            self.db.get_value_from_cloudparam(self.pod_id, "DistributedStorage", "FSMrootPassword")
        storage_net_args = self.get_install_os_args()
        business_separate_new_pool_or_node_args.update(storage_net_args)
        constant_args = self._get_constant_args()
        business_separate_new_pool_or_node_args.update(constant_args)

        osd_list = list()
        storage_bmc_list = self.db.get_install_os_list_info(self.pod_id)
        for bmc in storage_bmc_list:
            osd_node = dict()
            osd_node['bmc_ip'] = bmc["bmc_ip"]
            osd_node['om_ip'] = bmc["manageIp"]
            osd_node['hostname'] = bmc["hostname"]
            osd_node['model'] = bmc.get('equipment_model')
            _, osd_node['root_pwd'], osd_node['user'], osd_node['passwd'] = bmc["creuser"].split(',')
            osd_node['cabinet'] = bmc.get('rack_id')
            osd_list.append(osd_node)
        business_separate_new_pool_or_node_args['osd_list'] = osd_list
        business_separate_new_pool_or_node_args['fsa_list'] = osd_list
        # 获取存储节点BMC info
        nodes_info = self.db.get_install_os_list_info(self.pod_id)
        osd_bmc_infos = self.get_osd_node_bmc_info(nodes_info, osd_list)
        business_separate_new_pool_or_node_args['osd_bmc_infos'] = osd_bmc_infos

        # 配置存储网络
        frontend_storage_network_list = self.get_frontend_storage_network_info()
        backend_storage_network_list = self.get_backend_storage_network_info(frontend_storage_network_list)
        business_separate_new_pool_or_node_args['frontend_storage_network_list'] = frontend_storage_network_list
        business_separate_new_pool_or_node_args['backend_storage_network_list'] = backend_storage_network_list

        # 配置ntp服务，非扩容场景
        business_separate_new_pool_or_node_args['need_config_ntp_condition'] = self.ntp_bool

        # TC_Add_Node 新增参数
        business_separate_new_pool_or_node_args["tc_add_node_role_for_osd"] = ['storage']
        business_separate_new_pool_or_node_args["tc_add_node_role_for_vbs"] = ['compute']

        # 获取注册dmk的登录信息
        business_separate_new_pool_or_node_args.update(self.get_dmk_user_info())
        return business_separate_new_pool_or_node_args

    def get_manage_converge_args(self, mode=None):
        """
        :param mode:
        :return:
        manage_converge_args:
            'float_ip浮动ip':
            'ha模式ha_mode':
            '路径install_path':
            'dm初始密码dm_init_pwd':
            'dm修改密码dm_update_pwd':
            'fsa节点列表fsa_list':
                          fsa1:
                              'bmc_ip': ,
                              'om_ip': ,
                              'hostname': ,
                              'root_passwd': ,
                              'user': ,
                              'passwd':,
                          fsa2: ...
            'osd节点列表osd_list':
                          osd1:
                              'bmc_ip': ,
                              'om_ip': ,
                              'hostname': ,
                              'root_passwd': ,
                              'user': ,
                              'passwd':
                         osd2:...
            'vbs节点列表vbs_list':
                         vbs1:
                             'bmc_ip': ,
                             'om_ip': ,
                             'hostname': ,
                             'root_passwd': ,
                              'user': ,
                              'passwd':,
                        vbs2:...
        """
        manage_converge_args = dict()
        manage_converge_args['eth_port'] = DeployConstant.MGR_STORAGE_NET_INTF
        self.get_fsm_pwd_info(manage_converge_args)

        all_openstack_nodes, fsa_bmc_list, osd_bmc_list = self.get_params_depending_on_project_condition(
            manage_converge_args, mode)

        fsa_list, osd_list = self.get_node_info_when_manage_converge(
            all_openstack_nodes, fsa_bmc_list, manage_converge_args, osd_bmc_list)

        # 安装角色
        role_resource = self.get_management_role_resource(all_openstack_nodes, fsa_list, osd_list)
        manage_converge_args.update(role_resource)

        # 配置存储网络
        self.get_storage_network_params_when_manage_converge(manage_converge_args)

        # 创建客户端
        iscsi_condition = get_project_condition_boolean(self.project_id, 'TenantStorFB_iSCSI')
        manage_converge_args['iscsi_condition'] = iscsi_condition
        manage_converge_args['vbs_client_list'] = fsa_list

        # 配置ntp服务
        manage_converge_args['need_config_ntp_condition'] = self.ntp_bool
        manage_converge_args['time_zone'] = self.db.get_user_input_cloud_param_by_key(self.project_id, "time_zone")
        # TC_Create_VM 新增參數
        self.get_vm_params_when_manage_converge(manage_converge_args)
        # TC_Add_Node 新增參數
        manage_converge_args["tc_add_node_role_for_osd"] = ['compute', 'storage']
        manage_converge_args["tc_add_node_role_for_vbs"] = ['compute']
        # 管理场景安装管理节点不进行/etc/resolv.conf文件注释
        manage_converge_args["is_manage"] = True

        # 获取注册dmk的登录信息
        manage_converge_args.update(self.get_dmk_user_info())

        # 创/扩管理存储池工步，配置支持不同厂商nvme开关标志,涉及场景：部署工程管理融合、扩管理节点、扩管理存储池
        manage_converge_args['open_disk_vendor_switch'] = True
        return manage_converge_args

    def get_params_depending_on_project_condition(self, manage_converge_args, mode):
        # 获取依赖工程场景的参数
        exp_pod = get_project_condition_boolean(
            self.project_id, 'ManageStorFB80&(ExpansionScale_CloudServiceNode|ExpansionMgmtRes_ServiceNode)')
        all_manage_converge_args = self.db.get_all_data_with_key_value(self.pod_id, "DistributedStorageManage")
        fsa_bmc_list = OpenStackNodeManager.get_fsa_ip_list(self.db, self.pod_id, is_typeii=True, is_business=False)
        osd_bmc_list = OpenStackNodeManager.get_osd_ip_list(self.db, self.pod_id, is_typeii=True, is_business=False)
        curr_condition = ProjectApi().get_project_ha_dr_status(self.project_id)
        if curr_condition['RegionConHA']:
            manage_converge_args['scene'] = 'RegionConHA'
            manage_converge_args['ha_backend_name'] = DeployConstant.HA_BACKEND_NAME
            if mode == "master":
                all_openstack_nodes, site_node_list_info = self.get_dc001_params(
                    all_manage_converge_args, exp_pod, manage_converge_args)
            else:
                all_openstack_nodes, site_node_list_info = self.get_dc002_params(
                    all_manage_converge_args, exp_pod, manage_converge_args)
            site_node_list = [unit.get('bmc_ip') for unit in site_node_list_info]
            fsa_bmc_list = [node for node in fsa_bmc_list if node in site_node_list]
            osd_bmc_list = [node for node in osd_bmc_list if node in site_node_list]
        else:
            if exp_pod:
                # 扩POD场景
                manage_converge_args['float_ip'] = self.db.get_user_input_cloud_param_by_key(
                    self.project_id, "expansion_fsm_float_ip")
                manage_converge_args['dm_update_pwd'] = self.db.get_user_input_cloud_param_by_key(
                    self.project_id, "expansion_fs8_fsm_admin_passwd")
                manage_converge_args["fsadmin_pwd"] = self.db.get_user_input_cloud_param_by_key(
                    self.project_id, "expansion_fs8_fsm_fsadmin_passwd")
                manage_converge_args["fsm_root_pwd"] = self.db.get_user_input_cloud_param_by_key(
                    self.project_id, "expansion_fs8_fsm_root_passwd")
            else:
                manage_converge_args['float_ip'] = all_manage_converge_args.get('FSMOMFloatingIP', 'unKnown')
                host_list = self.db.get_ref_component_host_list(self.pod_id, REFCOMPONENTCONSTANT.MANAGE_FSM_VM)
                host_list = [unit.bmc_ip for unit in host_list]
                manage_converge_args['ha_mode'] = DeployConstant.HA_MODE
                manage_converge_args['master'] = self.get_fsm_node_info(host_list[0])
                manage_converge_args['standby'] = self.get_fsm_node_info(host_list[1])
            all_openstack_nodes = self.db.get_bmc_info_by_pod_id(pod_id=self.pod_id)
            manage_converge_args['scene'] = None
            manage_converge_args['mode'] = None
        manage_converge_args['backend_name'] = DeployConstant.BACKEND_NAME
        manage_converge_args['all_openstack_nodes'] = all_openstack_nodes
        return all_openstack_nodes, fsa_bmc_list, osd_bmc_list

    def get_dc002_params(self, all_manage_converge_args, exp_pod, manage_converge_args):
        if exp_pod:
            # 扩POD场景
            manage_converge_args['float_ip'] = self.db.get_user_input_cloud_param_by_key(
                self.project_id, "dc002_expansion_fsm_float_ip")
            manage_converge_args['dm_update_pwd'] = self.db.get_user_input_cloud_param_by_key(
                self.project_id, "dc002_expansion_fsm_admin_passwd")
            manage_converge_args["fsadmin_pwd"] = self.db.get_user_input_cloud_param_by_key(
                self.project_id, "dc002_expansion_fs8_fsm_fsadmin_passwd")
            manage_converge_args["fsm_root_pwd"] = self.db.get_user_input_cloud_param_by_key(
                self.project_id, "dc002_expansion_fs8_fsm_root_passwd")
        else:
            manage_converge_args['float_ip'] = all_manage_converge_args.get('HAFSMOMFloatingIP', 'unKnown')
            host_list = self.db.get_bmc_info_by_site_and_bmc_role(
                region_site.DC002, "controller", pod_id=self.pod_id)
            host_list = (host_list[0].get('bmc_ip'), host_list[1].get('bmc_ip'))
            manage_converge_args['ha_mode'] = DeployConstant.HA_MODE
            manage_converge_args['master'] = self.get_fsm_node_info(host_list[0])
            manage_converge_args['standby'] = self.get_fsm_node_info(host_list[1])
        all_openstack_nodes = self.db.get_bmc_info_by_site_and_bmc_role(region_site.DC002, pod_id=self.pod_id)
        site_node_list_info = self.db.get_bmc_info_by_site_and_bmc_role(region_site.DC002, pod_id=self.pod_id)
        manage_converge_args['mode'] = 'ha_standby'
        return all_openstack_nodes, site_node_list_info

    def get_dc001_params(self, all_manage_converge_args, exp_pod, manage_converge_args):
        if exp_pod:
            # 扩POD场景
            manage_converge_args['float_ip'] = self.db.get_user_input_cloud_param_by_key(
                self.project_id, "dc001_expansion_fsm_float_ip")
            manage_converge_args['dm_update_pwd'] = self.db.get_user_input_cloud_param_by_key(
                self.project_id, "dc001_expansion_fsm_admin_passwd")
            manage_converge_args["fsadmin_pwd"] = self.db.get_user_input_cloud_param_by_key(
                self.project_id, "dc001_expansion_fs8_fsm_fsadmin_passwd")
            manage_converge_args["fsm_root_pwd"] = self.db.get_user_input_cloud_param_by_key(
                self.project_id, "dc001_expansion_fs8_fsm_root_passwd")
        else:
            manage_converge_args['float_ip'] = all_manage_converge_args.get('FSMOMFloatingIP', 'unKnown')
            first_node = self.db.get_bmc_info_by_site_and_bmc_role(
                region_site.DC001, "first_node", pod_id=self.pod_id)
            controller_node = self.db.get_bmc_info_by_site_and_bmc_role(
                region_site.DC001, "controller", pod_id=self.pod_id)
            host_list = (first_node[0].get('bmc_ip'), controller_node[0].get('bmc_ip'))
            manage_converge_args['ha_mode'] = DeployConstant.HA_MODE
            manage_converge_args['master'] = self.get_fsm_node_info(host_list[0])
            manage_converge_args['standby'] = self.get_fsm_node_info(host_list[1])
        all_openstack_nodes = self.db.get_bmc_info_by_site_and_bmc_role(region_site.DC001, pod_id=self.pod_id)
        manage_converge_args['mode'] = 'ha_master'
        site_node_list_info = self.db.get_bmc_info_by_site_and_bmc_role(region_site.DC001, pod_id=self.pod_id)
        return all_openstack_nodes, site_node_list_info

    def get_storage_network_params_when_manage_converge(self, manage_converge_args):
        frontend_storage_network_list = list()
        backend_storage_network_list = list()
        obj = ManageMentStorageData(self.project_id, self.pod_id)
        storage_net_data_list = obj.get_management_storage_data_info()
        for storage_net_data in storage_net_data_list:
            manage_storage_netmask = storage_net_data.get('net_info_netmask')
            manage_storage_gateway = storage_net_data.get('net_info_gateway')
            manage_net_plane_segment = storage_net_data.get('net_info_range')
            if not manage_storage_netmask or not manage_storage_gateway or not manage_net_plane_segment:
                err_msg = "Failed to obtain network parameters. Check the network parameters in the LLD."
                logger.error(err_msg)
                raise Exception(err_msg)
            else:
                storage_network_info = dict()
                manage_net_segment_list = manage_net_plane_segment.split('-')
                manage_net_start = manage_net_segment_list[0]
                manage_net_plane = IP(manage_net_start).make_net(manage_storage_netmask)
                ip_net = IP(manage_net_plane)
                storage_network_info['gateway'] = manage_storage_gateway
                storage_network_info['netmask'] = manage_storage_netmask
                storage_network_info['subnet'] = ip_net.strNormal(3)
                frontend_storage_network_list.append(storage_network_info)
                backend_storage_network_list.append(storage_network_info)
        manage_converge_args['frontend_storage_network_list'] = frontend_storage_network_list
        manage_converge_args['backend_storage_network_list'] = backend_storage_network_list

    def get_node_info_when_manage_converge(self, all_openstack_nodes, fsa_bmc_list, manage_converge_args, osd_bmc_list):
        # 通过bmc ip获取管理IP
        fsa_list = self.get_role_node_list(fsa_bmc_list)
        osd_list = self.get_role_node_list(osd_bmc_list)
        self.get_node_extension_info(fsa_list, all_openstack_nodes)
        self.get_node_extension_info(osd_list, all_openstack_nodes)
        # 管理融合场景fsa/osd/vbs节点相同
        manage_converge_args['vbs_list'] = fsa_list
        manage_converge_args['fsa_list'] = fsa_list
        manage_converge_args['osd_list'] = osd_list
        # 获取存储节点BMC info
        nodes_info = self.db.get_bmc_info_by_pod_id(self.pod_id)
        osd_bmc_infos = self.get_osd_node_bmc_info(nodes_info, osd_list)
        manage_converge_args['osd_bmc_infos'] = osd_bmc_infos
        return fsa_list, osd_list

    def get_management_role_resource(self, all_openstack_nodes, fsa_list, osd_list):
        role_resource = dict()
        exp_bool = get_project_condition_boolean(self.project_id, 'ExpansionMgmtRes_ServiceNode')
        storage_slot = self.get_osd_node_storage_slot(all_openstack_nodes, expansion_service_bool=exp_bool)
        if exp_bool:
            cache_capacity, primary_capacity, vbs_bmc_ip_list, vbs_osd_bmc_ip_list, equipment_model = \
                self.get_storage_info_when_exp_cloud_service(all_openstack_nodes)
            osd_cpu, osd_memory = 6, 0
            if get_project_condition_boolean(self.project_id, "manageARM"):
                osd_cpu = 8
            if vbs_osd_bmc_ip_list:
                cache_type_list = [unit["cache_type"]
                                   for unit in all_openstack_nodes
                                   if unit["bmc_ip"] in vbs_osd_bmc_ip_list]
                cache_type = cache_type_list[0]
                osd_cpu, osd_memory = self.get_osd_node_memory_and_cpu(
                    cache_capacity, cache_type, osd_cpu, primary_capacity, storage_slot)
                if equipment_model in HYGONLIST:
                    osd_cpu = 12
            # 不提供存储能力的云服务节点
            vbs_cpu, vbs_memory = 4, 5
        else:
            control_node_info = self.get_control_node_info(all_openstack_nodes)
            cache_capacity, primary_capacity, cache_type, equipment_model = control_node_info[0]

            osd_cpu, vbs_cpu = 6, 6
            if get_project_condition_boolean(self.project_id, "manageARM"):
                osd_cpu, vbs_cpu = 8, 8
            osd_cpu, osd_memory = self.get_osd_node_memory_and_cpu(
                cache_capacity, cache_type, osd_cpu, primary_capacity, storage_slot)
            vbs_cpu = osd_cpu
            if equipment_model in HYGONLIST:
                osd_cpu, vbs_cpu = 12, 12
            # 云服务节点
            vbs_memory = osd_memory

            controller_bmc_ip_list = OpenStackNodeManager.get_controller_bmc_ip(self.db, self.pod_id)
            osd_bmc_ip_list = [osd.get('bmc_ip') for osd in osd_list]
            controller_osd_bmc_list = set(controller_bmc_ip_list).intersection(set(osd_bmc_ip_list))
            cloudservice_bmc_ip_list = OpenStackNodeManager.get_compute_cloudservice_bmc_ip(self.db, self.pod_id)
            fsa_bmc_ip_list = [fsa.get('bmc_ip') for fsa in fsa_list]
            cloudservice_fsa_bmc_list = set(cloudservice_bmc_ip_list).intersection(set(fsa_bmc_ip_list))
            vbs_osd_bmc_ip_list = list(controller_osd_bmc_list)
            vbs_bmc_ip_list = list(cloudservice_fsa_bmc_list)

        role_resource['osd_cpu'] = osd_cpu
        role_resource['osd_memory'] = osd_memory
        role_resource['vbs_cpu'] = vbs_cpu
        role_resource['vbs_memory'] = vbs_memory
        role_resource['vbs_osd_bmc_ip_list'] = vbs_osd_bmc_ip_list
        role_resource['vbs_bmc_ip_list'] = vbs_bmc_ip_list
        return role_resource

    def get_storage_info_when_exp_cloud_service(self, all_openstack_nodes):
        osd_role = constant.REFCOMPONENTCONSTANT.OSD
        cache_capacity, primary_capacity, equipment_model = None, None, None
        vbs_osd_bmc_ip_list = [unit["bmc_ip"]
                               for unit in all_openstack_nodes
                               if self.cloud_service_osd_node(osd_role, unit)]
        if vbs_osd_bmc_ip_list:
            cache_capacity, primary_capacity, equipment_model = [
                (unit["cache_capacity"], unit["primary_capacity"], unit["equipment_model"])
                for unit in all_openstack_nodes
                if self.cloud_service_osd_node(osd_role, unit)][0]
        vbs_bmc_ip_list = [unit["bmc_ip"]
                           for unit in all_openstack_nodes
                           if self.cloud_service_not_osd_node(osd_role, unit)]
        ret = cache_capacity, primary_capacity, vbs_bmc_ip_list, vbs_osd_bmc_ip_list, equipment_model
        return ret

    def get_frontend_storage_network_info(self):
        frontend_storage_network_list = list()
        if not get_project_condition_boolean(self.project_id,
                                             'ExpansionServiceStorage&!TenantStorFB80|ExpansionAdCloudService'):
            business_compute_node_storage_network_info_lst = self.get_business_compute_node_storage_network()
            if business_compute_node_storage_network_info_lst:
                frontend_storage_network_list.extend(business_compute_node_storage_network_info_lst)
                logger.info('compute storage network info:{}'.format(business_compute_node_storage_network_info_lst))
        if get_project_condition_boolean(
                self.project_id,
                '(ExpansionServiceStorage&!TenantStorFB80|ExpansionAdCloudService)'
                '&DRStorage_TFB_Sep&(CSDRStorage_TFB|CSHAStorage_TFB)'):
            rep_node_storage_network_lst = self.get_business_osd_node_storage_network(
                service_name=DeployConstant.REL_CLOUD_SERVICE_NAME)
            if rep_node_storage_network_lst:
                frontend_storage_network_list.extend(rep_node_storage_network_lst)

        business_osd_node_storage_network_lst = self.get_business_osd_node_storage_network()
        if business_osd_node_storage_network_lst:
            frontend_storage_network_list.extend(business_osd_node_storage_network_lst)
            logger.info('osd nodes storage network info:{}'.format(business_osd_node_storage_network_lst))
        return frontend_storage_network_list

    def get_backend_storage_network_info(self, frontend_storage_network_list):
        backend_storage_network_lst = list()
        kwargs = {"service_name": "DistributedStorageBusiness",
                  "netmask": "storage_backend_net_netmask",
                  "gateway": "storage_backend_net_gateway",
                  "subnet": "storage_backend_net_subnet",
                  "raise_status": False}
        storage_backend_network_info = self.get_network_from_cloudparam(**kwargs)
        if storage_backend_network_info:
            backend_storage_network_lst.append(storage_backend_network_info)
        else:
            backend_storage_network_lst = frontend_storage_network_list
        return backend_storage_network_lst

    def get_business_compute_node_storage_network(self):
        storage_network_info_lst = list()
        obj = ManageMentStorageData(self.project_id, self.pod_id)
        storage_net_data_list = obj.get_service_storage_data_info()
        for storage_net_data in storage_net_data_list:
            manage_storage_netmask = storage_net_data.get('net_info_netmask')
            manage_storage_gateway = storage_net_data.get('net_info_gateway')
            manage_net_plane_segment = storage_net_data.get('net_info_range')
            if not manage_storage_netmask or not manage_storage_gateway or not manage_net_plane_segment:
                err_msg = "Failed to obtain network parameters. Check the network parameters in the LLD."
                logger.error(err_msg)
                raise Exception(err_msg)
            storage_network_info = {'gateway': manage_storage_gateway,
                                    'netmask': manage_storage_netmask,
                                    'subnet': manage_net_plane_segment}
            storage_network_info_lst.append(storage_network_info)
        return storage_network_info_lst

    def get_business_osd_node_storage_network(self, service_name=DeployConstant.CLOUD_SERVICE_NAME):
        business_osd_node_storage_network_lst = list()
        kwargs = {"service_name": service_name,
                  "netmask": "business_separate_storage_netmask",
                  "gateway": "business_separate_storage_gateway",
                  "subnet": "business_separate_storage_subnet",
                  "raise_status": False}
        storage_network_info = self.get_network_from_cloudparam(**kwargs)
        if storage_network_info:
            business_osd_node_storage_network_lst.append(storage_network_info)
        return business_osd_node_storage_network_lst

    def get_fsm_node_info(self, node_bmc_ip):
        node_dic = dict()
        node_dic['bmc_ip'] = node_bmc_ip
        host_id, host_om_ip = self.cps_hosts.get_host_info([node_bmc_ip])
        if not host_om_ip:
            logger.error('Failed to obtain the om IP from the CPS, BMC ip: {}'.format(node_bmc_ip))
            raise HCCIException(626335, node_bmc_ip)
        node_dic['om_ip'] = host_om_ip[0]
        node_dic['hostname'] = host_id[0]
        node_dic['root_pwd'] = FSPasswordManager(self.pod_id).get_root_password()
        node_dic['user'] = 'fsp'
        node_dic['passwd'] = FSPasswordManager(self.pod_id).get_fsp_password()
        return node_dic

    def get_role_node_list(self, role_bmc_list):
        role_list = list()
        all_cps_hosts = self.cps_hosts.get_hosts_info()
        for host in all_cps_hosts:
            if host["metadata"].get('ipmiip') is None:
                continue
            for role_bmc in role_bmc_list:
                if role_bmc == host['metadata']['ipmiip']:
                    node = dict()
                    node['bmc_ip'] = role_bmc
                    node['om_ip'] = host['omip']
                    node['hostname'] = host['id']
                    node['user'] = 'fsp'
                    node['passwd'] = FSPasswordManager(self.pod_id).get_fsp_password()
                    node['root_pwd'] = FSPasswordManager(self.pod_id).get_root_password()
                    role_list.append(node)
        return role_list



    def get_node_list_by_host_id(self, host_id_list):
        node_list = list()
        if not host_id_list:
            logger.error("The host id list is empty")
            return node_list
        all_cps_hosts = self.cps_hosts.get_hosts_info()
        for host in all_cps_hosts:
            if host['id'] in host_id_list:
                node = dict()
                node['bmc_ip'] = host['metadata']['ipmiip']
                node['om_ip'] = host['omip']
                node['hostname'] = host['id']
                node['user'] = 'fsp'
                node['passwd'] = \
                    FSPasswordManager(self.pod_id).get_fsp_password()
                node['root_pwd'] = \
                    FSPasswordManager(self.pod_id).get_root_password()
                node_list.append(node)
        return node_list

    def get_install_os_args(self):
        fs_args = dict()
        fs_args["bmc_info_list"] = InstallOs.get_waitting_bmc_install_list(self.project_id, self.pod_id, ["osd"])
        fs_args["ip_type_is_ipv6"] = ProjectApi().is_ipv6_project(self.project_id)

        fs_args["fs_mgr_netmask"] = self.db.get_user_input_cloud_param_by_key(
            self.project_id, 'fusionstorage_manage_netmask')
        fs_args["fs_mgr_gw"] = self.db.get_user_input_cloud_param_by_key(
            self.project_id, 'fusionstorage_manage_gateway')
        fs_args["fs_mgr_vlan"] = self.db.get_user_input_cloud_param_by_key(
            self.project_id, 'fusionstorage_manage_vlan')
        fs_args["fs_stg_netmask"] = self.db.get_user_input_cloud_param_by_key(
            self.project_id, 'fusionstorage_service_netmask')
        fs_args["fs_stg_gw"] = self.db.get_user_input_cloud_param_by_key(
            self.project_id, 'fusionstorage_service_gateway')
        fs_args["fs_stg_vlan"] = self.db.get_user_input_cloud_param_by_key(
            self.project_id, 'fusionstorage_service_vlan')

        fs_args["iscsi_service_netmask"] = self.db.get_user_input_cloud_param_by_key(
            self.project_id, "iscsi_service_netmask")
        fs_args["iscsi_service_gateway"] = self.db.get_user_input_cloud_param_by_key(
            self.project_id, "iscsi_service_gateway")
        fs_args["iscsi_service_vlan"] = self.db.get_user_input_cloud_param_by_key(self.project_id, "iscsi_service_vlan")

        fs_args["fs_stg_inner_netmask"] = self.db.get_user_input_cloud_param_by_key(
            self.project_id, 'fusionstorage_inner_netmask')
        fs_args["fs_stg_inner_gw"] = self.db.get_user_input_cloud_param_by_key(
            self.project_id, 'fusionstorage_inner_gateway')
        fs_args["fs_stg_inner_vlan"] = self.db.get_user_input_cloud_param_by_key(
            self.project_id, 'fusionstorage_inner_vlan')
        fs_args["fs_rep1_netmask"] = self.db.get_user_input_cloud_param_by_key(
            self.project_id, 'fusionstorage_rep_netmask1')
        fs_args["fs_rep2_netmask"] = self.db.get_user_input_cloud_param_by_key(
            self.project_id, 'fusionstorage_rep_netmask2')
        csha_condition = get_project_condition_boolean(self.project_id, "CSHAStorage_TFB")
        if csha_condition:
            fs_args["fs_arb_netmask"] = self.db.get_user_input_cloud_param_by_key(
                self.project_id, 'fusionstorage_arb_netmask')
            fs_args["fs_arb_vlan"] = self.db.get_user_input_cloud_param_by_key(
                self.project_id, 'fusionstorage_arb_vlan')
        net_infos = self._get_install_os_net(fs_args)
        fs_args["net_infos"] = net_infos
        return fs_args

    def get_storage_backend_network_config(self, fs_args, net_infos, storage_inner_interface_name):
        fs_stg_inner_netmask = fs_args.get("fs_stg_inner_netmask")
        fs_stg_inner_vlan = fs_args.get("fs_stg_inner_vlan")
        if fs_stg_inner_netmask and fs_stg_inner_vlan:
            storage_backend_vlan_net = {
                "plane": ["storage_inner_plane"],
                "type": "vlan_bond", "vlan_name": storage_inner_interface_name,
                "bond_name": "bond0", "vlan_id": fs_stg_inner_vlan,
                "ip_mask": fs_stg_inner_netmask, "ip_name": "storageInnerIp"}
            net_infos["storage_inner_vlan_net"] = storage_backend_vlan_net
            storage_backend_port_net = {
                "plane": ["storage_inner_plane"],
                "type": "bond", "bond_mode": self._get_nic_mode('fusionstorage_service_plane_mode'),
                "bond_name": storage_inner_interface_name,
                "ip_mask": fs_stg_inner_netmask,
                "ip_name": "storageInnerIp", "nic_pci": None, "dev_port": None}
            net_infos["storage_inner_port_net"] = storage_backend_port_net

    def get_storage_front_network_config(self, fs_args, net_infos, storage_interface_name):
        storage_frontend_port_net = {
            "plane": ["storage_plane"],
            "type": "bond", "bond_mode": self._get_nic_mode('fusionstorage_service_plane_mode'),
            "bond_name": storage_interface_name, "ip_mask": fs_args.get("fs_stg_netmask"),
            "ip_name": "storageIp", "nic_pci": None, "dev_port": None}
        net_infos["storage_port_net"] = storage_frontend_port_net
        storage_frontend_vlan_net = {
            "plane": ["storage_plane"],
            "type": "vlan_bond", "vlan_name": storage_interface_name,
            "bond_name": "bond0", "vlan_id": fs_args.get("fs_stg_vlan"),
            "ip_mask": fs_args.get("fs_stg_netmask"), "ip_name": "storageIp"}
        net_infos["storage_vlan_net"] = storage_frontend_vlan_net

    def get_management_network_config(self, fs_args, net_infos):
        management_bond_net = {
            "plane": ["management_plane"],
            "type": "bond", "bond_mode": self._get_nic_mode('fusionstorage_manage_plane_mode'),
            "bond_name": "bond0",
            "nic_pci": None, "dev_port": None}
        net_infos["managemant_bond_net"] = management_bond_net
        management_vlan_net = {
            "plane": ["management_plane"],
            "type": "vlan_bond", "bond_name": "bond0",
            "vlan_id": fs_args.get("fs_mgr_vlan"), "ip_mask": fs_args.get("fs_mgr_netmask"),
            "gw": fs_args.get("fs_mgr_gw"), "vlan_name": 'mgmt',
            "ip_name": "manageIp"}
        net_infos["managemant_vlan_net"] = management_vlan_net

    def get_iscsi_network_config(self, fs_args, net_infos, storage_interface_name):
        # ISCSI既不复用管理口，也不复用存储口,独立组bond
        iscsi_service_netmask = fs_args.get("iscsi_service_netmask")
        iscsi_service_vlan = fs_args.get("iscsi_service_vlan")
        iscsi_bond_mode = self._get_nic_mode('iscsi_service_plane_mode')
        iscsi_independ_bond = {
            "plane": ["iscsi_business_plane"],
            "type": "bond",
            "bond_mode": iscsi_bond_mode,
            "bond_name": "iscsi_bond",
            "ip_mask": iscsi_service_netmask,
            "ip_name": "iscsi_business_plane_ip",
            "nic_pci": None,
            "dev_port": None
        }
        net_infos["iscsi_independ_bond"] = iscsi_independ_bond
        # ISCSI复用管理口
        iscsi_reuse_management = {
            "plane": ["iscsi_business_plane"],
            "type": "vlan_bond",
            "vlan_name": "iscsi." + str(iscsi_service_vlan),
            "bond_name": "bond0",
            "vlan_id": iscsi_service_vlan,
            "ip_mask": iscsi_service_netmask,
            "ip_name": "iscsi_business_plane_ip"
        }
        net_infos["iscsi_reuse_management"] = iscsi_reuse_management
        # ISCSI 复用存储口
        iscsi_reuse_storage = {
            "plane": ["iscsi_business_plane"],
            "type": "vlan_bond",
            "vlan_name": "iscsi." + str(iscsi_service_vlan),
            "bond_name": storage_interface_name,
            "vlan_id": iscsi_service_vlan,
            "ip_mask": iscsi_service_netmask,
            "ip_name": "iscsi_business_plane_ip"
        }
        net_infos["iscsi_reuse_storage"] = iscsi_reuse_storage

    def get_cache_type(self, nodes):
        # 获取缓存类型
        cache_type_list = [unit["cache_type"] for unit in nodes if self.osd_kvm_condition(unit)]
        if not cache_type_list:
            no_cache_type = None
            return no_cache_type
        cache_type = cache_type_list[0]
        return cache_type

    def osd_kvm_condition(self, unit):
        return constant.REFCOMPONENTCONSTANT.OSD in unit["ref_component"].replace(" ", "") \
               and (BMC_ROLE_INFO.KVM in unit["bmc_role"].split(',')
                    or BMC_ROLE_INFO.KVM_DPDK in unit["bmc_role"].split(','))

    def get_total_ec_data_and_verify_fragments(self, nodes, storagepool_redundancy_policy):
        total_ec_data_and_verify = 0
        if storagepool_redundancy_policy != 'ec':
            return total_ec_data_and_verify
        ec_data_fragments_str = self.get_ec_data_fragments(nodes)
        ec_verify_fragments_str = self.get_verify_fragments(nodes)
        # 校验分片为2时，数据分片取值4~22
        # 校验分片为3/4时，数据分片取值6~20
        ec_verify_fragments = int(ec_verify_fragments_str)
        ec_data_fragments = int(ec_data_fragments_str)
        if ec_verify_fragments == 2:
            if ec_data_fragments < 4 or ec_data_fragments > 22:
                err_msg = 'When the ec_verify_fragments is 2, the range of ec_data_fragments is 4~22'
                logger.error(err_msg)
                raise Exception(err_msg)
        elif ec_verify_fragments == 3 or ec_verify_fragments == 4:
            if ec_data_fragments < 6 or ec_data_fragments > 20:
                err_msg = 'When the ec_verify_fragments is 3 or 4, the range of ec_data_fragments is 6~20'
                logger.error(err_msg)
                raise Exception(err_msg)
        else:
            err_msg = 'The range of ec_verify_fragments is 2~4'
            logger.error(err_msg)
            raise Exception(err_msg)
        # ec校验分片和数据分片的和
        total_ec_data_and_verify = ec_verify_fragments + ec_data_fragments
        return total_ec_data_and_verify

    def get_verify_fragments(self, nodes):
        # 校验分片
        ec_verify_fragment_list = [unit["ec_verify_fragments"] for unit in nodes if self.osd_kvm_condition(unit)]
        # 校验分片一致性检查
        ec_verify_fragments = ''
        for ec_verify_fragment in ec_verify_fragment_list:
            if not ec_verify_fragments:
                if not ec_verify_fragment:
                    err_msg = 'When the storagepool redundancy policy is EC,The ec_verify_fragments is empty'
                    logger.error(err_msg)
                    raise Exception(err_msg)
                ec_verify_fragments = ec_verify_fragment
            else:
                if ec_verify_fragments != ec_verify_fragment:
                    err_msg = 'When the storagepool redundancy policy is EC,The ec_verify_fragments must be same.'
                    logger.error(err_msg)
                    raise Exception(err_msg)
        return ec_verify_fragments

    def get_ec_data_fragments(self, nodes):
        # 数据分片
        ec_data_fragment_list = [unit["ec_data_fragments"] for unit in nodes if self.osd_kvm_condition(unit)]
        # 数据分片一致性检查
        ec_data_fragments = ''
        for ec_data_fragment in ec_data_fragment_list:
            if not ec_data_fragments:
                if not ec_data_fragment:
                    raise Exception('When the storagepool redundancy policy is EC,The ec_data_fragments is empty')
                ec_data_fragments = ec_data_fragment
            else:
                if ec_data_fragments != ec_data_fragment:
                    raise Exception('When the storagepool redundancy policy is EC,The ec_data_fragments must be same')
        return ec_data_fragments

    def get_network_from_cloudparam(self, **kwargs):
        service_name = kwargs.get("service_name")
        storage_network_info = dict()
        storage_netmask = self.db.get_value_from_cloudparam(
            self.pod_id, service_name, kwargs.get("netmask"))
        storage_gateway = self.db.get_value_from_cloudparam(
            self.pod_id, service_name, kwargs.get("gateway"))
        storage_subnet = self.db.get_value_from_cloudparam(
            self.pod_id, service_name, kwargs.get("subnet"))
        if not storage_netmask or not storage_gateway or \
                not storage_subnet:
            err_msg = "Failed to get storage network: {}".format(kwargs)
            logger.error(err_msg)
            if kwargs.get("raise_status"):
                raise Exception(err_msg)
        else:
            storage_network_info['gateway'] = storage_gateway
            storage_network_info['netmask'] = storage_netmask
            storage_network_info['subnet'] = IP(storage_subnet).strNormal(3)
        return storage_network_info

    def get_hot_patch_path(self):
        pkg_regular = "^FusionStorage_8.([0-9.]|HP)+.tar.gz$"
        return self.get_package(pkg_regular)

    def get_dmk_user_info(self):
        """
        获取注册dmk用户的初始密码和登录密码
        """
        dmk_usr_info = dict()
        dmk_usr_info['dmk_init_pwd'] = self.db.get_value_from_cloudparam(
            self.pod_id, "DistributedStorage", "DMKInitPassword")
        dmk_usr_info['dmk_pwd'] = self.db.get_value_from_cloudparam(
            self.pod_id, "DistributedStorage", "DMKUpdatePassword")
        return dmk_usr_info

    def get_external_kms_info(self):
        external_kms_info = dict()
        external_kms_info['external_kms_ip'] = self.db.get_user_input_cloud_param_by_key(
            self.project_id,
            "external_kms_ip"
        )
        external_kms_info['external_kms_port'] = self.db.get_user_input_cloud_param_by_key(
            self.project_id,
            "external_kms_port"
        )
        external_kms_info['external_kms_type'] = self.db.get_user_input_cloud_param_by_key(
            self.project_id,
            "external_kms_type"
        )
        return external_kms_info

    def get_az_id(self):
        """
        openstack_region: region名，也是首个计算az（业务存储az）的az id
        openstack_expansion_az：除首个计算az以外的az id。

        往已有az扩容场景，若待扩容的az非首个计算az，首先取openstack_expansion_az参数。
        """
        expa_az = get_project_condition_boolean(self.project_id,
                                                '(TenantStorFB80|TenantStorFBReuse80)'
                                                '&(ExpansionAZ_KVM|ExpansionAZ_BMS)|TenantStorFBPoolReuse80')
        ipsan_exp_fs = get_project_condition_boolean(self.project_id, 'TenantStorFB80&ExpansionServiceStorage')
        new_pool = get_project_condition_boolean(self.project_id, 'TenantStorNewPool&ExpansionServiceStorage')
        if expa_az or ipsan_exp_fs:
            # 扩az或ipsan扩分布式存储
            az = self.db.get_user_input_cloud_param_by_key(self.project_id, "openstack_expansion_az")
            if not az:
                az = self.db.get_user_input_cloud_param_by_key(self.project_id, "openstack_region")
        elif new_pool:
            # 新增业务存储---新增存储池
            az = self.db.get_user_input_cloud_param_by_key(self.project_id, "openstack_expansion_az")
        else:
            # 部署工程
            az = self.db.get_user_input_cloud_param_by_key(self.project_id, "openstack_region")
        if not az:
            raise HCCIException(626380)
        return az

    def _get_constant_args(self):
        fs_args = dict()
        bms_condition = get_project_condition_boolean(
            self.project_id, 'TenantStorFB80&'
                             '(CascadedOpenStack_BMS|ExpansionPod_BMS)')
        storage_interface_name = DeployConstant.MGR_STORAGE_NET_INTF
        project_info = self.db.get_project_info(self.project_id)
        if "Type1" == project_info.get('region_type', ''):
            if bms_condition:
                # 新建pod为BMS场景下存储平面名
                storage_interface_name = "fsb_data0"
        storage_inner_interface_name = DeployConstant.BACKEND_STORAGE_NET_INTF
        fs_args["frontend_net_port_name"] = storage_interface_name
        fs_args["backend_net_port_name"] = storage_inner_interface_name
        fs_args["rest_username"] = DeployConstant.DM_LOGIN_USER
        return fs_args

    def _get_install_os_net(self, fs_args):
        constant_args = self._get_constant_args()
        storage_interface_name = constant_args.get("frontend_net_port_name")
        storage_inner_interface_name = constant_args.get("backend_net_port_name")
        net_infos = dict()
        self.get_management_network_config(fs_args, net_infos)
        self.get_storage_front_network_config(fs_args, net_infos, storage_interface_name)
        self.get_iscsi_network_config(fs_args, net_infos, storage_interface_name)
        self.get_storage_backend_network_config(fs_args, net_infos, storage_inner_interface_name)
        self.get_rep_netwrok_config(fs_args, net_infos)
        self.get_arb_network_config(fs_args, net_infos)
        return net_infos

    def _get_nic_mode(self, lld_key):
        nic_mode = self.db.get_user_input_cloud_param_by_key(
            self.project_id, lld_key)
        logger.info("Get nic mode:%s" % nic_mode)
        if nic_mode == 'active_standby':
            bond_mode = 1
        elif nic_mode == 'lacp':
            bond_mode = 4
        else:
            bond_mode = 4
        logger.info("bond mode:%s" % bond_mode)
        return bond_mode
