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状态重置成功"
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, '数据库记录修改成功'
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']
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)
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
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)
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)
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)
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
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)
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
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)
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)
def _task_esx_intodb(task): # 获取vm入参 vmname = task['vm_name'] vmip = task['vm_ip'] flavor_id = task['flavor_id'] vm_ostype = task['vm_ostype'] vm_app_info = task['vm_app_info'] vm_owner = task['vm_owner'] vm_segment = task['vm_segment'] vm_group_id = task['group_id'] dest_host = task['dest_host'] vmhost = ho_s.HostService().get_host_info_by_hostip(dest_host) ret_4 = ho_s.pre_allocate_host_resource(vmhost['id'], task['vm_cpu'], task['vm_mem_mb'], 50) if ret_4 != 1: logging.error('资源预分配失败') message = '资源预分配失败' return False, message # 获取并录入IP信息 vm_segment = seg_s.SegmentService().get_segment_info_bysegment(vm_segment) if vm_segment is None: message = '网段信息有误,无法进行v2v操作' return False, message else: segment_id = vm_segment['id'] vm_netmask = vm_segment['netmask'] vm_gateway = vm_segment['gateway_ip'] vm_dns1 = vm_segment['dns1'] vm_dns2 = vm_segment['dns2'] vmvlan = vm_segment['vlan'] ip_data = ip_s.IPService().get_ip_info_by_ipaddress(vmip) if ip_data is None: ip_data = { 'ip_address': vmip, 'segment_id': segment_id, 'netmask': vm_netmask, 'vlan': vmvlan, 'gateway_ip': vm_gateway, 'dns1': vm_dns1, 'dns2': vm_dns2, 'created_at': get_datetime_str(), 'status': '1' } ret = ip_s.IPService().add_ip_info(ip_data) if ret.get('row_num') <= 0: logging.info( 'add ip info error when create v2v task, insert_data: %s', ip_data) message = "录入IP信息失败" return False, message else: ip_id = ret.get('last_id') else: ip_data_status = ip_data['status'] vmvlan = ip_data['vlan'] if ip_data_status != '0': message = "IP与现有环境冲突,无法进行v2v操作" return False, message else: ip_id = ip_data['id'] where_data = {'id': ip_id} updata_data = {'status': '1', 'updated_at': get_datetime_str()} ret1 = ip_s.IPService().update_ip_info(updata_data, where_data) if not ret1: logging.info( 'update ip info error when create v2v task, update_data: %s', updata_data) message = "更新IP状态失败" return False, message # 生成request_id request_id = v2v_op.generate_req_id() # 生成vm的uuid和mac vmuuid = randomUUID() vmmac = randomMAC() # 信息入instance相关库表 instance_tag, instance_info = _instance_db_info( vmuuid, vmname, vm_app_info, vm_owner, flavor_id, vm_group_id, dest_host, vmmac, task['vm_disk'], ip_id, vm_ostype, request_id, task['vm_os_version']) if not instance_tag: message = instance_info return False, message # 将步骤信息存入instance_action表 v2v_cd_d1 = { 'action': esx_v2vActions.CREATE_DEST_DIR, 'request_id': request_id, 'message': 'start', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info(v2v_cd_d1) v2v_cr_pl = { 'action': esx_v2vActions.CREATE_STOR_POOL, 'request_id': request_id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info(v2v_cr_pl) v2v_cp_fl = { 'action': esx_v2vActions.COPY_FILE_TO_LOCAL, 'request_id': request_id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info(v2v_cp_fl) v2v_file = { 'action': esx_v2vActions.VIRT_V2V_FILES, 'request_id': request_id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info(v2v_file) v2v_del_tmp = { 'action': esx_v2vActions.DELETE_TMP_FILE, 'request_id': request_id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info(v2v_del_tmp) v2v_sysdisk_std = { 'action': esx_v2vActions.VM_SYS_DISK_STD, 'request_id': request_id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info( v2v_sysdisk_std) v2v_datadisk_std = { 'action': esx_v2vActions.VM_DATA_DISK_STD, 'request_id': request_id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info( v2v_datadisk_std) v2v_def_1 = { 'action': esx_v2vActions.VM_DEFINE1, 'request_id': request_id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info(v2v_def_1) v2v_star_1 = { 'action': esx_v2vActions.VM_START1, 'request_id': request_id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info(v2v_star_1) if vm_ostype == "Windows": v2v_att_disk = { 'action': esx_v2vActions.ATTACH_DISK, 'request_id': request_id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info( v2v_att_disk) v2v_win_std = { 'action': esx_v2vActions.WINDOWS_STD, 'request_id': request_id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info( v2v_win_std) v2v_vm_def2 = { 'action': esx_v2vActions.WINDOWS_DISK_CH, 'request_id': request_id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info( v2v_vm_def2) v2v_vm_star2 = { 'action': esx_v2vActions.VM_START2, 'request_id': request_id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info( v2v_vm_star2) # 将v2v信息存入v2v_task表 v2v_data = { 'source': VMCreateSource.ESX, 'request_id': request_id, 'destory': '0', 'start_time': get_datetime_str(), 'status': 0, 'vm_ip': vmip, 'vm_name': vmname, 'vmvlan': vmvlan, 'flavor_id': flavor_id, 'cloud_area': task['esx_env'], 'vm_ostype': vm_ostype, 'vm_app_info': vm_app_info, 'vm_owner': vm_owner, 'vm_group_id': vm_group_id, 'user_id': task['user_id'], 'vm_mac': vmmac, 'vm_uuid': vmuuid, 'cancel': '0', 'dest_dir': '/app/image/' + vmuuid, 'on_task': '0', 'dest_host': dest_host, 'esx_ip': task['esx_ip'], 'esx_passwd': task['esx_passwd'], 'vmware_vm': task['vmware_vm'], 'step_done': esx_v2vActions.BEGIN } v2v_insert = v2v_op.v2vTaskService().add_v2v_task_info(v2v_data) if v2v_insert.get('row_num') <= 0: logging.info('insert info to v2v_task failed! %s', v2v_data) message = '信息入库失败' return False, message message = '信息已添加至任务队列' return True, message
def 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)
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)
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)
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)
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)