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 net_area_delete(): net_area_ids = request.values.get('net_area_ids') if not net_area_ids: logging.error('no net_area_ids when delete net area') return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR) net_area_ids_list = net_area_ids.split(',') # 操作的net area数 all_num = len(net_area_ids_list) msg = None fail_num = 0 for _id in net_area_ids_list: # 有集群和网段的都不能删除 _hostpool_num = hostpool_s.HostPoolService( ).get_hostpool_nums_in_net_area(_id) if _hostpool_num > 0: logging.error('no allow to delete net area %s that has hostpool', _id) fail_num += 1 # 单台操作且已失败则直接跳出循环 if all_num == 1: msg = '该网络区域下已分配有集群,不允许删除' break continue _segment_num = segment_s.SegmentService().get_segment_nums_in_net_area( _id) if _segment_num > 0: logging.error( 'no allow to delete net area %s that has network segment', _id) fail_num += 1 # 单台操作且已失败则直接跳出循环 if all_num == 1: msg = '该网络区域下已分配有网段,不允许删除' break continue _ret = net_area_s.NetAreaService().delete_net_area(_id) if _ret <= 0: logging.error('db delete net area %s fail when delete net area', _id) fail_num += 1 continue # 全失败 if fail_num == all_num: logging.error("delete net area all failed") if msg: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=msg) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) # 部分成功 if 0 < fail_num < all_num: logging.error("delete all %s net area part %s failed", all_num, fail_num) return json_helper.format_api_resp(code=ErrorCode.SUCCESS_PART, msg="部分网络区域删除成功") return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
def add_segment(): ''' 录入一个新网段 ''' network_segment_match = request.json.get("network_segment_match",[]) segment_match_dic = {} for index, item in enumerate(network_segment_match): status, res = check_prdr(item) if not status: return json_helper.format_api_resp(ErrorCode.ALL_FAIL, msg=res) bond_dev = NetCardTypeToDevice.MSG_DICT.get(item['segment_type']) insert_data = { 'net_area_id': int(item['net_area_id']), 'segment': item['segment'], 'segment_type': item['segment_type'], 'host_bridge_name': 'br_' + bond_dev, 'netmask': str(item['netmask']), 'vlan': str(item['vlan']), 'gateway_ip': item['gateway'], 'dns1': item['dns1'], 'dns2': item['dns2'], 'status': NetworkSegmentStatus.ENABLE, 'created_at': get_datetime_str() } ret = segment_service.SegmentService().add_segment_info(insert_data) if ret['row_num'] <= 0: return json_helper.format_api_resp(code=ErrorCode.ALL_FAIL, msg="网段入库失败") if len(network_segment_match) == 2: dc_type = datacenter_service.DataCenterService().get_dctype_by_net_area_id(item['net_area_id']) if dc_type == '4': segment_match_dic['prd_segment_id'] = network_segment.get_network_segment_id_info_by_network_segment( item['net_area_id'], item['segment'], item['vlan'], item['gateway'], 'br_' + bond_dev) elif dc_type == '5': segment_match_dic['dr_segment_id'] = network_segment.get_network_segment_id_info_by_network_segment( item['net_area_id'], item['segment'], item['vlan'], item['gateway'], 'br_' + bond_dev) if len(network_segment_match) == 2: insert_data_match = { 'prd_segment_id': int(segment_match_dic['prd_segment_id']['id']), 'dr_segment_id': int(segment_match_dic['dr_segment_id']['id']), 'isdeleted': '0' } ret_match = segment_match.SegmentMatchService().add_segment_match_info(insert_data_match) if ret_match['row_num'] <= 0: return json_helper.format_api_resp(code=ErrorCode.ALL_FAIL, msg="匹配网段入库失败") return json_helper.format_api_resp(code=ErrorCode.SUCCESS, msg="匹配网段已成功加入")
def get_avail_tmp_ip(): ''' 从专用网段中获取一个ip分配给模板机 :param segments_list: :param count: :param env: :return: ''' segment_data = segment_s.SegmentService().get_segment_for_img_tmp() ips_info = ip.get_available_ip(segment_data['id']) if not ips_info: return False, '该网段id:%s没有可用ip' % str(segment_data['id']) ip_data = ips_info[0] return ip_data, segment_data
def ip_resource_display_to_other_platform_new(): ''' 将kvm已有的网段展示给其他平台新接口,查询指定网段可用的ip数量 :return: ''' data_from_vishnu = request.data logging.info(data_from_vishnu) data_requset = json_helper.loads(data_from_vishnu) req_datacenter = data_requset['dataCenter'] req_env = data_requset['env'] req_net_area = data_requset['netArea'] req_net_name = data_requset['netName'] # 校验入参是否为空 if not req_env or not req_net_area or not req_net_name or not req_datacenter: return json_helper.format_api_resp_msg_to_vishnu_resource(job_status=VsJobStatus.FAILED, detail='入参有空值') # 查询指定环境、网络区域是否有所需网段 ret_segment = segment_service.SegmentService().get_segment_info_bysegment(req_net_name.split('/')[0]) if not ret_segment: return json_helper.format_api_resp_msg_to_vishnu_resource(job_status=VsJobStatus.FAILED, detail="无法找到需要申请的网段") ret_net_area_info = net_area.NetAreaService().get_net_area_info(ret_segment['net_area_id']) if not ret_net_area_info: return json_helper.format_api_resp_msg_to_vishnu_resource(job_status=VsJobStatus.FAILED, detail="无法找到指定网段所属网络区域信息") ret_datacenter_info = datacenter_service.DataCenterService().get_datacenter_info( ret_net_area_info['datacenter_id']) if not ret_datacenter_info: return json_helper.format_api_resp_msg_to_vishnu_resource(job_status=VsJobStatus.FAILED, detail="无法找到指定机房信息") if req_env not in DataCenterTypeForVishnu.TYPE_DICT: return json_helper.format_api_resp_msg_to_vishnu_resource(job_status=VsJobStatus.FAILED, detail="无法找到指定机房类型信息") if str(DataCenterTypeForVishnu.TYPE_DICT[req_env]) != ret_datacenter_info['dc_type']: return json_helper.format_api_resp_msg_to_vishnu_resource(job_status=VsJobStatus.FAILED, detail="无法找到指定网络区域对应网段信息") # 获取可用ip ret_ip_available_status, ret_ip_available = ip_service.get_all_available_segment_ip(ret_segment['id'], str( DataCenterTypeForVishnu.TYPE_DICT[req_env])) if not ret_ip_available_status: ret_params = { "ip_num": 0 } return json_helper.format_api_resp_msg_to_vishnu_resource(job_status=VsJobStatus.SUCCEED, detail=ret_params) ret_params = { "ip_num": len(ret_ip_available) } return json_helper.format_api_resp_msg_to_vishnu_resource(job_status=VsJobStatus.SUCCEED, detail=ret_params)
def image_edit(): eimage_name = request.values.get('image_name') if not eimage_name: # message = { # 'code': ErrorCode.SYS_ERR, # 'msg': "入参缺失" # } # socketio.emit('image_edit_resp', message, namespace='/image_edit_return') return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='入参缺失') # 判断当前image状态是否正常 image_manage_data = im_s.ImageManageService().get_img_manage_data_by_name( eimage_name) image_manage_stat = image_manage_data[1]["status"] image_manage_type = image_manage_data[1]["os_type"] image_manage_osver = image_manage_data[1]["version"] enable_stat = [ImageManage.INIT, ImageManage.CHECKOUT, ImageManage.USABLE] if image_manage_stat not in enable_stat: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='当前模板机状态不允许此操作') # template vm start ret, message = im_man_act._img_tem_start(eimage_name) update_action = im_m_act.START_VEM if not ret: state_tag = im_m_act_sta.FAILED im_s.ImageStatusService().add_image_status_action( eimage_name, update_action, state_tag, message) im_s.ImageManageService().update_image_manage_msg(eimage_name, message) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=message) else: state_tag = im_m_act_sta.SUCCESSED im_s.ImageStatusService().add_image_status_action( eimage_name, update_action, state_tag, message) # update template vm stat update_data = {'template_status': img_tmp_status.RUNNING} where_data = {'eimage_name': eimage_name} im_s.ImageManageService().update_image_info(update_data, where_data) # template vm inject ip ret, res_data = im_s.ImageManageService().get_img_manage_data_by_name( eimage_name) update_action = im_m_act.IP_INJECT if not ret: state_tag = im_m_act_sta.FAILED error_msg = res_data im_s.ImageStatusService().add_image_status_action( eimage_name, update_action, state_tag, error_msg) im_s.ImageManageService().update_image_manage_msg(eimage_name, message) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='获取镜像信息失败') ip_address = res_data['template_vm_ip'] segment_data = segment_s.SegmentService().get_segment_for_img_tmp() if not segment_data: error_msg = '获取镜像模板专用网段失败' state_tag = im_m_act_sta.FAILED im_s.ImageStatusService().add_image_status_action( eimage_name, update_action, state_tag, error_msg) im_s.ImageManageService().update_image_manage_msg(eimage_name, message) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='获取镜像模板专用网段失败') netmask_int = int(segment_data['netmask']) netmask = exchange_maskint(netmask_int) gateway = segment_data['gateway_ip'] dns1 = segment_data['dns1'] dns2 = segment_data['dns2'] res, message = im_man_act._img_tem_inject(eimage_name, ip_address, netmask, gateway, image_manage_type, image_manage_osver, dns1, dns2) update_action = im_m_act.IP_INJECT if not res: error_msg = message state_tag = im_m_act_sta.FAILED im_s.ImageStatusService().add_image_status_action( eimage_name, update_action, state_tag, error_msg) im_s.ImageManageService().update_image_manage_msg(eimage_name, message) msg = '模板机%s 初始化注入失败' % eimage_name return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=msg) else: state_tag = im_m_act_sta.SUCCESSED im_s.ImageStatusService().add_image_status_action( eimage_name, update_action, state_tag, message) # 更新template_status message = '' im_s.ImageManageService().update_image_manage_status( eimage_name, message, ImageManage.EDITING) message = '模板机%s 开机编辑成功' % eimage_name return json_helper.format_api_resp(code=ErrorCode.SUCCESS, msg=message)
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 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 get_all_available_segment_ip(segment_id, env): ''' 返回指定网段所有可用ip :param segment_id: :param env: :return: ''' ips_list = [] ips_info = ip.get_available_ip(segment_id) if ips_info: # 多线程ping去掉通的ip global IP_AVAILABLE_LIST IP_AVAILABLE_LIST = [] threads = [] for _per_unused_ip in ips_info: ip_check_thread = threading.Thread(target=__ping_ip_available, args=(_per_unused_ip, )) threads.append(ip_check_thread) ip_check_thread.start() # 判断多线程是否结束 for t in threads: t.join() if len(IP_AVAILABLE_LIST) > 0: for _ip in IP_AVAILABLE_LIST: if int(env) == DataCenterType.PRD: segment_dr = segment_m.SegmentMatchService( ).get_segment_match_info_by_prd_segment_id(segment_id) if not segment_dr: continue segment_dr_data = segment_s.SegmentService( ).get_segment_info(segment_dr['dr_segment_id']) if not segment_dr_data: continue # 拼凑虚拟机容灾IP dr_ip = segment_dr_data['segment'].split('.')[0] + '.' + segment_dr_data['segment'].split('.')[1] + \ '.' + _ip['ip_address'].split('.')[2] + '.' + _ip['ip_address'].split('.')[3] # ping ip,通的话不允许分配 # ret_ping = __ping_ip_available_simple(dr_ip) # if not ret_ping: # continue dr_ip_info = IPService().get_ip_by_ip_address(dr_ip) # 如果容灾IP是未使用中状态,可以使用 if dr_ip_info: if dr_ip_info['status'] == IPStatus.UNUSED: ips_list.append(_ip) elif int(env) == DataCenterType.DR: segment_prd = segment_m.SegmentMatchService( ).get_segment_match_info_by_dr_segment_id(segment_id) if not segment_prd: continue segment_prd_data = segment_s.SegmentService( ).get_segment_info(segment_prd['prd_segment_id']) if not segment_prd_data: continue # 拼凑虚拟机生产IP prd_ip = segment_prd_data['segment'].split( '.')[0] + '.' + segment_prd_data['segment'].split( '.')[1] + '.' + _ip['ip_address'].split( '.')[2] + '.' + _ip['ip_address'].split('.')[3] # ping ip,通的话不允许分配 # ret_ping = __ping_ip_available_simple(prd_ip) # if not ret_ping: # continue prd_ip_info = IPService().get_ip_by_ip_address(prd_ip) # 如果生产环境ip是未使用中状态,可以使用 if prd_ip_info: if prd_ip_info['status'] == IPStatus.UNUSED: ips_list.append(_ip) else: ips_list.append(_ip) # 如果没有获取到合适的IP,返回失败 return True, ips_list
def get_available_ips(segments_list, count, env): ''' 从网段list中循环获取可使用的多个IP :param segments_list: :param count: :param env: :return: ''' for _segment in segments_list: ips_list = [] ips_info = ip.get_available_ip(_segment['id']) if ips_info: # 多线程ping去掉通的ip global IP_AVAILABLE_LIST IP_AVAILABLE_LIST = [] threads = [] for _per_unused_ip in ips_info: ip_check_thread = threading.Thread(target=__ping_ip_available, args=(_per_unused_ip, )) threads.append(ip_check_thread) ip_check_thread.start() logging.info("ip available list: {}".format(IP_AVAILABLE_LIST)) # 判断多线程是否结束 for t in threads: t.join() if len(IP_AVAILABLE_LIST) < count: continue for _ip in IP_AVAILABLE_LIST: if int(env) == DataCenterType.PRD: segment_dr = segment_m.SegmentMatchService( ).get_segment_match_info_by_prd_segment_id(_segment['id']) if not segment_dr: continue segment_dr_data = segment_s.SegmentService( ).get_segment_info(segment_dr['dr_segment_id']) if not segment_dr_data: continue # 拼凑虚拟机容灾IP dr_ip = segment_dr_data['segment'].split('.')[0] + '.' + segment_dr_data['segment'].split('.')[1] + \ '.' + _ip['ip_address'].split('.')[2] + '.' + _ip['ip_address'].split('.')[3] # ping ip,通的话不允许分配 ret_ping = __ping_ip_available_simple(dr_ip) if not ret_ping: continue dr_ip_info = IPService().get_ip_by_ip_address(dr_ip) # 如果容灾IP是未使用中状态,可以使用 if dr_ip_info: if dr_ip_info['status'] == IPStatus.UNUSED: ips_list.append(_ip) if len(ips_list) == int(count): return ips_list, _segment elif int(env) == DataCenterType.DR: segment_prd = segment_m.SegmentMatchService( ).get_segment_match_info_by_dr_segment_id(_segment['id']) if not segment_prd: continue segment_prd_data = segment_s.SegmentService( ).get_segment_info(segment_prd['prd_segment_id']) if not segment_prd_data: continue # 拼凑虚拟机生产IP prd_ip = segment_prd_data['segment'].split( '.')[0] + '.' + segment_prd_data['segment'].split( '.')[1] + '.' + _ip['ip_address'].split( '.')[2] + '.' + _ip['ip_address'].split('.')[3] ret_ping = __ping_ip_available_simple(prd_ip) if not ret_ping: continue prd_ip_info = IPService().get_ip_by_ip_address(prd_ip) # 如果生产环境ip是未使用中状态,可以使用 if prd_ip_info: if prd_ip_info['status'] == IPStatus.UNUSED: ips_list.append(_ip) if len(ips_list) == int(count): return ips_list, _segment else: ips_list.append(_ip) if len(ips_list) == int(count): return ips_list, _segment # 如果没有获取到合适的IP,返回失败 return False, ''
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 standard_host(manage_ip, hostpool_id): ''' 物理机标准化操作 :param manage_ip: :return: ''' url = HOST_STANDARD_DIR + '/host_std.yaml' host_list = [manage_ip] # 获取新增host所在网络区域的vlanlist hostpool_info = hp_s.HostPoolService().get_hostpool_info(hostpool_id) net_area_id = hostpool_info['net_area_id'] vlan_res, vlan_data = seg_s.SegmentService().get_area_segment_list( net_area_id) if not vlan_res: return False, vlan_data else: host_vlan_filter_dict = {} host_vlan_list = vlan_data # host_vlan_list_dupl = sorted(set(host_vlan_list), key=host_vlan_list.index) # 根据br_bond对网段进行分类 for _host_vlan in host_vlan_list: if _host_vlan['host_bridge_name'] in host_vlan_filter_dict.keys(): host_vlan_filter_dict[_host_vlan['host_bridge_name']].append( _host_vlan['vlan']) else: host_vlan_filter_dict[_host_vlan['host_bridge_name']] = [ _host_vlan['vlan'] ] # host_vlan_list_dupl = sorted(set(host_vlan_list), key=lambda i: i["host_bridge_name"]) # 循环调用playbook为不同bond新建网桥,每次调用完成后需要time.sleep(5) br_bond_create_shell_url = HOST_STANDARD_DIR + '/host_std_br_bond_create.yaml' for _bond_name, _vlan_list in host_vlan_filter_dict.items(): host_dict = { "srcdir": HOST_STANDARD_DIR, "host_vlan_list": _vlan_list, "br_bond": _bond_name.split('_')[1] } run_result, run_message = run_standard_host(br_bond_create_shell_url, manage_ip, host_dict) if not run_result: logging.info('物理机%s初始化新增内网vlan执行playbook失败,原因:%s' % (manage_ip, run_message)) return False, run_message time.sleep(2) time.sleep(2) # 构造host网桥检测入参内容 host_test_bridge_list = [] for vlan_info in vlan_data: bridge_name = vlan_info['host_bridge_name'] + '.' + vlan_info['vlan'] gateway_ip = vlan_info['gateway'] vlan = vlan_info['vlan'] host_test_bridge = { "bridge": bridge_name, "gateway": gateway_ip, "vlan": vlan } host_test_bridge_list.append(host_test_bridge) # # 循环调用playbook测试HOST上对指定网桥的访问是否正常 # bridge_test_shell_url = HOST_STANDARD_DIR + '/host_std_test_vlan.yaml' # host_dict = { # "test_bridge_info": host_test_bridge_list # } res, message = check_vlan_connection(manage_ip, host_test_bridge_list) if not res: return False, message logging.info('start to do host std playbook') # 获取host所在网络区域的yum源地址 datacenter_id = da_s.DataCenterService().get_dctype_by_net_area_id( net_area_id) if str(datacenter_id) in PRD_DC_TYPE: yum_server_addr = PRD_YUM_SERVER else: yum_server_addr = CS_YUM_SERVER # #构造vlan_list字符串传递给playbook作为入参 # vlan_list_str = " ".join(host_vlan_list) # vlan_str = "\'" + vlan_list_str + "\'" # print vlan_str playbook_url = HOST_STANDARD_DIR + '/host_std.yaml' host_dict = { "srcdir": HOST_STANDARD_DIR, "agentdir": HOST_AGENT_PACKAGE_COPY_DIR, "agentshelldir": HOST_AGENT_PACKAGE_INSTALL_SHELL_DIR, "libvirt_user_pwd": decrypt(HOST_LIBVIRT_PWD), "root_pwd": decrypt(ROOT_PWD), "yum_server_ip": yum_server_addr } run_result, run_message = run_standard_host(playbook_url, manage_ip, host_dict) if not run_result: return False, run_message logging.info('物理机%s初始化playbook执行成功' % manage_ip) # 创建池 pool_ret = _create_storage_pool(manage_ip) if not pool_ret: logging.info('host manage ip %s create pool fail when standard host', manage_ip) msg = "创建存储池失败" return False, msg # 创建clone池 pool_ret = _create_clone_pool(manage_ip) if not pool_ret: logging.info( 'host manage ip %s create clone pool fail when standard host', manage_ip) msg = "创建clone存储池失败" return False, msg # host 运行checklist ret_checklist, msg_checklist = host_std_checklist(manage_ip) if not ret_checklist: msg = msg_checklist logging.info(msg) return False, msg msg = "标准化主机成功" return True, msg
def v2v_esx_intodb(hostpool_id): ''' v2v_esx :param hostpool_id: :return: ''' #获取vm入库信息 vmname = request.values.get('vm_name') vmip = request.values.get('vm_ip') flavor_id = request.values.get('flavor_id') vm_ostype = request.values.get('vm_ostype') vm_app_info = request.values.get('vm_app_info') vm_owner = request.values.get('vm_owner') vm_group_id = request.values.get('vm_group_id') user_id = request.values.get('user_id') vm_segment = request.values.get('segment') vm_osver = request.values.get('vm_osver') vm_disk = request.values.get('vm_disk') esx_env = request.values.get('esx_env') esx_ip = request.values.get('esx_ip') esx_passwd1 = request.values.get('esx_passwd') vmware_vm = request.values.get('vmware_vm') # 入参完全性判断 if not vmname or not vmip or not flavor_id or not vm_ostype or not vm_app_info \ or not vm_osver or not vm_disk or not vm_owner or not vm_group_id or not user_id or not vm_segment or not esx_passwd1: logging.info('params are invalid or missing') return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR, msg='入参缺失') else: esx_passwd = base64.b64decode(esx_passwd1) powertag, msg_power = vm_powerState(esx_ip, esx_passwd, vmware_vm) if not powertag: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=msg_power) # 获取flavor信息 flavor_info = flavor_service.FlavorService().get_flavor_info(flavor_id) if not flavor_info: logging.info('id: %s flavor info not in db when create instance', flavor_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='实例规格数据有误,无法进行v2v') vmcpu = flavor_info['vcpu'] vmmem = flavor_info['memory_mb'] data_disk = int(vm_disk) # 获取可用目标host host_code, host_data, host_msg = cal_host(hostpool_id, vmcpu, vmmem, data_disk, vm_group_id) if host_code < 0: return json_helper.format_api_resp(code=host_code, msg=host_msg) else: host = host_data vmhost = ho_s.HostService().get_host_info_by_hostip(host) ret_4 = ho_s.pre_allocate_host_resource(vmhost['id'], vmcpu, vmmem, 50) if ret_4 != 1: logging.error('资源预分配失败') message = '资源预分频失败' return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=message) # 获取并录入IP信息 vm_segment = seg_s.SegmentService().get_segment_info_bysegment( vm_segment) if vm_segment == None: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='网段信息有误,无法进行v2v') else: segment_id = vm_segment['id'] vm_netmask = vm_segment['netmask'] vm_gateway = vm_segment['gateway_ip'] vm_dns1 = vm_segment['dns1'] vm_dns2 = vm_segment['dns2'] vmvlan = vm_segment['vlan'] ip_data = ip_s.IPService().get_ip_info_by_ipaddress(vmip) if ip_data == None: ip_data = { 'ip_address': vmip, 'segment_id': segment_id, 'netmask': vm_netmask, 'vlan': vmvlan, 'gateway_ip': vm_gateway, 'dns1': vm_dns1, 'dns2': vm_dns2, 'created_at': get_datetime_str(), 'status': '1' } ret = ip_s.IPService().add_ip_info(ip_data) if ret.get('row_num') <= 0: logging.info( 'add ip info error when create v2v task, insert_data: %s', ip_data) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg="录入IP信息失败") else: ip_id = ret.get('last_id') else: ip_data_status = ip_data['status'] vmvlan = ip_data['vlan'] if ip_data_status != '0': return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg="IP与现有环境冲突,无法进行v2v") else: ip_id = ip_data['id'] where_data = {'id': ip_id} updata_data = { 'status': '1', 'updated_at': get_datetime_str() } ret1 = ip_s.IPService().update_ip_info( updata_data, where_data) if not ret1: logging.info( 'update ip info error when create v2v task, update_data: %s', updata_data) return json_helper.format_api_resp( code=ErrorCode.SYS_ERR, msg="更新IP状态失败") # 生成request_id request_Id = v2v_op.generate_req_id() # 生成vm的uuid和mac vmuuid = randomUUID() vmmac = randomMAC() if not vm_osver: vm_osver = "unknown" # 信息入instance相关库表 instance_info = instance_db_info(vmuuid, vmname, vm_app_info, vm_owner, flavor_id, vm_group_id, host, vmmac, data_disk, ip_id, vm_ostype, request_Id, vm_osver) if instance_info < 0: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='信息入库失败') # 将步骤信息存入instance_action表 v2v_cd_d1 = { 'action': esx_v2vActions.CREATE_DEST_DIR, 'request_id': request_Id, 'message': 'start', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info(v2v_cd_d1) v2v_cr_pl = { 'action': esx_v2vActions.CREATE_STOR_POOL, 'request_id': request_Id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info(v2v_cr_pl) v2v_cp_fl = { 'action': esx_v2vActions.COPY_FILE_TO_LOCAL, 'request_id': request_Id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info(v2v_cp_fl) v2v_file = { 'action': esx_v2vActions.VIRT_V2V_FILES, 'request_id': request_Id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info(v2v_file) v2v_del_tmp = { 'action': esx_v2vActions.DELETE_TMP_FILE, 'request_id': request_Id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info(v2v_del_tmp) v2v_sysdisk_std = { 'action': esx_v2vActions.VM_SYS_DISK_STD, 'request_id': request_Id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info( v2v_sysdisk_std) v2v_datadisk_std = { 'action': esx_v2vActions.VM_DATA_DISK_STD, 'request_id': request_Id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info( v2v_datadisk_std) v2v_def_1 = { 'action': esx_v2vActions.VM_DEFINE1, 'request_id': request_Id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info(v2v_def_1) v2v_star_1 = { 'action': esx_v2vActions.VM_START1, 'request_id': request_Id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info(v2v_star_1) if vm_ostype == "Windows": v2v_att_disk = { 'action': esx_v2vActions.ATTACH_DISK, 'request_id': request_Id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info( v2v_att_disk) v2v_win_std = { 'action': esx_v2vActions.WINDOWS_STD, 'request_id': request_Id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info( v2v_win_std) v2v_vm_def2 = { 'action': esx_v2vActions.WINDOWS_DISK_CH, 'request_id': request_Id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info( v2v_vm_def2) v2v_vm_star2 = { 'action': esx_v2vActions.VM_START2, 'request_id': request_Id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info( v2v_vm_star2) message = '信息已添加至任务队列,等待执行' # 将v2v信息存入v2v_task表 v2v_data = { 'source': VMCreateSource.ESX, 'request_id': request_Id, 'destory': '0', 'start_time': get_datetime_str(), 'status': 0, 'vm_ip': vmip, 'vm_name': vmname, 'vmvlan': vmvlan, 'flavor_id': flavor_id, 'cloud_area': esx_env, 'vm_ostype': vm_ostype, 'vm_app_info': vm_app_info, 'vm_owner': vm_owner, 'vm_group_id': vm_group_id, 'user_id': user_id, 'vm_mac': vmmac, 'vm_uuid': vmuuid, 'cancel': '0', 'dest_dir': '/app/image/' + vmuuid, 'on_task': '0', 'dest_host': host, 'esx_ip': esx_ip, 'esx_passwd': esx_passwd, 'vmware_vm': vmware_vm, 'step_done': esx_v2vActions.BEGIN } v2v_insert = v2v_op.v2vTaskService().add_v2v_task_info(v2v_data) if v2v_insert.get('row_num') <= 0: logging.info('insert info to v2v_task failed! %s', v2v_data) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='信息入库失败') return json_helper.format_api_resp(code=ErrorCode.SUCCESS, msg=message)
def _check_task(i, row, user_id): # 当前行数 cur_line = str(i + 1) # Openstack环境 cloud_area = row[0] cloud_area = cloud_area.strip() # VM名称 vm_name = row[1] vm_name = vm_name.strip() # VM IP vm_ip = row[2] vm_ip = vm_ip.strip() # VM所在网段 vm_segment = row[3] vm_segment = vm_segment.strip() # 应用系统信息 vm_app_info = row[4] vm_app_info = vm_app_info.strip() # 应用管理员 vm_owner = row[5] vm_owner = vm_owner.strip() # VM环境 vm_env_name = row[6] vm_env_name = vm_env_name.strip() # VM网络区域 netarea_name = row[7] netarea_name = netarea_name.strip() # VM集群 hostpool_name = row[8] hostpool_name = hostpool_name.strip() # VM系统版本 vm_ostype = row[9] vm_ostype = vm_ostype.strip() # 应用组 group_name = row[10] group_name = group_name.strip() # CPU数量 cpu_num = row[11] cpu_num = cpu_num.strip() # 内存容量 mem_size = row[12] mem_size = mem_size.strip() # 内存容量单位 mem_size_unit = row[13] mem_size_unit = mem_size_unit.strip() if not cloud_area or not vm_name or not vm_ip or not vm_segment or not vm_app_info or not vm_owner \ or not vm_env_name or not netarea_name or not hostpool_name or not vm_ostype or not group_name \ or not cpu_num or not mem_size or not mem_size_unit: result = False, "第" + cur_line + "行:参数不正确" q.put(result) return # 1.判断flavor信息 if mem_size_unit == 'G': mem_size_mb = int(mem_size) * 1024 elif mem_size_unit == 'M': mem_size_mb = mem_size else: result = False, "第" + cur_line + "行:内存容量单位不正确" q.put(result) return flavor_info = flavor_s.get_flavor_by_vcpu_and_memory(cpu_num, mem_size_mb) if not flavor_info: result = False, "第" + cur_line + "行:实例规格数据有误" q.put(result) return # 2.根据机房类型、网络区域和集群名来判断集群信息 if vm_env_name == "DEV": vm_env = "3" elif vm_env_name == "SIT": vm_env = "1" elif vm_env_name == "STG": vm_env = "2" else: result = False, "第" + cur_line + "行:VM环境数据有误" q.put(result) return hostpool_data = hostpool_s.get_hostpool_by_vmenv_netarea_hostpool( vm_env, netarea_name, hostpool_name) if not hostpool_data: result = False, "第" + cur_line + "行:VM集群数据有误" q.put(result) return # 3.判断应用组信息 group_info = group_s.get_group_info_by_name_and_env(group_name, vm_env) if not group_info: result = False, "第" + cur_line + "行:应用组数据有误" q.put(result) return # 4.获取并录入IP信息 vm_segment_info = segment_s.SegmentService().get_segment_info_bysegment( vm_segment) if vm_segment_info is None: result = False, "第" + cur_line + "行:网段信息有误" q.put(result) return else: ip_data = ip_s.IPService().get_ip_info_by_ipaddress(vm_ip) if ip_data: if str(ip_data['status']) != IPStatus.UNUSED: result = False, "第" + cur_line + "行:IP与现有环境冲突" q.put(result) return # 5.获取对应openstack环境的管理节点及ssh账户信息 if cloud_area == "SIT": ctr_host = "10.202.83.12" ctr_pass = decrypt(OPENSTACK_SIT_PASS) elif cloud_area == "DEV": ctr_host = "10.202.123.4" ctr_pass = decrypt(OPENSTACK_DEV_PASS) else: result = False, "第" + cur_line + "行:openstack环境参数错误" q.put(result) return # 6.判断vm信息是否输入错误 vmexist = _vm_exist(vm_ip, ctr_host, ctr_pass) if not vmexist: result = False, "第" + cur_line + "行:获取vm信息失败" q.put(result) return # 7.获取OS版本失败 osstat, verdata = _get_vm_version(ctr_host, ctr_pass, vm_ostype, vm_ip) if not osstat: result = False, "第" + cur_line + "行:获取vm OS版本失败" q.put(result) return # 8.获取待迁移vm磁盘大小 vdiskdata = _vm_disk_size(vm_ip, ctr_host, ctr_pass) if not vdiskdata: result = False, "第" + cur_line + "行:获取vm磁盘信息失败" q.put(result) return data_disk = vdiskdata - 80 # 9.判断待转化vm是否关机 vmshutdown = _vm_state(vm_ip, ctr_host, ctr_pass) if not vmshutdown: result = False, "第" + cur_line + "行:待转化vm未关机" q.put(result) return # 10.判断主机名是否包含中文 check_chinese, msg = _check_chinese(vm_name) if not check_chinese: err_msg = "第" + cur_line + "行:" + msg result = False, err_msg q.put(result) return # 11.组装信息 _task = { 'vm_name': vm_name, 'vm_ip': vm_ip, 'flavor_id': flavor_info['id'], 'cloud_area': cloud_area, 'vm_ostype': vm_ostype, 'vm_app_info': vm_app_info, 'vm_owner': vm_owner, 'hostpool_id': hostpool_data['hostpool_id'], 'group_id': group_info['id'], 'user_id': user_id, 'segment': vm_segment, 'vm_disk': data_disk, 'vm_osver': verdata, } result = True, _task q.put(result)
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 check_prdr(in_env): if not all(in_env): return False, "请求入参缺失" # 校验网段是否合法 try: IP(in_env['segment'] + "/" + str(in_env['netmask'])) except: return False, "非法网段,请重新检查后录入" # 查询网段是否存在于数据库中. query_params = { 'WHERE_AND': { '=': { 'segment': in_env['segment'], 'netmask': str(in_env['netmask']) } }, } segment_nums, segment_datas = segment_service.SegmentService().query_data(**query_params) if segment_nums > 0: return False, "指定网段已存在于平台中,请确认" # 拉取网络区域下所有集群所有虚拟机列表 db_host_data = host_s._get_hosts_of_net_area(int(in_env['net_area_id'])) if not db_host_data: return False, "指定网络区域下没有一台物理机" # 判断物理机上是否有指定网桥对应的bond设备 bond_dev = NetCardTypeToDevice.MSG_DICT.get(in_env['segment_type']) if not bond_dev: return False, "不支持已选网络类型录入" ret_check_msg = "" for _host in db_host_data: ret_run_status, ret_run_msg = ansible_remote_check_host_bridge(_host['ipaddress'], bond_dev) if not ret_run_status: return False, ret_run_msg elif ret_run_status is 1: ret_check_msg += ret_run_msg if ret_check_msg: return False, ret_check_msg # 建桥,脚本满足已经创建过的跳过 ret_check_msg = "" for _host in db_host_data: host_list = [_host['ipaddress']] vlan_list = [int(in_env['vlan'])] host_bridge_dict = { "srcdir": HOST_STANDARD_DIR, "host_vlan_list": vlan_list, "br_bond": bond_dev } br_bond_create_shell_url = HOST_STANDARD_DIR + '/host_std_br_bond_create.yaml' run_result, run_message = run_standard_host(br_bond_create_shell_url, _host['ipaddress'], host_bridge_dict) if not run_result: logging.info('物理机%s初始化新增内网vlan执行playbook失败,原因:%s' % (_host['ipaddress'], run_message)) return False, run_message time.sleep(2) if ret_check_msg: return False, ret_check_msg # 判断物理机上指定网桥可用性,暂时使用for循环减少并发,有不通的反馈出来 host_test_bridge = { "bridge": 'br_' + bond_dev + '.' + str(in_env['vlan']), "gateway": in_env['gateway'], "vlan": in_env['vlan'] } host_test_bridge_list = [host_test_bridge] ret_check_msg = "" for _host in db_host_data: res, message = host_s.check_vlan_connection(_host['ipaddress'], host_test_bridge_list) if not res: ret_check_msg += message if ret_check_msg: return False, ret_check_msg return True, ''
def __instance_add_netcard(instance_netcard_datas): # 添加任务信息 task_id = instance_s.generate_task_id() insert_data = { 'action': InstaceActions.INSTANCE_ADD_NETCARD, 'instance_uuid': instance_netcard_datas['instance_uuid'], 'request_id': task_id, 'task_id': task_id, 'start_time': get_datetime_str() } ret_action = instance_action_s.InstanceActionsServices( ).add_instance_action_info(insert_data) if ret_action.get('row_num') < 1: logging.error( 'add instance change configure action info error, insert_data:%s', insert_data) return False, "添加操作步骤到instance_action表失败" # 判断要申请ip是否被分配了,如果是生产或容灾环境,需要判断其对应的容灾或生产ip是否为未使用状态 net_ip_list = [] new_ip_status = ip_s.IPService().get_ip_by_ip_address( instance_netcard_datas['ip_addr_new']) net_ip_list.append(new_ip_status) new_ip_segment_data = segment_s.SegmentService().get_segment_info( new_ip_status['segment_id']) if not new_ip_status or not new_ip_segment_data: _msg = '网卡配置ip:无法获取数据库中ip信息或ip对应的网段信息' _job_status = ActionStatus.FAILD __update_config_msg_to_db(task_id, _msg, _job_status) return False, "无法获取数据库中待使用ip信息或ip对应的网段信息" if new_ip_status['status'] != IPStatus.USED: _msg = '网卡配置ip:新ip:%s不是使用中状态' % instance_netcard_datas['ip_addr_new'] _job_status = ActionStatus.FAILD __update_config_msg_to_db(task_id, _msg, _job_status) return False, "新ip:%s不是使用中状态" % instance_netcard_datas['ip_addr_new'] # 需要修改xml配置,同时做ip、网关修改注入 instance_netcard_datas['netmask_new'] = __exchange_maskint( int(new_ip_status['netmask'])) instance_netcard_datas['gateway_new'] = new_ip_status['gateway_ip'] dev_name = new_ip_segment_data['host_bridge_name'] + '.' + str( new_ip_segment_data['vlan']) net_on_status, _msg = _instance_net_on( instance_netcard_datas['instance_name'], instance_netcard_datas['mac_addr'], instance_netcard_datas['host_ip'], dev_name) if not net_on_status: _job_status = ActionStatus.FAILD __update_config_msg_to_db(task_id, _msg, _job_status) _change_db_ip_unused(net_ip_list) return False, _msg ret_status, ret_msg = __change_instance_network( instance_netcard_datas['host_ip'], instance_netcard_datas['instance_name'], instance_netcard_datas) if ret_status: db_ret_status, db_ret_msg = __instance_ip_configure_change_db( instance_netcard_datas['instance_id'], instance_netcard_datas, instance_netcard_datas['env']) if not db_ret_status: _job_status = ActionStatus.FAILD __update_config_msg_to_db(task_id, db_ret_msg, _job_status) _change_db_ip_unused(net_ip_list) return False, db_ret_msg _job_status = ActionStatus.SUCCSESS __update_config_msg_to_db(task_id, db_ret_msg, _job_status) else: _job_status = ActionStatus.FAILD __update_config_msg_to_db(task_id, ret_msg, _job_status) _change_db_ip_unused(net_ip_list) return False, ret_msg return True, "网卡配置成功"
def _task_into_db(task): # 入参赋值 vmname = task['vm_name'] vmip = task['vm_ip'] flavor_id = task['flavor_id'] cloudarea = task['cloud_area'] vm_ostype = task['vm_ostype'] vm_app_info = task['vm_app_info'] vm_owner = task['vm_owner'] vm_group_id = task['group_id'] user_id = task['user_id'] vm_segment = task['segment'] vm_disk = task['vm_disk'] vm_osver = task['vm_osver'] host = task['dest_host'] # 入参完全性判断 if not vmname or not vmip or not flavor_id or not cloudarea or not vm_ostype \ or not vm_app_info or not vm_owner or not vm_group_id or not user_id or not vm_segment: logging.info('params are invalid or missing') message = '入参缺失' return False, message else: # 获取flavor信息 flavor_info = flavor_s.FlavorService().get_flavor_info(flavor_id) if not flavor_info: logging.info('id: %s flavor info not in db when create instance', flavor_id) message = '实例规格数据有误,无法进行v2v' return False, message vmcpu = flavor_info['vcpu'] vmmem = flavor_info['memory_mb'] vmhost = ho_s.HostService().get_host_info_by_hostip(host) ret_4 = ho_s.pre_allocate_host_resource(vmhost['id'], vmcpu, vmmem, 50) if ret_4 != 1: logging.error('资源预分配失败') message = '资源预分频失败' return False, message # 获取并录入IP信息 vm_segment = segment_s.SegmentService().get_segment_info_bysegment( vm_segment) if vm_segment is None: message = '网段信息有误,无法进行v2v' return False, message else: segment_id = vm_segment['id'] vm_netmask = vm_segment['netmask'] vm_gateway = vm_segment['gateway_ip'] vm_dns1 = vm_segment['dns1'] vm_dns2 = vm_segment['dns2'] vmvlan = vm_segment['vlan'] ip_data = ip_s.IPService().get_ip_info_by_ipaddress(vmip) if ip_data is None: ip_data = { 'ip_address': vmip, 'segment_id': segment_id, 'netmask': vm_netmask, 'vlan': vmvlan, 'gateway_ip': vm_gateway, 'dns1': vm_dns1, 'dns2': vm_dns2, 'created_at': get_datetime_str(), 'status': '1' } ret = ip_s.IPService().add_ip_info(ip_data) if ret.get('row_num') <= 0: logging.info( 'add ip info error when create v2v task, insert_data: %s', ip_data) message = "录入IP信息失败" return False, message else: ip_id = ret.get('last_id') else: ip_data_status = ip_data['status'] vmvlan = ip_data['vlan'] if ip_data_status != '0': message = "IP与现有环境冲突,无法进行v2v" return False, message else: ip_id = ip_data['id'] where_data = {'id': ip_id} updata_data = { 'status': '1', 'updated_at': get_datetime_str() } ret1 = ip_s.IPService().update_ip_info( updata_data, where_data) if not ret1: logging.info( 'update ip info error when create v2v task, update_data: %s', updata_data) message = "更新IP状态失败" return False, message # 生成request_id request_id = v2v_op.generate_req_id() # 生成vm的uuid和mac vmuuid = randomUUID() vmmac = randomMAC() # 信息入instance相关库表 instance_tag, instance_info = _instance_db_info( vmuuid, vmname, vm_app_info, vm_owner, flavor_id, vm_group_id, host, vmmac, vm_disk, ip_id, vm_ostype, request_id, vm_osver) if not instance_tag: message = instance_info return False, message # 将步骤信息存入instance_action表 # 将createdir信息存入instance_action表 v2v_cd_d1 = { 'action': v2vActions.CREATE_DEST_DIR, 'request_id': request_id, 'message': 'start', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info(v2v_cd_d1) # 将getfile信息存入instance_action表 v2v_gf_d1 = { 'action': v2vActions.GET_VM_FILE, 'request_id': request_id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info(v2v_gf_d1) # 将copy disk信息存入instance_action表 v2v_cpd_d1 = { 'action': v2vActions.COPY_VM_DISK, 'request_id': request_id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info(v2v_cpd_d1) # 将copy xml信息存入instance_action表 v2v_cpx_d1 = { 'action': v2vActions.COPY_VM_XML, 'request_id': request_id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info(v2v_cpx_d1) # 将创建存储池信息存入instance_action表 v2v_csp_d1 = { 'action': v2vActions.CREATE_STOR_POOL, 'request_id': request_id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info(v2v_csp_d1) # 将vm标准化信息存入instance_action表 v2v_vmd_d1 = { 'action': v2vActions.VM_STANDARDLIZE, 'request_id': request_id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info(v2v_vmd_d1) # 将vm注册信息存入instance_action表 v2v_vmdef_d1 = { 'action': v2vActions.VM_DEFINE, 'request_id': request_id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info(v2v_vmdef_d1) # 将IP注入信息存入instance_action表 v2v_vmipj_d1 = { 'action': v2vActions.IP_INJECT, 'request_id': request_id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info(v2v_vmipj_d1) # 将vm开机信息存入instance_action表 v2v_vmstar_d1 = { 'action': v2vActions.VM_START, 'request_id': request_id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info( v2v_vmstar_d1) message = '信息已添加至任务队列,等待执行' # 将v2v信息存入v2v_task表 v2v_data = { 'request_id': request_id, 'destory': '0', 'start_time': get_datetime_str(), 'status': 0, 'vm_ip': vmip, 'vm_name': vmname, 'vmvlan': vmvlan, 'flavor_id': flavor_id, 'cloud_area': cloudarea, 'vm_ostype': vm_ostype, 'vm_app_info': vm_app_info, 'vm_owner': vm_owner, 'vm_group_id': vm_group_id, 'user_id': user_id, 'vm_mac': vmmac, 'vm_uuid': vmuuid, 'cancel': '0', 'dest_dir': '/app/image/' + vmuuid, 'on_task': '0', 'port': '10000', 'source': VMCreateSource.OPENSTACK } v2v_insert = v2v_op.v2vTaskService().add_v2v_task_info(v2v_data) if v2v_insert.get('row_num') <= 0: logging.info('insert info to v2v_task failed! %s', v2v_data) message = '信息入库失败' return False, message # 将目标kvmhost存入信息表 v2v_op.update_v2v_desthost(request_id, host) v2v_op.update_v2v_step(request_id, v2vActions.BEGIN) return True, message
def ip_apply_from_other_platform(): ''' 外部平台申请ip :return: ''' data_from_vishnu = request.data logging.info(data_from_vishnu) data_requset = json_helper.loads(data_from_vishnu) req_datacenter = data_requset['datacenter'] req_env = data_requset['env'] req_net_area = data_requset['net_area'] req_net_name = data_requset['net_name'] cluster_id = data_requset['cluster_id'] opuser = data_requset['opUser'] sys_code = data_requset['sys_code'] taskid_vs = data_requset['taskid'] ip_count = data_requset['ipCount'] prd_dr_ip_all_needed = data_requset['prdDrAllNeeded'] # '0'代表普通申请,'1'需要同时申请prd、dr环境的ip # 校验入参是否为空 if not req_env or not req_net_area or not req_net_name or not req_datacenter: return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='empty input of env, net area information or net name ' 'when apply ip') if not cluster_id or not opuser or not sys_code or not taskid_vs: return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='empty input of cluster_id, opuser, ' 'task id or sys_code when apply ip') if not str(ip_count) or not str(prd_dr_ip_all_needed): return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='empty input of ipCount or prdDrAllNeeded when apply ip') # 查询指定环境、网络区域是否有所需网段 ret_segment = segment_service.SegmentService().get_segment_info_bysegment(req_net_name.split('/')[0]) if not ret_segment: return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail="无法找到需要申请的网段") ret_net_area_info = net_area.NetAreaService().get_net_area_info(ret_segment['net_area_id']) if not ret_net_area_info: return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail="无法找到指定网段所属网络区域信息") ret_datacenter_info = datacenter_service.DataCenterService().get_datacenter_info(ret_net_area_info['datacenter_id']) if not ret_datacenter_info: return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail="无法找到指定机房信息") if req_env not in DataCenterTypeForVishnu.TYPE_DICT: return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail="无法找到指定机房类型信息") if str(DataCenterTypeForVishnu.TYPE_DICT[req_env]) != ret_datacenter_info['dc_type']: return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail="无法找到指定网络区域对应网段信息") # 如果是申请生产或者容灾环境ip,需判断网段对应关系表中是否有记录 if req_env == 'PRD': segment_dr = segment_m.SegmentMatchService().get_segment_match_info_by_prd_segment_id( ret_segment['id']) if not segment_dr: return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='指定机房、网络区域下无法找到生产网段对应的容灾网段ID') segment_dr_data = segment_s.SegmentService().get_segment_info(segment_dr['dr_segment_id']) if not segment_dr_data: return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='指定机房、网络区域下无法找到生产网段对应的容灾网段详细信息') elif req_env == 'DR': segment_prd = segment_m.SegmentMatchService().get_segment_match_info_by_dr_segment_id( ret_segment['id']) if not segment_prd: return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='指定机房、网络区域下无法找到容灾网段对应的生产网段ID') segment_prd_data = segment_s.SegmentService().get_segment_info(segment_prd['prd_segment_id']) if not segment_prd_data: return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='指定机房、网络区域下无法找到容灾网段对应的生产网段详细信息') # 获取IP资源,先判断是否有人也在分配IP资源,有则等待1s,时间之后再优化 ip_lock_unused = False while not ip_lock_unused: ret_ip_lock_status = ip_l_s.IpLockService().get_ip_lock_info('ip') if not ret_ip_lock_status: logging.error('外部接口分配vip:检查IP时无法获取资源锁状态') return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='检查IP时无法获取资源锁状态') if ret_ip_lock_status['istraceing'] == IpLockStatus.USED: time.sleep(1) else: ip_lock_unused = True # 更新ip_lock表istraceing字段为1 ret_ip_lock_used_status, ret_ip_lock_used_datas = __update_ip_lock_used() if not ret_ip_lock_used_status: logging.error(ret_ip_lock_used_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail=ret_ip_lock_used_datas) try: segments_data_list = [] segments_data_list.append(ret_segment) # 获取可用ip ret_ip_datas, ret_ip_segment_datas = ip_service.get_available_ips(segments_data_list, int(ip_count), str( DataCenterTypeForVishnu.TYPE_DICT[req_env])) if not ret_ip_datas: ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused() if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail=ret_ip_lock_unused_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='指定机房、网络区域下无法找到%s个可用IP' % str(ip_count)) # 标记ip为预分配 logging.info(ret_ip_datas) ips_list = [] prd_ips_list = [] dr_ips_list = [] ip_details = {} for ip in ret_ip_datas: update_data = { 'status': IPStatus.USED } where_data = { 'id': ip['id'] } ret_mark_ip = ip_service.IPService().update_ip_info(update_data, where_data) if ret_mark_ip <= 0: continue # 录入vip信息到数据库中 insert_vip_data = { 'ip_id': ip['id'], 'cluster_id': cluster_id, 'apply_user_id': opuser, 'sys_code': sys_code, 'isdeleted': '0', 'created_at': get_datetime_str() } ret_vip = vip_service.VIPService().add_vip_info(insert_vip_data) if ret_vip.get('row_num') <= 0: continue ip_datas = { 'ip': ip['ip_address'], 'vlanId': ip['vlan'], 'subnetMask': __exchange_maskint(int(ip['netmask'])), 'gateway': ip['gateway_ip'] } ips_list.append(ip_datas) # 生产环境需要预分配对应容灾环境ip,容灾环境需要预分配生产环境ip if req_env == 'PRD': # 拼凑虚拟机容灾ip并预分配ip dr_ip = segment_dr_data['segment'].split('.')[0] + '.' + segment_dr_data['segment'].split('.')[1] + \ '.' + ip['ip_address'].split('.')[2] + '.' + ip['ip_address'].split('.')[3] dr_ip_info = ip_service.IPService().get_ip_by_ip_address(dr_ip) # 如果容灾环境ip未初始化,默认初始化 if not dr_ip_info: if not __init_ip(segment_dr_data, dr_ip): continue dr_ip_info = ip_service.IPService().get_ip_by_ip_address(dr_ip) if prd_dr_ip_all_needed == '1': update_data = { 'status': IPStatus.USED } where_data = { 'id': dr_ip_info['id'] } ret_mark_ip = ip_service.IPService().update_ip_info(update_data, where_data) if ret_mark_ip <= 0: continue # 录入vip信息到数据库中 insert_vip_data = { 'ip_id': dr_ip_info['id'], 'cluster_id': cluster_id, 'apply_user_id': opuser, 'sys_code': sys_code, 'isdeleted': '0', 'created_at': get_datetime_str() } ret_vip = vip_service.VIPService().add_vip_info(insert_vip_data) if ret_vip.get('row_num') <= 0: continue else: update_data = { 'status': IPStatus.PRE_ALLOCATION } where_data = { 'ip_address': dr_ip } ret_mark_ip = ip_service.IPService().update_ip_info(update_data, where_data) if ret_mark_ip <= 0: continue # 拼装容灾ip信息 dr_ip_datas = { 'ip': dr_ip_info['ip_address'], 'vlanId': dr_ip_info['vlan'], 'subnetMask': __exchange_maskint(int(dr_ip_info['netmask'])), 'gateway': dr_ip_info['gateway_ip'] } dr_ips_list.append(dr_ip_datas) elif req_env == 'DR': # 拼凑虚拟机生产ip并预分配ip prd_ip = segment_prd_data['segment'].split('.')[0] + '.' + segment_prd_data['segment'].split('.')[1] + \ '.' + ip['ip_address'].split('.')[2] + '.' + ip['ip_address'].split('.')[3] prd_ip_info = ip_service.IPService().get_ip_by_ip_address(prd_ip) # 如果生产环境ip未初始化,默认初始化 if not prd_ip_info: if not __init_ip(segment_prd_data, prd_ip): continue prd_ip_info = ip_service.IPService().get_ip_by_ip_address(prd_ip) if prd_dr_ip_all_needed == '1': update_data = { 'status': IPStatus.USED } where_data = { 'id': prd_ip_info['id'] } ret_mark_ip = ip_service.IPService().update_ip_info(update_data, where_data) if ret_mark_ip <= 0: continue # 录入vip信息到数据库中 insert_vip_data = { 'ip_id': prd_ip_info['id'], 'cluster_id': cluster_id, 'apply_user_id': opuser, 'sys_code': sys_code, 'isdeleted': '0', 'created_at': get_datetime_str() } ret_vip = vip_service.VIPService().add_vip_info(insert_vip_data) if ret_vip.get('row_num') <= 0: continue else: update_data = { 'status': IPStatus.PRE_ALLOCATION } where_data = { 'ip_address': prd_ip } ret_mark_ip = ip_service.IPService().update_ip_info(update_data, where_data) if ret_mark_ip <= 0: continue # 拼装生产ip信息 prd_ip_datas = { 'ip': prd_ip_info['ip_address'], 'vlanId': prd_ip_info['vlan'], 'subnetMask': __exchange_maskint(int(prd_ip_info['netmask'])), 'gateway': prd_ip_info['gateway_ip'] } prd_ips_list.append(prd_ip_datas) except Exception as e: _msg = '外部平台申请IP:预分配ip出现异常: distribution ip exception,err:%s'%e logging.error(_msg) ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused() if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=_msg) # 更新ip_lock表istraceing字段为0 ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused() if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail=ret_ip_lock_unused_datas) if len(ips_list) <= 0: return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='指定机房、网络区域下%s个可用IP修改为预分配状态全部失败' % str(ip_count)) elif req_env == 'PRD' and (len(ips_list) + len(dr_ips_list)) < int(ip_count) * 2: return json_helper.format_api_resp_msg(code=ErrorCode.SUCCESS_PART, job_status=VsJobStatus.FAILED, detail='生产环境指定机房、网络区域下%s个可用IP修改为预分配状态部分失败' % str(ip_count)) elif req_env == 'DR' and (len(ips_list) + len(prd_ips_list)) < int(ip_count) * 2: return json_helper.format_api_resp_msg(code=ErrorCode.SUCCESS_PART, job_status=VsJobStatus.FAILED, detail='容灾环境指定机房、网络区域下%s个可用IP修改为预分配状态部分失败' % str(ip_count)) elif len(ips_list) < int(ip_count): return json_helper.format_api_resp_msg(code=ErrorCode.SUCCESS_PART, job_status=VsJobStatus.FAILED, detail='指定机房、网络区域下%s个可用IP修改为预分配状态部分失败' % str(ip_count)) else: if req_env == 'PRD': ip_details['prd'] = ips_list ip_details['dr'] = dr_ips_list elif req_env == 'DR': ip_details['dr'] = ips_list ip_details['prd'] = prd_ips_list else: ip_details['default'] = ips_list return json_helper.format_api_resp_msg(code=ErrorCode.SUCCESS, job_status=VsJobStatus.SUCCEED, detail=ip_details)
def _task_esx_intodb(task): # 获取vm入参 vmname = task['vm_name'] vmip = task['vm_ip'] flavor_id = task['flavor_id'] vm_ostype = task['vm_ostype'] vm_app_info = task['vm_app_info'] vm_owner = task['vm_owner'] vm_segment = task['vm_segment'] vm_group_id = task['group_id'] dest_host = task['dest_host'] vmhost = ho_s.HostService().get_host_info_by_hostip(dest_host) ret_4 = ho_s.pre_allocate_host_resource(vmhost['id'], task['vm_cpu'], task['vm_mem_mb'], 50) if ret_4 != 1: logging.error('资源预分配失败') message = '资源预分配失败' return False, message # 获取并录入IP信息 vm_segment = seg_s.SegmentService().get_segment_info_bysegment(vm_segment) if vm_segment is None: message = '网段信息有误,无法进行v2v操作' return False, message else: segment_id = vm_segment['id'] vm_netmask = vm_segment['netmask'] vm_gateway = vm_segment['gateway_ip'] vm_dns1 = vm_segment['dns1'] vm_dns2 = vm_segment['dns2'] vmvlan = vm_segment['vlan'] ip_data = ip_s.IPService().get_ip_info_by_ipaddress(vmip) if ip_data is None: ip_data = { 'ip_address': vmip, 'segment_id': segment_id, 'netmask': vm_netmask, 'vlan': vmvlan, 'gateway_ip': vm_gateway, 'dns1': vm_dns1, 'dns2': vm_dns2, 'created_at': get_datetime_str(), 'status': '1' } ret = ip_s.IPService().add_ip_info(ip_data) if ret.get('row_num') <= 0: logging.info( 'add ip info error when create v2v task, insert_data: %s', ip_data) message = "录入IP信息失败" return False, message else: ip_id = ret.get('last_id') else: ip_data_status = ip_data['status'] vmvlan = ip_data['vlan'] if ip_data_status != '0': message = "IP与现有环境冲突,无法进行v2v操作" return False, message else: ip_id = ip_data['id'] where_data = {'id': ip_id} updata_data = {'status': '1', 'updated_at': get_datetime_str()} ret1 = ip_s.IPService().update_ip_info(updata_data, where_data) if not ret1: logging.info( 'update ip info error when create v2v task, update_data: %s', updata_data) message = "更新IP状态失败" return False, message # 生成request_id request_id = v2v_op.generate_req_id() # 生成vm的uuid和mac vmuuid = randomUUID() vmmac = randomMAC() # 信息入instance相关库表 instance_tag, instance_info = _instance_db_info( vmuuid, vmname, vm_app_info, vm_owner, flavor_id, vm_group_id, dest_host, vmmac, task['vm_disk'], ip_id, vm_ostype, request_id, task['vm_os_version']) if not instance_tag: message = instance_info return False, message # 将步骤信息存入instance_action表 v2v_cd_d1 = { 'action': esx_v2vActions.CREATE_DEST_DIR, 'request_id': request_id, 'message': 'start', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info(v2v_cd_d1) v2v_cr_pl = { 'action': esx_v2vActions.CREATE_STOR_POOL, 'request_id': request_id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info(v2v_cr_pl) v2v_cp_fl = { 'action': esx_v2vActions.COPY_FILE_TO_LOCAL, 'request_id': request_id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info(v2v_cp_fl) v2v_file = { 'action': esx_v2vActions.VIRT_V2V_FILES, 'request_id': request_id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info(v2v_file) v2v_del_tmp = { 'action': esx_v2vActions.DELETE_TMP_FILE, 'request_id': request_id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info(v2v_del_tmp) v2v_sysdisk_std = { 'action': esx_v2vActions.VM_SYS_DISK_STD, 'request_id': request_id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info( v2v_sysdisk_std) v2v_datadisk_std = { 'action': esx_v2vActions.VM_DATA_DISK_STD, 'request_id': request_id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info( v2v_datadisk_std) v2v_def_1 = { 'action': esx_v2vActions.VM_DEFINE1, 'request_id': request_id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info(v2v_def_1) v2v_star_1 = { 'action': esx_v2vActions.VM_START1, 'request_id': request_id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info(v2v_star_1) if vm_ostype == "Windows": v2v_att_disk = { 'action': esx_v2vActions.ATTACH_DISK, 'request_id': request_id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info( v2v_att_disk) v2v_win_std = { 'action': esx_v2vActions.WINDOWS_STD, 'request_id': request_id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info( v2v_win_std) v2v_vm_def2 = { 'action': esx_v2vActions.WINDOWS_DISK_CH, 'request_id': request_id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info( v2v_vm_def2) v2v_vm_star2 = { 'action': esx_v2vActions.VM_START2, 'request_id': request_id, 'message': 'other', 'start_time': get_datetime_str() } in_a_s.InstanceActionsServices().add_instance_action_info( v2v_vm_star2) # 将v2v信息存入v2v_task表 v2v_data = { 'source': VMCreateSource.ESX, 'request_id': request_id, 'destory': '0', 'start_time': get_datetime_str(), 'status': 0, 'vm_ip': vmip, 'vm_name': vmname, 'vmvlan': vmvlan, 'flavor_id': flavor_id, 'cloud_area': task['esx_env'], 'vm_ostype': vm_ostype, 'vm_app_info': vm_app_info, 'vm_owner': vm_owner, 'vm_group_id': vm_group_id, 'user_id': task['user_id'], 'vm_mac': vmmac, 'vm_uuid': vmuuid, 'cancel': '0', 'dest_dir': '/app/image/' + vmuuid, 'on_task': '0', 'dest_host': dest_host, 'esx_ip': task['esx_ip'], 'esx_passwd': task['esx_passwd'], 'vmware_vm': task['vmware_vm'], 'step_done': esx_v2vActions.BEGIN } v2v_insert = v2v_op.v2vTaskService().add_v2v_task_info(v2v_data) if v2v_insert.get('row_num') <= 0: logging.info('insert info to v2v_task failed! %s', v2v_data) message = '信息入库失败' return False, message message = '信息已添加至任务队列' return True, message
def ips_apply_from_other_platform(): ''' 外部平台申请KVM IP, IP会置为预分配 :return: ''' data_from_api = request.data logging.info(data_from_api) data_requset = json_helper.loads(data_from_api) req_datacenter = data_requset['dataCenter'] req_env = data_requset['env'] req_net_area = data_requset['netArea'] count = data_requset['ipNums'] netcare_type = data_requset.get('netCardType', NetCardType.INTERNAL) # 校验入参是否为空 if not req_net_area or not req_datacenter or not req_env or not count: return json_helper.format_api_resp_msg(code=ErrorCode.PARAM_ERR, job_status=VsJobStatus.FAILED, detail='机房、环境、网络区域或ip数量入参为空') # 查询指定环境、网络区域是否有所需网段,容灾微应用需要遍历联通、电信所有可用网段 if DataCenterTypeForVishnu.TYPE_DICT[req_env] == DataCenterType.MINIARCHDR: ret_segment_datas_telecom = segment_s.get_segments_data_by_type(req_net_area, req_datacenter, str(DataCenterTypeForVishnu.TYPE_DICT[req_env]), NetCardType.INTERNEL_TELECOM) ret_segment_datas_unicom = segment_s.get_segments_data_by_type(req_net_area, req_datacenter, str(DataCenterTypeForVishnu.TYPE_DICT[req_env]), NetCardType.INTERNEL_UNICOM) ret_segment_datas = ret_segment_datas_telecom + ret_segment_datas_unicom else: ret_segment_datas = segment_s.get_segments_data_by_type(req_net_area, req_datacenter, str(DataCenterTypeForVishnu.TYPE_DICT[req_env]), netcare_type) if not ret_segment_datas: return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='指定机房、网络区域下没有可用网段用于分配IP') # 获取IP资源,先判断是否有人也在分配IP资源,有则等待1s,时间之后再优化 ip_lock_unused = False while not ip_lock_unused: ret_ip_lock_status = ip_l_s.IpLockService().get_ip_lock_info('ip') if not ret_ip_lock_status: logging.error('外部接口分配vip:检查IP时无法获取资源锁状态') return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='检查IP时无法获取资源锁状态') if ret_ip_lock_status['istraceing'] == IpLockStatus.USED: time.sleep(1) else: ip_lock_unused = True # 更新ip_lock表istraceing字段为1 ret_ip_lock_used_status, ret_ip_lock_used_datas = __update_ip_lock_used() if not ret_ip_lock_used_status: logging.error(ret_ip_lock_used_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail=ret_ip_lock_used_datas) try: # 获取可用ip ret_ip_datas, ret_ip_segment_datas = ip_service.get_available_ips(ret_segment_datas, int(count), str(DataCenterTypeForVishnu.TYPE_DICT[req_env])) if not ret_ip_datas: ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused() if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail=ret_ip_lock_unused_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='指定机房、网络区域下无法找到%s个可用IP' % str(count)) # 如果是申请生产或者容灾环境ip,需判断网段对应关系表中是否有记录 if req_env == 'PRD': segment_dr = segment_m.SegmentMatchService().get_segment_match_info_by_prd_segment_id(ret_ip_segment_datas['id']) if not segment_dr: ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused() if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail=ret_ip_lock_unused_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='指定机房、网络区域下无法找到生产网段对应的容灾网段ID') segment_dr_data = segment_s.SegmentService().get_segment_info(segment_dr['dr_segment_id']) if not segment_dr_data: ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused() if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail=ret_ip_lock_unused_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='指定机房、网络区域下无法找到生产网段对应的容灾网段详细信息') elif req_env == 'DR': segment_prd = segment_m.SegmentMatchService().get_segment_match_info_by_dr_segment_id(ret_ip_segment_datas['id']) if not segment_prd: ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused() if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail=ret_ip_lock_unused_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='指定机房、网络区域下无法找到容灾网段对应的生产网段ID') segment_prd_data = segment_s.SegmentService().get_segment_info(segment_prd['prd_segment_id']) if not segment_prd_data: ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused() if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail=ret_ip_lock_unused_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='指定机房、网络区域下无法找到容灾网段对应的生产网段详细信息') # 标记ip为预分配 logging.info(ret_ip_datas) ips_list = [] prd_ips_list = [] dr_ips_list = [] ip_details = {} for ip in ret_ip_datas: update_data = { 'status': IPStatus.PRE_ALLOCATION, 'updated_at': get_datetime_str() } where_data = { 'id': ip['id'] } ret_mark_ip = ip_service.IPService().update_ip_info(update_data, where_data) if ret_mark_ip <= 0: continue ip_datas = { 'ip': ip['ip_address'], 'vlanId': ip['vlan'], 'subnetMask': __exchange_maskint(int(ip['netmask'])), 'gateway': ip['gateway_ip'], 'ip_type': ret_ip_segment_datas['segment_type'] } ips_list.append(ip_datas) # 生产环境需要预分配对应容灾环境ip,容灾环境需要预分配生产环境ip if req_env == 'PRD': # 拼凑虚拟机容灾ip并预分配ip dr_ip = segment_dr_data['segment'].split('.')[0] + '.' + segment_dr_data['segment'].split('.')[1] + \ '.' + ip['ip_address'].split('.')[2] + '.' + ip['ip_address'].split('.')[3] dr_ip_info = ip_service.IPService().get_ip_by_ip_address(dr_ip) # 如果容灾环境ip未初始化,默认初始化 if not dr_ip_info: if not __init_ip(segment_dr_data, dr_ip): continue dr_ip_info = ip_service.IPService().get_ip_by_ip_address(dr_ip) update_data = { 'status': IPStatus.PRE_ALLOCATION } where_data = { 'ip_address': dr_ip } ret_mark_ip = ip_service.IPService().update_ip_info(update_data, where_data) if ret_mark_ip <= 0: continue # 拼装容灾ip信息 dr_ip_datas = { 'ip': dr_ip_info['ip_address'], 'vlanId': dr_ip_info['vlan'], 'subnetMask': __exchange_maskint(int(dr_ip_info['netmask'])), 'gateway': dr_ip_info['gateway_ip'] } dr_ips_list.append(dr_ip_datas) elif req_env == 'DR': # 拼凑虚拟机生产ip并预分配ip prd_ip = segment_prd_data['segment'].split('.')[0] + '.' + segment_prd_data['segment'].split('.')[1] + \ '.' + ip['ip_address'].split('.')[2] + '.' + ip['ip_address'].split('.')[3] prd_ip_info = ip_service.IPService().get_ip_by_ip_address(prd_ip) # 如果生产环境ip未初始化,默认初始化 if not prd_ip_info: if not __init_ip(segment_prd_data, prd_ip): continue prd_ip_info = ip_service.IPService().get_ip_by_ip_address(prd_ip) update_data = { 'status': IPStatus.PRE_ALLOCATION } where_data = { 'ip_address': prd_ip } ret_mark_ip = ip_service.IPService().update_ip_info(update_data, where_data) if ret_mark_ip <= 0: continue # 拼装生产ip信息 prd_ip_datas = { 'ip': prd_ip_info['ip_address'], 'vlanId': prd_ip_info['vlan'], 'subnetMask': __exchange_maskint(int(prd_ip_info['netmask'])), 'gateway': prd_ip_info['gateway_ip'] } prd_ips_list.append(prd_ip_datas) except Exception as e: _msg = '外部接口预分配IP:预分配ip出现异常: distribution ip exception,err:%s' %e logging.error(_msg) ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused() if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=_msg) # 更新ip_lock表istraceing字段为0 ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused() if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail=ret_ip_lock_unused_datas) if len(ips_list) <= 0: return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='指定机房、网络区域下%s个可用IP修改为预分配状态全部失败' % str(count)) elif req_env == 'PRD' and (len(ips_list) + len(dr_ips_list)) < int(count)*2: return json_helper.format_api_resp_msg(code=ErrorCode.SUCCESS_PART, job_status=VsJobStatus.FAILED, detail='生产环境指定机房、网络区域下%s个可用IP修改为预分配状态部分失败' % str(count)) elif req_env == 'DR' and (len(ips_list) + len(prd_ips_list)) < int(count)*2: return json_helper.format_api_resp_msg(code=ErrorCode.SUCCESS_PART, job_status=VsJobStatus.FAILED, detail='容灾环境指定机房、网络区域下%s个可用IP修改为预分配状态部分失败' % str(count)) elif len(ips_list) < int(count): return json_helper.format_api_resp_msg(code=ErrorCode.SUCCESS_PART, job_status=VsJobStatus.FAILED, detail='指定机房、网络区域下%s个可用IP修改为预分配状态部分失败' % str(count)) else: if req_env == 'PRD': ip_details['prd'] = ips_list ip_details['dr'] = dr_ips_list elif req_env == 'DR': ip_details['dr'] = ips_list ip_details['prd'] = prd_ips_list else: ip_details['default'] = ips_list logging.info(ip_details) return json_helper.format_api_resp_msg(code=ErrorCode.SUCCESS, job_status=VsJobStatus.SUCCEED, detail=ip_details)
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 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)