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 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 __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 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 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 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)