def __change_drprd_status(env, ip_new):
    '''
        编辑ip表
    :param env:
    :param ip_new:
    :return:
    '''
    # 更新新ip状态
    if int(env) == DataCenterType.PRD:
        segment_dr = segment_match_s.SegmentMatchService(
        ).get_segment_match_info_by_prd_segment_id(ip_new['segment_id'])
        if not segment_dr:
            return False, "无法获取当前生产IP对应容灾网段信息"
        segment_dr_data = segment_s.SegmentService().get_segment_info(
            segment_dr['dr_segment_id'])
        if not segment_dr_data:
            return False, "无法获取当前生产IP对应容灾网段详细信息"
        # 拼凑虚拟机容灾IP
        dr_ip = segment_dr_data['segment'].split('.')[0] + '.' + segment_dr_data['segment'].split('.')[1] + \
                '.' + ip_new['ip_address'].split('.')[2] + '.' + ip_new['ip_address'].split('.')[3]
        dr_ip_info = ip_s.IPService().get_ip_by_ip_address(dr_ip)
        # 如果容灾IP是未使用中状态,可以使用
        if dr_ip_info:
            if dr_ip_info['status'] == IPStatus.UNUSED:
                # 重置对应ip为未使用
                update_dr_ip_data = {'status': IPStatus.PRE_ALLOCATION}
                where_dr_ip_data = {'id': dr_ip_info['id']}
                ret_mark_ip = ip_s.IPService().update_ip_info(
                    update_dr_ip_data, where_dr_ip_data)
                if ret_mark_ip <= 0:
                    return False, "当前生产IP对应容灾IP从预分配重置为未使用状态失败"

    elif int(env) == DataCenterType.DR:
        segment_prd = segment_match_s.SegmentMatchService(
        ).get_segment_match_info_by_dr_segment_id(ip_new['segment_id'])
        if not segment_prd:
            return False, "无法获取当前容灾IP对应生产网段信息"
        segment_prd_data = segment_s.SegmentService().get_segment_info(
            segment_prd['prd_segment_id'])
        if not segment_prd_data:
            return False, "无法获取当前容灾IP对应生产网段详细信息"
        # 拼凑虚拟机生产IP
        prd_ip = segment_prd_data['segment'].split('.')[0] + '.' + segment_prd_data['segment'].split('.')[
            1] + '.' + \
                 ip_new['ip_address'].split('.')[2] + '.' + ip_new['ip_address'].split('.')[3]
        prd_ip_info = ip_s.IPService().get_ip_by_ip_address(prd_ip)
        # 如果生产环境ip是未使用中状态,可以使用
        if prd_ip_info:
            if prd_ip_info['status'] == IPStatus.UNUSED:
                # 重置对应ip为未使用
                update_dr_ip_data = {'status': IPStatus.PRE_ALLOCATION}
                where_dr_ip_data = {'id': prd_ip_info['id']}
                ret_mark_ip = ip_s.IPService().update_ip_info(
                    update_dr_ip_data, where_dr_ip_data)
                if ret_mark_ip <= 0:
                    return False, "当前容灾IP对应生产IP从预分配重置为未使用状态失败"

    return True, "生产、容灾IP状态重置成功"
Example #2
0
def net_area_delete():
    net_area_ids = request.values.get('net_area_ids')
    if not net_area_ids:
        logging.error('no net_area_ids when delete net area')
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR)

    net_area_ids_list = net_area_ids.split(',')
    # 操作的net area数
    all_num = len(net_area_ids_list)
    msg = None
    fail_num = 0
    for _id in net_area_ids_list:
        # 有集群和网段的都不能删除
        _hostpool_num = hostpool_s.HostPoolService(
        ).get_hostpool_nums_in_net_area(_id)
        if _hostpool_num > 0:
            logging.error('no allow to delete net area %s that has hostpool',
                          _id)
            fail_num += 1
            # 单台操作且已失败则直接跳出循环
            if all_num == 1:
                msg = '该网络区域下已分配有集群,不允许删除'
                break
            continue

        _segment_num = segment_s.SegmentService().get_segment_nums_in_net_area(
            _id)
        if _segment_num > 0:
            logging.error(
                'no allow to delete net area %s that has network segment', _id)
            fail_num += 1
            # 单台操作且已失败则直接跳出循环
            if all_num == 1:
                msg = '该网络区域下已分配有网段,不允许删除'
                break
            continue

        _ret = net_area_s.NetAreaService().delete_net_area(_id)
        if _ret <= 0:
            logging.error('db delete net area %s fail when delete net area',
                          _id)
            fail_num += 1
            continue

    # 全失败
    if fail_num == all_num:
        logging.error("delete net area all failed")
        if msg:
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=msg)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
    # 部分成功
    if 0 < fail_num < all_num:
        logging.error("delete all %s net area part %s failed", all_num,
                      fail_num)
        return json_helper.format_api_resp(code=ErrorCode.SUCCESS_PART,
                                           msg="部分网络区域删除成功")
    return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
Example #3
0
def add_segment():
    '''
        录入一个新网段
    '''
    network_segment_match = request.json.get("network_segment_match",[])
    segment_match_dic = {}
    for index, item in enumerate(network_segment_match):
        status, res = check_prdr(item)
        if not status:
            return json_helper.format_api_resp(ErrorCode.ALL_FAIL, msg=res)
        bond_dev = NetCardTypeToDevice.MSG_DICT.get(item['segment_type'])
        insert_data = {
            'net_area_id': int(item['net_area_id']),
            'segment': item['segment'],
            'segment_type': item['segment_type'],
            'host_bridge_name': 'br_' + bond_dev,
            'netmask': str(item['netmask']),
            'vlan': str(item['vlan']),
            'gateway_ip': item['gateway'],
            'dns1': item['dns1'],
            'dns2': item['dns2'],
            'status': NetworkSegmentStatus.ENABLE,
            'created_at': get_datetime_str()
        }
        ret = segment_service.SegmentService().add_segment_info(insert_data)
        if ret['row_num'] <= 0:
            return json_helper.format_api_resp(code=ErrorCode.ALL_FAIL, msg="网段入库失败")
        if len(network_segment_match) == 2:
            dc_type = datacenter_service.DataCenterService().get_dctype_by_net_area_id(item['net_area_id'])
            if dc_type == '4':
                segment_match_dic['prd_segment_id'] = network_segment.get_network_segment_id_info_by_network_segment(
                    item['net_area_id'], item['segment'],
                    item['vlan'], item['gateway'],
                    'br_' + bond_dev)
            elif dc_type == '5':
                segment_match_dic['dr_segment_id'] = network_segment.get_network_segment_id_info_by_network_segment(
                    item['net_area_id'], item['segment'],
                    item['vlan'], item['gateway'],
                    'br_' + bond_dev)
    if len(network_segment_match) == 2:
        insert_data_match = {
            'prd_segment_id': int(segment_match_dic['prd_segment_id']['id']),
            'dr_segment_id': int(segment_match_dic['dr_segment_id']['id']),
            'isdeleted': '0'
        }
        ret_match = segment_match.SegmentMatchService().add_segment_match_info(insert_data_match)
        if ret_match['row_num'] <= 0:
            return json_helper.format_api_resp(code=ErrorCode.ALL_FAIL, msg="匹配网段入库失败")

    return json_helper.format_api_resp(code=ErrorCode.SUCCESS, msg="匹配网段已成功加入")
Example #4
0
def get_avail_tmp_ip():
    '''
        从专用网段中获取一个ip分配给模板机
    :param segments_list:
    :param count:
    :param env:
    :return:
    '''
    segment_data = segment_s.SegmentService().get_segment_for_img_tmp()
    ips_info = ip.get_available_ip(segment_data['id'])
    if not ips_info:
        return False, '该网段id:%s没有可用ip' % str(segment_data['id'])
    ip_data = ips_info[0]
    return ip_data, segment_data
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)
Example #6
0
def image_edit():
    eimage_name = request.values.get('image_name')
    if not eimage_name:
        # message =  {
        #     'code': ErrorCode.SYS_ERR,
        #     'msg': "入参缺失"
        # }
        # socketio.emit('image_edit_resp', message, namespace='/image_edit_return')
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='入参缺失')

    # 判断当前image状态是否正常
    image_manage_data = im_s.ImageManageService().get_img_manage_data_by_name(
        eimage_name)
    image_manage_stat = image_manage_data[1]["status"]
    image_manage_type = image_manage_data[1]["os_type"]
    image_manage_osver = image_manage_data[1]["version"]
    enable_stat = [ImageManage.INIT, ImageManage.CHECKOUT, ImageManage.USABLE]
    if image_manage_stat not in enable_stat:
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg='当前模板机状态不允许此操作')

    # template vm start
    ret, message = im_man_act._img_tem_start(eimage_name)
    update_action = im_m_act.START_VEM
    if not ret:
        state_tag = im_m_act_sta.FAILED
        im_s.ImageStatusService().add_image_status_action(
            eimage_name, update_action, state_tag, message)
        im_s.ImageManageService().update_image_manage_msg(eimage_name, message)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=message)
    else:
        state_tag = im_m_act_sta.SUCCESSED
        im_s.ImageStatusService().add_image_status_action(
            eimage_name, update_action, state_tag, message)

    # update template vm stat
    update_data = {'template_status': img_tmp_status.RUNNING}
    where_data = {'eimage_name': eimage_name}
    im_s.ImageManageService().update_image_info(update_data, where_data)

    # template vm inject ip
    ret, res_data = im_s.ImageManageService().get_img_manage_data_by_name(
        eimage_name)
    update_action = im_m_act.IP_INJECT
    if not ret:
        state_tag = im_m_act_sta.FAILED
        error_msg = res_data
        im_s.ImageStatusService().add_image_status_action(
            eimage_name, update_action, state_tag, error_msg)
        im_s.ImageManageService().update_image_manage_msg(eimage_name, message)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg='获取镜像信息失败')
    ip_address = res_data['template_vm_ip']
    segment_data = segment_s.SegmentService().get_segment_for_img_tmp()
    if not segment_data:
        error_msg = '获取镜像模板专用网段失败'
        state_tag = im_m_act_sta.FAILED
        im_s.ImageStatusService().add_image_status_action(
            eimage_name, update_action, state_tag, error_msg)
        im_s.ImageManageService().update_image_manage_msg(eimage_name, message)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg='获取镜像模板专用网段失败')
    netmask_int = int(segment_data['netmask'])
    netmask = exchange_maskint(netmask_int)
    gateway = segment_data['gateway_ip']
    dns1 = segment_data['dns1']
    dns2 = segment_data['dns2']
    res, message = im_man_act._img_tem_inject(eimage_name, ip_address, netmask,
                                              gateway, image_manage_type,
                                              image_manage_osver, dns1, dns2)
    update_action = im_m_act.IP_INJECT
    if not res:
        error_msg = message
        state_tag = im_m_act_sta.FAILED
        im_s.ImageStatusService().add_image_status_action(
            eimage_name, update_action, state_tag, error_msg)
        im_s.ImageManageService().update_image_manage_msg(eimage_name, message)
        msg = '模板机%s 初始化注入失败' % eimage_name
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=msg)
    else:
        state_tag = im_m_act_sta.SUCCESSED
        im_s.ImageStatusService().add_image_status_action(
            eimage_name, update_action, state_tag, message)
    # 更新template_status
    message = ''
    im_s.ImageManageService().update_image_manage_status(
        eimage_name, message, ImageManage.EDITING)
    message = '模板机%s 开机编辑成功' % eimage_name
    return json_helper.format_api_resp(code=ErrorCode.SUCCESS, msg=message)
Example #7
0
def v2v_openstack_intodb(hostpool_id):
    '''
                v2v_openstack
            :param hostpool_id:
            :return:
    '''

    # 判断是否为重试操作
    retry = request.values.get('retry')
    # 如果非重试进行以下步骤
    if retry != '1':
        # 入参赋值
        vmname = request.values.get('vm_name').strip()
        vmip = request.values.get('vm_ip').strip()
        flavor_id = request.values.get('flavor_id').strip()
        cloudarea = request.values.get('cloud_area').strip()
        vm_ostype = request.values.get('vm_ostype').strip()
        vm_app_info = request.values.get('vm_app_info').strip()
        vm_owner = request.values.get('vm_owner').strip()
        vm_group_id = request.values.get('group_id').strip()
        user_id = request.values.get('user_id').strip()
        vm_segment = request.values.get('segment').strip()

        # 入参完全性判断
        if not vmname or not vmip  or not flavor_id or not cloudarea or not vm_ostype \
                or not vm_app_info or not vm_owner or not vm_group_id or not user_id or not vm_segment:
            logging.info('params are invalid or missing')
            return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR,
                                               msg='入参缺失')
        else:
            # 获取flavor信息
            flavor_info = flavor_service.FlavorService().get_flavor_info(
                flavor_id)
            if not flavor_info:
                logging.info(
                    'id: %s flavor info not in db when create instance',
                    flavor_id)
                return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                                   msg='实例规格数据有误,无法进行v2v')
            vmcpu = flavor_info['vcpu']
            vmmem = flavor_info['memory_mb']

            # 获取对应openstack环境的管理节点及ssh账户信息
            if cloudarea == "SIT":
                ctr_host = '10.202.83.12'
                ctr_pass = decrypt(OPENSTACK_SIT_PASS)
            elif cloudarea == "DEV":
                ctr_host = "10.202.123.4"
                ctr_pass = decrypt(OPENSTACK_DEV_PASS)
            else:
                return json_helper.format_api_resp(
                    code=ErrorCode.SYS_ERR, msg='openstack环境参数错误,无法进行v2v操作')

            #判断vm信息是否输入错误
            vmexist = vm_exist(vmip, ctr_host, ctr_pass)
            if vmexist == False:
                return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                                   msg='获取vm信息失败')

            #获取OS版本失败
            osstat, verdata = get_vm_version(ctr_host, ctr_pass, vm_ostype,
                                             vmip)
            if osstat == False:
                return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                                   msg='获取vmOS版本失败')
            else:
                ver_data = verdata

            # 获取待迁移vm磁盘大小
            vdiskdata = vm_disk_size(vmip, cloudarea, ctr_host, ctr_pass)
            if vdiskdata == False:
                return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                                   msg='获取vm磁盘信息失败')
            vdisk = vdiskdata
            data_disk = vdisk - 80

            # 判断待转化vm是否关机
            vmshutdown = vm_stat(vmip, ctr_host, ctr_pass)
            if vmshutdown == False:
                return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                                   msg='待转化vm未关机')

            # 获取可用目标host
            host_code, host_data, host_msg = cal_host(hostpool_id, vmcpu,
                                                      vmmem, data_disk,
                                                      vm_group_id)
            if host_code < 0:
                return json_helper.format_api_resp(code=host_code,
                                                   msg=host_msg)
            else:
                host = host_data

            vmhost = ho_s.HostService().get_host_info_by_hostip(host)
            ret_4 = ho_s.pre_allocate_host_resource(vmhost['id'], vmcpu, vmmem,
                                                    50)
            if ret_4 != 1:
                logging.error('资源预分配失败')
                message = '资源预分频失败'
                return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                                   msg=message)

            # 获取并录入IP信息

            vm_segment = seg_s.SegmentService().get_segment_info_bysegment(
                vm_segment)
            if vm_segment == None:
                return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                                   msg='网段信息有误,无法进行v2v')
            else:
                segment_id = vm_segment['id']
                vm_netmask = vm_segment['netmask']
                vm_gateway = vm_segment['gateway_ip']
                vm_dns1 = vm_segment['dns1']
                vm_dns2 = vm_segment['dns2']
                vmvlan = vm_segment['vlan']
                ip_data = ip_s.IPService().get_ip_info_by_ipaddress(vmip)
                if ip_data == None:
                    ip_data = {
                        'ip_address': vmip,
                        'segment_id': segment_id,
                        'netmask': vm_netmask,
                        'vlan': vmvlan,
                        'gateway_ip': vm_gateway,
                        'dns1': vm_dns1,
                        'dns2': vm_dns2,
                        'created_at': get_datetime_str(),
                        'status': '1'
                    }
                    ret = ip_s.IPService().add_ip_info(ip_data)
                    if ret.get('row_num') <= 0:
                        logging.info(
                            'add ip info error when create v2v task, insert_data: %s',
                            ip_data)
                        return json_helper.format_api_resp(
                            code=ErrorCode.SYS_ERR, msg="录入IP信息失败")
                    else:
                        ip_id = ret.get('last_id')
                else:
                    ip_data_status = ip_data['status']
                    vmvlan = ip_data['vlan']
                    if ip_data_status != '0':
                        return json_helper.format_api_resp(
                            code=ErrorCode.SYS_ERR, msg="IP与现有环境冲突,无法进行v2v")
                    else:
                        ip_id = ip_data['id']
                        where_data = {'id': ip_id}
                        updata_data = {
                            'status': '1',
                            'updated_at': get_datetime_str()
                        }
                        ret1 = ip_s.IPService().update_ip_info(
                            updata_data, where_data)
                        if not ret1:
                            logging.info(
                                'update ip info error when create v2v task, update_data: %s',
                                updata_data)
                            return json_helper.format_api_resp(
                                code=ErrorCode.SYS_ERR, msg="更新IP状态失败")

            # 生成request_id
            request_Id = v2v_op.generate_req_id()

            # 生成vm的uuid和mac
            vmuuid = randomUUID()
            vmmac = randomMAC()

            # 信息入instance相关库表
            instance_info = instance_db_info(vmuuid, vmname, vm_app_info,
                                             vm_owner, flavor_id, vm_group_id,
                                             host, vmmac, data_disk, ip_id,
                                             vm_ostype, request_Id, ver_data)
            if instance_info < 0:
                return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                                   msg='信息入库失败')

            #   将步骤信息存入instance_action表
            # 将createdir信息存入instance_action表
            v2v_cd_d1 = {
                'action': v2vActions.CREATE_DEST_DIR,
                'request_id': request_Id,
                'message': 'start',
                'start_time': get_datetime_str()
            }
            in_a_s.InstanceActionsServices().add_instance_action_info(
                v2v_cd_d1)

            # 将getfile信息存入instance_action表
            v2v_gf_d1 = {
                'action': v2vActions.GET_VM_FILE,
                'request_id': request_Id,
                'message': 'other',
                'start_time': get_datetime_str()
            }
            in_a_s.InstanceActionsServices().add_instance_action_info(
                v2v_gf_d1)

            # 将copy disk信息存入instance_action表
            v2v_cpd_d1 = {
                'action': v2vActions.COPY_VM_DISK,
                'request_id': request_Id,
                'message': 'other',
                'start_time': get_datetime_str()
            }
            in_a_s.InstanceActionsServices().add_instance_action_info(
                v2v_cpd_d1)

            # 将copy xml信息存入instance_action表
            v2v_cpx_d1 = {
                'action': v2vActions.COPY_VM_XML,
                'request_id': request_Id,
                'message': 'other',
                'start_time': get_datetime_str()
            }
            in_a_s.InstanceActionsServices().add_instance_action_info(
                v2v_cpx_d1)

            # 将创建存储池信息存入instance_action表
            v2v_csp_d1 = {
                'action': v2vActions.CREATE_STOR_POOL,
                'request_id': request_Id,
                'message': 'other',
                'start_time': get_datetime_str()
            }
            in_a_s.InstanceActionsServices().add_instance_action_info(
                v2v_csp_d1)

            # 将vm标准化信息存入instance_action表
            v2v_vmd_d1 = {
                'action': v2vActions.VM_STANDARDLIZE,
                'request_id': request_Id,
                'message': 'other',
                'start_time': get_datetime_str()
            }
            in_a_s.InstanceActionsServices().add_instance_action_info(
                v2v_vmd_d1)

            # 将vm注册信息存入instance_action表
            v2v_vmdef_d1 = {
                'action': v2vActions.VM_DEFINE,
                'request_id': request_Id,
                'message': 'other',
                'start_time': get_datetime_str()
            }
            in_a_s.InstanceActionsServices().add_instance_action_info(
                v2v_vmdef_d1)

            # 将IP注入信息存入instance_action表
            v2v_vmipj_d1 = {
                'action': v2vActions.IP_INJECT,
                'request_id': request_Id,
                'message': 'other',
                'start_time': get_datetime_str()
            }
            in_a_s.InstanceActionsServices().add_instance_action_info(
                v2v_vmipj_d1)

            # 将vm开机信息存入instance_action表
            v2v_vmstar_d1 = {
                'action': v2vActions.VM_START,
                'request_id': request_Id,
                'message': 'other',
                'start_time': get_datetime_str()
            }
            in_a_s.InstanceActionsServices().add_instance_action_info(
                v2v_vmstar_d1)

            message = '信息已添加至任务队列,等待执行'

            # 将v2v信息存入v2v_task表
            v2v_data = {
                'request_id': request_Id,
                'destory': '0',
                'start_time': get_datetime_str(),
                'status': 0,
                'vm_ip': vmip,
                'vm_name': vmname,
                'vmvlan': vmvlan,
                'flavor_id': flavor_id,
                'cloud_area': cloudarea,
                'vm_ostype': vm_ostype,
                'vm_app_info': vm_app_info,
                'vm_owner': vm_owner,
                'vm_group_id': vm_group_id,
                'user_id': user_id,
                'vm_mac': vmmac,
                'vm_uuid': vmuuid,
                'cancel': '0',
                'dest_dir': '/app/image/' + vmuuid,
                'on_task': '0',
                'port': '10000',
                'source': VMCreateSource.OPENSTACK
            }
            v2v_insert = v2v_op.v2vTaskService().add_v2v_task_info(v2v_data)

            if v2v_insert.get('row_num') <= 0:
                logging.info('insert info to v2v_task failed! %s', v2v_data)
                return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                                   msg='信息入库失败')

            # 将目标kvmhost存入信息表
            v2v_op.update_v2v_desthost(request_Id, host)

            v2v_op.update_v2v_step(request_Id, v2vActions.BEGIN)
            return json_helper.format_api_resp(code=ErrorCode.SUCCESS,
                                               msg=message)
Example #8
0
def task_check():

    # 入参赋值
    vmip = request.values.get('vm_ip')
    flavor_id = request.values.get('flavor_id')
    cloudarea = request.values.get('cloud_area')
    vm_ostype = request.values.get('vm_ostype')
    vm_segment = request.values.get('segment')

    # 入参完全性判断
    if not vmip or not flavor_id or not cloudarea or not vm_ostype or not vm_segment:
        logging.info('params are invalid or missing')
        message = '入参缺失'
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR,
                                           msg=message)
    else:
        # 获取flavor信息
        flavor_info = flavor_service.FlavorService().get_flavor_info(flavor_id)
        if not flavor_info:
            logging.info('id: %s flavor info not in db when create instance',
                         flavor_id)
            message = '实例规格数据有误,无法进行v2v'
            return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR,
                                               msg=message)

        # 获取对应openstack环境的管理节点及ssh账户信息
        if cloudarea == "SIT":
            ctr_host = '10.202.83.12'
            ctr_pass = decrypt(OPENSTACK_SIT_PASS)
        elif cloudarea == "DEV":
            ctr_host = "10.202.123.4"
            ctr_pass = decrypt(OPENSTACK_DEV_PASS)
        else:
            message = 'openstack环境参数错误,无法进行v2v操作'
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg=message)

        # 判断vm信息是否输入错误
        vmexist = vm_exist(vmip, ctr_host, ctr_pass)
        if vmexist == False:
            message = '获取vm信息失败'
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg=message)

        # 获取OS版本失败
        osstat, verdata = get_vm_version(ctr_host, ctr_pass, vm_ostype, vmip)
        if osstat == False:
            message = '获取vmOS版本失败'
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg=message)
        else:
            ver_data = verdata

        # 获取待迁移vm磁盘大小
        vdiskdata = vm_disk_size(vmip, cloudarea, ctr_host, ctr_pass)
        if vdiskdata == False:
            message = '获取vm磁盘信息失败'
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg=message)
        vdisk = vdiskdata
        data_disk = vdisk - 80

        # 判断待转化vm是否关机
        vmshutdown = vm_stat(vmip, ctr_host, ctr_pass)
        if vmshutdown == False:
            message = '待转化vm未关机'
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg=message)

        # 获取并录入IP信息

        vm_segment = seg_s.SegmentService().get_segment_info_bysegment(
            vm_segment)
        if vm_segment == None:
            message = '网段信息有误,无法进行v2v'
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg=message)
        else:
            ip_data = ip_s.IPService().get_ip_info_by_ipaddress(vmip)
            if ip_data:
                ip_data_status = ip_data['status']
                if ip_data_status != '0':
                    message = "IP与现有环境冲突,无法进行v2v"
                    return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                                       msg=message)

        return_info = {'vm_osver': ver_data, 'vm_disk': str(data_disk)}
        message = "获取VM信息成功"
        return json_helper.format_api_resp(code=ErrorCode.SUCCESS,
                                           msg=message,
                                           data=return_info)
Example #9
0
def get_all_available_segment_ip(segment_id, env):
    '''
        返回指定网段所有可用ip
    :param segment_id:
    :param env:
    :return:
    '''
    ips_list = []
    ips_info = ip.get_available_ip(segment_id)
    if ips_info:
        # 多线程ping去掉通的ip
        global IP_AVAILABLE_LIST
        IP_AVAILABLE_LIST = []
        threads = []
        for _per_unused_ip in ips_info:
            ip_check_thread = threading.Thread(target=__ping_ip_available,
                                               args=(_per_unused_ip, ))
            threads.append(ip_check_thread)
            ip_check_thread.start()
        # 判断多线程是否结束
        for t in threads:
            t.join()

        if len(IP_AVAILABLE_LIST) > 0:
            for _ip in IP_AVAILABLE_LIST:
                if int(env) == DataCenterType.PRD:
                    segment_dr = segment_m.SegmentMatchService(
                    ).get_segment_match_info_by_prd_segment_id(segment_id)
                    if not segment_dr:
                        continue
                    segment_dr_data = segment_s.SegmentService(
                    ).get_segment_info(segment_dr['dr_segment_id'])
                    if not segment_dr_data:
                        continue
                    # 拼凑虚拟机容灾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]
                    # ping ip,通的话不允许分配
                    # ret_ping = __ping_ip_available_simple(dr_ip)
                    # if not ret_ping:
                    #     continue
                    dr_ip_info = IPService().get_ip_by_ip_address(dr_ip)
                    # 如果容灾IP是未使用中状态,可以使用
                    if dr_ip_info:
                        if dr_ip_info['status'] == IPStatus.UNUSED:
                            ips_list.append(_ip)
                elif int(env) == DataCenterType.DR:
                    segment_prd = segment_m.SegmentMatchService(
                    ).get_segment_match_info_by_dr_segment_id(segment_id)
                    if not segment_prd:
                        continue
                    segment_prd_data = segment_s.SegmentService(
                    ).get_segment_info(segment_prd['prd_segment_id'])
                    if not segment_prd_data:
                        continue
                    # 拼凑虚拟机生产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]
                    # ping ip,通的话不允许分配
                    # ret_ping = __ping_ip_available_simple(prd_ip)
                    # if not ret_ping:
                    #     continue
                    prd_ip_info = IPService().get_ip_by_ip_address(prd_ip)
                    # 如果生产环境ip是未使用中状态,可以使用
                    if prd_ip_info:
                        if prd_ip_info['status'] == IPStatus.UNUSED:
                            ips_list.append(_ip)
                else:
                    ips_list.append(_ip)

    # 如果没有获取到合适的IP,返回失败
    return True, ips_list
Example #10
0
def get_available_ips(segments_list, count, env):
    '''
        从网段list中循环获取可使用的多个IP
    :param segments_list:
    :param count:
    :param env:
    :return:
    '''
    for _segment in segments_list:
        ips_list = []
        ips_info = ip.get_available_ip(_segment['id'])
        if ips_info:
            # 多线程ping去掉通的ip
            global IP_AVAILABLE_LIST
            IP_AVAILABLE_LIST = []
            threads = []
            for _per_unused_ip in ips_info:
                ip_check_thread = threading.Thread(target=__ping_ip_available,
                                                   args=(_per_unused_ip, ))
                threads.append(ip_check_thread)
                ip_check_thread.start()
            logging.info("ip available list: {}".format(IP_AVAILABLE_LIST))
            # 判断多线程是否结束
            for t in threads:
                t.join()

            if len(IP_AVAILABLE_LIST) < count:
                continue

            for _ip in IP_AVAILABLE_LIST:
                if int(env) == DataCenterType.PRD:
                    segment_dr = segment_m.SegmentMatchService(
                    ).get_segment_match_info_by_prd_segment_id(_segment['id'])
                    if not segment_dr:
                        continue
                    segment_dr_data = segment_s.SegmentService(
                    ).get_segment_info(segment_dr['dr_segment_id'])
                    if not segment_dr_data:
                        continue
                    # 拼凑虚拟机容灾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]
                    # ping ip,通的话不允许分配
                    ret_ping = __ping_ip_available_simple(dr_ip)
                    if not ret_ping:
                        continue
                    dr_ip_info = IPService().get_ip_by_ip_address(dr_ip)
                    # 如果容灾IP是未使用中状态,可以使用
                    if dr_ip_info:
                        if dr_ip_info['status'] == IPStatus.UNUSED:
                            ips_list.append(_ip)
                            if len(ips_list) == int(count):
                                return ips_list, _segment
                elif int(env) == DataCenterType.DR:
                    segment_prd = segment_m.SegmentMatchService(
                    ).get_segment_match_info_by_dr_segment_id(_segment['id'])
                    if not segment_prd:
                        continue
                    segment_prd_data = segment_s.SegmentService(
                    ).get_segment_info(segment_prd['prd_segment_id'])
                    if not segment_prd_data:
                        continue
                    # 拼凑虚拟机生产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]
                    ret_ping = __ping_ip_available_simple(prd_ip)
                    if not ret_ping:
                        continue
                    prd_ip_info = IPService().get_ip_by_ip_address(prd_ip)
                    # 如果生产环境ip是未使用中状态,可以使用
                    if prd_ip_info:
                        if prd_ip_info['status'] == IPStatus.UNUSED:
                            ips_list.append(_ip)
                            if len(ips_list) == int(count):
                                return ips_list, _segment
                else:
                    ips_list.append(_ip)
                    if len(ips_list) == int(count):
                        return ips_list, _segment

    # 如果没有获取到合适的IP,返回失败
    return False, ''
Example #11
0
def ip_instance_info():
    '''
        获取IP分配给VM的详细信息
    :return:
    '''
    ip_address = request.values.get('ip_address')
    if not ip_address:
        logging.info('no ip_address when get ip info')
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR)

    ip_info = ip_s.IPService().get_ip_info_by_ipaddress(ip_address)
    if not ip_info:
        logging.error('IP %s info no exist in db when get ip info', ip_address)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)

    # 检查ip是否为应用vip
    vip_info = vip_s.VIPService().get_vip_by_id(ip_info['id'])
    if not vip_info:
        if ip_info['status'] != IPStatus.USED:
            logging.info('IP %s status %s is not used when get ip info',
                         ip_address, ip_info['status'])
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg="IP状态不对,不能查看IP详细信息")

        ip_instance_data = ip_s.get_instance_info_by_ip(ip_address)
        if ip_instance_data:
            instance_name = ip_instance_data.get('instance_name', None)
            datacenter_name = ip_instance_data.get('datacenter_name', None)
            net_area_name = ip_instance_data.get('net_area_name', None)
        else:
            instance_name = None
            datacenter_name = None
            net_area_name = None

        ip_data = {
            'ip_address': ip_address,
            'datacenter': datacenter_name,
            'net_area': net_area_name,
            'instance_name': instance_name,
            'gateway': ip_info['gateway_ip'],
            'netmask': ip_info['netmask'],
            'vlan': ip_info['vlan'],
            'service_id': '',
            'is_vip': '0'
        }
    else:
        segment_info = segment_s.SegmentService().get_segment_info(
            ip_info['segment_id'])
        if not segment_info:
            _msg = '无法获取IP:%s的网段信息' % ip_address
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg=_msg)

        net_area_info = net_area.NetAreaService().get_net_area_info(
            segment_info['net_area_id'])
        if not net_area_info:
            net_area_name = ''
        net_area_name = net_area_info['name']
        datacenter_info = datacenter_service.DataCenterService(
        ).get_datacenter_info(net_area_info['datacenter_id'])
        if not datacenter_info:
            datacenter_name = ''
        datacenter_name = datacenter_info['name']

        ip_data = {
            'ip_address': ip_address,
            'datacenter': datacenter_name,
            'net_area': net_area_name,
            'instance_name': '',
            'gateway': ip_info['gateway_ip'],
            'netmask': ip_info['netmask'],
            'vlan': ip_info['vlan'],
            'sys_code': vip_info['sys_code'],
            'is_vip': '1'
        }

    return json_helper.format_api_resp(code=ErrorCode.SUCCESS, data=ip_data)
Example #12
0
def standard_host(manage_ip, hostpool_id):
    '''
        物理机标准化操作
    :param manage_ip:
    :return:
    '''
    url = HOST_STANDARD_DIR + '/host_std.yaml'

    host_list = [manage_ip]

    # 获取新增host所在网络区域的vlanlist
    hostpool_info = hp_s.HostPoolService().get_hostpool_info(hostpool_id)
    net_area_id = hostpool_info['net_area_id']
    vlan_res, vlan_data = seg_s.SegmentService().get_area_segment_list(
        net_area_id)
    if not vlan_res:
        return False, vlan_data
    else:
        host_vlan_filter_dict = {}
        host_vlan_list = vlan_data
        # host_vlan_list_dupl = sorted(set(host_vlan_list), key=host_vlan_list.index)
        # 根据br_bond对网段进行分类
        for _host_vlan in host_vlan_list:
            if _host_vlan['host_bridge_name'] in host_vlan_filter_dict.keys():
                host_vlan_filter_dict[_host_vlan['host_bridge_name']].append(
                    _host_vlan['vlan'])
            else:
                host_vlan_filter_dict[_host_vlan['host_bridge_name']] = [
                    _host_vlan['vlan']
                ]
        # host_vlan_list_dupl = sorted(set(host_vlan_list), key=lambda i: i["host_bridge_name"])

    # 循环调用playbook为不同bond新建网桥,每次调用完成后需要time.sleep(5)
    br_bond_create_shell_url = HOST_STANDARD_DIR + '/host_std_br_bond_create.yaml'
    for _bond_name, _vlan_list in host_vlan_filter_dict.items():
        host_dict = {
            "srcdir": HOST_STANDARD_DIR,
            "host_vlan_list": _vlan_list,
            "br_bond": _bond_name.split('_')[1]
        }

        run_result, run_message = run_standard_host(br_bond_create_shell_url,
                                                    manage_ip, host_dict)
        if not run_result:
            logging.info('物理机%s初始化新增内网vlan执行playbook失败,原因:%s' %
                         (manage_ip, run_message))

            return False, run_message

        time.sleep(2)

        time.sleep(2)

    # 构造host网桥检测入参内容
    host_test_bridge_list = []
    for vlan_info in vlan_data:
        bridge_name = vlan_info['host_bridge_name'] + '.' + vlan_info['vlan']
        gateway_ip = vlan_info['gateway']
        vlan = vlan_info['vlan']
        host_test_bridge = {
            "bridge": bridge_name,
            "gateway": gateway_ip,
            "vlan": vlan
        }
        host_test_bridge_list.append(host_test_bridge)

    # # 循环调用playbook测试HOST上对指定网桥的访问是否正常
    # bridge_test_shell_url = HOST_STANDARD_DIR + '/host_std_test_vlan.yaml'
    # host_dict = {
    #     "test_bridge_info": host_test_bridge_list
    # }
    res, message = check_vlan_connection(manage_ip, host_test_bridge_list)
    if not res:
        return False, message

    logging.info('start to do host std playbook')
    # 获取host所在网络区域的yum源地址
    datacenter_id = da_s.DataCenterService().get_dctype_by_net_area_id(
        net_area_id)
    if str(datacenter_id) in PRD_DC_TYPE:
        yum_server_addr = PRD_YUM_SERVER
    else:
        yum_server_addr = CS_YUM_SERVER

    # #构造vlan_list字符串传递给playbook作为入参
    # vlan_list_str = " ".join(host_vlan_list)
    # vlan_str = "\'" + vlan_list_str + "\'"
    # print vlan_str
    playbook_url = HOST_STANDARD_DIR + '/host_std.yaml'
    host_dict = {
        "srcdir": HOST_STANDARD_DIR,
        "agentdir": HOST_AGENT_PACKAGE_COPY_DIR,
        "agentshelldir": HOST_AGENT_PACKAGE_INSTALL_SHELL_DIR,
        "libvirt_user_pwd": decrypt(HOST_LIBVIRT_PWD),
        "root_pwd": decrypt(ROOT_PWD),
        "yum_server_ip": yum_server_addr
    }

    run_result, run_message = run_standard_host(playbook_url, manage_ip,
                                                host_dict)

    if not run_result:
        return False, run_message

    logging.info('物理机%s初始化playbook执行成功' % manage_ip)

    # 创建池
    pool_ret = _create_storage_pool(manage_ip)
    if not pool_ret:
        logging.info('host manage ip %s create pool fail when standard host',
                     manage_ip)
        msg = "创建存储池失败"
        return False, msg

    # 创建clone池
    pool_ret = _create_clone_pool(manage_ip)
    if not pool_ret:
        logging.info(
            'host manage ip %s create clone pool fail when standard host',
            manage_ip)
        msg = "创建clone存储池失败"
        return False, msg

    # host 运行checklist
    ret_checklist, msg_checklist = host_std_checklist(manage_ip)
    if not ret_checklist:
        msg = msg_checklist
        logging.info(msg)
        return False, msg

    msg = "标准化主机成功"
    return True, msg
Example #13
0
def v2v_esx_intodb(hostpool_id):
    '''
                v2v_esx
            :param hostpool_id:
            :return:
    '''

    #获取vm入库信息
    vmname = request.values.get('vm_name')
    vmip = request.values.get('vm_ip')
    flavor_id = request.values.get('flavor_id')
    vm_ostype = request.values.get('vm_ostype')
    vm_app_info = request.values.get('vm_app_info')
    vm_owner = request.values.get('vm_owner')
    vm_group_id = request.values.get('vm_group_id')
    user_id = request.values.get('user_id')
    vm_segment = request.values.get('segment')
    vm_osver = request.values.get('vm_osver')
    vm_disk = request.values.get('vm_disk')
    esx_env = request.values.get('esx_env')
    esx_ip = request.values.get('esx_ip')
    esx_passwd1 = request.values.get('esx_passwd')
    vmware_vm = request.values.get('vmware_vm')

    # 入参完全性判断
    if not vmname or not vmip  or not flavor_id or not  vm_ostype or not vm_app_info \
        or not vm_osver or not vm_disk  or not vm_owner or not vm_group_id or not user_id or not vm_segment or not esx_passwd1:
        logging.info('params are invalid or missing')
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR,
                                           msg='入参缺失')
    else:
        esx_passwd = base64.b64decode(esx_passwd1)
        powertag, msg_power = vm_powerState(esx_ip, esx_passwd, vmware_vm)
        if not powertag:
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg=msg_power)

        # 获取flavor信息
        flavor_info = flavor_service.FlavorService().get_flavor_info(flavor_id)
        if not flavor_info:
            logging.info('id: %s flavor info not in db when create instance',
                         flavor_id)
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg='实例规格数据有误,无法进行v2v')
        vmcpu = flavor_info['vcpu']
        vmmem = flavor_info['memory_mb']

        data_disk = int(vm_disk)

        # 获取可用目标host

        host_code, host_data, host_msg = cal_host(hostpool_id, vmcpu, vmmem,
                                                  data_disk, vm_group_id)
        if host_code < 0:
            return json_helper.format_api_resp(code=host_code, msg=host_msg)
        else:
            host = host_data

        vmhost = ho_s.HostService().get_host_info_by_hostip(host)
        ret_4 = ho_s.pre_allocate_host_resource(vmhost['id'], vmcpu, vmmem, 50)
        if ret_4 != 1:
            logging.error('资源预分配失败')
            message = '资源预分频失败'
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg=message)

        # 获取并录入IP信息

        vm_segment = seg_s.SegmentService().get_segment_info_bysegment(
            vm_segment)
        if vm_segment == None:
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg='网段信息有误,无法进行v2v')
        else:
            segment_id = vm_segment['id']
            vm_netmask = vm_segment['netmask']
            vm_gateway = vm_segment['gateway_ip']
            vm_dns1 = vm_segment['dns1']
            vm_dns2 = vm_segment['dns2']
            vmvlan = vm_segment['vlan']
            ip_data = ip_s.IPService().get_ip_info_by_ipaddress(vmip)
            if ip_data == None:
                ip_data = {
                    'ip_address': vmip,
                    'segment_id': segment_id,
                    'netmask': vm_netmask,
                    'vlan': vmvlan,
                    'gateway_ip': vm_gateway,
                    'dns1': vm_dns1,
                    'dns2': vm_dns2,
                    'created_at': get_datetime_str(),
                    'status': '1'
                }
                ret = ip_s.IPService().add_ip_info(ip_data)
                if ret.get('row_num') <= 0:
                    logging.info(
                        'add ip info error when create v2v task, insert_data: %s',
                        ip_data)
                    return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                                       msg="录入IP信息失败")
                else:
                    ip_id = ret.get('last_id')
            else:
                ip_data_status = ip_data['status']
                vmvlan = ip_data['vlan']
                if ip_data_status != '0':
                    return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                                       msg="IP与现有环境冲突,无法进行v2v")
                else:
                    ip_id = ip_data['id']
                    where_data = {'id': ip_id}
                    updata_data = {
                        'status': '1',
                        'updated_at': get_datetime_str()
                    }
                    ret1 = ip_s.IPService().update_ip_info(
                        updata_data, where_data)
                    if not ret1:
                        logging.info(
                            'update ip info error when create v2v task, update_data: %s',
                            updata_data)
                        return json_helper.format_api_resp(
                            code=ErrorCode.SYS_ERR, msg="更新IP状态失败")

        # 生成request_id
        request_Id = v2v_op.generate_req_id()

        # 生成vm的uuid和mac
        vmuuid = randomUUID()
        vmmac = randomMAC()

        if not vm_osver:
            vm_osver = "unknown"

        # 信息入instance相关库表
        instance_info = instance_db_info(vmuuid, vmname, vm_app_info, vm_owner,
                                         flavor_id, vm_group_id, host, vmmac,
                                         data_disk, ip_id, vm_ostype,
                                         request_Id, vm_osver)
        if instance_info < 0:
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg='信息入库失败')

        #   将步骤信息存入instance_action表
        v2v_cd_d1 = {
            'action': esx_v2vActions.CREATE_DEST_DIR,
            'request_id': request_Id,
            'message': 'start',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_cd_d1)

        v2v_cr_pl = {
            'action': esx_v2vActions.CREATE_STOR_POOL,
            'request_id': request_Id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_cr_pl)

        v2v_cp_fl = {
            'action': esx_v2vActions.COPY_FILE_TO_LOCAL,
            'request_id': request_Id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_cp_fl)

        v2v_file = {
            'action': esx_v2vActions.VIRT_V2V_FILES,
            'request_id': request_Id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_file)

        v2v_del_tmp = {
            'action': esx_v2vActions.DELETE_TMP_FILE,
            'request_id': request_Id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_del_tmp)

        v2v_sysdisk_std = {
            'action': esx_v2vActions.VM_SYS_DISK_STD,
            'request_id': request_Id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(
            v2v_sysdisk_std)

        v2v_datadisk_std = {
            'action': esx_v2vActions.VM_DATA_DISK_STD,
            'request_id': request_Id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(
            v2v_datadisk_std)

        v2v_def_1 = {
            'action': esx_v2vActions.VM_DEFINE1,
            'request_id': request_Id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_def_1)

        v2v_star_1 = {
            'action': esx_v2vActions.VM_START1,
            'request_id': request_Id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_star_1)

        if vm_ostype == "Windows":

            v2v_att_disk = {
                'action': esx_v2vActions.ATTACH_DISK,
                'request_id': request_Id,
                'message': 'other',
                'start_time': get_datetime_str()
            }
            in_a_s.InstanceActionsServices().add_instance_action_info(
                v2v_att_disk)

            v2v_win_std = {
                'action': esx_v2vActions.WINDOWS_STD,
                'request_id': request_Id,
                'message': 'other',
                'start_time': get_datetime_str()
            }
            in_a_s.InstanceActionsServices().add_instance_action_info(
                v2v_win_std)

            v2v_vm_def2 = {
                'action': esx_v2vActions.WINDOWS_DISK_CH,
                'request_id': request_Id,
                'message': 'other',
                'start_time': get_datetime_str()
            }
            in_a_s.InstanceActionsServices().add_instance_action_info(
                v2v_vm_def2)

            v2v_vm_star2 = {
                'action': esx_v2vActions.VM_START2,
                'request_id': request_Id,
                'message': 'other',
                'start_time': get_datetime_str()
            }
            in_a_s.InstanceActionsServices().add_instance_action_info(
                v2v_vm_star2)

        message = '信息已添加至任务队列,等待执行'

        # 将v2v信息存入v2v_task表
        v2v_data = {
            'source': VMCreateSource.ESX,
            'request_id': request_Id,
            'destory': '0',
            'start_time': get_datetime_str(),
            'status': 0,
            'vm_ip': vmip,
            'vm_name': vmname,
            'vmvlan': vmvlan,
            'flavor_id': flavor_id,
            'cloud_area': esx_env,
            'vm_ostype': vm_ostype,
            'vm_app_info': vm_app_info,
            'vm_owner': vm_owner,
            'vm_group_id': vm_group_id,
            'user_id': user_id,
            'vm_mac': vmmac,
            'vm_uuid': vmuuid,
            'cancel': '0',
            'dest_dir': '/app/image/' + vmuuid,
            'on_task': '0',
            'dest_host': host,
            'esx_ip': esx_ip,
            'esx_passwd': esx_passwd,
            'vmware_vm': vmware_vm,
            'step_done': esx_v2vActions.BEGIN
        }
        v2v_insert = v2v_op.v2vTaskService().add_v2v_task_info(v2v_data)

        if v2v_insert.get('row_num') <= 0:
            logging.info('insert info to v2v_task failed! %s', v2v_data)
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg='信息入库失败')

        return json_helper.format_api_resp(code=ErrorCode.SUCCESS, msg=message)
def _check_task(i, row, user_id):
    # 当前行数
    cur_line = str(i + 1)

    # Openstack环境
    cloud_area = row[0]
    cloud_area = cloud_area.strip()
    # VM名称
    vm_name = row[1]
    vm_name = vm_name.strip()
    # VM IP
    vm_ip = row[2]
    vm_ip = vm_ip.strip()
    # VM所在网段
    vm_segment = row[3]
    vm_segment = vm_segment.strip()
    # 应用系统信息
    vm_app_info = row[4]
    vm_app_info = vm_app_info.strip()
    # 应用管理员
    vm_owner = row[5]
    vm_owner = vm_owner.strip()
    # VM环境
    vm_env_name = row[6]
    vm_env_name = vm_env_name.strip()
    # VM网络区域
    netarea_name = row[7]
    netarea_name = netarea_name.strip()
    # VM集群
    hostpool_name = row[8]
    hostpool_name = hostpool_name.strip()
    # VM系统版本
    vm_ostype = row[9]
    vm_ostype = vm_ostype.strip()
    # 应用组
    group_name = row[10]
    group_name = group_name.strip()
    # CPU数量
    cpu_num = row[11]
    cpu_num = cpu_num.strip()
    # 内存容量
    mem_size = row[12]
    mem_size = mem_size.strip()
    # 内存容量单位
    mem_size_unit = row[13]
    mem_size_unit = mem_size_unit.strip()

    if not cloud_area or not vm_name or not vm_ip or not vm_segment or not vm_app_info or not vm_owner \
            or not vm_env_name or not netarea_name or not hostpool_name or not vm_ostype or not group_name \
            or not cpu_num or not mem_size or not mem_size_unit:
        result = False, "第" + cur_line + "行:参数不正确"
        q.put(result)
        return

    # 1.判断flavor信息
    if mem_size_unit == 'G':
        mem_size_mb = int(mem_size) * 1024
    elif mem_size_unit == 'M':
        mem_size_mb = mem_size
    else:
        result = False, "第" + cur_line + "行:内存容量单位不正确"
        q.put(result)
        return

    flavor_info = flavor_s.get_flavor_by_vcpu_and_memory(cpu_num, mem_size_mb)
    if not flavor_info:
        result = False, "第" + cur_line + "行:实例规格数据有误"
        q.put(result)
        return

    # 2.根据机房类型、网络区域和集群名来判断集群信息
    if vm_env_name == "DEV":
        vm_env = "3"
    elif vm_env_name == "SIT":
        vm_env = "1"
    elif vm_env_name == "STG":
        vm_env = "2"
    else:
        result = False, "第" + cur_line + "行:VM环境数据有误"
        q.put(result)
        return

    hostpool_data = hostpool_s.get_hostpool_by_vmenv_netarea_hostpool(
        vm_env, netarea_name, hostpool_name)
    if not hostpool_data:
        result = False, "第" + cur_line + "行:VM集群数据有误"
        q.put(result)
        return

    # 3.判断应用组信息

    group_info = group_s.get_group_info_by_name_and_env(group_name, vm_env)
    if not group_info:
        result = False, "第" + cur_line + "行:应用组数据有误"
        q.put(result)
        return

    # 4.获取并录入IP信息
    vm_segment_info = segment_s.SegmentService().get_segment_info_bysegment(
        vm_segment)
    if vm_segment_info is None:
        result = False, "第" + cur_line + "行:网段信息有误"
        q.put(result)
        return
    else:
        ip_data = ip_s.IPService().get_ip_info_by_ipaddress(vm_ip)
        if ip_data:
            if str(ip_data['status']) != IPStatus.UNUSED:
                result = False, "第" + cur_line + "行:IP与现有环境冲突"
                q.put(result)
                return

    # 5.获取对应openstack环境的管理节点及ssh账户信息
    if cloud_area == "SIT":
        ctr_host = "10.202.83.12"
        ctr_pass = decrypt(OPENSTACK_SIT_PASS)
    elif cloud_area == "DEV":
        ctr_host = "10.202.123.4"
        ctr_pass = decrypt(OPENSTACK_DEV_PASS)
    else:
        result = False, "第" + cur_line + "行:openstack环境参数错误"
        q.put(result)
        return

    # 6.判断vm信息是否输入错误
    vmexist = _vm_exist(vm_ip, ctr_host, ctr_pass)
    if not vmexist:
        result = False, "第" + cur_line + "行:获取vm信息失败"
        q.put(result)
        return

    # 7.获取OS版本失败
    osstat, verdata = _get_vm_version(ctr_host, ctr_pass, vm_ostype, vm_ip)
    if not osstat:
        result = False, "第" + cur_line + "行:获取vm OS版本失败"
        q.put(result)
        return

    # 8.获取待迁移vm磁盘大小
    vdiskdata = _vm_disk_size(vm_ip, ctr_host, ctr_pass)
    if not vdiskdata:
        result = False, "第" + cur_line + "行:获取vm磁盘信息失败"
        q.put(result)
        return

    data_disk = vdiskdata - 80

    # 9.判断待转化vm是否关机
    vmshutdown = _vm_state(vm_ip, ctr_host, ctr_pass)
    if not vmshutdown:
        result = False, "第" + cur_line + "行:待转化vm未关机"
        q.put(result)
        return

    # 10.判断主机名是否包含中文
    check_chinese, msg = _check_chinese(vm_name)
    if not check_chinese:
        err_msg = "第" + cur_line + "行:" + msg
        result = False, err_msg
        q.put(result)
        return

    # 11.组装信息
    _task = {
        'vm_name': vm_name,
        'vm_ip': vm_ip,
        'flavor_id': flavor_info['id'],
        'cloud_area': cloud_area,
        'vm_ostype': vm_ostype,
        'vm_app_info': vm_app_info,
        'vm_owner': vm_owner,
        'hostpool_id': hostpool_data['hostpool_id'],
        'group_id': group_info['id'],
        'user_id': user_id,
        'segment': vm_segment,
        'vm_disk': data_disk,
        'vm_osver': verdata,
    }
    result = True, _task
    q.put(result)
Example #15
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')
Example #16
0
def check_prdr(in_env):
    if not all(in_env):
        return False, "请求入参缺失"

    # 校验网段是否合法
    try:
        IP(in_env['segment'] + "/" + str(in_env['netmask']))
    except:
        return False, "非法网段,请重新检查后录入"

    # 查询网段是否存在于数据库中.

    query_params = {
        'WHERE_AND': {
            '=': {
                'segment': in_env['segment'],
                'netmask': str(in_env['netmask'])
            }
        },
    }
    segment_nums, segment_datas = segment_service.SegmentService().query_data(**query_params)
    if segment_nums > 0:
        return False, "指定网段已存在于平台中,请确认"

    # 拉取网络区域下所有集群所有虚拟机列表
    db_host_data = host_s._get_hosts_of_net_area(int(in_env['net_area_id']))
    if not db_host_data:
        return False, "指定网络区域下没有一台物理机"

    # 判断物理机上是否有指定网桥对应的bond设备
    bond_dev = NetCardTypeToDevice.MSG_DICT.get(in_env['segment_type'])
    if not bond_dev:
        return False, "不支持已选网络类型录入"

    ret_check_msg = ""
    for _host in db_host_data:
        ret_run_status, ret_run_msg = ansible_remote_check_host_bridge(_host['ipaddress'], bond_dev)
        if not ret_run_status:
            return False, ret_run_msg
        elif ret_run_status is 1:
            ret_check_msg += ret_run_msg

    if ret_check_msg:
        return False, ret_check_msg

    # 建桥,脚本满足已经创建过的跳过
    ret_check_msg = ""
    for _host in db_host_data:
        host_list = [_host['ipaddress']]
        vlan_list = [int(in_env['vlan'])]
        host_bridge_dict = {
            "srcdir": HOST_STANDARD_DIR,
            "host_vlan_list": vlan_list,
            "br_bond": bond_dev
        }
        br_bond_create_shell_url = HOST_STANDARD_DIR + '/host_std_br_bond_create.yaml'
        run_result, run_message = run_standard_host(br_bond_create_shell_url, _host['ipaddress'], host_bridge_dict)
        if not run_result:
            logging.info('物理机%s初始化新增内网vlan执行playbook失败,原因:%s' % (_host['ipaddress'], run_message))

            return False, run_message

        time.sleep(2)

    if ret_check_msg:
        return False, ret_check_msg

    # 判断物理机上指定网桥可用性,暂时使用for循环减少并发,有不通的反馈出来
    host_test_bridge = {
        "bridge": 'br_' + bond_dev + '.' + str(in_env['vlan']),
        "gateway": in_env['gateway'],
        "vlan": in_env['vlan']
    }
    host_test_bridge_list = [host_test_bridge]

    ret_check_msg = ""
    for _host in db_host_data:
        res, message = host_s.check_vlan_connection(_host['ipaddress'], host_test_bridge_list)
        if not res:
            ret_check_msg += message

    if ret_check_msg:
        return False, ret_check_msg

    return True, ''
def __instance_add_netcard(instance_netcard_datas):
    # 添加任务信息
    task_id = instance_s.generate_task_id()
    insert_data = {
        'action': InstaceActions.INSTANCE_ADD_NETCARD,
        'instance_uuid': instance_netcard_datas['instance_uuid'],
        'request_id': task_id,
        'task_id': task_id,
        'start_time': get_datetime_str()
    }
    ret_action = instance_action_s.InstanceActionsServices(
    ).add_instance_action_info(insert_data)
    if ret_action.get('row_num') < 1:
        logging.error(
            'add instance change configure action info error, insert_data:%s',
            insert_data)
        return False, "添加操作步骤到instance_action表失败"
    # 判断要申请ip是否被分配了,如果是生产或容灾环境,需要判断其对应的容灾或生产ip是否为未使用状态
    net_ip_list = []
    new_ip_status = ip_s.IPService().get_ip_by_ip_address(
        instance_netcard_datas['ip_addr_new'])
    net_ip_list.append(new_ip_status)
    new_ip_segment_data = segment_s.SegmentService().get_segment_info(
        new_ip_status['segment_id'])
    if not new_ip_status or not new_ip_segment_data:
        _msg = '网卡配置ip:无法获取数据库中ip信息或ip对应的网段信息'
        _job_status = ActionStatus.FAILD
        __update_config_msg_to_db(task_id, _msg, _job_status)
        return False, "无法获取数据库中待使用ip信息或ip对应的网段信息"

    if new_ip_status['status'] != IPStatus.USED:
        _msg = '网卡配置ip:新ip:%s不是使用中状态' % instance_netcard_datas['ip_addr_new']
        _job_status = ActionStatus.FAILD
        __update_config_msg_to_db(task_id, _msg, _job_status)
        return False, "新ip:%s不是使用中状态" % instance_netcard_datas['ip_addr_new']
    # 需要修改xml配置,同时做ip、网关修改注入
    instance_netcard_datas['netmask_new'] = __exchange_maskint(
        int(new_ip_status['netmask']))
    instance_netcard_datas['gateway_new'] = new_ip_status['gateway_ip']

    dev_name = new_ip_segment_data['host_bridge_name'] + '.' + str(
        new_ip_segment_data['vlan'])
    net_on_status, _msg = _instance_net_on(
        instance_netcard_datas['instance_name'],
        instance_netcard_datas['mac_addr'], instance_netcard_datas['host_ip'],
        dev_name)
    if not net_on_status:
        _job_status = ActionStatus.FAILD
        __update_config_msg_to_db(task_id, _msg, _job_status)
        _change_db_ip_unused(net_ip_list)
        return False, _msg

    ret_status, ret_msg = __change_instance_network(
        instance_netcard_datas['host_ip'],
        instance_netcard_datas['instance_name'], instance_netcard_datas)
    if ret_status:
        db_ret_status, db_ret_msg = __instance_ip_configure_change_db(
            instance_netcard_datas['instance_id'], instance_netcard_datas,
            instance_netcard_datas['env'])
        if not db_ret_status:
            _job_status = ActionStatus.FAILD
            __update_config_msg_to_db(task_id, db_ret_msg, _job_status)
            _change_db_ip_unused(net_ip_list)
            return False, db_ret_msg

        _job_status = ActionStatus.SUCCSESS
        __update_config_msg_to_db(task_id, db_ret_msg, _job_status)
    else:
        _job_status = ActionStatus.FAILD
        __update_config_msg_to_db(task_id, ret_msg, _job_status)
        _change_db_ip_unused(net_ip_list)
        return False, ret_msg

    return True, "网卡配置成功"
def _task_into_db(task):
    # 入参赋值
    vmname = task['vm_name']
    vmip = task['vm_ip']
    flavor_id = task['flavor_id']
    cloudarea = task['cloud_area']
    vm_ostype = task['vm_ostype']
    vm_app_info = task['vm_app_info']
    vm_owner = task['vm_owner']
    vm_group_id = task['group_id']
    user_id = task['user_id']
    vm_segment = task['segment']
    vm_disk = task['vm_disk']
    vm_osver = task['vm_osver']
    host = task['dest_host']

    # 入参完全性判断
    if not vmname or not vmip or not flavor_id or not cloudarea or not vm_ostype \
            or not vm_app_info or not vm_owner or not vm_group_id or not user_id or not vm_segment:
        logging.info('params are invalid or missing')
        message = '入参缺失'
        return False, message
    else:
        # 获取flavor信息
        flavor_info = flavor_s.FlavorService().get_flavor_info(flavor_id)
        if not flavor_info:
            logging.info('id: %s flavor info not in db when create instance',
                         flavor_id)
            message = '实例规格数据有误,无法进行v2v'
            return False, message
        vmcpu = flavor_info['vcpu']
        vmmem = flavor_info['memory_mb']

        vmhost = ho_s.HostService().get_host_info_by_hostip(host)
        ret_4 = ho_s.pre_allocate_host_resource(vmhost['id'], vmcpu, vmmem, 50)
        if ret_4 != 1:
            logging.error('资源预分配失败')
            message = '资源预分频失败'
            return False, message

        # 获取并录入IP信息
        vm_segment = segment_s.SegmentService().get_segment_info_bysegment(
            vm_segment)
        if vm_segment is None:
            message = '网段信息有误,无法进行v2v'
            return False, message
        else:
            segment_id = vm_segment['id']
            vm_netmask = vm_segment['netmask']
            vm_gateway = vm_segment['gateway_ip']
            vm_dns1 = vm_segment['dns1']
            vm_dns2 = vm_segment['dns2']
            vmvlan = vm_segment['vlan']
            ip_data = ip_s.IPService().get_ip_info_by_ipaddress(vmip)
            if ip_data is None:
                ip_data = {
                    'ip_address': vmip,
                    'segment_id': segment_id,
                    'netmask': vm_netmask,
                    'vlan': vmvlan,
                    'gateway_ip': vm_gateway,
                    'dns1': vm_dns1,
                    'dns2': vm_dns2,
                    'created_at': get_datetime_str(),
                    'status': '1'
                }
                ret = ip_s.IPService().add_ip_info(ip_data)
                if ret.get('row_num') <= 0:
                    logging.info(
                        'add ip info error when create v2v task, insert_data: %s',
                        ip_data)
                    message = "录入IP信息失败"
                    return False, message
                else:
                    ip_id = ret.get('last_id')
            else:
                ip_data_status = ip_data['status']
                vmvlan = ip_data['vlan']
                if ip_data_status != '0':
                    message = "IP与现有环境冲突,无法进行v2v"
                    return False, message
                else:
                    ip_id = ip_data['id']
                    where_data = {'id': ip_id}
                    updata_data = {
                        'status': '1',
                        'updated_at': get_datetime_str()
                    }
                    ret1 = ip_s.IPService().update_ip_info(
                        updata_data, where_data)
                    if not ret1:
                        logging.info(
                            'update ip info error when create v2v task, update_data: %s',
                            updata_data)
                        message = "更新IP状态失败"
                        return False, message

        # 生成request_id
        request_id = v2v_op.generate_req_id()

        # 生成vm的uuid和mac
        vmuuid = randomUUID()
        vmmac = randomMAC()

        # 信息入instance相关库表
        instance_tag, instance_info = _instance_db_info(
            vmuuid, vmname, vm_app_info, vm_owner, flavor_id, vm_group_id,
            host, vmmac, vm_disk, ip_id, vm_ostype, request_id, vm_osver)
        if not instance_tag:
            message = instance_info
            return False, message

        # 将步骤信息存入instance_action表
        # 将createdir信息存入instance_action表
        v2v_cd_d1 = {
            'action': v2vActions.CREATE_DEST_DIR,
            'request_id': request_id,
            'message': 'start',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_cd_d1)

        # 将getfile信息存入instance_action表
        v2v_gf_d1 = {
            'action': v2vActions.GET_VM_FILE,
            'request_id': request_id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_gf_d1)

        # 将copy disk信息存入instance_action表
        v2v_cpd_d1 = {
            'action': v2vActions.COPY_VM_DISK,
            'request_id': request_id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_cpd_d1)

        # 将copy xml信息存入instance_action表
        v2v_cpx_d1 = {
            'action': v2vActions.COPY_VM_XML,
            'request_id': request_id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_cpx_d1)

        # 将创建存储池信息存入instance_action表
        v2v_csp_d1 = {
            'action': v2vActions.CREATE_STOR_POOL,
            'request_id': request_id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_csp_d1)

        # 将vm标准化信息存入instance_action表
        v2v_vmd_d1 = {
            'action': v2vActions.VM_STANDARDLIZE,
            'request_id': request_id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_vmd_d1)

        # 将vm注册信息存入instance_action表
        v2v_vmdef_d1 = {
            'action': v2vActions.VM_DEFINE,
            'request_id': request_id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_vmdef_d1)

        # 将IP注入信息存入instance_action表
        v2v_vmipj_d1 = {
            'action': v2vActions.IP_INJECT,
            'request_id': request_id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_vmipj_d1)

        # 将vm开机信息存入instance_action表
        v2v_vmstar_d1 = {
            'action': v2vActions.VM_START,
            'request_id': request_id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(
            v2v_vmstar_d1)

        message = '信息已添加至任务队列,等待执行'

        # 将v2v信息存入v2v_task表
        v2v_data = {
            'request_id': request_id,
            'destory': '0',
            'start_time': get_datetime_str(),
            'status': 0,
            'vm_ip': vmip,
            'vm_name': vmname,
            'vmvlan': vmvlan,
            'flavor_id': flavor_id,
            'cloud_area': cloudarea,
            'vm_ostype': vm_ostype,
            'vm_app_info': vm_app_info,
            'vm_owner': vm_owner,
            'vm_group_id': vm_group_id,
            'user_id': user_id,
            'vm_mac': vmmac,
            'vm_uuid': vmuuid,
            'cancel': '0',
            'dest_dir': '/app/image/' + vmuuid,
            'on_task': '0',
            'port': '10000',
            'source': VMCreateSource.OPENSTACK
        }
        v2v_insert = v2v_op.v2vTaskService().add_v2v_task_info(v2v_data)

        if v2v_insert.get('row_num') <= 0:
            logging.info('insert info to v2v_task failed! %s', v2v_data)
            message = '信息入库失败'
            return False, message

        # 将目标kvmhost存入信息表
        v2v_op.update_v2v_desthost(request_id, host)

        v2v_op.update_v2v_step(request_id, v2vActions.BEGIN)
        return True, message
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 #20
0
def _task_esx_intodb(task):
    # 获取vm入参
    vmname = task['vm_name']
    vmip = task['vm_ip']
    flavor_id = task['flavor_id']
    vm_ostype = task['vm_ostype']
    vm_app_info = task['vm_app_info']
    vm_owner = task['vm_owner']
    vm_segment = task['vm_segment']
    vm_group_id = task['group_id']
    dest_host = task['dest_host']

    vmhost = ho_s.HostService().get_host_info_by_hostip(dest_host)
    ret_4 = ho_s.pre_allocate_host_resource(vmhost['id'], task['vm_cpu'],
                                            task['vm_mem_mb'], 50)
    if ret_4 != 1:
        logging.error('资源预分配失败')
        message = '资源预分配失败'
        return False, message

    # 获取并录入IP信息
    vm_segment = seg_s.SegmentService().get_segment_info_bysegment(vm_segment)
    if vm_segment is None:
        message = '网段信息有误,无法进行v2v操作'
        return False, message
    else:
        segment_id = vm_segment['id']
        vm_netmask = vm_segment['netmask']
        vm_gateway = vm_segment['gateway_ip']
        vm_dns1 = vm_segment['dns1']
        vm_dns2 = vm_segment['dns2']
        vmvlan = vm_segment['vlan']
        ip_data = ip_s.IPService().get_ip_info_by_ipaddress(vmip)
        if ip_data is None:
            ip_data = {
                'ip_address': vmip,
                'segment_id': segment_id,
                'netmask': vm_netmask,
                'vlan': vmvlan,
                'gateway_ip': vm_gateway,
                'dns1': vm_dns1,
                'dns2': vm_dns2,
                'created_at': get_datetime_str(),
                'status': '1'
            }
            ret = ip_s.IPService().add_ip_info(ip_data)
            if ret.get('row_num') <= 0:
                logging.info(
                    'add ip info error when create v2v task, insert_data: %s',
                    ip_data)
                message = "录入IP信息失败"
                return False, message
            else:
                ip_id = ret.get('last_id')
        else:
            ip_data_status = ip_data['status']
            vmvlan = ip_data['vlan']
            if ip_data_status != '0':
                message = "IP与现有环境冲突,无法进行v2v操作"
                return False, message
            else:
                ip_id = ip_data['id']
                where_data = {'id': ip_id}
                updata_data = {'status': '1', 'updated_at': get_datetime_str()}
                ret1 = ip_s.IPService().update_ip_info(updata_data, where_data)
                if not ret1:
                    logging.info(
                        'update ip info error when create v2v task, update_data: %s',
                        updata_data)
                    message = "更新IP状态失败"
                    return False, message

        # 生成request_id
        request_id = v2v_op.generate_req_id()

        # 生成vm的uuid和mac
        vmuuid = randomUUID()
        vmmac = randomMAC()

        # 信息入instance相关库表
        instance_tag, instance_info = _instance_db_info(
            vmuuid, vmname, vm_app_info, vm_owner, flavor_id, vm_group_id,
            dest_host, vmmac, task['vm_disk'], ip_id, vm_ostype, request_id,
            task['vm_os_version'])
        if not instance_tag:
            message = instance_info
            return False, message

        # 将步骤信息存入instance_action表
        v2v_cd_d1 = {
            'action': esx_v2vActions.CREATE_DEST_DIR,
            'request_id': request_id,
            'message': 'start',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_cd_d1)

        v2v_cr_pl = {
            'action': esx_v2vActions.CREATE_STOR_POOL,
            'request_id': request_id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_cr_pl)

        v2v_cp_fl = {
            'action': esx_v2vActions.COPY_FILE_TO_LOCAL,
            'request_id': request_id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_cp_fl)

        v2v_file = {
            'action': esx_v2vActions.VIRT_V2V_FILES,
            'request_id': request_id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_file)

        v2v_del_tmp = {
            'action': esx_v2vActions.DELETE_TMP_FILE,
            'request_id': request_id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_del_tmp)

        v2v_sysdisk_std = {
            'action': esx_v2vActions.VM_SYS_DISK_STD,
            'request_id': request_id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(
            v2v_sysdisk_std)

        v2v_datadisk_std = {
            'action': esx_v2vActions.VM_DATA_DISK_STD,
            'request_id': request_id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(
            v2v_datadisk_std)

        v2v_def_1 = {
            'action': esx_v2vActions.VM_DEFINE1,
            'request_id': request_id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_def_1)

        v2v_star_1 = {
            'action': esx_v2vActions.VM_START1,
            'request_id': request_id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_star_1)

        if vm_ostype == "Windows":
            v2v_att_disk = {
                'action': esx_v2vActions.ATTACH_DISK,
                'request_id': request_id,
                'message': 'other',
                'start_time': get_datetime_str()
            }
            in_a_s.InstanceActionsServices().add_instance_action_info(
                v2v_att_disk)

            v2v_win_std = {
                'action': esx_v2vActions.WINDOWS_STD,
                'request_id': request_id,
                'message': 'other',
                'start_time': get_datetime_str()
            }
            in_a_s.InstanceActionsServices().add_instance_action_info(
                v2v_win_std)

            v2v_vm_def2 = {
                'action': esx_v2vActions.WINDOWS_DISK_CH,
                'request_id': request_id,
                'message': 'other',
                'start_time': get_datetime_str()
            }
            in_a_s.InstanceActionsServices().add_instance_action_info(
                v2v_vm_def2)

            v2v_vm_star2 = {
                'action': esx_v2vActions.VM_START2,
                'request_id': request_id,
                'message': 'other',
                'start_time': get_datetime_str()
            }
            in_a_s.InstanceActionsServices().add_instance_action_info(
                v2v_vm_star2)

        # 将v2v信息存入v2v_task表
        v2v_data = {
            'source': VMCreateSource.ESX,
            'request_id': request_id,
            'destory': '0',
            'start_time': get_datetime_str(),
            'status': 0,
            'vm_ip': vmip,
            'vm_name': vmname,
            'vmvlan': vmvlan,
            'flavor_id': flavor_id,
            'cloud_area': task['esx_env'],
            'vm_ostype': vm_ostype,
            'vm_app_info': vm_app_info,
            'vm_owner': vm_owner,
            'vm_group_id': vm_group_id,
            'user_id': task['user_id'],
            'vm_mac': vmmac,
            'vm_uuid': vmuuid,
            'cancel': '0',
            'dest_dir': '/app/image/' + vmuuid,
            'on_task': '0',
            'dest_host': dest_host,
            'esx_ip': task['esx_ip'],
            'esx_passwd': task['esx_passwd'],
            'vmware_vm': task['vmware_vm'],
            'step_done': esx_v2vActions.BEGIN
        }
        v2v_insert = v2v_op.v2vTaskService().add_v2v_task_info(v2v_data)

        if v2v_insert.get('row_num') <= 0:
            logging.info('insert info to v2v_task failed! %s', v2v_data)
            message = '信息入库失败'
            return False, message

        message = '信息已添加至任务队列'
        return True, message
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)
Example #22
0
def __check_ip_resource(env, dc_name, net_area, count):
    '''
        判断IP资源是否足够
    :param hostpool_id:
    :param count:
    :return:
    '''
    # 查询指定环境、网络区域是否有所需网段,容灾微应用需要遍历联通、电信所有可用网段
    if env == str(DataCenterType.MINIARCHDR):
        ret_segment_datas_telecom = segment_s.get_segments_data_by_type(
            net_area, dc_name, env, NetCardType.INTERNEL_TELECOM)
        ret_segment_datas_unicom = segment_s.get_segments_data_by_type(
            net_area, dc_name, 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(
            net_area, dc_name, env, NetCardType.INTERNAL)
    if not ret_segment_datas:
        return False, '集群所在机房、网络区域下没有可用网段用于分配IP', ''

    # 获取可用ip
    ret_ip_datas, ret_ip_segment_datas = ip_service.get_available_ips(
        ret_segment_datas, int(count), env)
    if not ret_ip_datas:
        return False, '集群所在机房、网络区域下无法找到%s个可用IP' % str(count), ''

    # 如果是申请生产或者容灾环境ip,需判断网段对应关系表中是否有记录
    if int(env) == DataCenterType.PRD:
        segment_dr = segment_m.SegmentMatchService(
        ).get_segment_match_info_by_prd_segment_id(ret_ip_segment_datas['id'])
        if not segment_dr:
            return False, '集群所在机房、网络区域下无法找到生产网段对应的容灾网段ID', ''
        segment_dr_data = segment_s.SegmentService().get_segment_info(
            segment_dr['dr_segment_id'])
        if not segment_dr_data:
            return False, '集群所在机房、网络区域下无法找到生产网段对应的容灾网段详细信息', ''

    elif int(env) == DataCenterType.DR:
        segment_prd = segment_m.SegmentMatchService(
        ).get_segment_match_info_by_dr_segment_id(ret_ip_segment_datas['id'])
        if not segment_prd:
            return False, '指定机房、网络区域下无法找到容灾网段对应的生产网段ID', ''
        segment_prd_data = segment_s.SegmentService().get_segment_info(
            segment_prd['prd_segment_id'])
        if not segment_prd_data:
            return False, '指定机房、网络区域下无法找到容灾网段对应的生产网段详细信息', ''

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

        # 生产环境需要预分配对应容灾环境ip,容灾环境需要预分配生产环境ip
        if int(env) == DataCenterType.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
            dr_ips_list.append(dr_ip_info)
        elif int(env) == DataCenterType.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
            prd_ips_list.append(prd_ip_info)

    if len(ips_list) <= 0:
        return False, '虚拟机创建所需%s个可用IP修改为预分配状态全部失败' % str(count), ''
    elif int(env) == DataCenterType.PRD and (
            len(ips_list) + len(dr_ips_list)) < int(count) * 2:
        return False, '生产环境虚拟机创建所需%s个可用IP修改为预分配状态部分失败' % str(count), ''
    elif int(env) == DataCenterType.DR and (
            len(ips_list) + len(prd_ips_list)) < int(count) * 2:
        return False, '容灾环境虚拟机创建所需%s个可用IP修改为预分配状态部分失败' % str(count), ''
    elif len(ips_list) < int(count):
        return False, '虚拟机创建所需%s个可用IP修改为预分配状态部分失败' % str(count), ''
    else:
        return True, ret_ip_datas, ret_ip_segment_datas
Example #23
0
def ip_apply():
    '''
        IP申请
    :return:
    '''
    req_env = request.values.get('env')
    req_net_area = request.values.get('net_area')
    req_net_name = request.values.get('segment')
    cluster_id = request.values.get('cluster_id')
    opuser = request.values.get('opUser')
    sys_code = request.values.get('sys_code')

    # 校验入参是否为空
    if not req_env or not req_net_area or not req_net_name:
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg="环境、网络区域、网段名输入为空")
    if not cluster_id or not opuser or not sys_code:
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg="物理集群、操作用户、系统编码为空输入为空")

    # 查询指定环境、网络区域是否有所需网段
    ret_segment = segment_service.SegmentService().get_segment_info_bysegment(
        req_net_name)
    if not ret_segment:
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg="无法找到需要申请的网段")

    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(code=ErrorCode.SYS_ERR,
                                           msg="无法找到指定网络区域信息")
    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(code=ErrorCode.SYS_ERR,
                                           msg="无法找到指定机房信息")
    if req_env not in DataCenterTypeForVishnu.TYPE_DICT:
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg="无法找到指定机房类型信息")
    if str(DataCenterTypeForVishnu.TYPE_DICT[req_env]
           ) != ret_datacenter_info['dc_type']:
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg="无法找到指定网络区域对应网段信息")

    # 获取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('kvm平台分配vip:检查IP时无法获取资源锁状态')
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg='检查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(code=ErrorCode.SYS_ERR,
                                           msg=ret_ip_lock_used_datas)
    # 获取可用ip
    try:
        ret_ip_available_status, ret_ip_available = ip_service.get_available_segment_ip(
            ret_segment['id'], str(DataCenterTypeForVishnu.TYPE_DICT[req_env]))
    except Exception as e:
        _msg = 'IP申请ip_apply:获取指定网段可用ip出现异常 : get segment available ip exception when ip apply,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)

    if not ret_ip_available_status:
        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="指定网段没有可用ip")

    # 标记ip已使用
    update_data = {'status': IPStatus.USED}
    where_data = {'id': ret_ip_available['id']}
    ret_mark_ip = ip_service.IPService().update_ip_info(
        update_data, where_data)
    if ret_mark_ip <= 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(code=ErrorCode.SYS_ERR,
                                               msg=ret_ip_lock_unused_datas)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg="标记ip为已使用状态失败,请重新申请")

    # 更新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(code=ErrorCode.SYS_ERR,
                                           msg=ret_ip_lock_unused_datas)

    # 录入vip信息到数据库中
    insert_vip_data = {
        'ip_id': ret_ip_available['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(code=ErrorCode.SYS_ERR,
                                           msg="录入ip信息失败,请联系系统管理员")

    ip_msg = {"vip": ret_ip_available['ip_address']}

    return json_helper.format_api_resp(code=ErrorCode.SUCCESS, data=ip_msg)