def instance_performance_data_to_other_platform(): '''获取web服务器的性能数据''' msg = '' command = "supervisorctl status | awk -F ' ' '{print $2}'" supervisorctl_data = os.popen(command).read() supervisorctl_list = supervisorctl_data.split('\n')[:-1] for i in supervisorctl_list: if i.strip() != "RUNNING": msg += 'web服务器性能数据存在非running状态; ' table_vishi = ip_lock_service.IpLockService().get_ip_lock_info( "performance_data") if table_vishi: update_data = {"istraceing": "0"} where_data = {"table_name": "performance_data"} ip_lock_service.IpLockService().update_ip_lock_info( update_data, where_data) else: insert_data = {"table_name": "performance_data", "istraceing": "0"} ip_lock_service.IpLockService().add_ip_lock_db(insert_data) ret_ip_lock = ip_lock_service.IpLockService().get_ip_lock_info( "performance_data") if ret_ip_lock["istraceing"] != "0": msg += 'web服务器性能数据设置检测初始化数据失败; ' data = { "routing_key": "INSTANCE.PERFORMANCE", "send_time": get_datetime_str(), "data": { "table_name": "performance_data" } } send_async_msg(KAFKA_TOPIC_NAME, data) nums = 0 status = False while nums < 10: table_vishi = ip_lock_service.IpLockService().get_ip_lock_info( "performance_data") if str(table_vishi["istraceing"]) == '1': status = True break else: nums += 1 time.sleep(1) if not status: msg += 'kafka消费任务异常,超时10秒; ' if msg: return json_helper.format_api_resp_msg_to_vishnu_resource( job_status=VsJobStatus.FAILED, detail=msg) return json_helper.format_api_resp_msg_to_vishnu_resource( job_status=VsJobStatus.SUCCEED, detail='web服务器正常,kafka消费正常')
def instance_performance(msg): '''虚拟机创建的性能检测接口''' msg = json_helper.read(msg) data = msg.get('data') table_name = data.get("table_name") if table_name != "performance_data": return 0 update_data = {"istraceing": "1"} where_data = {"table_name": "performance_data"} ip_lock_service.IpLockService().update_ip_lock_info( update_data, where_data) return 0
def __update_table_lock_used(): ''' 更新ip_lock表istraceing字段为1 :return: ''' update_ip_lock_data = {'istraceing': IpLockStatus.USED} where_ip_lock_data = {'table_name': 'request_record'} ret_update_ip_lock = ip_l_s.IpLockService().update_ip_lock_info( update_ip_lock_data, where_ip_lock_data) if not ret_update_ip_lock: return False, '工单追踪:无法更新数据库表request_record资源锁状态为使用中' return True, '工单追踪:更新数据库表request_record资源锁状态为使用中成功'
def __update_ip_lock_unused(): ''' 更新ip_lock表istraceing字段为0 :return: ''' update_ip_lock_data = {'istraceing': IpLockStatus.UNUSED} where_ip_lock_data = {'table_name': 'ip'} ret_update_ip_lock = ip_l_s.IpLockService().update_ip_lock_info( update_ip_lock_data, where_ip_lock_data) if not ret_update_ip_lock: return False, '外部接口新增网卡分配ip:无法更新资源锁状态为未使用中' return True, '外部接口新增网卡分配ip:更新资源锁状态为未使用中成功'
def __update_ip_lock_used(): ''' 更新ip_lock表istraceing字段为1 :return: ''' update_ip_lock_data = {'istraceing': IpLockStatus.USED} where_ip_lock_data = {'table_name': 'ip'} ret_update_ip_lock = ip_l_s.IpLockService().update_ip_lock_info( update_ip_lock_data, where_ip_lock_data) if not ret_update_ip_lock: return False, '创建VM 步骤10:检查IP时无法更新资源锁状态为使用中' return True, '创建VM 步骤10:检查IP时更新资源锁状态为使用中成功'
ret_update_ip_lock = ip_l_s.IpLockService().update_ip_lock_info( update_ip_lock_data, where_ip_lock_data) if not ret_update_ip_lock: return False, '工单追踪:无法更新数据库表request_record资源锁状态为使用中' return True, '工单追踪:更新数据库表request_record资源锁状态为使用中成功' if __name__ == '__main__': _init_log('trace_and_update_request_status') while True: threads = [] # 获取工单信息,先判断是否有人也在操作工单表格,有则等待1s,时间之后再优化 request_lock_unused = False while not request_lock_unused: ret_request_lock_status = ip_l_s.IpLockService().get_ip_lock_info( 'request_record') if not ret_request_lock_status: logging.error('工单追踪:无法获取资源锁状态') time.sleep(2) continue if ret_request_lock_status['istraceing'] == IpLockStatus.USED: time.sleep(1) else: request_lock_unused = True # 更新ip_lock表istraceing字段为1 ret_request_lock_used_status, ret_request_lock_used_datas = __update_table_lock_used( ) if not ret_request_lock_used_status: logging.error(ret_request_lock_used_datas)
def cancel_init_ips(): ''' 批量取消初始化IP :return: ''' begin_ip = request.values.get('begin_ip') end_ip = request.values.get('end_ip') if not begin_ip or not end_ip: logging.info('begin or end ip is empty when cancel init ips') return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR) # 获取IP资源,先判断是否有人也在分配IP资源,有则等待1s,时间之后再优化 ip_lock_unused = False while not ip_lock_unused: ret_ip_lock_status = ip_l_s.IpLockService().get_ip_lock_info('ip') if not ret_ip_lock_status: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='批量去初始化IP时无法获取资源锁状态,请稍后再试') if ret_ip_lock_status['istraceing'] == IpLockStatus.USED: time.sleep(1) else: ip_lock_unused = True # 更新ip_lock表istraceing字段为1 ret_ip_lock_used_status, ret_ip_lock_used_datas = __update_ip_lock_used() if not ret_ip_lock_used_status: logging.error(ret_ip_lock_used_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_ip_lock_used_datas) try: # 截取IP地址最后一位 begin_ip_org = begin_ip.split('.')[3] end_ip_org = end_ip.split('.')[3] # 起始IP不能大于结束IP if int(begin_ip_org) > int(end_ip_org) or int(begin_ip_org) > 254 or int(begin_ip_org) < 1 \ or int(end_ip_org) > 254 or int(end_ip_org) < 1: logging.info('begin or end ip is invalid when cancel init ips') ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused( ) if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp( code=ErrorCode.SYS_ERR, msg=ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR) ips_cancel_list = [] for i in range(int(begin_ip_org), int(end_ip_org) + 1): ips_cancel_list.append(i) if not ips_cancel_list: logging.info( 'no ip can cancel init when cancel init ips, begin: %s, end: %s', begin_ip, end_ip) ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused( ) if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp( code=ErrorCode.SYS_ERR, msg=ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) # 截取IP地址前三位 ip_c = begin_ip.split('.')[0] + '.' + begin_ip.split( '.')[1] + '.' + begin_ip.split('.')[2] + '.' # 操作的IP数 all_num = len(ips_cancel_list) fail_num = 0 for _cancel_ip in ips_cancel_list: cancel_ip_address = str(ip_c) + str(_cancel_ip) # 要确保该IP未使用 ip_info = ip_service.IPService().get_ip_info_by_ipaddress( cancel_ip_address) if not (ip_info and ip_info['status'] == IPStatus.UNUSED): logging.info('only unused ip can do when cancel init ip') fail_num += 1 continue ret = ip_service.del_ip_info(ip_info['id']) if ret == -1: logging.info('del ip info error when cancel init ip') fail_num += 1 continue except Exception as e: _msg = '批量取消初始化IP:取消初始化ip出现异常begin_ip %s,end_ip%s: cancel ips init exception,err:%s' % ( begin_ip, end_ip, e) logging.error(_msg) ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused( ) if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=_msg) # 更新ip_lock表istraceing字段为0 ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused( ) if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_ip_lock_unused_datas) # 全失败 if fail_num == all_num: logging.error("cancel init ips all failed") return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) # 部分成功 if 0 < fail_num < all_num: logging.error("cancel init ips part failed") return json_helper.format_api_resp(code=ErrorCode.SUCCESS_PART, msg="部分IP取消初始化成功") return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
def cancel_init_ip(): ''' 取消初始化IP :return: ''' ip_address = request.values.get('ip_address') if not ip_address: logging.info('no ip_address when cancel init ip') return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR) # 获取IP资源,先判断是否有人也在分配IP资源,有则等待1s,时间之后再优化 ip_lock_unused = False while not ip_lock_unused: ret_ip_lock_status = ip_l_s.IpLockService().get_ip_lock_info('ip') if not ret_ip_lock_status: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='去初始化IP时无法获取资源锁状态,请稍后再试') if ret_ip_lock_status['istraceing'] == IpLockStatus.USED: time.sleep(1) else: ip_lock_unused = True # 更新ip_lock表istraceing字段为1 ret_ip_lock_used_status, ret_ip_lock_used_datas = __update_ip_lock_used() if not ret_ip_lock_used_status: logging.error(ret_ip_lock_used_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_ip_lock_used_datas) # 要确保该IP未使用 try: ip_info = ip_service.IPService().get_ip_info_by_ipaddress(ip_address) if not (ip_info and ip_info['status'] == IPStatus.UNUSED): logging.info('only unused ip can do when cancel init ip') ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused( ) if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp( code=ErrorCode.SYS_ERR, msg=ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg="只有未使用的IP才能取消初始化") ret = ip_service.del_ip_info(ip_info['id']) except Exception as e: _msg = '取消初始化IP:取消初始化ip出现异常ip%s: cancel ip init exception,err:%s' % ( ip_address, e) logging.error(_msg) ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused( ) if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=_msg) # 更新ip_lock表istraceing字段为0 ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused( ) if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_ip_lock_unused_datas) if ret == -1: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
def init_ip(segment_id): ''' 初始化IP :param segment_id: :return: ''' ip_address = request.values.get('ip_address') if not ip_address or not segment_id: logging.info('no ip_address or segment_id when init ip') return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR) # 获取IP资源,先判断是否有人也在分配IP资源,有则等待1s,时间之后再优化 ip_lock_unused = False while not ip_lock_unused: ret_ip_lock_status = ip_l_s.IpLockService().get_ip_lock_info('ip') if not ret_ip_lock_status: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='初始化IP时无法获取资源锁状态,请稍后再试') if ret_ip_lock_status['istraceing'] == IpLockStatus.USED: time.sleep(1) else: ip_lock_unused = True # 更新ip_lock表istraceing字段为1 ret_ip_lock_used_status, ret_ip_lock_used_datas = __update_ip_lock_used() if not ret_ip_lock_used_status: logging.error(ret_ip_lock_used_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_ip_lock_used_datas) # 要确保该IP没有被初始化 try: ip_info = ip_service.IPService().get_ip_by_ip_address(ip_address) if ip_info: logging.info('the IP has inited in db when init ip') ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused( ) if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp( code=ErrorCode.SYS_ERR, msg=ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg="该IP已经初始化") ip_info_from_segment = segment_service.ip_info_in_segment(segment_id) if not ip_info_from_segment: logging.info('no segment: %s in db when init ip', segment_id) ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused( ) if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp( code=ErrorCode.SYS_ERR, msg=ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) ip_vlan = ip_info_from_segment['vlan'] ip_netmask = ip_info_from_segment['netmask'] ip_segment_id = ip_info_from_segment['id'] ip_gateway_ip = ip_info_from_segment['gateway_ip'] ip_dns1 = ip_info_from_segment['dns1'] ip_dns2 = ip_info_from_segment['dns2'] insert_data = { 'ip_address': ip_address, 'segment_id': ip_segment_id, 'netmask': ip_netmask, 'vlan': ip_vlan, 'gateway_ip': ip_gateway_ip, 'dns1': ip_dns1, 'dns2': ip_dns2, 'status': IPStatus.UNUSED, 'created_at': get_datetime_str() } ret = ip_service.IPService().add_ip_info(insert_data) except Exception as e: _msg = '初始化IP:ip初始化时出现异常 网段%s IP%s:ip init exception when ip init,err:%s' % ( segment_id, ip_address, e) logging.error(_msg) ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused( ) if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=_msg) # 更新ip_lock表istraceing字段为0 ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused( ) if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_ip_lock_unused_datas) if ret == -1: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
def init_ips(segment_id): ''' 批量初始化IP :param segment_id: :return: ''' begin_ip = request.values.get('begin_ip') end_ip = request.values.get('end_ip') if not begin_ip or not end_ip: logging.info('begin or end ip is empty when init ips') return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR) # 获取IP资源,先判断是否有人也在分配IP资源,有则等待1s,时间之后再优化 ip_lock_unused = False while not ip_lock_unused: ret_ip_lock_status = ip_l_s.IpLockService().get_ip_lock_info('ip') if not ret_ip_lock_status: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='批量初始化IP时无法获取资源锁状态,请稍后再试') if ret_ip_lock_status['istraceing'] == IpLockStatus.USED: time.sleep(1) else: ip_lock_unused = True # 更新ip_lock表istraceing字段为1 ret_ip_lock_used_status, ret_ip_lock_used_datas = __update_ip_lock_used() if not ret_ip_lock_used_status: logging.error(ret_ip_lock_used_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_ip_lock_used_datas) try: # 截取IP地址最后一位 begin_ip_org = begin_ip.split('.')[3] end_ip_org = end_ip.split('.')[3] # 起始IP不能大于结束IP if int(begin_ip_org) > int(end_ip_org) or int(begin_ip_org) > 254 or int(begin_ip_org) < 1 \ or int(end_ip_org) > 254 or int(end_ip_org) < 1: logging.info('begin or end ip is invalid when init ips') ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused( ) if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp( code=ErrorCode.SYS_ERR, msg=ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR) inited_ips_list = [] ips_init_list = [] # 查询该网段下已初始化的IP数量 ips_inited_db = ip_service.ip_inited_in_segment(segment_id) ip_info_db = segment_service.ip_info_in_segment(segment_id) if not ip_info_db: logging.info('segment info is invalid in db when init ips') ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused( ) if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp( code=ErrorCode.SYS_ERR, msg=ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) ip_vlan = ip_info_db['vlan'] ip_netmask = ip_info_db['netmask'] ip_segment_id = ip_info_db['id'] ip_gateway_ip = ip_info_db['gateway_ip'] ip_dns1 = ip_info_db['dns1'] ip_dns2 = ip_info_db['dns2'] for i in range(len(ips_inited_db)): inited_ips_list.append(str(ips_inited_db[i]['ip_address'])) # 截取IP地址前三位 ip_c = begin_ip.split('.')[0] + '.' + begin_ip.split( '.')[1] + '.' + begin_ip.split('.')[2] + '.' for i in range(int(begin_ip_org), int(end_ip_org) + 1): ip_for_insert_to_sql = str(ip_c) + str(i) if ip_for_insert_to_sql in inited_ips_list: continue else: ips_init_list.append(i) if not ips_init_list: logging.info('no ip can init when init ips') ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused( ) if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp( code=ErrorCode.SYS_ERR, msg=ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) # 操作的IP数 all_num = len(ips_init_list) fail_num = 0 for _ip_init in ips_init_list: ip_init_address = str(ip_c) + str(_ip_init) insert_data = { 'ip_address': ip_init_address, 'segment_id': ip_segment_id, 'netmask': ip_netmask, 'vlan': ip_vlan, 'gateway_ip': ip_gateway_ip, 'dns1': ip_dns1, 'dns2': ip_dns2, 'status': IPStatus.UNUSED, 'created_at': get_datetime_str() } ret = ip_service.IPService().add_ip_info(insert_data) if ret <= 0: logging.error("init ips error, insert_data: %s", str(insert_data)) fail_num += 1 continue except Exception as e: _msg = '批量初始化IP:初始化ip出现异常begin_ip %s,end_ip%s: batch ip init exception when ips init,err:%s' % ( begin_ip, end_ip, e) logging.error(_msg) ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused( ) if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=_msg) # 更新ip_lock表istraceing字段为0 ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused( ) if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_ip_lock_unused_datas) # 全失败 if fail_num == all_num: logging.error("init ips all failed") return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) # 部分成功 if 0 < fail_num < all_num: logging.error("init ips part failed") return json_helper.format_api_resp(code=ErrorCode.SUCCESS_PART, msg="部分IP初始化成功") return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
def image_update_by_exist(): eimage_name = request.values.get('eimage_name') displayname = request.values.get('displayname') version = request.values.get('version') template_ostype = request.values.get('os_type') tag = randomUUID() if not eimage_name or not displayname or not version or not template_ostype: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='入参缺失') # 判断当前image表是否有该镜像信息 image_nums, image_data = image_service.ImageService().get_images_by_name( eimage_name) if not image_data: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='image表不存在此镜像') # 判断当前image_manage表是否有同名镜像 eimage_data = image_service.ImageManageService( ).get_image_manage_info_by_name(eimage_name) if eimage_data: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='image_manage表已存在同名镜像') # 获取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('创建新镜像 %s 失败:检查IP时无法获取资源锁状态') % eimage_name return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='检查IP时无法获取资源锁状态') if ret_ip_lock_status['istraceing'] == IpLockStatus.USED: time.sleep(1) else: ip_lock_unused = True # 更新ip_lock表istraceing字段为1 ret_ip_lock_used_status, ret_ip_lock_used_datas = __update_ip_lock_used() if not ret_ip_lock_used_status: logging.error(ret_ip_lock_used_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_ip_lock_used_datas) try: ret_ips_status, ret_ips_data = __check_ip_resource() except Exception as e: _msg = '已有镜像补录:判断IP资源是否足够出现异常 : check ip resource exception when image update by exist ,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_ips_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=ret_ips_data) # 更新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) ip_data = ret_ips_data message = '模板机 %s 创建预分配IP成功' % eimage_name logging.info(message) # 在镜像编辑服务器上创建相应文件夹 dest_dir = '/app/image/' + eimage_name ret, msg = ansibleCmdV2.create_destdir(IMAGE_EDIT_SERVER, dest_dir) if not ret: logging.error(msg) _set_ip_init(ip_data) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=msg) # 获取新镜像文件的list到镜像编辑服务器 ret, message = im_man_act._img_create_from_exist(eimage_name, eimage_name) if not ret: logging.error(message) _set_ip_init(ip_data) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=message) # 模板机define ret, message = im_man_act._img_tem_define(eimage_name) if not ret: logging.error(message) _set_ip_init(ip_data) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=message) # 根据已有镜像生成镜像的接口 insert_data = { 'eimage_name': eimage_name, 'displayname': displayname, # status=-1:初始化;0:使用中;1:编辑中;2:待发布 'status': ImageManage.INIT, 'related_image_tag': tag, 'version': version, # 根据已有的镜像创建,template_status只默认1 'template_status': img_tmp_status.SHUTDOWN, 'template_vm_ip': ip_data['ip_address'], 'message': '创建完成', 'create_type': image_ceate_type.UPDATE_EXIST, 'create_time': get_datetime_str(), 'os_type': template_ostype, } ret = image_service.ImageManageService().add_image_info(insert_data) if ret.get('row_num') <= 0: logging.error("add image error, insert_data:%s", str(insert_data)) error_msg = "添加新镜像 %s 失败", str(insert_data) _set_ip_init(ip_data) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=error_msg) return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
def ips_apply_from_other_platform(): ''' 外部平台申请KVM IP, IP会置为预分配 :return: ''' data_from_api = request.data logging.info(data_from_api) data_requset = json_helper.loads(data_from_api) req_datacenter = data_requset['dataCenter'] req_env = data_requset['env'] req_net_area = data_requset['netArea'] count = data_requset['ipNums'] netcare_type = data_requset.get('netCardType', NetCardType.INTERNAL) # 校验入参是否为空 if not req_net_area or not req_datacenter or not req_env or not count: return json_helper.format_api_resp_msg(code=ErrorCode.PARAM_ERR, job_status=VsJobStatus.FAILED, detail='机房、环境、网络区域或ip数量入参为空') # 查询指定环境、网络区域是否有所需网段,容灾微应用需要遍历联通、电信所有可用网段 if DataCenterTypeForVishnu.TYPE_DICT[req_env] == DataCenterType.MINIARCHDR: ret_segment_datas_telecom = segment_s.get_segments_data_by_type(req_net_area, req_datacenter, str(DataCenterTypeForVishnu.TYPE_DICT[req_env]), NetCardType.INTERNEL_TELECOM) ret_segment_datas_unicom = segment_s.get_segments_data_by_type(req_net_area, req_datacenter, str(DataCenterTypeForVishnu.TYPE_DICT[req_env]), NetCardType.INTERNEL_UNICOM) ret_segment_datas = ret_segment_datas_telecom + ret_segment_datas_unicom else: ret_segment_datas = segment_s.get_segments_data_by_type(req_net_area, req_datacenter, str(DataCenterTypeForVishnu.TYPE_DICT[req_env]), netcare_type) if not ret_segment_datas: return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='指定机房、网络区域下没有可用网段用于分配IP') # 获取IP资源,先判断是否有人也在分配IP资源,有则等待1s,时间之后再优化 ip_lock_unused = False while not ip_lock_unused: ret_ip_lock_status = ip_l_s.IpLockService().get_ip_lock_info('ip') if not ret_ip_lock_status: logging.error('外部接口分配vip:检查IP时无法获取资源锁状态') return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='检查IP时无法获取资源锁状态') if ret_ip_lock_status['istraceing'] == IpLockStatus.USED: time.sleep(1) else: ip_lock_unused = True # 更新ip_lock表istraceing字段为1 ret_ip_lock_used_status, ret_ip_lock_used_datas = __update_ip_lock_used() if not ret_ip_lock_used_status: logging.error(ret_ip_lock_used_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail=ret_ip_lock_used_datas) try: # 获取可用ip ret_ip_datas, ret_ip_segment_datas = ip_service.get_available_ips(ret_segment_datas, int(count), str(DataCenterTypeForVishnu.TYPE_DICT[req_env])) if not ret_ip_datas: ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused() if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail=ret_ip_lock_unused_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='指定机房、网络区域下无法找到%s个可用IP' % str(count)) # 如果是申请生产或者容灾环境ip,需判断网段对应关系表中是否有记录 if req_env == 'PRD': segment_dr = segment_m.SegmentMatchService().get_segment_match_info_by_prd_segment_id(ret_ip_segment_datas['id']) if not segment_dr: ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused() if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail=ret_ip_lock_unused_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='指定机房、网络区域下无法找到生产网段对应的容灾网段ID') segment_dr_data = segment_s.SegmentService().get_segment_info(segment_dr['dr_segment_id']) if not segment_dr_data: ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused() if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail=ret_ip_lock_unused_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='指定机房、网络区域下无法找到生产网段对应的容灾网段详细信息') elif req_env == 'DR': segment_prd = segment_m.SegmentMatchService().get_segment_match_info_by_dr_segment_id(ret_ip_segment_datas['id']) if not segment_prd: ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused() if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail=ret_ip_lock_unused_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='指定机房、网络区域下无法找到容灾网段对应的生产网段ID') segment_prd_data = segment_s.SegmentService().get_segment_info(segment_prd['prd_segment_id']) if not segment_prd_data: ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused() if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail=ret_ip_lock_unused_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='指定机房、网络区域下无法找到容灾网段对应的生产网段详细信息') # 标记ip为预分配 logging.info(ret_ip_datas) ips_list = [] prd_ips_list = [] dr_ips_list = [] ip_details = {} for ip in ret_ip_datas: update_data = { 'status': IPStatus.PRE_ALLOCATION, 'updated_at': get_datetime_str() } where_data = { 'id': ip['id'] } ret_mark_ip = ip_service.IPService().update_ip_info(update_data, where_data) if ret_mark_ip <= 0: continue ip_datas = { 'ip': ip['ip_address'], 'vlanId': ip['vlan'], 'subnetMask': __exchange_maskint(int(ip['netmask'])), 'gateway': ip['gateway_ip'], 'ip_type': ret_ip_segment_datas['segment_type'] } ips_list.append(ip_datas) # 生产环境需要预分配对应容灾环境ip,容灾环境需要预分配生产环境ip if req_env == 'PRD': # 拼凑虚拟机容灾ip并预分配ip dr_ip = segment_dr_data['segment'].split('.')[0] + '.' + segment_dr_data['segment'].split('.')[1] + \ '.' + ip['ip_address'].split('.')[2] + '.' + ip['ip_address'].split('.')[3] dr_ip_info = ip_service.IPService().get_ip_by_ip_address(dr_ip) # 如果容灾环境ip未初始化,默认初始化 if not dr_ip_info: if not __init_ip(segment_dr_data, dr_ip): continue dr_ip_info = ip_service.IPService().get_ip_by_ip_address(dr_ip) update_data = { 'status': IPStatus.PRE_ALLOCATION } where_data = { 'ip_address': dr_ip } ret_mark_ip = ip_service.IPService().update_ip_info(update_data, where_data) if ret_mark_ip <= 0: continue # 拼装容灾ip信息 dr_ip_datas = { 'ip': dr_ip_info['ip_address'], 'vlanId': dr_ip_info['vlan'], 'subnetMask': __exchange_maskint(int(dr_ip_info['netmask'])), 'gateway': dr_ip_info['gateway_ip'] } dr_ips_list.append(dr_ip_datas) elif req_env == 'DR': # 拼凑虚拟机生产ip并预分配ip prd_ip = segment_prd_data['segment'].split('.')[0] + '.' + segment_prd_data['segment'].split('.')[1] + \ '.' + ip['ip_address'].split('.')[2] + '.' + ip['ip_address'].split('.')[3] prd_ip_info = ip_service.IPService().get_ip_by_ip_address(prd_ip) # 如果生产环境ip未初始化,默认初始化 if not prd_ip_info: if not __init_ip(segment_prd_data, prd_ip): continue prd_ip_info = ip_service.IPService().get_ip_by_ip_address(prd_ip) update_data = { 'status': IPStatus.PRE_ALLOCATION } where_data = { 'ip_address': prd_ip } ret_mark_ip = ip_service.IPService().update_ip_info(update_data, where_data) if ret_mark_ip <= 0: continue # 拼装生产ip信息 prd_ip_datas = { 'ip': prd_ip_info['ip_address'], 'vlanId': prd_ip_info['vlan'], 'subnetMask': __exchange_maskint(int(prd_ip_info['netmask'])), 'gateway': prd_ip_info['gateway_ip'] } prd_ips_list.append(prd_ip_datas) except Exception as e: _msg = '外部接口预分配IP:预分配ip出现异常: distribution ip exception,err:%s' %e logging.error(_msg) ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused() if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=_msg) # 更新ip_lock表istraceing字段为0 ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused() if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail=ret_ip_lock_unused_datas) if len(ips_list) <= 0: return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='指定机房、网络区域下%s个可用IP修改为预分配状态全部失败' % str(count)) elif req_env == 'PRD' and (len(ips_list) + len(dr_ips_list)) < int(count)*2: return json_helper.format_api_resp_msg(code=ErrorCode.SUCCESS_PART, job_status=VsJobStatus.FAILED, detail='生产环境指定机房、网络区域下%s个可用IP修改为预分配状态部分失败' % str(count)) elif req_env == 'DR' and (len(ips_list) + len(prd_ips_list)) < int(count)*2: return json_helper.format_api_resp_msg(code=ErrorCode.SUCCESS_PART, job_status=VsJobStatus.FAILED, detail='容灾环境指定机房、网络区域下%s个可用IP修改为预分配状态部分失败' % str(count)) elif len(ips_list) < int(count): return json_helper.format_api_resp_msg(code=ErrorCode.SUCCESS_PART, job_status=VsJobStatus.FAILED, detail='指定机房、网络区域下%s个可用IP修改为预分配状态部分失败' % str(count)) else: if req_env == 'PRD': ip_details['prd'] = ips_list ip_details['dr'] = dr_ips_list elif req_env == 'DR': ip_details['dr'] = ips_list ip_details['prd'] = prd_ips_list else: ip_details['default'] = ips_list logging.info(ip_details) return json_helper.format_api_resp_msg(code=ErrorCode.SUCCESS, job_status=VsJobStatus.SUCCEED, detail=ip_details)
def ip_apply_from_other_platform(): ''' 外部平台申请ip :return: ''' data_from_vishnu = request.data logging.info(data_from_vishnu) data_requset = json_helper.loads(data_from_vishnu) req_datacenter = data_requset['datacenter'] req_env = data_requset['env'] req_net_area = data_requset['net_area'] req_net_name = data_requset['net_name'] cluster_id = data_requset['cluster_id'] opuser = data_requset['opUser'] sys_code = data_requset['sys_code'] taskid_vs = data_requset['taskid'] ip_count = data_requset['ipCount'] prd_dr_ip_all_needed = data_requset['prdDrAllNeeded'] # '0'代表普通申请,'1'需要同时申请prd、dr环境的ip # 校验入参是否为空 if not req_env or not req_net_area or not req_net_name or not req_datacenter: return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='empty input of env, net area information or net name ' 'when apply ip') if not cluster_id or not opuser or not sys_code or not taskid_vs: return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='empty input of cluster_id, opuser, ' 'task id or sys_code when apply ip') if not str(ip_count) or not str(prd_dr_ip_all_needed): return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='empty input of ipCount or prdDrAllNeeded when apply ip') # 查询指定环境、网络区域是否有所需网段 ret_segment = segment_service.SegmentService().get_segment_info_bysegment(req_net_name.split('/')[0]) if not ret_segment: return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail="无法找到需要申请的网段") ret_net_area_info = net_area.NetAreaService().get_net_area_info(ret_segment['net_area_id']) if not ret_net_area_info: return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail="无法找到指定网段所属网络区域信息") ret_datacenter_info = datacenter_service.DataCenterService().get_datacenter_info(ret_net_area_info['datacenter_id']) if not ret_datacenter_info: return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail="无法找到指定机房信息") if req_env not in DataCenterTypeForVishnu.TYPE_DICT: return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail="无法找到指定机房类型信息") if str(DataCenterTypeForVishnu.TYPE_DICT[req_env]) != ret_datacenter_info['dc_type']: return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail="无法找到指定网络区域对应网段信息") # 如果是申请生产或者容灾环境ip,需判断网段对应关系表中是否有记录 if req_env == 'PRD': segment_dr = segment_m.SegmentMatchService().get_segment_match_info_by_prd_segment_id( ret_segment['id']) if not segment_dr: return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='指定机房、网络区域下无法找到生产网段对应的容灾网段ID') segment_dr_data = segment_s.SegmentService().get_segment_info(segment_dr['dr_segment_id']) if not segment_dr_data: return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='指定机房、网络区域下无法找到生产网段对应的容灾网段详细信息') elif req_env == 'DR': segment_prd = segment_m.SegmentMatchService().get_segment_match_info_by_dr_segment_id( ret_segment['id']) if not segment_prd: return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='指定机房、网络区域下无法找到容灾网段对应的生产网段ID') segment_prd_data = segment_s.SegmentService().get_segment_info(segment_prd['prd_segment_id']) if not segment_prd_data: return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='指定机房、网络区域下无法找到容灾网段对应的生产网段详细信息') # 获取IP资源,先判断是否有人也在分配IP资源,有则等待1s,时间之后再优化 ip_lock_unused = False while not ip_lock_unused: ret_ip_lock_status = ip_l_s.IpLockService().get_ip_lock_info('ip') if not ret_ip_lock_status: logging.error('外部接口分配vip:检查IP时无法获取资源锁状态') return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='检查IP时无法获取资源锁状态') if ret_ip_lock_status['istraceing'] == IpLockStatus.USED: time.sleep(1) else: ip_lock_unused = True # 更新ip_lock表istraceing字段为1 ret_ip_lock_used_status, ret_ip_lock_used_datas = __update_ip_lock_used() if not ret_ip_lock_used_status: logging.error(ret_ip_lock_used_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail=ret_ip_lock_used_datas) try: segments_data_list = [] segments_data_list.append(ret_segment) # 获取可用ip ret_ip_datas, ret_ip_segment_datas = ip_service.get_available_ips(segments_data_list, int(ip_count), str( DataCenterTypeForVishnu.TYPE_DICT[req_env])) if not ret_ip_datas: ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused() if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail=ret_ip_lock_unused_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='指定机房、网络区域下无法找到%s个可用IP' % str(ip_count)) # 标记ip为预分配 logging.info(ret_ip_datas) ips_list = [] prd_ips_list = [] dr_ips_list = [] ip_details = {} for ip in ret_ip_datas: update_data = { 'status': IPStatus.USED } where_data = { 'id': ip['id'] } ret_mark_ip = ip_service.IPService().update_ip_info(update_data, where_data) if ret_mark_ip <= 0: continue # 录入vip信息到数据库中 insert_vip_data = { 'ip_id': ip['id'], 'cluster_id': cluster_id, 'apply_user_id': opuser, 'sys_code': sys_code, 'isdeleted': '0', 'created_at': get_datetime_str() } ret_vip = vip_service.VIPService().add_vip_info(insert_vip_data) if ret_vip.get('row_num') <= 0: continue ip_datas = { 'ip': ip['ip_address'], 'vlanId': ip['vlan'], 'subnetMask': __exchange_maskint(int(ip['netmask'])), 'gateway': ip['gateway_ip'] } ips_list.append(ip_datas) # 生产环境需要预分配对应容灾环境ip,容灾环境需要预分配生产环境ip if req_env == 'PRD': # 拼凑虚拟机容灾ip并预分配ip dr_ip = segment_dr_data['segment'].split('.')[0] + '.' + segment_dr_data['segment'].split('.')[1] + \ '.' + ip['ip_address'].split('.')[2] + '.' + ip['ip_address'].split('.')[3] dr_ip_info = ip_service.IPService().get_ip_by_ip_address(dr_ip) # 如果容灾环境ip未初始化,默认初始化 if not dr_ip_info: if not __init_ip(segment_dr_data, dr_ip): continue dr_ip_info = ip_service.IPService().get_ip_by_ip_address(dr_ip) if prd_dr_ip_all_needed == '1': update_data = { 'status': IPStatus.USED } where_data = { 'id': dr_ip_info['id'] } ret_mark_ip = ip_service.IPService().update_ip_info(update_data, where_data) if ret_mark_ip <= 0: continue # 录入vip信息到数据库中 insert_vip_data = { 'ip_id': dr_ip_info['id'], 'cluster_id': cluster_id, 'apply_user_id': opuser, 'sys_code': sys_code, 'isdeleted': '0', 'created_at': get_datetime_str() } ret_vip = vip_service.VIPService().add_vip_info(insert_vip_data) if ret_vip.get('row_num') <= 0: continue else: update_data = { 'status': IPStatus.PRE_ALLOCATION } where_data = { 'ip_address': dr_ip } ret_mark_ip = ip_service.IPService().update_ip_info(update_data, where_data) if ret_mark_ip <= 0: continue # 拼装容灾ip信息 dr_ip_datas = { 'ip': dr_ip_info['ip_address'], 'vlanId': dr_ip_info['vlan'], 'subnetMask': __exchange_maskint(int(dr_ip_info['netmask'])), 'gateway': dr_ip_info['gateway_ip'] } dr_ips_list.append(dr_ip_datas) elif req_env == 'DR': # 拼凑虚拟机生产ip并预分配ip prd_ip = segment_prd_data['segment'].split('.')[0] + '.' + segment_prd_data['segment'].split('.')[1] + \ '.' + ip['ip_address'].split('.')[2] + '.' + ip['ip_address'].split('.')[3] prd_ip_info = ip_service.IPService().get_ip_by_ip_address(prd_ip) # 如果生产环境ip未初始化,默认初始化 if not prd_ip_info: if not __init_ip(segment_prd_data, prd_ip): continue prd_ip_info = ip_service.IPService().get_ip_by_ip_address(prd_ip) if prd_dr_ip_all_needed == '1': update_data = { 'status': IPStatus.USED } where_data = { 'id': prd_ip_info['id'] } ret_mark_ip = ip_service.IPService().update_ip_info(update_data, where_data) if ret_mark_ip <= 0: continue # 录入vip信息到数据库中 insert_vip_data = { 'ip_id': prd_ip_info['id'], 'cluster_id': cluster_id, 'apply_user_id': opuser, 'sys_code': sys_code, 'isdeleted': '0', 'created_at': get_datetime_str() } ret_vip = vip_service.VIPService().add_vip_info(insert_vip_data) if ret_vip.get('row_num') <= 0: continue else: update_data = { 'status': IPStatus.PRE_ALLOCATION } where_data = { 'ip_address': prd_ip } ret_mark_ip = ip_service.IPService().update_ip_info(update_data, where_data) if ret_mark_ip <= 0: continue # 拼装生产ip信息 prd_ip_datas = { 'ip': prd_ip_info['ip_address'], 'vlanId': prd_ip_info['vlan'], 'subnetMask': __exchange_maskint(int(prd_ip_info['netmask'])), 'gateway': prd_ip_info['gateway_ip'] } prd_ips_list.append(prd_ip_datas) except Exception as e: _msg = '外部平台申请IP:预分配ip出现异常: distribution ip exception,err:%s'%e logging.error(_msg) ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused() if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=_msg) # 更新ip_lock表istraceing字段为0 ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused() if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail=ret_ip_lock_unused_datas) if len(ips_list) <= 0: return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='指定机房、网络区域下%s个可用IP修改为预分配状态全部失败' % str(ip_count)) elif req_env == 'PRD' and (len(ips_list) + len(dr_ips_list)) < int(ip_count) * 2: return json_helper.format_api_resp_msg(code=ErrorCode.SUCCESS_PART, job_status=VsJobStatus.FAILED, detail='生产环境指定机房、网络区域下%s个可用IP修改为预分配状态部分失败' % str(ip_count)) elif req_env == 'DR' and (len(ips_list) + len(prd_ips_list)) < int(ip_count) * 2: return json_helper.format_api_resp_msg(code=ErrorCode.SUCCESS_PART, job_status=VsJobStatus.FAILED, detail='容灾环境指定机房、网络区域下%s个可用IP修改为预分配状态部分失败' % str(ip_count)) elif len(ips_list) < int(ip_count): return json_helper.format_api_resp_msg(code=ErrorCode.SUCCESS_PART, job_status=VsJobStatus.FAILED, detail='指定机房、网络区域下%s个可用IP修改为预分配状态部分失败' % str(ip_count)) else: if req_env == 'PRD': ip_details['prd'] = ips_list ip_details['dr'] = dr_ips_list elif req_env == 'DR': ip_details['dr'] = ips_list ip_details['prd'] = prd_ips_list else: ip_details['default'] = ips_list return json_helper.format_api_resp_msg(code=ErrorCode.SUCCESS, job_status=VsJobStatus.SUCCEED, detail=ip_details)
def instance_add_netcard_from_other_platform(): ''' kvm平台虚拟机添加网卡外部接口 入参说明: { "instanceMainIp": "虚拟机主网ip列表" "apiOrigin": "", "netCardType": "" } :return: ''' _init_log('instance_add_netcard_from_other_platform') logging.info(request.data) logging.info(request.values) logging.info(request.form) req_json = request.data req_data = json_helper.loads(req_json) instance_ip_list = req_data["instanceMainIp"] req_origin = req_data["apiOrigin"] netcard_type = req_data["netCardType"] # 判断需要配置网卡所有虚拟机是否存在 if not instance_ip_list or not req_origin or not netcard_type: return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='入参有空值,请检查') _ip_datas_list = [] instance_data_list = [] env_list = [] dc_list = [] net_area_list = [] ip_str = "" # 判断ip列表中是否有不存在于kvm平台的 for _ip in instance_ip_list: _instance_info = ip_s.get_instance_info_by_ip(_ip['ip']) if not _instance_info: ip_str += _ip['ip'] + " " else: _instance_params = { "instance_ip": _ip['ip'], "instance_uuid": _instance_info['instance_uuid'], "instance_id": _instance_info['instance_id'], "instance_name": _instance_info['instance_name'], "host_ip": _instance_info['host_ip'], "env": _instance_info['env'], "net_area": _instance_info['net_area_name'], "dc_name": _instance_info['datacenter_name'], } instance_data_list.append(_instance_params) env_list.append(_instance_info['env']) dc_list.append(_instance_info['datacenter_name']) net_area_list.append(_instance_info['net_area_name']) if ip_str: return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='ip:%s无法在kvm平台中找到' % ip_str) if len(set(env_list)) > 1: return json_helper.format_api_resp_msg( code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='需要配置网卡的虚拟机属于不同环境,不允许同时配置') if len(set(dc_list)) > 1: return json_helper.format_api_resp_msg( code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='需要配置网卡的虚拟机属于不同机房,不允许同时配置') if len(set(net_area_list)) > 1: return json_helper.format_api_resp_msg( code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='需要配置网卡的虚拟机属于不同网络区域,不允许同时配置') instance_str = "" instance_data_filter_list = [] # 查询指定虚拟机网卡数量,目前不能超过3块,同一类型网卡只能有一块 for _instance in instance_data_list: instance_same_netcard_type_str = "" instance_net_card = instance_s.get_net_info_of_instance( _instance['instance_id']) if instance_net_card: for _net_card in instance_net_card: if _net_card['segment_type'] == netcard_type: instance_same_netcard_type_str += _instance[ 'instance_ip'] + " " _ip_datas = { "instanceIp": _instance['instance_ip'], "nasIp": _net_card['ip_address'] } _ip_datas_list.append(_ip_datas) if not instance_same_netcard_type_str: instance_data_filter_list.append(_instance) if len(instance_net_card) >= INSTANCE_NETCARD_NUMS: instance_str += _instance['instance_ip'] + " " if instance_str: return json_helper.format_api_resp_msg( code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='虚拟机:%s网卡数量不能大于%s' % (ip_str, str(INSTANCE_NETCARD_NUMS))) # if instance_same_netcar_type_str: # return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, # detail='虚拟机:%s已配置相同类型网卡,不可重复申请' % ip_str) if len(instance_data_filter_list) == 0: return json_helper.format_api_resp_msg(code=ErrorCode.SUCCESS, job_status=VsJobStatus.SUCCEED, detail=_ip_datas_list) # 判断虚拟机虚拟机是否开机中 instance_unstarting_str = "" for _instance in instance_data_filter_list: vm_status = vmManager.libvirt_instance_status( _instance['host_ip'], _instance['instance_name']) # 虚拟机开机状态才可以做网卡配置 if vm_status != VMLibvirtStatus.STARTUP: instance_unstarting_str += _instance['instance_ip'] + " " if instance_unstarting_str: return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='虚拟机:%s非运行中状态,无法添加网卡' % ip_str) # 识别需要创建的网卡类型并分配ip net_type = [ NetCardType.INTERNAL, NetCardType.INTERNEL_TELECOM, NetCardType.INTERNEL_UNICOM, NetCardType.INTERNAL_IMAGE, NetCardType.INTERNAL_NAS ] if netcard_type not in net_type: return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='KVM虚拟机没有网卡类型:%s ' % netcard_type) # 获取IP资源,先判断是否有人也在分配IP资源,有则等待1s,时间之后再优化 ip_lock_unused = False while not ip_lock_unused: ret_ip_lock_status = ip_l_s.IpLockService().get_ip_lock_info('ip') if not ret_ip_lock_status: logging.error('外部接口新增网卡分配ip:检查IP时无法获取资源锁状态') return json_helper.format_api_resp_msg( code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='检查IP时无法获取资源锁状态') if ret_ip_lock_status['istraceing'] == IpLockStatus.USED: time.sleep(1) else: ip_lock_unused = True # 更新ip_lock表istraceing字段为1 ret_ip_lock_used_status, ret_ip_lock_used_datas = __update_ip_lock_used() if not ret_ip_lock_used_status: logging.error(ret_ip_lock_used_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail=ret_ip_lock_used_datas) # 查询指定环境、网络区域是否有所需网段 try: ret_segment_datas = segment_s.get_segments_data_by_type( net_area_list[0], dc_list[0], str(env_list[0]), str(netcard_type)) if not ret_segment_datas: ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused( ) if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp_msg( code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail=ret_ip_lock_unused_datas) return json_helper.format_api_resp_msg( code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail='虚拟机所在网络区域没有指定网卡类型可用网段') # 获取可用ip并标记为已使用 ret_ip_status, ret_ip_data, ret_ip_msg = __check_ip_resource( ret_segment_datas, str(env_list[0]), len(instance_data_filter_list)) if not ret_ip_status: _change_db_ip_unused(ret_ip_data) ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused( ) if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp_msg( code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail=ret_ip_lock_unused_datas) return json_helper.format_api_resp_msg( code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail=ret_ip_msg) except Exception as e: _msg = '添加网卡外部接口:获取网段标记ip出现异常 %s: check ip resource exception when instance add nic from platform,err:%s' % ( ip_str, e) logging.error(_msg) ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused( ) if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=_msg) # 更新ip_lock表istraceing字段为0 ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused( ) if not ret_ip_lock_unused_status: _change_db_ip_unused(ret_ip_data) logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail=ret_ip_lock_unused_datas) error_msg = [] # 拼装虚拟机网卡信息用于配置网卡 i = 0 for _instance in instance_data_filter_list: mac = randomMAC() _instance['ip_addr_new'] = ret_ip_data[i]['ip_address'] _instance['mac_addr'] = mac i += 1 ret_status, ret_error_msg = __instance_add_netcard(_instance) if not ret_status: _msg = {"ip": _instance['instance_ip'], "error_msg": ret_error_msg} error_msg.append(_msg) else: _ip_datas = { "instanceIp": _instance['instance_ip'], "nasIp": _instance['ip_addr_new'] } _ip_datas_list.append(_ip_datas) if error_msg: return json_helper.format_api_resp_msg(code=ErrorCode.SYS_ERR, job_status=VsJobStatus.FAILED, detail=error_msg) return json_helper.format_api_resp_msg(code=ErrorCode.SUCCESS, job_status=VsJobStatus.SUCCEED, detail=_ip_datas_list)
def image_create_new(): eimage_name = request.values.get('image_name') displayname = request.values.get('displayname') template_ostype = request.values.get('os_type') version = request.values.get('version') if not eimage_name or not displayname or not version or not template_ostype: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='入参缺失') # 判断当前image表是否有同名镜像 image_nums, image_data = image_service.ImageService().get_images_by_name( eimage_name) if image_data: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='image表已存在同名镜像') # 判断当前image_manage表是否有同名镜像 eimage_data = image_service.ImageManageService( ).get_image_manage_info_by_name(eimage_name) if eimage_data: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='image_manage表已存在同名镜像') # 获取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('创建新镜像 %s 失败:检查IP时无法获取资源锁状态') % eimage_name return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='检查IP时无法获取资源锁状态') if ret_ip_lock_status['istraceing'] == IpLockStatus.USED: time.sleep(1) else: ip_lock_unused = True # 更新ip_lock表istraceing字段为1 ret_ip_lock_used_status, ret_ip_lock_used_datas = __update_ip_lock_used() if not ret_ip_lock_used_status: logging.error(ret_ip_lock_used_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_ip_lock_used_datas) try: ret_ips_status, ret_ips_data = __check_ip_resource() except Exception as e: _msg = '创建全新镜像:判断IP资源是否足够出现异常 : check ip resource exception when create new image ,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_ips_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=ret_ips_data) # 更新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) #segment_data = segment_s.SegmentService().get_segment_for_img_tmp() ip_data = ret_ips_data message = '模板机 %s 创建预分配IP成功' % eimage_name logging.info(message) # 模板机define ret, message = im_man_act._img_tem_define(eimage_name) if not ret: logging.error(message) # 将预分频的ip释放 _set_ip_init(ip_data) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=message) tag = randomUUID() # 添加信息到image_manage表 insert_data = { 'eimage_name': eimage_name, 'displayname': displayname, # status=-1:初始化;0:使用中;1:编辑中;2:待发布 'status': ImageManage.INIT, 'related_image_tag': tag, 'os_type': template_ostype, 'version': version, #创建全新镜像,template_status值默认1 'template_status': img_tmp_status.SHUTDOWN, 'template_vm_ip': ip_data['ip_address'], 'message': '创建完成', 'create_type': image_ceate_type.ALL_NEW, 'create_time': get_datetime_str() } # 创建全新的镜像 ret = image_service.ImageManageService().add_image_info(insert_data) if ret.get('row_num') <= 0: logging.error("add image error, insert_data:%s", str(insert_data)) error_msg = "添加新镜像 %s 失败", str(insert_data) _set_ip_init(ip_data) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=error_msg) return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
def instance_create(hostpool_id): ''' 创建虚机 :param hostpool_id: :return: ''' image_name = request.values.get('image_name') flavor_id = request.values.get('flavor_id') disk_gb = request.values.get('disk_gb') count = request.values.get('count') app_info = request.values.get('app_info') group_id = request.values.get('group_id') owner = request.values.get('owner') password = request.values.get('password') task_id = ins_s.generate_task_id() logging.info( '创建VM 步骤1:检查参数 task %s : check params start when create instance', task_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( '创建VM 步骤1:检查参数失败 参数错误 task %s : params are invalid when create instance', task_id) return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR, msg='参数错误') if int(count) > int(INSTANCE_MAX_CREATE): logging.error( '创建VM 步骤1:检查参数失败 批量创建数超过最大数 ' 'task %s : create count %s > max num %s when create instance', task_id, count, INSTANCE_MAX_CREATE) return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR, msg='批量创建最大实例数不能超过' + INSTANCE_MAX_CREATE + '个') owner_exist = user_s.UserService().check_userid_exist(owner) if not owner_exist: logging.error( '创建VM 步骤1:检查参数失败 应用管理员工号不存在 ' 'task %s : no such user %s in db when create instance', task_id, owner) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='应用管理员工号不存在,无法创建实例') logging.info( '创建VM 步骤1:检查参数成功 task %s : check params successful when create instance', task_id) # 数据盘最少50GB # todo:这里只是一个数据盘,后面有多个数据盘 vm_disk_gb = int(disk_gb) if int(disk_gb) > DATA_DISK_GB else DATA_DISK_GB # 获取主机列表(不包括锁定、维护状态) logging.info( '创建VM 步骤2:获取集群所有HOST列表 ' 'task %s : get all hosts in hostpool %s start when create instance', task_id, 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( '创建VM 步骤2:获取集群所有HOST列表失败 集群不够资源 ' 'task %s : available host resource not enough when create instance', task_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='集群不够资源,无法创建实例') logging.info( '创建VM 步骤2:获取集群所有HOST列表成功,总host数:%s ' 'task %s : get all hosts in hostpool %s successful, all hosts nums %s when create instance', all_hosts_nums, task_id, hostpool_id, all_hosts_nums) # 过滤host logging.info( '创建VM 步骤3:HOST过滤 task %s : filter hosts start when create instance', task_id) 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( '创建VM 步骤3:HOST过滤失败 没有合适主机 ' 'task %s : no available host when create instance', task_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='集群物理机资源无法满足你的申请需求,请联系系统组同事') logging.info( '创建VM 步骤3:HOST过滤成功 task %s : filter hosts successful when create instance', task_id) # 获取flavor信息 logging.info( '创建VM 步骤4:获取必需信息 task %s : get need info start when create instance', task_id) flavor_info = flavor_service.FlavorService().get_flavor_info(flavor_id) if not flavor_info: logging.error( '创建VM 步骤4:获取必需信息失败 实例规格数据有误 ' 'task %s : flavor %s info not in db when create instance', task_id, flavor_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='实例规格数据有误,无法创建实例') # VM分配给HOST logging.info( '创建VM 步骤5:HOST分配 task %s : match hosts start when create instance', task_id) 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( '创建VM 步骤5:HOST分配失败 没有合适主机 ' 'task %s : match host resource not enough when create instance', task_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='集群物理机资源无法满足你的申请需求,请联系系统组同事') logging.info( '创建VM 步骤5:HOST分配成功 task %s : match hosts successful when create instance', task_id) # 获取hostpool的net area信息 hostpool_info = hostpool_service.HostPoolService().get_hostpool_info( hostpool_id) if not hostpool_info: logging.error( '创建VM 步骤6:获取必需信息失败 物理机池所属网络区域信息有误 ' 'task %s : hostpool %s info not in db when create instance', task_id, hostpool_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='物理机池所属网络区域信息有误,无法创建实例') net_area_id = hostpool_info['net_area_id'] logging.info( '创建VM 步骤6:获取必需信息成功 task %s : get need info successful when create instance', task_id) # 组配额控制 logging.info( '创建VM 步骤7:检查组配额 task %s : check group quota start when create instance', task_id) is_quota_enough, quota_msg = check_group_quota(group_id, flavor_info, vm_disk_gb, count) if not is_quota_enough: logging.error( '创建VM 步骤7:检查组配额失败 配额不足 ' 'task %s : group %s is no enough quota when create instance', task_id, group_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=quota_msg) logging.info( '创建VM 步骤7:检查组配额成功 task %s : check group quota successful when create instance', task_id) logging.info( '创建VM 步骤8:获取必需信息 task %s : get need 1 info start when create instance', task_id) # 获取镜像信息,一个image_name可能对应多个id image_nums, image_data = image_service.ImageService().get_images_by_name( image_name) if image_nums <= 0: logging.info( '创建VM 步骤8:获取必需信息失败 镜像资源不足 ' 'task %s : no image %s info in db when create instance', task_id, image_name) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='没有镜像资源,无法创建实例') # 实例操作系统 instance_system = image_data[0]['system'] logging.info( '创建VM 步骤8:获取必需信息成功 ' 'task %s : get need 1 info successful when create instance', task_id) # 获取集群所在的环境 vm_env = hostpool_service.get_env_of_hostpool(hostpool_id) # hostpool对应的机房名 dc_name = hostpool_service.get_dc_name_of_hostpool(hostpool_id) # 获取集群所在网络区域名 net_area_name = hostpool_service.get_level_info_by_id(hostpool_id).get( 'net_area_name', '') # 获取虚机名资源 logging.info( '创建VM 步骤9:获取主机名资源 ' 'task %s : check instance name resource start when create instance', task_id) is_name_enough, instance_name_list = _check_instance_name_resource( vm_env, dc_name, instance_system, count) if not is_name_enough: logging.error( '创建VM 步骤9:获取主机名资源失败 主机名资源不足 ' 'task %s : datacenter %s has no enough instance name resource', task_id, dc_name) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='主机名资源不足,无法创建实例') logging.info( '创建VM 步骤9:获取主机名资源成功 ' 'task %s : check instance name resource successful when create instance', task_id) # 获取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( '创建VM 步骤10:检查IP时无法获取资源锁状态' 'task %s : check ip resource can not get lock', task_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='检查IP时无法获取资源锁状态') if ret_ip_lock_status['istraceing'] == IpLockStatus.USED: time.sleep(1) else: ip_lock_unused = True # 更新ip_lock表istraceing字段为1 ret_ip_lock_used_status, ret_ip_lock_used_datas = __update_ip_lock_used() if not ret_ip_lock_used_status: logging.error(ret_ip_lock_used_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_ip_lock_used_datas) try: ret_ips_status, ret_ips_data, ret_segment = __check_ip_resource( vm_env, dc_name, net_area_name, count) except Exception as e: _msg = '创建VM 步骤10:检查IP资源是否足够出现异常task_id %s: check ip resource exception when instance create,err:%s' % ( task_id, 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_ips_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=ret_ips_data) # 更新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) ips_list = ret_ips_data segment_data = ret_segment logging.info( '创建VM 步骤10:检查IP资源成功 task %s : check ip resource successful when create instance', task_id) # 挂载点 if instance_system == 'linux': mount_point = '/app' else: mount_point = 'E' logging.info( '创建VM 步骤11:多线程发送创建信息 task %s : create thread start when create instance', task_id) 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, instance_name, app_info, owner, password, flavor_id, group_id, vm_host, flavor_info, image_data, ip_data, vm_disk_gb, mount_point, instance_system, net_area_id, segment_data, vm_env, user_id), name='thread-instance-create-' + task_id) all_threads.append(create_ins_t) create_ins_t.start() for thread in all_threads: thread.join() logging.info( '创建VM 步骤11:多线程发送创建信息成功 ' 'task %s : create thread successful when create instance', task_id) return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
def ip_apply(): ''' IP申请 :return: ''' req_env = request.values.get('env') req_net_area = request.values.get('net_area') req_net_name = request.values.get('segment') cluster_id = request.values.get('cluster_id') opuser = request.values.get('opUser') sys_code = request.values.get('sys_code') # 校验入参是否为空 if not req_env or not req_net_area or not req_net_name: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg="环境、网络区域、网段名输入为空") if not cluster_id or not opuser or not sys_code: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg="物理集群、操作用户、系统编码为空输入为空") # 查询指定环境、网络区域是否有所需网段 ret_segment = segment_service.SegmentService().get_segment_info_bysegment( req_net_name) if not ret_segment: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg="无法找到需要申请的网段") ret_net_area_info = net_area.NetAreaService().get_net_area_info( ret_segment['net_area_id']) if not ret_net_area_info: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg="无法找到指定网络区域信息") ret_datacenter_info = datacenter_service.DataCenterService( ).get_datacenter_info(ret_net_area_info['datacenter_id']) if not ret_datacenter_info: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg="无法找到指定机房信息") if req_env not in DataCenterTypeForVishnu.TYPE_DICT: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg="无法找到指定机房类型信息") if str(DataCenterTypeForVishnu.TYPE_DICT[req_env] ) != ret_datacenter_info['dc_type']: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg="无法找到指定网络区域对应网段信息") # 获取IP资源,先判断是否有人也在分配IP资源,有则等待1s,时间之后再优化 ip_lock_unused = False while not ip_lock_unused: ret_ip_lock_status = ip_l_s.IpLockService().get_ip_lock_info('ip') if not ret_ip_lock_status: logging.error('kvm平台分配vip:检查IP时无法获取资源锁状态') return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='检查IP时无法获取资源锁状态') if ret_ip_lock_status['istraceing'] == IpLockStatus.USED: time.sleep(1) else: ip_lock_unused = True # 更新ip_lock表istraceing字段为1 ret_ip_lock_used_status, ret_ip_lock_used_datas = __update_ip_lock_used() if not ret_ip_lock_used_status: logging.error(ret_ip_lock_used_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_ip_lock_used_datas) # 获取可用ip try: ret_ip_available_status, ret_ip_available = ip_service.get_available_segment_ip( ret_segment['id'], str(DataCenterTypeForVishnu.TYPE_DICT[req_env])) except Exception as e: _msg = 'IP申请ip_apply:获取指定网段可用ip出现异常 : get segment available ip exception when ip apply,err:%s' % e logging.error(_msg) ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused( ) if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=_msg) if not ret_ip_available_status: ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused( ) if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg="指定网段没有可用ip") # 标记ip已使用 update_data = {'status': IPStatus.USED} where_data = {'id': ret_ip_available['id']} ret_mark_ip = ip_service.IPService().update_ip_info( update_data, where_data) if ret_mark_ip <= 0: ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused( ) if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg="标记ip为已使用状态失败,请重新申请") # 更新ip_lock表istraceing字段为0 ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused( ) if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_ip_lock_unused_datas) # 录入vip信息到数据库中 insert_vip_data = { 'ip_id': ret_ip_available['id'], 'cluster_id': cluster_id, 'apply_user_id': opuser, 'sys_code': sys_code, 'isdeleted': '0', 'created_at': get_datetime_str() } ret_vip = vip_service.VIPService().add_vip_info(insert_vip_data) if ret_vip.get('row_num') <= 0: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg="录入ip信息失败,请联系系统管理员") ip_msg = {"vip": ret_ip_available['ip_address']} return json_helper.format_api_resp(code=ErrorCode.SUCCESS, data=ip_msg)