Beispiel #1
0
def hold_ip():
    '''
        保留IP
    :return:
    '''
    ip_address = request.values.get('ip_address')
    if not ip_address:
        logging.info('no ip_address when hold ip')
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR)

    ip_info = ip_service.IPService().get_ip_info_by_ipaddress(ip_address)
    # 已初始化且未使用的IP才能保留
    if not (ip_info and ip_info['status'] == IPStatus.UNUSED):
        logging.info('IP status is wrong when hold ip')
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg="只能保留已初始化且未使用的IP")

    update_data = {
        'status': IPStatus.HOLD,
        'updated_at': get_datetime_str(),
    }
    where_data = {
        'ip_address': ip_address,
    }
    ret = ip_service.IPService().update_ip_info(update_data, where_data)
    if ret <= 0:
        logging.error("hold ip error, update_data:%s, where_data:%s",
                      str(update_data), str(where_data))
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
    return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
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状态重置成功"
Beispiel #3
0
def __init_ip(segment_datas, ip_address):
    '''
        IP初始化
    :param segment_datas:
    :param ip_address:
    :return:
    '''
    ip_vlan = segment_datas['vlan']
    ip_netmask = segment_datas['netmask']
    ip_segment_id = segment_datas['id']
    ip_gateway_ip = segment_datas['gateway_ip']
    ip_dns1 = segment_datas['dns1']
    ip_dns2 = segment_datas['dns2']

    insert_data = {
        'ip_address': ip_address,
        'segment_id': ip_segment_id,
        'netmask': ip_netmask,
        'vlan': ip_vlan,
        'gateway_ip': ip_gateway_ip,
        'dns1': ip_dns1,
        'dns2': ip_dns2,
        'status': IPStatus.UNUSED,
        'created_at': get_datetime_str()
    }
    ret = ip_service.IPService().add_ip_info(insert_data)
    if ret == -1:
        return False
    return True
def __check_ip_resource(segment_datas, env, count):
    '''
        判断IP资源是否足够
    :param segment_datas:
    :param env:
    :param count:
    :return:
    '''
    # 获取可用ip
    ret_ip_datas, ret_ip_segment_datas = ip_s.get_available_ips(
        segment_datas, int(count), env)
    if not ret_ip_datas:
        return False, [], '虚拟机所在机房、网络区域下无法找到%s个可用IP' % str(count)

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

    if len(ips_list) < int(count):
        return False, [], '虚拟机网卡配置ip所需%s个可用IP修改为使用中状态部分失败' % str(count)
    else:
        return True, ret_ip_datas, ret_ip_segment_datas
def __instance_ip_configure_change_db(ins_id, net_info, env):
    '''
        编辑instance_ip表
    :param ins_id:
    :param net_info:
    :param env:
    :return:
    '''
    ip_id_new = ip_s.IPService().get_ip_by_ip_address(net_info['ip_addr_new'])
    if not ip_id_new:
        msg = '无法在数据库中找到ip:%s 记录' % ip_id_new
        return False, msg

    # 查找生产、容灾环境对应的容灾、生产环境IP
    ret_change_status, ret_change_detail = __change_drprd_status(
        env, ip_id_new)
    if not ret_change_status:
        return False, ret_change_detail

    instance_ip_data = {
        'instance_id': ins_id,
        'ip_id': ip_id_new['id'],
        'mac': net_info['mac_addr'],
        'type': InstanceNicType.NORMAL_NETWORK_NIC,
        'isdeleted': '0',
        'created_at': get_datetime_str()
    }
    ret_add_ip = instance_ip_s.InstanceIPService().add_instance_ip_info(
        instance_ip_data)
    if ret_add_ip.get('row_num') <= 0:
        msg = "新增虚拟机网卡ip:%s信息到数据库失败" % ip_id_new['ip_address']
        return False, msg

    return True, '数据库记录修改成功'
Beispiel #6
0
def _set_ip_init(ret_ip_data):
    # 标记ip为初始化状态
    update_data = {'status': IPStatus.UNUSED}
    where_data = {'id': ret_ip_data['id']}
    ret_mark_ip = ip_service.IPService().update_ip_info(
        update_data, where_data)
    if ret_mark_ip <= 0:
        return False, 'IP %s 状态重置为初始化失败' % ret_ip_data['ip_address']
    else:
        return True, 'IP %s 状态重置为初始化成功' % ret_ip_data['ip_address']
Beispiel #7
0
def win_vm_std(request_id):
    v2v_task = v2v_op.v2vTaskService().get_v2v_task_by_requestid(request_id)
    vmip = v2v_task['vm_ip']
    ostype = 'Windows'
    ip_data = ip_s.IPService().get_ip_by_ip_address(vmip)
    vmmask_int = int(ip_data['netmask'])
    vmmask = exchange_maskint(vmmask_int)
    vmgateway = ip_data['gateway_ip']
    vmname = v2v_task['vm_name']
    dns1 = ip_data['dns1']
    dns2 = ip_data['dns2']
    host_ip = v2v_task['dest_host']
    cloudarea = v2v_task['cloud_area']
    connect_instance = instanceManager.libvirt_get_connect(
        host_ip, conn_type='instance', vmname=vmname)
    inject_stauts, mesg = instanceManager.v2v_esx_win_inject(
        connect_instance, vmname, vmip, vmgateway, dns1, dns2, vmmask, ostype,
        cloudarea)
    if inject_stauts:
        message = "信息注入成功"
        threadlock = threading.Lock()
        threadlock.acquire()
        v2v_op.updata_v2v_message(request_id, message)
        in_a_s.update_instance_actions(request_id, esx_v2vActions.WINDOWS_STD,
                                       ActionStatus.SUCCSESS, message)
        v2v_op.update_v2v_step(request_id, esx_v2vActions.WINDOWS_STD)
        v2v_op.updata_v2v_ontask(request_id, '0')
        vm_uuid = v2v_op.v2vTaskService().get_v2v_task_by_requestid(
            request_id)['vm_uuid']
        v2v_op.update_v2v_actions(request_id, 1)
        v2v_op.update_v2v_step(request_id, esx_v2vActions.WINDOWS_STD)
        where_data = {'uuid': vm_uuid}
        update_data = {'status': '3'}
        ins_s.InstanceService().update_instance_info(update_data, where_data)
        threadlock.release()
    else:
        message = "信息注入失败"
        threadlock = threading.Lock()
        threadlock.acquire()
        v2v_op.updata_v2v_message(request_id, message)
        v2v_op.update_v2v_actions(request_id, ActionStatus.FAILD)
        v2v_op.updata_v2v_ontask(request_id, '0')
        in_a_s.update_instance_actions(request_id, esx_v2vActions.WINDOWS_STD,
                                       ActionStatus.FAILD, message)
        threadlock.release()
def _change_db_ip_unused(ip_info):
    '''
        修改数据库ip表中ip状态为未使用
    :param ip_info:
    :return:
    '''
    # 标记ip为预分配
    ip_change_succeed_list = []
    for ip in ip_info:
        update_data = {'status': IPStatus.UNUSED}
        where_data = {'id': ip['id']}
        ret_mark_ip = ip_s.IPService().update_ip_info(update_data, where_data)
        if ret_mark_ip <= 0:
            continue
        ip_change_succeed_list.append(ip)

    if len(ip_change_succeed_list) < len(ip_info):
        return False, '虚拟机网卡配置ip所需%s个可用IP修改为使用中状态部分失败' % len(ip_info)
    else:
        return True, '虚拟机网卡配置ip所需%s个可用IP修改为使用中全部成功' % len(ip_info)
Beispiel #9
0
def __check_ip_resource():
    '''
        判断IP资源是否足够
    :param hostpool_id:
    :param count:
    :return:
    '''
    # 获取可用ip
    ret_ip_data, ret_ip_segment_datas = ip_service.get_avail_tmp_ip()
    if not ret_ip_data:
        return False, '未找到可用的IP用于分配给模板机'

    # 标记ip为预分配
    update_data = {'status': IPStatus.PRE_ALLOCATION}
    where_data = {'id': ret_ip_data['id']}
    ret_mark_ip = ip_service.IPService().update_ip_info(
        update_data, where_data)
    if ret_mark_ip <= 0:
        return False, '模板机预分频IP %s 失败' % ret_ip_data['ip_address']
    else:
        return True, ret_ip_data
Beispiel #10
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)
Beispiel #11
0
def cancel_init_ips():
    '''
        批量取消初始化IP
    :return:
    '''
    begin_ip = request.values.get('begin_ip')
    end_ip = request.values.get('end_ip')

    if not begin_ip or not end_ip:
        logging.info('begin or end ip is empty when cancel init ips')
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR)

    # 获取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:
            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)

    try:
        # 截取IP地址最后一位
        begin_ip_org = begin_ip.split('.')[3]
        end_ip_org = end_ip.split('.')[3]
        # 起始IP不能大于结束IP
        if int(begin_ip_org) > int(end_ip_org) or int(begin_ip_org) > 254 or int(begin_ip_org) < 1 \
                or int(end_ip_org) > 254 or int(end_ip_org) < 1:
            logging.info('begin or end ip is invalid when cancel init ips')
            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.PARAM_ERR)

        ips_cancel_list = []
        for i in range(int(begin_ip_org), int(end_ip_org) + 1):
            ips_cancel_list.append(i)

        if not ips_cancel_list:
            logging.info(
                'no ip can cancel init when cancel init ips, begin: %s, end: %s',
                begin_ip, end_ip)
            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)

        # 截取IP地址前三位
        ip_c = begin_ip.split('.')[0] + '.' + begin_ip.split(
            '.')[1] + '.' + begin_ip.split('.')[2] + '.'
        # 操作的IP数
        all_num = len(ips_cancel_list)
        fail_num = 0
        for _cancel_ip in ips_cancel_list:
            cancel_ip_address = str(ip_c) + str(_cancel_ip)
            # 要确保该IP未使用
            ip_info = ip_service.IPService().get_ip_info_by_ipaddress(
                cancel_ip_address)
            if not (ip_info and ip_info['status'] == IPStatus.UNUSED):
                logging.info('only unused ip can do when cancel init ip')
                fail_num += 1
                continue

            ret = ip_service.del_ip_info(ip_info['id'])
            if ret == -1:
                logging.info('del ip info error when cancel init ip')
                fail_num += 1
                continue
    except Exception as e:
        _msg = '批量取消初始化IP:取消初始化ip出现异常begin_ip %s,end_ip%s: cancel ips init exception,err:%s' % (
            begin_ip, end_ip, 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(code=ErrorCode.SYS_ERR,
                                           msg=ret_ip_lock_unused_datas)

    # 全失败
    if fail_num == all_num:
        logging.error("cancel init ips all failed")
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
    # 部分成功
    if 0 < fail_num < all_num:
        logging.error("cancel init ips part failed")
        return json_helper.format_api_resp(code=ErrorCode.SUCCESS_PART,
                                           msg="部分IP取消初始化成功")
    return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
Beispiel #12
0
def cancel_init_ip():
    '''
        取消初始化IP
    :return:
    '''
    ip_address = request.values.get('ip_address')
    if not ip_address:
        logging.info('no ip_address when cancel init ip')
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR)

    # 获取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:
            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:
        ip_info = ip_service.IPService().get_ip_info_by_ipaddress(ip_address)
        if not (ip_info and ip_info['status'] == IPStatus.UNUSED):
            logging.info('only unused ip can do when cancel init ip')
            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才能取消初始化")

        ret = ip_service.del_ip_info(ip_info['id'])
    except Exception as e:
        _msg = '取消初始化IP:取消初始化ip出现异常ip%s: cancel ip init exception,err:%s' % (
            ip_address, 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(code=ErrorCode.SYS_ERR,
                                           msg=ret_ip_lock_unused_datas)

    if ret == -1:
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
    return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
Beispiel #13
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
Beispiel #14
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 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)
Beispiel #16
0
def instance_create_from_other_platform_with_ip():
    '''
      外部平台虚拟机创建
    :return:
    '''
    _init_log('instanc_create_request_from_other_platform')
    data_from_other_platform = request.data
    logging.info(data_from_other_platform)
    data_requset = json_helper.loads(data_from_other_platform)
    image_name = data_requset['image']
    vcpu = data_requset['vcpu']
    mem_mb = data_requset['mem_MB']
    disk_gb = data_requset['disk_GB']
    count = data_requset['count']
    sys_code = data_requset['sys_code']
    opuser = data_requset['opUser']
    taskid_vs = data_requset['taskid']
    req_env = data_requset['env']
    req_net_area = data_requset['net_area']
    req_datacenter = data_requset['datacenter']
    task_id_kvm = ins_s.generate_task_id()
    sys_opr_name = data_requset['Op_Main_Engineer_Primary']
    sys_opr_id = data_requset['Op_Main_Engineer_Prim']
    cluster_id = data_requset['cluster_id']
    vip_needed = data_requset['vip_needed']  # 是否需要vip,0为不需要,1需要
    vm_ip_info = data_requset['vm_info']
    vip_info = data_requset['vip_info']
    api_origin = data_requset[
        'apiOrigin']  # api名称,维石为vishnu, 软负载为sfslb, 其他的需要定义
    # 前端暂时不是传虚拟机root密码过来
    password = None
    app_info = data_requset['application_info']
    # hostpool_id = int(data_requset['hostpool_id'])  # 特殊类型应用,返回集群id
    hostpool_id = ''

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    for thread in all_threads:
        thread.join()

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

    return json_helper.format_api_resp_msg_to_vishnu(
        req_id=taskid_vs,
        job_status=VsJobStatus.SUCCEED,
        detail='start to create vm')
def __instance_add_netcard(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 _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)
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
Beispiel #20
0
def hold_ips():
    '''
        批量保留IP
    :return:
    '''
    begin_ip = request.values.get('begin_ip')
    end_ip = request.values.get('end_ip')

    if not begin_ip or not end_ip:
        logging.info('begin or end ip is empty when hold ips')
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR)

    # 截取IP地址最后一位
    begin_ip_org = begin_ip.split('.')[3]
    end_ip_org = end_ip.split('.')[3]
    # 起始IP不能大于结束IP
    if int(begin_ip_org) > int(end_ip_org) or int(begin_ip_org) > 254 or int(begin_ip_org) < 1 \
            or int(end_ip_org) > 254 or int(end_ip_org) < 1:
        logging.info('begin or end ip is invalid when hold ips')
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR)

    ips_hold_list = []
    for i in range(int(begin_ip_org), int(end_ip_org) + 1):
        ips_hold_list.append(i)

    if not ips_hold_list:
        logging.info('no ip can hold when hold ips, begin: %s, end: %s',
                     begin_ip, end_ip)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)

    # 截取IP地址前三位
    ip_c = begin_ip.split('.')[0] + '.' + begin_ip.split(
        '.')[1] + '.' + begin_ip.split('.')[2] + '.'
    # 操作的IP数
    all_num = len(ips_hold_list)
    fail_num = 0
    for _hold_ip in ips_hold_list:
        hold_ip_address = str(ip_c) + str(_hold_ip)
        ip_info = ip_service.IPService().get_ip_by_ip_address(hold_ip_address)
        # 已初始化且未使用的IP才能保留
        if not (ip_info and ip_info['status'] == IPStatus.UNUSED):
            fail_num += 1
            continue

        update_data = {
            'status': IPStatus.HOLD,
            'updated_at': get_datetime_str(),
        }
        where_data = {
            'ip_address': hold_ip_address,
        }
        ret = ip_service.IPService().update_ip_info(update_data, where_data)
        if ret <= 0:
            logging.error("hold ips error, update_data:%s, where_data:%s",
                          str(update_data), str(where_data))
            fail_num += 1
            continue

    # 全失败
    if fail_num == all_num:
        logging.error("hold ips all failed")
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
    # 部分成功
    if 0 < fail_num < all_num:
        logging.error("hold ips part failed")
        return json_helper.format_api_resp(code=ErrorCode.SUCCESS_PART,
                                           msg="部分IP保留成功")
    return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
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)
Beispiel #22
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)
Beispiel #23
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
Beispiel #24
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)
Beispiel #25
0
def _create_instance_info(task_id, instance_name, app_info, owner, 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):
    uuid = randomUUID()
    request_id = ins_s.generate_req_id()
    # 往instance表添加记录
    logging.info(
        '创建VM 步骤10-1:插入instance表 task %s : insert instance table start when create instance',
        task_id)
    instance_data = {
        'uuid': uuid,
        'name': instance_name,
        'displayname': instance_name,
        'description': '',
        'status': VMStatus.CREATING,
        'typestatus': VMTypeStatus.NORMAL,
        'create_source': VMCreateSource.CLOUD_SOURCE,
        'isdeleted': '0',
        'app_info': app_info,
        'owner': owner,
        'created_at': get_datetime_str(),
        'password': encrypt_helper.encrypt(str(password)),  # 密码加密
        'request_id': request_id,
        'task_id': task_id
    }
    ret = ins_s.InstanceService().add_instance_info(instance_data)
    if ret.get('row_num') <= 0:
        logging.error(
            'task %s : add instance info error when create instance, insert_data: %s',
            task_id, instance_data)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
    logging.info(
        '创建VM 步骤10-1:插入instance表成功 '
        'task %s : insert instance table successful when create instance',
        task_id)

    instance_id = ret.get('last_id')

    # 往instance_flavor表添加记录
    logging.info(
        '创建VM 步骤10-2:插入instance_flavor表 '
        'task %s : insert instance_flavor table start when create instance',
        task_id)
    instance_flavor_data = {
        'instance_id': instance_id,
        'flavor_id': flavor_id,
        'created_at': get_datetime_str()
    }
    ret1 = ins_f_s.InstanceFlavorService().add_instance_flavor_info(
        instance_flavor_data)
    if ret1.get('row_num') <= 0:
        logging.error(
            'task %s : add instance_flavor info error when create instance, insert_data: %s',
            task_id, instance_flavor_data)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
    logging.info(
        '创建VM 步骤10-2:插入instance_flavor表成功 '
        'task %s : insert instance_flavor table successful when create instance',
        task_id)

    # 往instance_group表添加记录
    logging.info(
        '创建VM 步骤10-3:插入instance_group表 task %s : insert instance_group table start when create instance',
        task_id)
    instance_group_data = {
        'instance_id': instance_id,
        'group_id': group_id,
        'created_at': get_datetime_str()
    }
    ret2 = ins_g_s.InstanceGroupService().add_instance_group_info(
        instance_group_data)
    if ret2.get('row_num') <= 0:
        logging.error(
            'task %s : add instance_group info error when create instance, insert_data: %s',
            task_id, instance_group_data)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
    logging.info(
        '创建VM 步骤10-3:插入instance_group表成功 task %s : insert instance_group table successful when create instance',
        task_id)

    # 往instance_host表添加记录
    logging.info(
        '创建VM 步骤10-4:插入instance_host表 task %s : insert instance_host table start when create instance',
        task_id)
    instance_host_data = {
        'instance_id': instance_id,
        'instance_name': instance_name,
        'host_id': vm_host['host_id'],
        'host_name': vm_host['name'],
        'isdeleted': '0',
        'created_at': get_datetime_str()
    }
    ret3 = ins_h_s.InstanceHostService().add_instance_host_info(
        instance_host_data)
    if ret3.get('row_num') <= 0:
        logging.error(
            'task %s : add instance_host info error when create instance, insert_data: %s',
            task_id, instance_host_data)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
    logging.info(
        '创建VM 步骤10-4:插入instance_host表成功 '
        'task %s : insert instance_host table successful when create instance',
        task_id)

    # host预分配资源
    logging.info(
        '创建VM 步骤10-5:host预分配资源 task %s : pre allocate host resource start when create instance',
        task_id)
    ret4 = host_s.pre_allocate_host_resource(vm_host['host_id'],
                                             flavor_info['vcpu'],
                                             flavor_info['memory_mb'],
                                             flavor_info['root_disk_gb'])
    if ret4 != 1:
        logging.error(
            'task %s : pre allocate host resource to db error when create instance',
            task_id)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
    logging.info(
        '创建VM 步骤10-5:host预分配资源成功 '
        'task %s : pre allocate host resource successful when create instance',
        task_id)

    # 往instance_image表添加记录
    logging.info(
        '创建VM 步骤10-6:插入instance_image表 task %s : insert instance_image table start when create instance',
        task_id)
    for _image in image_data:
        instance_image_data = {
            'instance_id': instance_id,
            'image_id': _image['id'],
            'created_at': get_datetime_str()
        }
        ret5 = ins_img_s.InstanceImageService().add_instance_image_info(
            instance_image_data)
        if ret5.get('row_num') <= 0:
            logging.error(
                'task %s : add instance_image info error when create instance, insert_data: %s',
                task_id, instance_image_data)
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
    logging.info(
        '创建VM 步骤10-6:插入instance_image表成功 '
        'task %s : insert instance_image table successful when create instance',
        task_id)

    # 往instance_ip表添加记录
    logging.info(
        '创建VM 步骤10-7:插入instance_ip表 '
        'task %s : insert instance_ip table start when create instance',
        task_id)
    mac = randomMAC()
    data_ip_address = ip_data['ip_address']
    instance_ip_data = {
        'instance_id': instance_id,
        'ip_id': ip_data['id'],
        'mac': mac,
        'type': InstanceNicType.MAIN_NETWORK_NIC,
        'isdeleted': '0',
        'created_at': get_datetime_str()
    }
    ret6 = ins_ip_s.InstanceIPService().add_instance_ip_info(instance_ip_data)
    if ret6.get('row_num') <= 0:
        logging.error(
            'task %s : add instance_ip info error when create instance, insert_data: %s',
            task_id, instance_ip_data)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
    logging.info(
        '创建VM 步骤10-7:插入instance_ip表成功 '
        'task %s : insert instance_ip table successful when create instance',
        task_id)

    # 标识该IP为已使用
    logging.info(
        '创建VM 步骤10-8:设置IP为已使用 task %s : set ip used start when create instance',
        task_id)
    update_data = {'status': IPStatus.USED}
    where_data = {'id': ip_data['id']}
    ret7 = ip_service.IPService().update_ip_info(update_data, where_data)
    if ret7 <= 0:
        logging.info(
            'task %s : update ip info error when create instance, update_data: %s, where_data: %s',
            task_id, update_data, where_data)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
    logging.info(
        '创建VM 步骤10-8:设置IP为已使用成功 task %s : set ip used successful when create instance',
        task_id)

    # 拼装消息需要的镜像信息
    logging.info(
        '创建VM 步骤10-9:拼装所需的镜像信息 '
        'task %s : piece together need image info start when create instance',
        task_id)
    image_list = []
    # 数据盘数量
    data_image_num = 0
    for _image in image_data:
        _image_type = _image['type']
        _info = {
            "disk_format": _image['format'],
            "url": _image['url'],
            # "md5sum": _image['md5'],
            "image_size_gb": _image['size_gb']  # 镜像预分配大小
        }
        # 系统盘
        if _image_type == ImageType.SYSTEMDISK:
            _disk_name = instance_name + '.img'
            _info['image_dir_path'] = '/app/image/' + uuid + '/' + _disk_name
            _info['disk_name'] = _disk_name
            _info['disk_size_gb'] = None
            _info['dev_name'] = 'vda'

            # 如果只有一块盘且为系统盘,则预先分配一块数据盘的数据存入instance_disk表
            if len(image_data) == 1:
                logging.info(
                    'task %s : pre insert instance_disk table that has only one system disk start when create '
                    'instance', task_id)
                instance_disk_data = {
                    'instance_id': instance_id,
                    'size_gb': vm_disk_gb,
                    'mount_point': mount_point,
                    'dev_name': 'vdb',
                    'isdeleted': '0',
                    'created_at': get_datetime_str()
                }
                ret9 = ins_d_s.InstanceDiskService().add_instance_disk_info(
                    instance_disk_data)
                if ret9.get('row_num') <= 0:
                    logging.info(
                        'task %s : pre add instance_disk info that has only one system disk error when create '
                        'instance, insert_data: %s', task_id,
                        instance_disk_data)
                    return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
                logging.info(
                    'task %s : pre insert instance_disk table that has only one system disk successful when '
                    'create instance', task_id)
        else:
            # 数据盘
            _disk_name = instance_name + '.disk' + str(data_image_num + 1)
            _disk_dev_name = _get_vd_map(data_image_num)
            _info['image_dir_path'] = '/app/image/' + uuid + '/' + _disk_name
            _info['disk_name'] = _disk_name
            _info['disk_size_gb'] = vm_disk_gb
            _info['dev_name'] = _disk_dev_name
            data_image_num += 1

            # 往instance_disk表添加记录
            logging.info(
                'task %s : insert instance_disk table start when create instance',
                task_id)
            instance_disk_data = {
                'instance_id': instance_id,
                'size_gb': vm_disk_gb,
                'mount_point': mount_point,
                'dev_name': _disk_dev_name,
                'isdeleted': '0',
                'created_at': get_datetime_str()
            }
            ret8 = ins_d_s.InstanceDiskService().add_instance_disk_info(
                instance_disk_data)
            if ret8.get('row_num') <= 0:
                logging.info(
                    'task %s : add instance_disk info error when create instance, insert_data: %s',
                    task_id, instance_disk_data)
                return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
            logging.info(
                'task %s : insert instance_disk table successful when create instance',
                task_id)

        image_list.append(_info)
    logging.info(
        '创建VM 步骤10-9:拼装所需的镜像信息成功 '
        'task %s : piece together need image info successful when create instance',
        task_id)

    # 发送异步消息到队列
    logging.info(
        '创建VM 步骤10-10:发送异步消息给队列 '
        'task %s : send kafka message start when create instance', task_id)
    data = {
        "routing_key": "INSTANCE.CREATE",
        "send_time": get_datetime_str(),
        "data": {
            "task_id":
            task_id,
            "request_id":
            request_id,
            "host_ip":
            vm_host['ipaddress'],
            "uuid":
            uuid,
            "hostname":
            instance_name,  # 实例名
            "memory_mb":
            flavor_info['memory_mb'],
            "vcpu":
            flavor_info['vcpu'],
            "ostype":
            instance_system,
            "user_id":
            user_id,
            "disks":
            image_list,
            "disk_size":
            vm_disk_gb,
            "image_name":
            _image['url'].split('/')[-1],
            "net_area_id":
            net_area_id,
            "networks": [{
                "net_card_name": "br_bond0." + segment_data['vlan'],
                "ip": data_ip_address,
                "netmask": segment_data['netmask'],
                "dns1": segment_data['dns1'],
                "dns2": segment_data['dns2'],
                "mac": mac,
                "gateway": segment_data['gateway_ip'],
                "env": vm_env  # SIT STG PRD DR
            }]
        }
    }
    ret_kafka = send_async_msg(KAFKA_TOPIC_NAME, data)
Beispiel #26
0
def init_ips(segment_id):
    '''
        批量初始化IP
    :param segment_id:
    :return:
    '''
    begin_ip = request.values.get('begin_ip')
    end_ip = request.values.get('end_ip')

    if not begin_ip or not end_ip:
        logging.info('begin or end ip is empty when init ips')
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR)

    # 获取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:
            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)
    try:
        # 截取IP地址最后一位
        begin_ip_org = begin_ip.split('.')[3]
        end_ip_org = end_ip.split('.')[3]
        # 起始IP不能大于结束IP
        if int(begin_ip_org) > int(end_ip_org) or int(begin_ip_org) > 254 or int(begin_ip_org) < 1 \
                or int(end_ip_org) > 254 or int(end_ip_org) < 1:
            logging.info('begin or end ip is invalid when init ips')
            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.PARAM_ERR)

        inited_ips_list = []
        ips_init_list = []
        # 查询该网段下已初始化的IP数量
        ips_inited_db = ip_service.ip_inited_in_segment(segment_id)

        ip_info_db = segment_service.ip_info_in_segment(segment_id)
        if not ip_info_db:
            logging.info('segment info is invalid in db when init ips')
            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)
        ip_vlan = ip_info_db['vlan']
        ip_netmask = ip_info_db['netmask']
        ip_segment_id = ip_info_db['id']
        ip_gateway_ip = ip_info_db['gateway_ip']
        ip_dns1 = ip_info_db['dns1']
        ip_dns2 = ip_info_db['dns2']

        for i in range(len(ips_inited_db)):
            inited_ips_list.append(str(ips_inited_db[i]['ip_address']))

        # 截取IP地址前三位
        ip_c = begin_ip.split('.')[0] + '.' + begin_ip.split(
            '.')[1] + '.' + begin_ip.split('.')[2] + '.'
        for i in range(int(begin_ip_org), int(end_ip_org) + 1):
            ip_for_insert_to_sql = str(ip_c) + str(i)
            if ip_for_insert_to_sql in inited_ips_list:
                continue
            else:
                ips_init_list.append(i)

        if not ips_init_list:
            logging.info('no ip can init when init ips')
            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)

        # 操作的IP数
        all_num = len(ips_init_list)
        fail_num = 0
        for _ip_init in ips_init_list:
            ip_init_address = str(ip_c) + str(_ip_init)
            insert_data = {
                'ip_address': ip_init_address,
                'segment_id': ip_segment_id,
                'netmask': ip_netmask,
                'vlan': ip_vlan,
                'gateway_ip': ip_gateway_ip,
                'dns1': ip_dns1,
                'dns2': ip_dns2,
                'status': IPStatus.UNUSED,
                'created_at': get_datetime_str()
            }
            ret = ip_service.IPService().add_ip_info(insert_data)
            if ret <= 0:
                logging.error("init ips error, insert_data: %s",
                              str(insert_data))
                fail_num += 1
                continue
    except Exception as e:
        _msg = '批量初始化IP:初始化ip出现异常begin_ip %s,end_ip%s: batch ip init exception when ips init,err:%s' % (
            begin_ip, end_ip, 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(code=ErrorCode.SYS_ERR,
                                           msg=ret_ip_lock_unused_datas)

    # 全失败
    if fail_num == all_num:
        logging.error("init ips all failed")
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
    # 部分成功
    if 0 < fail_num < all_num:
        logging.error("init ips part failed")
        return json_helper.format_api_resp(code=ErrorCode.SUCCESS_PART,
                                           msg="部分IP初始化成功")
    return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
Beispiel #27
0
def init_ip(segment_id):
    '''
        初始化IP
    :param segment_id:
    :return:
    '''
    ip_address = request.values.get('ip_address')
    if not ip_address or not segment_id:
        logging.info('no ip_address or segment_id when init ip')
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR)

    # 获取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:
            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:
        ip_info = ip_service.IPService().get_ip_by_ip_address(ip_address)
        if ip_info:
            logging.info('the IP has inited in db when init ip')
            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_info_from_segment = segment_service.ip_info_in_segment(segment_id)
        if not ip_info_from_segment:
            logging.info('no segment: %s in db when init ip', segment_id)
            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)
        ip_vlan = ip_info_from_segment['vlan']
        ip_netmask = ip_info_from_segment['netmask']
        ip_segment_id = ip_info_from_segment['id']
        ip_gateway_ip = ip_info_from_segment['gateway_ip']
        ip_dns1 = ip_info_from_segment['dns1']
        ip_dns2 = ip_info_from_segment['dns2']

        insert_data = {
            'ip_address': ip_address,
            'segment_id': ip_segment_id,
            'netmask': ip_netmask,
            'vlan': ip_vlan,
            'gateway_ip': ip_gateway_ip,
            'dns1': ip_dns1,
            'dns2': ip_dns2,
            'status': IPStatus.UNUSED,
            'created_at': get_datetime_str()
        }
        ret = ip_service.IPService().add_ip_info(insert_data)
    except Exception as e:
        _msg = '初始化IP:ip初始化时出现异常 网段%s IP%s:ip init exception when ip init,err:%s' % (
            segment_id, ip_address, 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(code=ErrorCode.SYS_ERR,
                                           msg=ret_ip_lock_unused_datas)

    if ret == -1:
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
    return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
Beispiel #28
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)