def ip_resource_display_to_other_platform_new():
    '''
        将kvm已有的网段展示给其他平台新接口,查询指定网段可用的ip数量
    :return:
    '''
    data_from_vishnu = request.data
    logging.info(data_from_vishnu)
    data_requset = json_helper.loads(data_from_vishnu)
    req_datacenter = data_requset['dataCenter']
    req_env = data_requset['env']
    req_net_area = data_requset['netArea']
    req_net_name = data_requset['netName']
    # 校验入参是否为空
    if not req_env or not req_net_area or not req_net_name or not req_datacenter:
        return json_helper.format_api_resp_msg_to_vishnu_resource(job_status=VsJobStatus.FAILED, detail='入参有空值')

    # 查询指定环境、网络区域是否有所需网段
    ret_segment = segment_service.SegmentService().get_segment_info_bysegment(req_net_name.split('/')[0])
    if not ret_segment:
        return json_helper.format_api_resp_msg_to_vishnu_resource(job_status=VsJobStatus.FAILED, detail="无法找到需要申请的网段")

    ret_net_area_info = net_area.NetAreaService().get_net_area_info(ret_segment['net_area_id'])
    if not ret_net_area_info:
        return json_helper.format_api_resp_msg_to_vishnu_resource(job_status=VsJobStatus.FAILED, detail="无法找到指定网段所属网络区域信息")

    ret_datacenter_info = datacenter_service.DataCenterService().get_datacenter_info(
        ret_net_area_info['datacenter_id'])
    if not ret_datacenter_info:
        return json_helper.format_api_resp_msg_to_vishnu_resource(job_status=VsJobStatus.FAILED, detail="无法找到指定机房信息")
    if req_env not in DataCenterTypeForVishnu.TYPE_DICT:
        return json_helper.format_api_resp_msg_to_vishnu_resource(job_status=VsJobStatus.FAILED, detail="无法找到指定机房类型信息")
    if str(DataCenterTypeForVishnu.TYPE_DICT[req_env]) != ret_datacenter_info['dc_type']:
        return json_helper.format_api_resp_msg_to_vishnu_resource(job_status=VsJobStatus.FAILED, detail="无法找到指定网络区域对应网段信息")

    # 获取可用ip
    ret_ip_available_status, ret_ip_available = ip_service.get_all_available_segment_ip(ret_segment['id'], str(
        DataCenterTypeForVishnu.TYPE_DICT[req_env]))

    if not ret_ip_available_status:
        ret_params = {
            "ip_num": 0
        }
        return json_helper.format_api_resp_msg_to_vishnu_resource(job_status=VsJobStatus.SUCCEED, detail=ret_params)
    ret_params = {
        "ip_num": len(ret_ip_available)
    }
    return json_helper.format_api_resp_msg_to_vishnu_resource(job_status=VsJobStatus.SUCCEED, detail=ret_params)
def instance_os_version_modify(instance_id):
    '''
        修改os版本为unknown的虚拟机
    :param instance_id:
    :json param :
    :return:
    '''
    req_json = request.data
    req_data = json_helper.loads(req_json)
    n_os_version = req_data["os_version"]

    if not instance_id or not str(n_os_version):
        logging.info(
            'no instance_id or os_version when modify instance os version')
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR)

    ins_data = ins_s.InstanceService().get_instance_info(instance_id)
    if not ins_data:
        logging.error(
            'instance %s info is no exist in db when modify instance os version',
            instance_id)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)

    # VM创建来源
    create_source = ins_data['create_source']

    # 本平台
    if create_source == VMCreateSource.OPENSTACK or create_source == VMCreateSource.ESX:
        # v2v迁移的VM
        ins_v2v_data = v2v_i_i_s.v2vInstanceinfo(
        ).get_v2v_instance_info_by_instance_id(instance_id)
        if ins_v2v_data:
            if ins_v2v_data['os_version'] and ins_v2v_data[
                    'os_version'] == "unknown":
                # 更新v2v虚拟机os版本
                update_data = {'os_version': n_os_version}
                where_data = {'instance_id': instance_id}
                v2v_i_i_s.v2vInstanceinfo().update_v2v_status(
                    update_data, where_data)
    else:
        # todo: kvm2.0需要增加对平台自身创建虚拟机操作系统版本校验,unknown的可以修改
        pass

    return json_helper.format_api_resp(code=ErrorCode.SUCCESS,
                                       msg="操作系统版本更新成功")
def host_perform_data_to_db():
    '''
      此函数用于将物理机上报上来的性能数据写入数据库
    :return:
    '''
    data_from_host = request.data
    data = json_helper.loads(data_from_host)

    if not data or not data['ip']:
        # 物理机性能数据中ip为空,不做任何操作
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg='无法获取上传性能数据中的物理机ip信息,录入性能数据失败')

    # ret_msg = _msg_format(host_ip=data['ip'], host_name=data['hostname'], cpu_core=data['cpu_core'],
    #                       mem_size=data['mem_size'], disk_size=data['disk_size'], net_size=data['net_size'],
    #                       current_cpu_used=data['current_cpu_used'],
    #                       current_mem_used=data['current_mem_used'],
    #                       current_disk_used=data['current_disk_used'],
    #                       week_cpu_p95_used=data['week_cpu_p95_used'],
    #                       week_mem_p95_used=data['week_mem_p95_used'],
    #                       current_net_rx_used=data['current_net_rx_used'],
    #                       current_net_tx_used=data['current_net_tx_used'],
    #                       start_time=data['start_time'],
    #                       libvirt_port=data['libvirt_port'],
    #                       libvirt_status=data['libvirt_status'],
    #                       images=data['images'])
    # 更新host表
    __update_host_table(data['ip'], data['ostype'], data['cpu_core'],
                        data['mem_size'], data['disk_size'], data['net_size'],
                        data['current_cpu_used'], data['current_mem_used'],
                        data['current_disk_used'], data['week_cpu_p95_used'],
                        data['week_mem_p95_used'], data['current_net_rx_used'],
                        data['current_net_tx_used'], data['start_time'],
                        data['libvirt_port'], data['images'],
                        data['libvirt_status'])
    # flush_host_perform_data_to_db(datadict=ret_msg)
    return json_helper.format_api_resp(code=ErrorCode.SUCCESS,
                                       msg='%s:录入性能数据成功' % data['ip'])
def segment_capacity_to_other_platform():
    '''
        外部平台获取kvm网段或IP资源使用信息
    :return:
    '''
    data_from_vishnu = request.data
    logging.info(data_from_vishnu)
    data_requset = json_helper.loads(data_from_vishnu)
    datacenter = data_requset['dataCenter']
    env = data_requset['env']
    net_area = data_requset['netArea']
    network_segment = data_requset['networkSegment']
    page_num = data_requset['currentPage']
    page_size = data_requset['pageSize']

    if not datacenter or not env:
        return json_helper.format_api_resp_msg_to_vishnu_resource(
            job_status=VsJobStatus.FAILED, detail='输入机房、环境信息为空')

    get_network_segment_detail = False
    if network_segment:
        get_network_segment_detail = True

    get_net_area_detail = False
    if net_area:
        get_net_area_detail = True

    if get_net_area_detail and get_network_segment_detail:
        db_network_segment_datas = get_network_segments_data_by_segment_name(
            datacenter, str(DataCenterTypeForVishnu.TYPE_DICT[env]), net_area,
            network_segment)
        if not db_network_segment_datas:
            network_segments_params = {"result": []}
            return json_helper.format_api_resp_msg_to_vishnu_resource(
                job_status=VsJobStatus.SUCCEED, detail=network_segments_params)

        ip_data_lists = []
        all_ip_datas = get_ip_datas_by_segmentid(
            db_network_segment_datas['id'])
        if not all_ip_datas:
            # 计算该网段应该有的所有ip
            for __per_calculate_ip in IPy.IP(
                    db_network_segment_datas['segment'] + '/' +
                    db_network_segment_datas['netmask']):
                ip_params = {"ip": __per_calculate_ip, "status": IpType.UNINIT}
                ip_data_lists.append(ip_params)
            all_ip_params = {"result": ip_data_lists}
            return json_helper.format_api_resp_msg_to_vishnu_resource(
                job_status=VsJobStatus.SUCCEED, detail=all_ip_params)

        # 计算该网段应该有的所有ip
        calculate_ip_lists = []
        calculate_ip_data_lists = []
        for __per_calculate_ip in IPy.IP(db_network_segment_datas['segment'] +
                                         '/' +
                                         db_network_segment_datas['netmask']):
            __per_calculate_ip_params = {
                "ip": str(__per_calculate_ip),
                "status": IpTypeTransform.MSG_DICT[IpType.UNINIT]
            }
            calculate_ip_data_lists.append(__per_calculate_ip_params)
            calculate_ip_lists.append(str(__per_calculate_ip))

        for per_ip in all_ip_datas:
            if str(per_ip['ip_address']) in calculate_ip_lists:
                for __per_calculate_ip_data in calculate_ip_data_lists:
                    if __per_calculate_ip_data['ip'] == str(
                            per_ip['ip_address']):
                        __per_calculate_ip_data[
                            'status'] = IpTypeTransform.MSG_DICT[
                                per_ip['status']]

        all_ip_params = {"result": calculate_ip_data_lists}
        return json_helper.format_api_resp_msg_to_vishnu_resource(
            job_status=VsJobStatus.SUCCEED, detail=all_ip_params)

    elif get_net_area_detail:
        # 获取指定机房、环境、网络环境下的所有网段信息,需要分页
        network_segment_nums, db_network_segment_datas = get_network_segments_data_paging(
            datacenter, str(DataCenterTypeForVishnu.TYPE_DICT[env]), net_area,
            page_num, page_size)
        if network_segment_nums <= 0:
            network_segments_params = {
                "rows": [],
                "current": page_num,
                "rowCount": page_size,
                "total": 0
            }
            return json_helper.format_api_resp_msg_to_vishnu_resource(
                job_status=VsJobStatus.SUCCEED, detail=network_segments_params)
        network_segment_datas = []
        for network_segment in db_network_segment_datas:
            ip_init_datas = ip_service.ip_inited_in_segment(
                network_segment['id'])
            ret_ip_available_status, ip_availables = ip_service.get_available_ip_by_segment_id(
                network_segment['id'])
            if not ip_init_datas:
                ip_total = 0
                ip_canallocated = 0
                ip_usedrate = 0
            else:
                if len(ip_init_datas) <= 0:
                    ip_total = 0
                    ip_canallocated = 0
                    ip_usedrate = 0
                else:
                    ip_total = len(ip_init_datas)
                    if not ret_ip_available_status:
                        ip_canallocated = 0
                    ip_canallocated = ip_availables
                    ip_usedrate = float(
                        '%.4f' %
                        (float(ip_total - ip_canallocated) / float(ip_total)))

            per_network_segment_datas = {
                "canAllocated": ip_canallocated,
                "environment": env,
                "gateway": network_segment['gateway_ip'],
                "netDomain": net_area,
                "netName": network_segment['segment'],
                "networkId": '',
                "outerId": '',
                "subnetMask": network_segment['netmask'],
                "total": ip_total,
                "usedRate": ip_usedrate,
                "userType": "KVM",
                "vlanId": network_segment['vlan']
            }
            network_segment_datas.append(per_network_segment_datas)

        network_segments_params = {
            "rows": network_segment_datas,
            "current": page_num,
            "rowCount": page_size,
            "total": network_segment_nums
        }
        return json_helper.format_api_resp_msg_to_vishnu_resource(
            job_status=VsJobStatus.SUCCEED, detail=network_segments_params)

    else:
        # 返回指定机房、环境下的所有网段信息,需要分页
        network_segment_nums, db_network_segment_datas = get_network_segments_data_in_dc_paging(
            datacenter, str(DataCenterTypeForVishnu.TYPE_DICT[env]), page_num,
            page_size)
        if network_segment_nums <= 0:
            network_segments_params = {
                "rows": [],
                "current": page_num,
                "rowCount": page_size,
                "total": 0
            }
            return json_helper.format_api_resp_msg_to_vishnu_resource(
                job_status=VsJobStatus.SUCCEED, detail=network_segments_params)
        network_segment_datas = []
        for network_segment in db_network_segment_datas:
            ip_init_datas = ip_service.ip_inited_in_segment(
                network_segment['id'])
            ret_ip_available_status, ip_availables = ip_service.get_available_ip_by_segment_id(
                network_segment['id'])
            if not ip_init_datas:
                ip_total = 0
                ip_canallocated = 0
                ip_usedrate = 0
            else:
                if len(ip_init_datas) <= 0:
                    ip_total = 0
                    ip_canallocated = 0
                    ip_usedrate = 0
                else:
                    ip_total = len(ip_init_datas)
                    if not ret_ip_available_status:
                        ip_canallocated = 0
                    ip_canallocated = ip_availables
                    ip_usedrate = float(
                        '%.4f' %
                        (float(ip_total - ip_canallocated) / float(ip_total)))

            per_network_segment_datas = {
                "canAllocated": ip_canallocated,
                "environment": env,
                "gateway": network_segment['gateway_ip'],
                "netDomain": network_segment['net_area'],
                "netName": network_segment['segment'],
                "networkId": '',
                "outerId": '',
                "subnetMask": network_segment['netmask'],
                "total": ip_total,
                "usedRate": ip_usedrate,
                "userType": "KVM",
                "vlanId": network_segment['vlan']
            }
            network_segment_datas.append(per_network_segment_datas)

        network_segments_params = {
            "rows": network_segment_datas,
            "current": page_num,
            "rowCount": page_size,
            "total": network_segment_nums
        }
        return json_helper.format_api_resp_msg_to_vishnu_resource(
            job_status=VsJobStatus.SUCCEED, detail=network_segments_params)
Example #5
0
def hostpool_capacity_to_other_platform():
    '''
        外部平台获取kvm物理集群资源信息
    :return:
    '''
    data_from_vishnu = request.data
    logging.info(data_from_vishnu)
    data_requset = json_helper.loads(data_from_vishnu)
    # data_requset = request.values.get("data")
    # data_requset = json.loads(data_requset)
    datacenter = data_requset['datacenter']
    env = data_requset['env']
    vcpu = data_requset['vcpu']
    mem_mb = data_requset['mem_MB']
    disk_gb = data_requset['disk_GB']
    page_num = data_requset['currentPage']
    page_size = data_requset['pageSize']
    net_area = data_requset['net_area']

    all_available_vm_count = 0

    # 获取指定机房详细信息存入dc_list列表
    dc_list = []
    dc_ret, dc_datas = dc_s().get_all_datacenters_by_name(datacenter)
    if not dc_ret:
        return json_helper.format_api_resp_msg_to_vishnu_resource(job_status=VsJobStatus.FAILED, detail='无法找到指定机房信息')
    for one_dc_data in dc_datas:
        dc_type = DataCenterTypeTransform.MSG_DICT.get(int(one_dc_data['dc_type']))
        if env.lower() == dc_type:
            dc_detail = {
                "dc_id": one_dc_data['id'],
                "dc_name": one_dc_data['name'],
                "dc_area_id": one_dc_data['area_id'],
                "dc_type": DataCenterTypeTransform.MSG_DICT.get(int(one_dc_data['dc_type'])),
            }
            dc_list.append(dc_detail)

    if len(dc_list) != 1:
        return json_helper.format_api_resp_msg_to_vishnu_resource(job_status=VsJobStatus.FAILED,
                                                                  detail='无法找到机房中对应环境%s的信息' % env)

    # 查询指定环境、机房下的网络区域信息
    if net_area:
        net_area_info = get_netarea_info_by_name(str(DataCenterTypeForVishnu.TYPE_DICT[env]), datacenter, net_area)
        if net_area_info:
            available_ip_count = __all_ip_available_num(dc_list[0]['dc_id'], net_area_info['id'])
        else:
            available_ip_count = 0
    else:
        available_ip_count = __all_ip_available_num(dc_list[0]['dc_id'])

    # 如果net_area为空,获取指定机房下所有集群信息。否则查询指定机房指定网络区域下的集群信息
    hostpool_num, hostpool_infos = hostpool.get_datacenter_hostpool_list(dc_list[0]['dc_id'], net_area, page_num,
                                                                         page_size)

    if hostpool_num <= 0:
        params = {
            "currentPage": int(page_num),
            "pageSize": int(page_size),
            "total": 0,
            "available_vm_count": all_available_vm_count,
            "available_ip_count": available_ip_count,
            "cluster_datas": []
        }
        return json_helper.format_api_resp_msg_to_vishnu_resource(job_status=VsJobStatus.SUCCEED,
                                                                  detail=params)
    capacity_detail = []

    for per_hostpool_info in hostpool_infos:
        if not per_hostpool_info['cluster_id']:
            pass
        else:
            # 查找每一个集群使用情况,以及集群中每一台物理机使用情况
            _all_host_num, _all_host_data = host_s.HostService().get_hosts_of_hostpool(per_hostpool_info['cluster_id'])
            if _all_host_num > 0:
                # # 过滤超过50台虚拟机的物理机
                v_filter = instance_filter.instance_nums_filter(INSTANCE_MAX_NUMS_IN_HOST)
                hosts = filter(v_filter, _all_host_data)
                if not hosts:
                    pass
                else:
                    _host_pool_cpu_mem_used = get_hostpool_mem_cpu_disk_used(hosts, mem_mb, disk_gb
                                                                             , per_hostpool_info['cluster_id'])
                    host_pool_params = {
                        "cluster_id": per_hostpool_info['cluster_id'],
                        "cluster_app_code": per_hostpool_info['cluster_app_code'],
                        "cluster_type": per_hostpool_info["cluster_type"],
                        "cluster_name": per_hostpool_info['cluster_name'],
                        "env": env,
                        "datacenter": datacenter,
                        "net_area": per_hostpool_info['net_area_name'],
                        "available_host_num": _host_pool_cpu_mem_used['all_available_host_num'],
                        "total_capacity": {
                            "mem_mb": _host_pool_cpu_mem_used['mem_all'],
                            "vcpu": _host_pool_cpu_mem_used['cpu_all'],
                            "disk_gb": _host_pool_cpu_mem_used['disk_all']
                        },
                        "assign_capacity": {
                            "mem_mb": _host_pool_cpu_mem_used['mem_assign'],
                            "vcpu": _host_pool_cpu_mem_used['cpu_assign'],
                            "disk_gb": _host_pool_cpu_mem_used['disk_assign']
                        },
                        "available_capacity": {
                            "mem_mb": _host_pool_cpu_mem_used['mem_available'],
                            "vcpu": _host_pool_cpu_mem_used['cpu_unused'],
                            "disk_gb": _host_pool_cpu_mem_used['disk_available'],
                            "vm_count": _host_pool_cpu_mem_used['available_create_vm'],
                            "ip_count": __all_ip_available_num(dc_list[0]['dc_id'], per_hostpool_info['net_area_id'])
                        },
                        "performance": {
                            "mem_usage": _host_pool_cpu_mem_used['mem_used_per'],
                            "vcpu_usage": _host_pool_cpu_mem_used['cpu_used_per'],
                            "disk_usage": _host_pool_cpu_mem_used['disk_used_per']
                        },
                        "host_datas": _host_pool_cpu_mem_used['all_host_performance_datas']
                    }
                    capacity_detail.append(host_pool_params)
                    all_available_vm_count += _host_pool_cpu_mem_used['available_create_vm']
    # TODO 维石之后取消
    # net_set = []
    # delete_set = []
    #
    # for index, each in enumerate(capacity_detail):
    #     net_area = each["net_area"]
    #     if net_area in net_set:
    #         delete_set.append(each)
    #     else:
    #         net_set.append(net_area)
    # for delete_each in delete_set:
    #     capacity_detail.remove(delete_each)
    # TODO 结束

    params = {
        "currentPage": int(page_num),
        "pageSize": int(page_size),
        "total": len(capacity_detail),
        "available_vm_count": all_available_vm_count,
        "available_ip_count": available_ip_count,
        "cluster_datas": capacity_detail
    }

    return json_helper.format_api_resp_msg_to_vishnu_resource(job_status=VsJobStatus.SUCCEED,
                                                              detail=params)
def ips_apply_from_other_platform():
    '''
        外部平台申请KVM IP, IP会置为预分配
    :return:
    '''
    data_from_api = request.data
    logging.info(data_from_api)
    data_requset = json_helper.loads(data_from_api)
    req_datacenter = data_requset['dataCenter']
    req_env = data_requset['env']
    req_net_area = data_requset['netArea']
    count = data_requset['ipNums']
    netcare_type = data_requset.get('netCardType', NetCardType.INTERNAL)

    # 校验入参是否为空
    if not req_net_area or not req_datacenter or not req_env or not count:
        return json_helper.format_api_resp_msg(code=ErrorCode.PARAM_ERR, job_status=VsJobStatus.FAILED,
                                               detail='机房、环境、网络区域或ip数量入参为空')

    # 查询指定环境、网络区域是否有所需网段,容灾微应用需要遍历联通、电信所有可用网段
    if DataCenterTypeForVishnu.TYPE_DICT[req_env] == DataCenterType.MINIARCHDR:
        ret_segment_datas_telecom = segment_s.get_segments_data_by_type(req_net_area, req_datacenter,
                                                                        str(DataCenterTypeForVishnu.TYPE_DICT[req_env]),
                                                                        NetCardType.INTERNEL_TELECOM)
        ret_segment_datas_unicom = segment_s.get_segments_data_by_type(req_net_area, req_datacenter,
                                                                       str(DataCenterTypeForVishnu.TYPE_DICT[req_env]),
                                                                       NetCardType.INTERNEL_UNICOM)
        ret_segment_datas = ret_segment_datas_telecom + ret_segment_datas_unicom

    else:
        ret_segment_datas = segment_s.get_segments_data_by_type(req_net_area, req_datacenter,
                                                                str(DataCenterTypeForVishnu.TYPE_DICT[req_env]),
                                                                netcare_type)
    if not ret_segment_datas:
        return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
                                               detail='指定机房、网络区域下没有可用网段用于分配IP')

    # 获取IP资源,先判断是否有人也在分配IP资源,有则等待1s,时间之后再优化
    ip_lock_unused = False
    while not ip_lock_unused:
        ret_ip_lock_status = ip_l_s.IpLockService().get_ip_lock_info('ip')
        if not ret_ip_lock_status:
            logging.error('外部接口分配vip:检查IP时无法获取资源锁状态')
            return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
                                                   detail='检查IP时无法获取资源锁状态')
        if ret_ip_lock_status['istraceing'] == IpLockStatus.USED:
            time.sleep(1)
        else:
            ip_lock_unused = True

    # 更新ip_lock表istraceing字段为1
    ret_ip_lock_used_status, ret_ip_lock_used_datas = __update_ip_lock_used()
    if not ret_ip_lock_used_status:
        logging.error(ret_ip_lock_used_datas)
        return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
                                               detail=ret_ip_lock_used_datas)

    try:
        # 获取可用ip
        ret_ip_datas, ret_ip_segment_datas = ip_service.get_available_ips(ret_segment_datas, int(count), str(DataCenterTypeForVishnu.TYPE_DICT[req_env]))
        if not ret_ip_datas:
            ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused()
            if not ret_ip_lock_unused_status:
                logging.error(ret_ip_lock_unused_datas)
                return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
                                                       detail=ret_ip_lock_unused_datas)
            return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
                                                   detail='指定机房、网络区域下无法找到%s个可用IP' % str(count))

        # 如果是申请生产或者容灾环境ip,需判断网段对应关系表中是否有记录
        if req_env == 'PRD':
            segment_dr = segment_m.SegmentMatchService().get_segment_match_info_by_prd_segment_id(ret_ip_segment_datas['id'])
            if not segment_dr:
                ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused()
                if not ret_ip_lock_unused_status:
                    logging.error(ret_ip_lock_unused_datas)
                    return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
                                                           detail=ret_ip_lock_unused_datas)
                return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
                                                       detail='指定机房、网络区域下无法找到生产网段对应的容灾网段ID')
            segment_dr_data = segment_s.SegmentService().get_segment_info(segment_dr['dr_segment_id'])
            if not segment_dr_data:
                ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused()
                if not ret_ip_lock_unused_status:
                    logging.error(ret_ip_lock_unused_datas)
                    return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
                                                           detail=ret_ip_lock_unused_datas)
                return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
                                                       detail='指定机房、网络区域下无法找到生产网段对应的容灾网段详细信息')

        elif req_env == 'DR':
            segment_prd = segment_m.SegmentMatchService().get_segment_match_info_by_dr_segment_id(ret_ip_segment_datas['id'])
            if not segment_prd:
                ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused()
                if not ret_ip_lock_unused_status:
                    logging.error(ret_ip_lock_unused_datas)
                    return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
                                                           detail=ret_ip_lock_unused_datas)
                return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
                                                       detail='指定机房、网络区域下无法找到容灾网段对应的生产网段ID')
            segment_prd_data = segment_s.SegmentService().get_segment_info(segment_prd['prd_segment_id'])
            if not segment_prd_data:
                ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused()
                if not ret_ip_lock_unused_status:
                    logging.error(ret_ip_lock_unused_datas)
                    return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
                                                           detail=ret_ip_lock_unused_datas)
                return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
                                                       detail='指定机房、网络区域下无法找到容灾网段对应的生产网段详细信息')

        # 标记ip为预分配
        logging.info(ret_ip_datas)
        ips_list = []
        prd_ips_list = []
        dr_ips_list = []
        ip_details = {}
        for ip in ret_ip_datas:
            update_data = {
                'status': IPStatus.PRE_ALLOCATION,
                'updated_at': get_datetime_str()
            }
            where_data = {
                'id': ip['id']
            }
            ret_mark_ip = ip_service.IPService().update_ip_info(update_data, where_data)
            if ret_mark_ip <= 0:
                continue
            ip_datas = {
                'ip': ip['ip_address'],
                'vlanId': ip['vlan'],
                'subnetMask': __exchange_maskint(int(ip['netmask'])),
                'gateway': ip['gateway_ip'],
                'ip_type': ret_ip_segment_datas['segment_type']
            }
            ips_list.append(ip_datas)

            # 生产环境需要预分配对应容灾环境ip,容灾环境需要预分配生产环境ip
            if req_env == 'PRD':
                # 拼凑虚拟机容灾ip并预分配ip
                dr_ip = segment_dr_data['segment'].split('.')[0] + '.' + segment_dr_data['segment'].split('.')[1] + \
                        '.' + ip['ip_address'].split('.')[2] + '.' + ip['ip_address'].split('.')[3]
                dr_ip_info = ip_service.IPService().get_ip_by_ip_address(dr_ip)
                # 如果容灾环境ip未初始化,默认初始化
                if not dr_ip_info:
                    if not __init_ip(segment_dr_data, dr_ip):
                        continue
                    dr_ip_info = ip_service.IPService().get_ip_by_ip_address(dr_ip)

                update_data = {
                    'status': IPStatus.PRE_ALLOCATION
                }
                where_data = {
                    'ip_address': dr_ip
                }
                ret_mark_ip = ip_service.IPService().update_ip_info(update_data, where_data)
                if ret_mark_ip <= 0:
                    continue

                # 拼装容灾ip信息
                dr_ip_datas = {
                    'ip': dr_ip_info['ip_address'],
                    'vlanId': dr_ip_info['vlan'],
                    'subnetMask': __exchange_maskint(int(dr_ip_info['netmask'])),
                    'gateway': dr_ip_info['gateway_ip']
                }
                dr_ips_list.append(dr_ip_datas)
            elif req_env == 'DR':
                # 拼凑虚拟机生产ip并预分配ip
                prd_ip = segment_prd_data['segment'].split('.')[0] + '.' + segment_prd_data['segment'].split('.')[1] + \
                         '.' + ip['ip_address'].split('.')[2] + '.' + ip['ip_address'].split('.')[3]
                prd_ip_info = ip_service.IPService().get_ip_by_ip_address(prd_ip)
                # 如果生产环境ip未初始化,默认初始化
                if not prd_ip_info:
                    if not __init_ip(segment_prd_data, prd_ip):
                        continue
                    prd_ip_info = ip_service.IPService().get_ip_by_ip_address(prd_ip)
                update_data = {
                    'status': IPStatus.PRE_ALLOCATION
                }
                where_data = {
                    'ip_address': prd_ip
                }
                ret_mark_ip = ip_service.IPService().update_ip_info(update_data, where_data)
                if ret_mark_ip <= 0:
                    continue

                # 拼装生产ip信息
                prd_ip_datas = {
                    'ip': prd_ip_info['ip_address'],
                    'vlanId': prd_ip_info['vlan'],
                    'subnetMask': __exchange_maskint(int(prd_ip_info['netmask'])),
                    'gateway': prd_ip_info['gateway_ip']
                }
                prd_ips_list.append(prd_ip_datas)
    except Exception as e:
        _msg = '外部接口预分配IP:预分配ip出现异常: distribution ip exception,err:%s' %e
        logging.error(_msg)
        ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused()
        if not ret_ip_lock_unused_status:
            logging.error(ret_ip_lock_unused_datas)
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_ip_lock_unused_datas)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=_msg)
    # 更新ip_lock表istraceing字段为0
    ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused()
    if not ret_ip_lock_unused_status:
        logging.error(ret_ip_lock_unused_datas)
        return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
                                               detail=ret_ip_lock_unused_datas)

    if len(ips_list) <= 0:
        return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
                                               detail='指定机房、网络区域下%s个可用IP修改为预分配状态全部失败' % str(count))
    elif req_env == 'PRD' and (len(ips_list) + len(dr_ips_list)) < int(count)*2:
        return json_helper.format_api_resp_msg(code=ErrorCode.SUCCESS_PART, job_status=VsJobStatus.FAILED,
                                               detail='生产环境指定机房、网络区域下%s个可用IP修改为预分配状态部分失败' % str(count))
    elif req_env == 'DR' and (len(ips_list) + len(prd_ips_list)) < int(count)*2:
        return json_helper.format_api_resp_msg(code=ErrorCode.SUCCESS_PART, job_status=VsJobStatus.FAILED,
                                               detail='容灾环境指定机房、网络区域下%s个可用IP修改为预分配状态部分失败' % str(count))
    elif len(ips_list) < int(count):
        return json_helper.format_api_resp_msg(code=ErrorCode.SUCCESS_PART, job_status=VsJobStatus.FAILED,
                                               detail='指定机房、网络区域下%s个可用IP修改为预分配状态部分失败' % str(count))
    else:
        if req_env == 'PRD':
            ip_details['prd'] = ips_list
            ip_details['dr'] = dr_ips_list
        elif req_env == 'DR':
            ip_details['dr'] = ips_list
            ip_details['prd'] = prd_ips_list
        else:
            ip_details['default'] = ips_list
        logging.info(ip_details)
        return json_helper.format_api_resp_msg(code=ErrorCode.SUCCESS, job_status=VsJobStatus.SUCCEED,
                                               detail=ip_details)
def ip_apply_from_other_platform():
    '''
        外部平台申请ip
    :return:
    '''
    data_from_vishnu = request.data
    logging.info(data_from_vishnu)
    data_requset = json_helper.loads(data_from_vishnu)
    req_datacenter = data_requset['datacenter']
    req_env = data_requset['env']
    req_net_area = data_requset['net_area']
    req_net_name = data_requset['net_name']
    cluster_id = data_requset['cluster_id']
    opuser = data_requset['opUser']
    sys_code = data_requset['sys_code']
    taskid_vs = data_requset['taskid']
    ip_count = data_requset['ipCount']
    prd_dr_ip_all_needed = data_requset['prdDrAllNeeded']  # '0'代表普通申请,'1'需要同时申请prd、dr环境的ip

    # 校验入参是否为空
    if not req_env or not req_net_area or not req_net_name or not req_datacenter:
        return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
                                               detail='empty input of env, net area information or net name '
                                                      'when apply ip')
    if not cluster_id or not opuser or not sys_code or not taskid_vs:
        return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
                                               detail='empty input of cluster_id, opuser, '
                                                      'task id or sys_code when apply ip')

    if not str(ip_count) or not str(prd_dr_ip_all_needed):
        return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
                                               detail='empty input of ipCount or prdDrAllNeeded when apply ip')

    # 查询指定环境、网络区域是否有所需网段
    ret_segment = segment_service.SegmentService().get_segment_info_bysegment(req_net_name.split('/')[0])
    if not ret_segment:
        return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
                                               detail="无法找到需要申请的网段")

    ret_net_area_info = net_area.NetAreaService().get_net_area_info(ret_segment['net_area_id'])
    if not ret_net_area_info:
        return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
                                               detail="无法找到指定网段所属网络区域信息")

    ret_datacenter_info = datacenter_service.DataCenterService().get_datacenter_info(ret_net_area_info['datacenter_id'])
    if not ret_datacenter_info:
        return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
                                               detail="无法找到指定机房信息")
    if req_env not in DataCenterTypeForVishnu.TYPE_DICT:
        return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
                                               detail="无法找到指定机房类型信息")
    if str(DataCenterTypeForVishnu.TYPE_DICT[req_env]) != ret_datacenter_info['dc_type']:
        return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
                                               detail="无法找到指定网络区域对应网段信息")

    # 如果是申请生产或者容灾环境ip,需判断网段对应关系表中是否有记录
    if req_env == 'PRD':
        segment_dr = segment_m.SegmentMatchService().get_segment_match_info_by_prd_segment_id(
            ret_segment['id'])
        if not segment_dr:
            return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
                                                   detail='指定机房、网络区域下无法找到生产网段对应的容灾网段ID')
        segment_dr_data = segment_s.SegmentService().get_segment_info(segment_dr['dr_segment_id'])
        if not segment_dr_data:
            return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
                                                   detail='指定机房、网络区域下无法找到生产网段对应的容灾网段详细信息')

    elif req_env == 'DR':
        segment_prd = segment_m.SegmentMatchService().get_segment_match_info_by_dr_segment_id(
            ret_segment['id'])
        if not segment_prd:
            return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
                                                   detail='指定机房、网络区域下无法找到容灾网段对应的生产网段ID')
        segment_prd_data = segment_s.SegmentService().get_segment_info(segment_prd['prd_segment_id'])
        if not segment_prd_data:
            return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
                                                   detail='指定机房、网络区域下无法找到容灾网段对应的生产网段详细信息')

    # 获取IP资源,先判断是否有人也在分配IP资源,有则等待1s,时间之后再优化
    ip_lock_unused = False
    while not ip_lock_unused:
        ret_ip_lock_status = ip_l_s.IpLockService().get_ip_lock_info('ip')
        if not ret_ip_lock_status:
            logging.error('外部接口分配vip:检查IP时无法获取资源锁状态')
            return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
                                                   detail='检查IP时无法获取资源锁状态')
        if ret_ip_lock_status['istraceing'] == IpLockStatus.USED:
            time.sleep(1)
        else:
            ip_lock_unused = True

    # 更新ip_lock表istraceing字段为1
    ret_ip_lock_used_status, ret_ip_lock_used_datas = __update_ip_lock_used()
    if not ret_ip_lock_used_status:
        logging.error(ret_ip_lock_used_datas)
        return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
                                               detail=ret_ip_lock_used_datas)
    try:
        segments_data_list = []
        segments_data_list.append(ret_segment)
        # 获取可用ip
        ret_ip_datas, ret_ip_segment_datas = ip_service.get_available_ips(segments_data_list, int(ip_count), str(
            DataCenterTypeForVishnu.TYPE_DICT[req_env]))
        if not ret_ip_datas:
            ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused()
            if not ret_ip_lock_unused_status:
                logging.error(ret_ip_lock_unused_datas)
                return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
                                                       detail=ret_ip_lock_unused_datas)
            return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
                                                   detail='指定机房、网络区域下无法找到%s个可用IP' % str(ip_count))

        # 标记ip为预分配
        logging.info(ret_ip_datas)
        ips_list = []
        prd_ips_list = []
        dr_ips_list = []
        ip_details = {}
        for ip in ret_ip_datas:
            update_data = {
                'status': IPStatus.USED
            }
            where_data = {
                'id': ip['id']
            }
            ret_mark_ip = ip_service.IPService().update_ip_info(update_data, where_data)
            if ret_mark_ip <= 0:
                continue

            # 录入vip信息到数据库中
            insert_vip_data = {
                'ip_id': ip['id'],
                'cluster_id': cluster_id,
                'apply_user_id': opuser,
                'sys_code': sys_code,
                'isdeleted': '0',
                'created_at': get_datetime_str()
            }
            ret_vip = vip_service.VIPService().add_vip_info(insert_vip_data)
            if ret_vip.get('row_num') <= 0:
                continue

            ip_datas = {
                'ip': ip['ip_address'],
                'vlanId': ip['vlan'],
                'subnetMask': __exchange_maskint(int(ip['netmask'])),
                'gateway': ip['gateway_ip']
            }
            ips_list.append(ip_datas)

            # 生产环境需要预分配对应容灾环境ip,容灾环境需要预分配生产环境ip
            if req_env == 'PRD':
                # 拼凑虚拟机容灾ip并预分配ip
                dr_ip = segment_dr_data['segment'].split('.')[0] + '.' + segment_dr_data['segment'].split('.')[1] + \
                        '.' + ip['ip_address'].split('.')[2] + '.' + ip['ip_address'].split('.')[3]
                dr_ip_info = ip_service.IPService().get_ip_by_ip_address(dr_ip)
                # 如果容灾环境ip未初始化,默认初始化
                if not dr_ip_info:
                    if not __init_ip(segment_dr_data, dr_ip):
                        continue
                    dr_ip_info = ip_service.IPService().get_ip_by_ip_address(dr_ip)

                if prd_dr_ip_all_needed == '1':
                    update_data = {
                        'status': IPStatus.USED
                    }
                    where_data = {
                        'id': dr_ip_info['id']
                    }
                    ret_mark_ip = ip_service.IPService().update_ip_info(update_data, where_data)
                    if ret_mark_ip <= 0:
                        continue

                    # 录入vip信息到数据库中
                    insert_vip_data = {
                        'ip_id': dr_ip_info['id'],
                        'cluster_id': cluster_id,
                        'apply_user_id': opuser,
                        'sys_code': sys_code,
                        'isdeleted': '0',
                        'created_at': get_datetime_str()
                    }
                    ret_vip = vip_service.VIPService().add_vip_info(insert_vip_data)
                    if ret_vip.get('row_num') <= 0:
                        continue
                else:
                    update_data = {
                        'status': IPStatus.PRE_ALLOCATION
                    }
                    where_data = {
                        'ip_address': dr_ip
                    }
                    ret_mark_ip = ip_service.IPService().update_ip_info(update_data, where_data)
                    if ret_mark_ip <= 0:
                        continue

                # 拼装容灾ip信息
                dr_ip_datas = {
                    'ip': dr_ip_info['ip_address'],
                    'vlanId': dr_ip_info['vlan'],
                    'subnetMask': __exchange_maskint(int(dr_ip_info['netmask'])),
                    'gateway': dr_ip_info['gateway_ip']
                }
                dr_ips_list.append(dr_ip_datas)
            elif req_env == 'DR':
                # 拼凑虚拟机生产ip并预分配ip
                prd_ip = segment_prd_data['segment'].split('.')[0] + '.' + segment_prd_data['segment'].split('.')[1] + \
                         '.' + ip['ip_address'].split('.')[2] + '.' + ip['ip_address'].split('.')[3]
                prd_ip_info = ip_service.IPService().get_ip_by_ip_address(prd_ip)
                # 如果生产环境ip未初始化,默认初始化
                if not prd_ip_info:
                    if not __init_ip(segment_prd_data, prd_ip):
                        continue
                    prd_ip_info = ip_service.IPService().get_ip_by_ip_address(prd_ip)

                if prd_dr_ip_all_needed == '1':
                    update_data = {
                        'status': IPStatus.USED
                    }
                    where_data = {
                        'id': prd_ip_info['id']
                    }
                    ret_mark_ip = ip_service.IPService().update_ip_info(update_data, where_data)
                    if ret_mark_ip <= 0:
                        continue

                    # 录入vip信息到数据库中
                    insert_vip_data = {
                        'ip_id': prd_ip_info['id'],
                        'cluster_id': cluster_id,
                        'apply_user_id': opuser,
                        'sys_code': sys_code,
                        'isdeleted': '0',
                        'created_at': get_datetime_str()
                    }
                    ret_vip = vip_service.VIPService().add_vip_info(insert_vip_data)
                    if ret_vip.get('row_num') <= 0:
                        continue
                else:
                    update_data = {
                        'status': IPStatus.PRE_ALLOCATION
                    }
                    where_data = {
                        'ip_address': prd_ip
                    }
                    ret_mark_ip = ip_service.IPService().update_ip_info(update_data, where_data)
                    if ret_mark_ip <= 0:
                        continue

                # 拼装生产ip信息
                prd_ip_datas = {
                    'ip': prd_ip_info['ip_address'],
                    'vlanId': prd_ip_info['vlan'],
                    'subnetMask': __exchange_maskint(int(prd_ip_info['netmask'])),
                    'gateway': prd_ip_info['gateway_ip']
                }
                prd_ips_list.append(prd_ip_datas)
    except Exception as e:
        _msg = '外部平台申请IP:预分配ip出现异常: distribution ip exception,err:%s'%e
        logging.error(_msg)
        ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused()
        if not ret_ip_lock_unused_status:
            logging.error(ret_ip_lock_unused_datas)
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_ip_lock_unused_datas)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=_msg)

    # 更新ip_lock表istraceing字段为0
    ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused()
    if not ret_ip_lock_unused_status:
        logging.error(ret_ip_lock_unused_datas)
        return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
                                               detail=ret_ip_lock_unused_datas)

    if len(ips_list) <= 0:
        return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
                                               detail='指定机房、网络区域下%s个可用IP修改为预分配状态全部失败' % str(ip_count))
    elif req_env == 'PRD' and (len(ips_list) + len(dr_ips_list)) < int(ip_count) * 2:
        return json_helper.format_api_resp_msg(code=ErrorCode.SUCCESS_PART, job_status=VsJobStatus.FAILED,
                                               detail='生产环境指定机房、网络区域下%s个可用IP修改为预分配状态部分失败' % str(ip_count))
    elif req_env == 'DR' and (len(ips_list) + len(prd_ips_list)) < int(ip_count) * 2:
        return json_helper.format_api_resp_msg(code=ErrorCode.SUCCESS_PART, job_status=VsJobStatus.FAILED,
                                               detail='容灾环境指定机房、网络区域下%s个可用IP修改为预分配状态部分失败' % str(ip_count))
    elif len(ips_list) < int(ip_count):
        return json_helper.format_api_resp_msg(code=ErrorCode.SUCCESS_PART, job_status=VsJobStatus.FAILED,
                                               detail='指定机房、网络区域下%s个可用IP修改为预分配状态部分失败' % str(ip_count))
    else:
        if req_env == 'PRD':
            ip_details['prd'] = ips_list
            ip_details['dr'] = dr_ips_list
        elif req_env == 'DR':
            ip_details['dr'] = ips_list
            ip_details['prd'] = prd_ips_list
        else:
            ip_details['default'] = ips_list
        return json_helper.format_api_resp_msg(code=ErrorCode.SUCCESS, job_status=VsJobStatus.SUCCEED,
                                               detail=ip_details)
Example #8
0
def instance_create_from_other_platform_with_ip():
    '''
      外部平台虚拟机创建
    :return:
    '''
    _init_log('instanc_create_request_from_other_platform')
    data_from_other_platform = request.data
    logging.info(data_from_other_platform)
    data_requset = json_helper.loads(data_from_other_platform)
    image_name = data_requset['image']
    vcpu = data_requset['vcpu']
    mem_mb = data_requset['mem_MB']
    disk_gb = data_requset['disk_GB']
    count = data_requset['count']
    sys_code = data_requset['sys_code']
    opuser = data_requset['opUser']
    taskid_vs = data_requset['taskid']
    req_env = data_requset['env']
    req_net_area = data_requset['net_area']
    req_datacenter = data_requset['datacenter']
    task_id_kvm = ins_s.generate_task_id()
    sys_opr_name = data_requset['Op_Main_Engineer_Primary']
    sys_opr_id = data_requset['Op_Main_Engineer_Prim']
    cluster_id = data_requset['cluster_id']
    vip_needed = data_requset['vip_needed']  # 是否需要vip,0为不需要,1需要
    vm_ip_info = data_requset['vm_info']
    vip_info = data_requset['vip_info']
    api_origin = data_requset[
        'apiOrigin']  # api名称,维石为vishnu, 软负载为sfslb, 其他的需要定义
    # 前端暂时不是传虚拟机root密码过来
    password = None
    app_info = data_requset['application_info']
    # hostpool_id = int(data_requset['hostpool_id'])  # 特殊类型应用,返回集群id
    hostpool_id = ''

    logging.info('task %s : check params start when create instance',
                 task_id_kvm)

    if not taskid_vs or not api_origin:
        return json_helper.format_api_resp_msg_to_vishnu(
            req_id=taskid_vs,
            job_status=VsJobStatus.FAILED,
            detail='empty input of taskid or api_origin when create '
            'instance')

    # 判断工单是否为失败重做
    check_job_data = {
        'WHERE_AND': {
            '=': {
                'taskid_api': taskid_vs
            },
        },
    }
    ret_job_num, ret_job_data = request_r_s.RequestRecordService(
    ).request_db_query_data(**check_job_data)
    if ret_job_num == 1:
        for _job_data in ret_job_data:
            if _job_data['task_status'] == '0':
                return json_helper.format_api_resp_msg_to_vishnu(
                    req_id=taskid_vs,
                    job_status=VsJobStatus.FAILED,
                    detail='task is now doing, wait a moment, '
                    'do not repeat create')
            elif _job_data['task_status'] == '1':
                # 将request_record数据库表中“task_status”、“response_to_api”重置为0重启任务
                update_db_time = get_datetime_str()
                _update_data = {
                    'task_status': '0',
                    'response_to_api': '0',
                    'finish_time': update_db_time,
                    'request_status_collect_time': update_db_time,
                }
                _where_data = {
                    'taskid_api': taskid_vs,
                }
                ret = request_r_s.RequestRecordService().update_request_status(
                    _update_data, _where_data)
                if ret <= 0:
                    return json_helper.format_api_resp_msg_to_vishnu(
                        req_id=taskid_vs,
                        job_status=VsJobStatus.FAILED,
                        detail='update request status failed, '
                        'please call kvm system manager '
                        'or retry create again')
                return json_helper.format_api_resp_msg_to_vishnu(
                    req_id=taskid_vs,
                    job_status=VsJobStatus.SUCCEED,
                    detail='start to recreate vm')
            elif _job_data['task_status'] == '2':
                threads = []
                # 将request_record数据库表中“task_status”、“response_to_api”重置为0重启任务
                update_db_time = get_datetime_str()
                _update_data = {
                    'task_status': '0',
                    'response_to_api': '0',
                    'finish_time': update_db_time,
                    'request_status_collect_time': update_db_time,
                }
                _where_data = {
                    'taskid_api': taskid_vs,
                }
                ret = request_r_s.RequestRecordService().update_request_status(
                    _update_data, _where_data)
                if ret <= 0:
                    return json_helper.format_api_resp_msg_to_vishnu(
                        req_id=taskid_vs,
                        job_status=VsJobStatus.FAILED,
                        detail='update request status failed, '
                        'please call kvm system manager '
                        'or retry create again')
                # 找到工单对应的虚拟机,发送task_id、request_id到kafka重新创建
                ins_params = {
                    'WHERE_AND': {
                        "=": {
                            'task_id': _job_data['taskid_kvm'],
                            'isdeleted': '0',
                            'status': '100'
                        }
                    },
                }
                ins_num, ins_data = ins_s.InstanceService().query_data(
                    **ins_params)
                if ins_num > 0:
                    for per_ins_data in ins_data:
                        kafka_send_thread = threading.Thread(
                            target=instance_msg_send_to_kafka,
                            args=(
                                per_ins_data['task_id'],
                                per_ins_data['request_id'],
                            ))
                        threads.append(kafka_send_thread)
                        kafka_send_thread.start()
                    # 判断多线程是否结束
                    for t in threads:
                        t.join()
                return json_helper.format_api_resp_msg_to_vishnu(
                    req_id=taskid_vs,
                    job_status=VsJobStatus.SUCCEED,
                    detail='start to recreate vm')

    if api_origin == ApiOriginString.VISHNU:
        api_origin = ApiOrigin.VISHNU
    elif api_origin == ApiOriginString.SFSLB:
        api_origin = ApiOrigin.SFSLB
    elif api_origin == ApiOriginString.FWAF:
        api_origin = ApiOrigin.FWAF
    else:
        api_origin = ApiOrigin.VISHNU

    if vip_needed == '1' and len(vip_info) <= 0:
        return json_helper.format_api_resp_msg_to_vishnu(
            req_id=taskid_vs,
            job_status=VsJobStatus.FAILED,
            detail='empty input of vip datas when create instance')

    # 校验前端vip是否存在数据库中且ip为预保留状态
    if vip_needed == '1':
        vip_available = 0
        vip_info_list = []
        for per_vip in vip_info:
            per_vip_info = ip_service.IPService().get_ip_by_ip_address(
                per_vip['ip'])
            if per_vip_info and per_vip_info[
                    'status'] == IPStatus.PRE_ALLOCATION:
                vip_info_list.append(per_vip_info)
                vip_available += 1

        if vip_available != len(vip_info):
            return json_helper.format_api_resp_msg_to_vishnu(
                req_id=taskid_vs,
                job_status=VsJobStatus.FAILED,
                detail='vip nums from vishnu not equal apply vip nums '
                'when create instance')

    # 校验前端ip是否存在数据库中且ip为预保留状态
    ip_available = 0
    ip_info_list = []
    for per_ip in vm_ip_info:
        per_ip_info = ip_service.IPService().get_ip_by_ip_address(per_ip['ip'])
        if per_ip_info and per_ip_info['status'] == IPStatus.PRE_ALLOCATION:
            ip_info_list.append(per_ip_info)
            ip_available += 1

    if ip_available != int(count):
        return json_helper.format_api_resp_msg_to_vishnu(
            req_id=taskid_vs,
            job_status=VsJobStatus.FAILED,
            detail='vm ip nums from vishnu not equal apply vm nums '
            'when create instance')

    # 获取ip对应的网段信息
    segment_info = segment_service.SegmentService().get_segment_info(
        ip_info_list[0]['segment_id'])
    if not segment_info:
        return json_helper.format_api_resp_msg_to_vishnu(
            req_id=taskid_vs,
            job_status=VsJobStatus.FAILED,
            detail='can not find segment infomation for ip '
            'when create instance')

    # 根据维石平台输入的虚拟机cpu、内存选择模板
    if not vcpu or not mem_mb:
        return json_helper.format_api_resp_msg_to_vishnu(
            req_id=taskid_vs,
            job_status=VsJobStatus.FAILED,
            detail='empty input of vcpu or mem_MB when create instance')
    flavor_query = flavor_service.get_flavor_by_vcpu_and_memory(vcpu, mem_mb)
    if not flavor_query:
        return json_helper.format_api_resp_msg_to_vishnu(
            req_id=taskid_vs,
            job_status=VsJobStatus.FAILED,
            detail='can not get flavor information when create instance')
    flavor_id = flavor_query['id']

    # 根据维石平台输入的环境、网络区域查找对应的物理集群
    if not req_env or not req_net_area:
        return json_helper.format_api_resp_msg_to_vishnu(
            req_id=taskid_vs,
            job_status=VsJobStatus.FAILED,
            detail='empty input of req_net_area or req_env '
            'when create instance')
    if not hostpool_id:
        hostpool_query = hostpool_service.get_hostpool_info_by_name(
            str(DataCenterTypeForVishnu.TYPE_DICT[req_env]), req_datacenter,
            req_net_area)
        if not hostpool_query:
            return json_helper.format_api_resp_msg_to_vishnu(
                req_id=taskid_vs,
                job_status=VsJobStatus.FAILED,
                detail='can not get host_pool information '
                'when create instance')
        hostpool_id = hostpool_query['hostpool_id']

    # 根据维石平台输入的系统运维人员工号维护对应应用组信息
    if not sys_opr_id or not cluster_id:
        return json_helper.format_api_resp_msg_to_vishnu(
            req_id=taskid_vs,
            job_status=VsJobStatus.FAILED,
            detail='empty input of sys_opr_name, sys_opr_id '
            'or cluster_id when create instance')

    ret_group, group_id = _user_group_check(
        str(DataCenterTypeForVishnu.TYPE_DICT[req_env]), sys_code,
        sys_opr_name, sys_opr_id, cluster_id)
    if not ret_group:
        return json_helper.format_api_resp_msg_to_vishnu(
            req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail=group_id)

    if not hostpool_id or not image_name or not flavor_id or not disk_gb or not group_id \
            or not count or int(count) < 1:
        logging.error('task %s : params are invalid when create instance',
                      task_id_kvm)
        return json_helper.format_api_resp_msg_to_vishnu(
            req_id=taskid_vs,
            job_status=VsJobStatus.FAILED,
            detail='empty input of image_name, disk_gb '
            'or count when create instance')

    if int(count) > int(INSTANCE_MAX_CREATE):
        logging.error(
            'task %s : create count %s > max num %s when create instance',
            task_id_kvm, count, INSTANCE_MAX_CREATE)
        return json_helper.format_api_resp_msg_to_vishnu(
            req_id=taskid_vs,
            job_status=VsJobStatus.FAILED,
            detail='批量创建最大实例数不能超过32个')

    logging.info('task %s : check params successful when create instance',
                 task_id_kvm)

    # 数据盘最少50GB
    # 这里只是一个数据盘,后面有多个数据盘
    vm_disk_gb = int(disk_gb) if int(disk_gb) > DATA_DISK_GB else DATA_DISK_GB

    # 获取主机列表(不包括锁定、维护状态)
    logging.info(
        'task %s : get all hosts in hostpool %s start when create instance',
        task_id_kvm, hostpool_id)
    all_hosts_nums, all_hosts_data = host_s.HostService(
    ).get_available_hosts_of_hostpool(hostpool_id)
    # 可用物理机数量不足
    least_host_num = hostpool_service.HostPoolService().get_least_host_num(
        hostpool_id)
    if all_hosts_nums < least_host_num or all_hosts_nums < 1:
        logging.error(
            'task %s : available host resource not enough when create instance',
            task_id_kvm)
        return json_helper.format_api_resp_msg_to_vishnu(
            req_id=taskid_vs,
            job_status=VsJobStatus.FAILED,
            detail='集群不够资源,无法创建实例')
    logging.info(
        'task %s : get all hosts in hostpool %s successful, all hosts nums %s when create instance',
        task_id_kvm, hostpool_id, all_hosts_nums)

    # 过滤host
    logging.info('task %s : filter hosts start when create instance',
                 task_id_kvm)
    hosts_after_filter = host_s_s.filter_hosts(all_hosts_data)
    if len(hosts_after_filter
           ) == 0 or len(hosts_after_filter) < least_host_num:
        logging.error('task %s : no available host when create instance',
                      task_id_kvm)
        return json_helper.format_api_resp_msg_to_vishnu(
            req_id=taskid_vs,
            job_status=VsJobStatus.FAILED,
            detail='没有适合的主机,无法创建实例')
    logging.info('task %s : filter hosts successful when create instance',
                 task_id_kvm)

    logging.info('task %s : get need info start when create instance',
                 task_id_kvm)
    # 获取flavor信息
    flavor_info = flavor_service.FlavorService().get_flavor_info(flavor_id)
    if not flavor_info:
        logging.error(
            'task %s : flavor %s info not in db when create instance',
            task_id_kvm, flavor_id)
        return json_helper.format_api_resp_msg_to_vishnu(
            req_id=taskid_vs,
            job_status=VsJobStatus.FAILED,
            detail='实例规格数据有误,无法创建实例')

    # VM分配给HOST
    logging.info('task %s : match hosts start when create instance',
                 task_id_kvm)
    vm = {
        "vcpu": flavor_info['vcpu'],
        "mem_MB": flavor_info['memory_mb'],
        "disk_GB": flavor_info['root_disk_gb'] + vm_disk_gb,  # 系统盘加数据盘
        "group_id": group_id,
        "count": count
    }
    host_list = host_s_s.match_hosts(hosts_after_filter,
                                     vm,
                                     least_host_num=least_host_num,
                                     max_disk=2000)
    host_len = len(host_list)
    if host_len == 0:
        logging.error(
            'task %s : match host resource not enough when create instance',
            task_id_kvm)
        return json_helper.format_api_resp_msg_to_vishnu(
            req_id=taskid_vs,
            job_status=VsJobStatus.FAILED,
            detail='没有适合的主机,无法创建实例')
    logging.info('task %s : match hosts successful when create instance',
                 task_id_kvm)

    # 获取hostpool的net area信息
    hostpool_info = hostpool_service.HostPoolService().get_hostpool_info(
        hostpool_id)
    if not hostpool_info:
        logging.error(
            'task %s : hostpool %s info not in db when create instance',
            task_id_kvm, hostpool_id)
        return json_helper.format_api_resp_msg_to_vishnu(
            req_id=taskid_vs,
            job_status=VsJobStatus.FAILED,
            detail='物理机池所属网络区域信息有误,无法创建实例')

    net_area_id = hostpool_info['net_area_id']
    logging.info('task %s : get need info successful when create instance',
                 task_id_kvm)

    # 组配额控制
    logging.info('task %s : check group quota start when create instance',
                 task_id_kvm)
    is_quota_enough, quota_msg = check_group_quota(group_id, flavor_info,
                                                   vm_disk_gb, count)
    if not is_quota_enough:
        logging.error(
            'task %s : group %s is no enough quota when create instance',
            task_id_kvm, group_id)
        return json_helper.format_api_resp_msg_to_vishnu(
            req_id=taskid_vs,
            job_status=VsJobStatus.FAILED,
            detail='资源组配额不足,无法创建实例')
    logging.info('task %s : check group quota successful when create instance',
                 task_id_kvm)

    ips_list = ip_info_list
    segment_data = segment_info
    logging.info('task %s : check ip resource start when create instance',
                 task_id_kvm)

    logging.info('task %s : get need 1 info start when create instance',
                 task_id_kvm)
    # 获取镜像信息,一个image_name可能对应多个id
    image_nums, image_data = image_service.ImageService().get_images_by_name(
        image_name)
    if image_nums <= 0:
        logging.info('task %s : no image %s info in db when create instance',
                     task_id_kvm, image_name)
        return json_helper.format_api_resp_msg_to_vishnu(
            req_id=taskid_vs,
            job_status=VsJobStatus.FAILED,
            detail='没有镜像资源,无法创建实例')

    # 获取集群所在的环境
    vm_env = hostpool_service.get_env_of_hostpool(hostpool_id)
    # hostpool对应的机房名
    dc_name = hostpool_service.get_dc_name_of_hostpool(hostpool_id)
    # 实例操作系统
    instance_system = image_data[0]['system']
    logging.info('task %s : get need 1 info successful when create instance',
                 task_id_kvm)

    # 获取虚机名资源
    logging.info(
        'task %s : check instance name resource start when create instance',
        task_id_kvm)
    is_name_enough, instance_name_list = _check_instance_name_resource(
        vm_env, dc_name, instance_system, count)
    if not is_name_enough:
        logging.error(
            'task %s : datacenter %s has no enough instance name resource',
            task_id_kvm, dc_name)
        return json_helper.format_api_resp_msg_to_vishnu(
            req_id=taskid_vs,
            job_status=VsJobStatus.FAILED,
            detail='主机名资源不足,无法创建实例')
    logging.info(
        'task %s : check instance name resource successful when create instance',
        task_id_kvm)

    # 如果需要vip,分配第‘count + 1’个同时记录vip_info表格
    if vip_needed == '1':
        for per_avalible_vip in vip_info_list:
            # 标记ip已使用
            update_vip_data = {'status': IPStatus.USED}
            where_vip_data = {'id': per_avalible_vip['id']}
            ret_mark_ip = ip_service.IPService().update_ip_info(
                update_vip_data, where_vip_data)
            if ret_mark_ip <= 0:
                return json_helper.format_api_resp_msg_to_vishnu(
                    req_id=taskid_vs,
                    job_status=VsJobStatus.FAILED,
                    detail="标记ip为已使用状态失败,请重新申请")
            # 录入vip信息到数据库中
            insert_vip_data = {
                'ip_id': per_avalible_vip['id'],
                'cluster_id': cluster_id,
                'apply_user_id': opuser,
                'sys_code': sys_code,
                'isdeleted': '0',
                'created_at': get_datetime_str()
            }
            ret_vip = vip_service.VIPService().add_vip_info(insert_vip_data)
            if ret_vip.get('row_num') <= 0:
                return json_helper.format_api_resp_msg_to_vishnu(
                    req_id=taskid_vs,
                    job_status=VsJobStatus.FAILED,
                    detail="录入ip信息失败,请联系系统管理员")

    # 挂载点
    if instance_system == 'linux':
        mount_point = '/app'
    else:
        mount_point = 'E'

    logging.info('task %s : create thread start when create instance',
                 task_id_kvm)
    user_id = get_user()['user_id']
    all_threads = []
    for i in range(int(count)):
        instance_name = str(instance_name_list[i])
        ip_data = ips_list[i]

        # 轮询host
        index = i % host_len
        vm_host = host_list[index]

        create_ins_t = threading.Thread(
            target=_create_instance_info,
            args=(task_id_kvm, instance_name, app_info, sys_opr_id, password,
                  flavor_id, group_id, vm_host, flavor_info, image_data,
                  ip_data, vm_disk_gb, mount_point, instance_system,
                  net_area_id, segment_data, vm_env, user_id, cluster_id),
            name='thread-instance-create-' + task_id_kvm)
        all_threads.append(create_ins_t)
        create_ins_t.start()

    for thread in all_threads:
        thread.join()

    logging.info('task %s : create thread successful when create instance',
                 task_id_kvm)
    # 录入外应用的taskid到工单表格中
    time_now_for_insert_request_to_db = get_datetime_str()
    request_info_data = {
        "taskid_api": taskid_vs,
        "api_origin": api_origin,
        "taskid_kvm": task_id_kvm,
        "vm_count": count,
        "user_id": opuser,
        "start_time": time_now_for_insert_request_to_db,
        "task_status": "0",  # 代表任务执行中
        "response_to_api": "0",
        "istraceing": "0",
        "request_status_collect_time": time_now_for_insert_request_to_db
    }
    request_record_db_ret = request_r_s.RequestRecordService(
    ).add_request_record_info(request_info_data)
    if request_record_db_ret.get('row_num') <= 0:
        logging.error(
            'task %s : can not add request record information to db when create instance',
            task_id_kvm)
        return json_helper.format_api_resp_msg_to_vishnu(
            req_id=taskid_vs,
            job_status=VsJobStatus.FAILED,
            detail='录入工单信息到数据库失败')

    return json_helper.format_api_resp_msg_to_vishnu(
        req_id=taskid_vs,
        job_status=VsJobStatus.SUCCEED,
        detail='start to create vm')
def instance_add_netcard_from_other_platform():
    '''
        kvm平台虚拟机添加网卡外部接口
        入参说明:
            {
                "instanceMainIp": "虚拟机主网ip列表"
                "apiOrigin": "",
                "netCardType": ""
            }
    :return:
    '''
    _init_log('instance_add_netcard_from_other_platform')
    logging.info(request.data)
    logging.info(request.values)
    logging.info(request.form)
    req_json = request.data
    req_data = json_helper.loads(req_json)

    instance_ip_list = req_data["instanceMainIp"]
    req_origin = req_data["apiOrigin"]
    netcard_type = req_data["netCardType"]

    # 判断需要配置网卡所有虚拟机是否存在
    if not instance_ip_list or not req_origin or not netcard_type:
        return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR,
                                               job_status=VsJobStatus.FAILED,
                                               detail='入参有空值,请检查')

    _ip_datas_list = []
    instance_data_list = []
    env_list = []
    dc_list = []
    net_area_list = []
    ip_str = ""
    # 判断ip列表中是否有不存在于kvm平台的
    for _ip in instance_ip_list:
        _instance_info = ip_s.get_instance_info_by_ip(_ip['ip'])
        if not _instance_info:
            ip_str += _ip['ip'] + " "
        else:
            _instance_params = {
                "instance_ip": _ip['ip'],
                "instance_uuid": _instance_info['instance_uuid'],
                "instance_id": _instance_info['instance_id'],
                "instance_name": _instance_info['instance_name'],
                "host_ip": _instance_info['host_ip'],
                "env": _instance_info['env'],
                "net_area": _instance_info['net_area_name'],
                "dc_name": _instance_info['datacenter_name'],
            }
            instance_data_list.append(_instance_params)
            env_list.append(_instance_info['env'])
            dc_list.append(_instance_info['datacenter_name'])
            net_area_list.append(_instance_info['net_area_name'])

    if ip_str:
        return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR,
                                               job_status=VsJobStatus.FAILED,
                                               detail='ip:%s无法在kvm平台中找到' %
                                               ip_str)

    if len(set(env_list)) > 1:
        return json_helper.format_api_resp_msg(
            code=ErrorCode.SYS_ERR,
            job_status=VsJobStatus.FAILED,
            detail='需要配置网卡的虚拟机属于不同环境,不允许同时配置')

    if len(set(dc_list)) > 1:
        return json_helper.format_api_resp_msg(
            code=ErrorCode.SYS_ERR,
            job_status=VsJobStatus.FAILED,
            detail='需要配置网卡的虚拟机属于不同机房,不允许同时配置')

    if len(set(net_area_list)) > 1:
        return json_helper.format_api_resp_msg(
            code=ErrorCode.SYS_ERR,
            job_status=VsJobStatus.FAILED,
            detail='需要配置网卡的虚拟机属于不同网络区域,不允许同时配置')

    instance_str = ""
    instance_data_filter_list = []
    # 查询指定虚拟机网卡数量,目前不能超过3块,同一类型网卡只能有一块
    for _instance in instance_data_list:
        instance_same_netcard_type_str = ""
        instance_net_card = instance_s.get_net_info_of_instance(
            _instance['instance_id'])
        if instance_net_card:
            for _net_card in instance_net_card:
                if _net_card['segment_type'] == netcard_type:
                    instance_same_netcard_type_str += _instance[
                        'instance_ip'] + " "
                    _ip_datas = {
                        "instanceIp": _instance['instance_ip'],
                        "nasIp": _net_card['ip_address']
                    }
                    _ip_datas_list.append(_ip_datas)

            if not instance_same_netcard_type_str:
                instance_data_filter_list.append(_instance)

            if len(instance_net_card) >= INSTANCE_NETCARD_NUMS:
                instance_str += _instance['instance_ip'] + " "

    if instance_str:
        return json_helper.format_api_resp_msg(
            code=ErrorCode.SYS_ERR,
            job_status=VsJobStatus.FAILED,
            detail='虚拟机:%s网卡数量不能大于%s' % (ip_str, str(INSTANCE_NETCARD_NUMS)))

    # if instance_same_netcar_type_str:
    #     return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED,
    #                                            detail='虚拟机:%s已配置相同类型网卡,不可重复申请' % ip_str)

    if len(instance_data_filter_list) == 0:
        return json_helper.format_api_resp_msg(code=ErrorCode.SUCCESS,
                                               job_status=VsJobStatus.SUCCEED,
                                               detail=_ip_datas_list)

    # 判断虚拟机虚拟机是否开机中
    instance_unstarting_str = ""
    for _instance in instance_data_filter_list:
        vm_status = vmManager.libvirt_instance_status(
            _instance['host_ip'], _instance['instance_name'])
        # 虚拟机开机状态才可以做网卡配置
        if vm_status != VMLibvirtStatus.STARTUP:
            instance_unstarting_str += _instance['instance_ip'] + " "

    if instance_unstarting_str:
        return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR,
                                               job_status=VsJobStatus.FAILED,
                                               detail='虚拟机:%s非运行中状态,无法添加网卡' %
                                               ip_str)

    # 识别需要创建的网卡类型并分配ip
    net_type = [
        NetCardType.INTERNAL, NetCardType.INTERNEL_TELECOM,
        NetCardType.INTERNEL_UNICOM, NetCardType.INTERNAL_IMAGE,
        NetCardType.INTERNAL_NAS
    ]
    if netcard_type not in net_type:
        return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR,
                                               job_status=VsJobStatus.FAILED,
                                               detail='KVM虚拟机没有网卡类型:%s ' %
                                               netcard_type)

    # 获取IP资源,先判断是否有人也在分配IP资源,有则等待1s,时间之后再优化
    ip_lock_unused = False
    while not ip_lock_unused:
        ret_ip_lock_status = ip_l_s.IpLockService().get_ip_lock_info('ip')
        if not ret_ip_lock_status:
            logging.error('外部接口新增网卡分配ip:检查IP时无法获取资源锁状态')
            return json_helper.format_api_resp_msg(
                code=ErrorCode.SYS_ERR,
                job_status=VsJobStatus.FAILED,
                detail='检查IP时无法获取资源锁状态')
        if ret_ip_lock_status['istraceing'] == IpLockStatus.USED:
            time.sleep(1)
        else:
            ip_lock_unused = True

    # 更新ip_lock表istraceing字段为1
    ret_ip_lock_used_status, ret_ip_lock_used_datas = __update_ip_lock_used()
    if not ret_ip_lock_used_status:
        logging.error(ret_ip_lock_used_datas)
        return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR,
                                               job_status=VsJobStatus.FAILED,
                                               detail=ret_ip_lock_used_datas)

    # 查询指定环境、网络区域是否有所需网段
    try:
        ret_segment_datas = segment_s.get_segments_data_by_type(
            net_area_list[0], dc_list[0], str(env_list[0]), str(netcard_type))
        if not ret_segment_datas:
            ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused(
            )
            if not ret_ip_lock_unused_status:
                logging.error(ret_ip_lock_unused_datas)
                return json_helper.format_api_resp_msg(
                    code=ErrorCode.SYS_ERR,
                    job_status=VsJobStatus.FAILED,
                    detail=ret_ip_lock_unused_datas)
            return json_helper.format_api_resp_msg(
                code=ErrorCode.SYS_ERR,
                job_status=VsJobStatus.FAILED,
                detail='虚拟机所在网络区域没有指定网卡类型可用网段')

        # 获取可用ip并标记为已使用
        ret_ip_status, ret_ip_data, ret_ip_msg = __check_ip_resource(
            ret_segment_datas, str(env_list[0]),
            len(instance_data_filter_list))
        if not ret_ip_status:
            _change_db_ip_unused(ret_ip_data)
            ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused(
            )
            if not ret_ip_lock_unused_status:
                logging.error(ret_ip_lock_unused_datas)
                return json_helper.format_api_resp_msg(
                    code=ErrorCode.SYS_ERR,
                    job_status=VsJobStatus.FAILED,
                    detail=ret_ip_lock_unused_datas)
            return json_helper.format_api_resp_msg(
                code=ErrorCode.SYS_ERR,
                job_status=VsJobStatus.FAILED,
                detail=ret_ip_msg)
    except Exception as e:
        _msg = '添加网卡外部接口:获取网段标记ip出现异常 %s: check ip resource exception when instance add nic from platform,err:%s' % (
            ip_str, e)
        logging.error(_msg)
        ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused(
        )
        if not ret_ip_lock_unused_status:
            logging.error(ret_ip_lock_unused_datas)
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg=ret_ip_lock_unused_datas)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=_msg)

    # 更新ip_lock表istraceing字段为0
    ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused(
    )
    if not ret_ip_lock_unused_status:
        _change_db_ip_unused(ret_ip_data)
        logging.error(ret_ip_lock_unused_datas)
        return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR,
                                               job_status=VsJobStatus.FAILED,
                                               detail=ret_ip_lock_unused_datas)

    error_msg = []
    # 拼装虚拟机网卡信息用于配置网卡
    i = 0
    for _instance in instance_data_filter_list:
        mac = randomMAC()
        _instance['ip_addr_new'] = ret_ip_data[i]['ip_address']
        _instance['mac_addr'] = mac
        i += 1
        ret_status, ret_error_msg = __instance_add_netcard(_instance)
        if not ret_status:
            _msg = {"ip": _instance['instance_ip'], "error_msg": ret_error_msg}
            error_msg.append(_msg)
        else:
            _ip_datas = {
                "instanceIp": _instance['instance_ip'],
                "nasIp": _instance['ip_addr_new']
            }
            _ip_datas_list.append(_ip_datas)

    if error_msg:
        return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR,
                                               job_status=VsJobStatus.FAILED,
                                               detail=error_msg)

    return json_helper.format_api_resp_msg(code=ErrorCode.SUCCESS,
                                           job_status=VsJobStatus.SUCCEED,
                                           detail=_ip_datas_list)