def _validate_ether_line_topology(config, iResult): permanent_lanzone_set = iResult['permanent_lanzone_set'] temporary_lanzone_set = iResult['temporary_lanzone_set'] permanent_host_set = iResult['permanent_host_set'] lanzones = invt_list_vswitch_lan_zones() hosts = invt_list_vswitch_hosts() interfaces = invt_list_vswitch_interfaces() start_lanzone_id = config['initial_lanzones'][0] end_lanzone_id = config['initial_lanzones'][1] e_line = invt_get_vswitch_ether_service(iResult['service_id']) iface_type = E3VSWITCH_INTERFACE_TYPE_EXCLUSIVE if e_line.link_type != E3NET_ETHER_SERVICE_LINK_EXCLUSIVE: iface_type = E3VSWITCH_INTERFACE_TYPE_SHARED target_lanzone_id = end_lanzone_id while True: weight, path = permanent_lanzone_set[target_lanzone_id] iface0_id, host_id, iface1_id = path if not host_id: assert (target_lanzone_id == start_lanzone_id) break iface0 = interfaces[iface0_id] host = hosts[host_id] iface1 = interfaces[iface1_id] assert (iface0.lanzone_id == target_lanzone_id) assert (iface0.host_id == host_id) assert (iface0.interface_type == iface_type) assert (iface1.host_id == host_id) assert (iface1.interface_type == iface_type) target_lanzone_id = iface1.lanzone_id
def rpc_get_vswitch_lanzone(self, request, context): lanzone = None if request.per_uuid == True: lanzone = invt_get_vswitch_lan_zone(request.uuid) else: lanzones = invt_list_vswitch_lan_zones() for _lanzone_id in lanzones: _lanzone = lanzones[_lanzone_id] if _lanzone.name == request.lanzone_name: lanzone = _lanzone break assert (lanzone) return to_vswitch_lanzone_pb2(lanzone)
def util_create_interface(host_name, lanzone_name, dev_address): from e3net.inventory.invt_vswitch_lan_zone import invt_list_vswitch_lan_zones from e3net.inventory.invt_vswitch_host import invt_list_vswitch_hosts from e3net.inventory.invt_vswitch_interface import invt_register_vswitch_interface hosts = invt_list_vswitch_hosts() lanzones = invt_list_vswitch_lan_zones() host_id = None for _host in hosts: host = hosts[_host] if host.name == host_name: host_id = host.id break lanzones = invt_list_vswitch_lan_zones() lanzone_id = None for _lanzone in lanzones: lanzone = lanzones[_lanzone] if lanzone.name == lanzone_name: lanzone_id = lanzone.id break spec = dict() spec['host_id'] = host_id spec['dev_address'] = dev_address spec['lanzone_id'] = lanzone_id invt_register_vswitch_interface(spec)
def rpc_list_vswitch_lanzones(self, request_iterator, context): lanzones = invt_list_vswitch_lan_zones() raw_lanzones = dict() for _key in request_iterator: if _key.per_uuid == True: raw_lanzones[_key.uuid] = invt_get_vswitch_lan_zone(_key.uuid) else: lanzone = None for _lanzone_id in lanzones: _lanzone = lanzones[_lanzone_id] if _lanzone.name == _key.lanzone_name: lanzone = _lanzone break assert (lanzone) raw_lanzones[lanzone.id] = lanzone _raw_lanzones = raw_lanzones if len(raw_lanzones) else lanzones for _lanzone_id in _raw_lanzones: _lanzone = _raw_lanzones[_lanzone_id] yield to_vswitch_lanzone_pb2(_lanzone)
def _create_ether_line_topology_edge(config, iResult): permanent_lanzone_set = iResult['permanent_lanzone_set'] lanzones = invt_list_vswitch_lan_zones() hosts = invt_list_vswitch_hosts() interfaces = invt_list_vswitch_interfaces() start_lanzone_id = config['initial_lanzones'][0] end_lanzone_id = config['initial_lanzones'][1] e_line = invt_get_vswitch_ether_service(iResult['service_id']) target_lanzone_id = end_lanzone_id hosts_to_push = list() while True: weight, path = permanent_lanzone_set[target_lanzone_id] iface0_id, host_id, iface1_id = path if not host_id: break hosts_to_push.append(host_id) spec = dict() spec['interface0'] = iface0_id spec['interface1'] = iface1_id spec['service_id'] = e_line.id invt_register_vswitch_topology_edge(spec) target_lanzone_id = interfaces[iface1_id].lanzone_id iResult['hosts_to_push'] = hosts_to_push
def _add_lanzones_to_ether_lan(config, iResult): e_lan = invt_get_vswitch_ether_service(config['service_id']) iResult['service_id'] = config['service_id'] initial_lanzones = iResult['initial_lanzones'] assert (len(initial_lanzones) >= 1) assert (iResult['operation'] == E_LAN_OPERATION_ADDITION) #prepare the topology elements infinite_weight = 0x7fffffff lanzones = invt_list_vswitch_lan_zones() hosts = invt_list_vswitch_hosts() interfaces = invt_list_vswitch_interfaces() edges = invt_list_vswitch_topology_edges() topology_edges = dict() iface_weight = dict() e3loger.debug('original lanzones set:') for lanzone_id in lanzones: e3loger.debug('\t%s' % (lanzones[lanzone_id])) e3loger.debug('original host set:') for host_id in hosts: e3loger.debug('\t%s' % (hosts[host_id])) e3loger.debug('original interface set:') for iface_id in interfaces: e3loger.debug('\t%s' % (interfaces[iface_id])) #calculate the weight of all existing topology edge for iface_id in interfaces: iface_weight[iface_id] = 0 for edge_id in edges: edge = edges[edge_id] iface0 = edge.interface0 iface1 = edge.interface1 iface_weight[iface0] = iface_weight[iface0] + 1 iface_weight[iface1] = iface_weight[iface1] + 1 e3loger.debug('interface weight:') for iface_id in iface_weight: e3loger.debug('\t%s:%s' % (iface_id, iface_weight[iface_id])) #filter the topology whose service id is the one we are operating for _edge_id in edges: edge = edges[_edge_id] if edge.service_id == e_lan.id: topology_edges[_edge_id] = edge e3loger.debug('existing topology edges for service:%s' % (e_lan)) for _edge_id in topology_edges: e3loger.debug('\t%s' % (topology_edges[_edge_id])) # #to improve the efficiency to search interfaces with lanzone/host #split interfaces list into these two maps. note this will ve used several times # lanzone_2_iface = dict() host_2_iface = dict() for _iface_id in interfaces: iface = interfaces[_iface_id] lanzone_id = iface.lanzone_id host_id = iface.host_id if lanzone_id not in lanzone_2_iface: lanzone_2_iface[lanzone_id] = set() assert (lanzone_id in lanzone_2_iface) lanzone_2_iface[lanzone_id].add(_iface_id) if host_id not in host_2_iface: host_2_iface[host_id] = set() assert (host_id in host_2_iface) host_2_iface[host_id].add(_iface_id) e3loger.debug('lanzone to interface mapping:') for lanzone_id in lanzone_2_iface: e3loger.debug(' lanzone id:%s' % (lanzone_id)) for iface_id in lanzone_2_iface[lanzone_id]: e3loger.debug(' %s' % (iface_id)) e3loger.debug('host to interface mapping:') for host_id in host_2_iface: e3loger.debug(' host id:%s' % (host_id)) for iface_id in host_2_iface[host_id]: e3loger.debug(' %s' % (iface_id)) # #setup intermediate variables # permanent_lanzone_set = dict() temporary_lanzone_set = list() unused_lanzone_set = set() _local_degree = dict() start_lanzone_id = None lanzone_host_iface_mapping = dict() #recover the environment to remuse the algorithm for _edge_id in topology_edges: edge = topology_edges[_edge_id] lanzone0_id = interfaces[edge.interface0].lanzone_id lanzone1_id = interfaces[edge.interface1].lanzone_id _local_degree[ lanzone0_id] = 1 if lanzone0_id not in _local_degree else _local_degree[ lanzone0_id] + 1 _local_degree[ lanzone1_id] = 1 if lanzone1_id not in _local_degree else _local_degree[ lanzone1_id] + 1 for _lanzone_id in _local_degree: if _local_degree[_lanzone_id] == 1: lanzone = lanzones[_lanzone_id] assert (lanzone.zone_type == E3VSWITCH_LAN_ZONE_TYPE_CUSTOMER) start_lanzone_id = _lanzone_id break if not start_lanzone_id: assert (len(initial_lanzones) > 1) start_lanzone_id = list(initial_lanzones)[-1] permanent_lanzone_set[start_lanzone_id] = (0, (None, None, None)) while True: _should_terminate = True for _edge_id in topology_edges: edge = topology_edges[_edge_id] lanzone0_id = interfaces[edge.interface0].lanzone_id lanzone1_id = interfaces[edge.interface1].lanzone_id host0_id = interfaces[edge.interface0].host_id host1_id = interfaces[edge.interface1].host_id if lanzone0_id not in lanzone_host_iface_mapping: lanzone_host_iface_mapping[lanzone0_id] = dict() if lanzone1_id not in lanzone_host_iface_mapping: lanzone_host_iface_mapping[lanzone1_id] = dict() lanzone_host_iface_mapping[lanzone0_id][host0_id] = edge.interface0 lanzone_host_iface_mapping[lanzone1_id][host1_id] = edge.interface1 if lanzone0_id in permanent_lanzone_set and lanzone1_id in permanent_lanzone_set: continue if lanzone0_id in permanent_lanzone_set: permanent_lanzone_set[lanzone1_id] = (0, (edge.interface1, host0_id, edge.interface0)) _should_terminate = False elif lanzone1_id in permanent_lanzone_set: permanent_lanzone_set[lanzone0_id] = (0, (edge.interface0, host1_id, edge.interface1)) _should_terminate = False if _should_terminate: break for _lanzone_id in _local_degree: assert (_lanzone_id in permanent_lanzone_set) #continue specify temporary and unused lanzone sets for _lanzone_id in lanzones: lanzone = lanzones[_lanzone_id] if _lanzone_id in permanent_lanzone_set: continue elif _lanzone_id in iResult['ban_lanzones']: unused_lanzone_set.add(_lanzone_id) elif lanzone.zone_type == E3VSWITCH_LAN_ZONE_TYPE_CUSTOMER and _lanzone_id not in iResult[ 'initial_lanzones']: unused_lanzone_set.add(_lanzone_id) else: temporary_lanzone_set.append(_lanzone_id) e3loger.debug('start lanzone id:%s' % (start_lanzone_id)) e3loger.debug('permanent lanzone set:%s' % (permanent_lanzone_set)) e3loger.debug('temporary lanzone set:%s' % (temporary_lanzone_set)) e3loger.debug('unused_lanzone_set:%s' % (unused_lanzone_set)) #recover the degree structure with existing topology edges g_degree = dict() for _edge_id in topology_edges: edge = topology_edges[_edge_id] lanzone0_id = interfaces[edge.interface0].lanzone_id lanzone1_id = interfaces[edge.interface1].lanzone_id g_degree[lanzone0_id] = 1 if lanzone0_id not in g_degree else g_degree[ lanzone0_id] + 1 g_degree[lanzone1_id] = 1 if lanzone1_id not in g_degree else g_degree[ lanzone1_id] + 1 #resume Prim's algorithm with current layout while True: _next_least_edge_weight = infinite_weight _next_lanzone_id = None _next_iface0_id = None _next_iface1_id = None _next_host_id = None for p_lanzone_id in permanent_lanzone_set: e3loger.debug('choose permanent lanzone:%s' % (p_lanzone_id)) #find the bottom half of the topology edge intermediate_host = dict() for _iface_id in lanzone_2_iface[p_lanzone_id]: if _iface_id in iResult['ban_interfaces']: continue iface = interfaces[_iface_id] if e_lan.link_type == E3NET_ETHER_SERVICE_LINK_EXCLUSIVE: if iface.interface_type != E3VSWITCH_INTERFACE_TYPE_EXCLUSIVE or iface_weight[ _iface_id] != 0: continue else: if iface.interface_type != E3VSWITCH_INTERFACE_TYPE_SHARED: continue if iface.host_id in iResult['ban_hosts']: continue if iface.lanzone_id in lanzone_host_iface_mapping and \ iface.host_id in lanzone_host_iface_mapping[iface.lanzone_id] and \ _iface_id != lanzone_host_iface_mapping[iface.lanzone_id][iface.host_id]: continue if iface.host_id not in intermediate_host: intermediate_host[iface.host_id] = _iface_id elif iface_weight[_iface_id] < iface_weight[intermediate_host[ iface.host_id]]: intermediate_host[iface.host_id] = _iface_id e3loger.debug('intermediate_host:%s' % (intermediate_host)) #find the top half of the topology edge intermediate_lanzone = dict() for _host_id in intermediate_host: host = hosts[_host_id] for _iface_id in host_2_iface[_host_id]: iface = interfaces[_iface_id] if _iface_id in iResult['ban_interfaces']: continue if iface.lanzone_id not in temporary_lanzone_set: continue if e_lan.link_type == E3NET_ETHER_SERVICE_LINK_EXCLUSIVE: if iface.interface_type != E3VSWITCH_INTERFACE_TYPE_EXCLUSIVE or iface_weight[ _iface_id] != 0: continue else: if iface.interface_type != E3VSWITCH_INTERFACE_TYPE_SHARED: continue if iface.lanzone_id in lanzone_host_iface_mapping and \ iface.host_id in lanzone_host_iface_mapping[iface.lanzone_id] and \ _iface_id != lanzone_host_iface_mapping[iface.lanzone_id][iface.host_id]: continue if iface.lanzone_id not in intermediate_lanzone: intermediate_lanzone[iface.lanzone_id] = ( _iface_id, _host_id, intermediate_host[_host_id]) elif iface_weight[_iface_id]+iface_weight[intermediate_host[_host_id]]< \ iface_weight[intermediate_lanzone[iface.lanzone_id][0]]+ \ iface_weight[intermediate_lanzone[iface.lanzone_id][2]]: intermediate_lanzone[iface.lanzone_id] = ( _iface_id, _host_id, intermediate_host[_host_id]) e3loger.debug('intermediate_lanzone:%s' % (intermediate_lanzone)) #find the least weighted topology edge for p_lanzone_id for _immediate_lanzone_id in intermediate_lanzone: iface0_id, host_id, iface1_id = intermediate_lanzone[ _immediate_lanzone_id] _edge_weight = iface_weight[iface0_id] + iface_weight[iface1_id] #prevent customer lanzone from being a immediate backbone lanzone #i.e. if the customer lanzone is already in the permanent lanzone set, #skip it. _iface1 = interfaces[iface1_id] if _iface1.lanzone_id in g_degree and \ lanzones[_iface1.lanzone_id].zone_type==E3VSWITCH_LAN_ZONE_TYPE_CUSTOMER \ and g_degree[_iface1.lanzone_id]==1: continue #two customer lanzones can not constitute a topology edge _iface0 = interfaces[iface0_id] if lanzones[_iface1.lanzone_id].zone_type==E3VSWITCH_LAN_ZONE_TYPE_CUSTOMER \ and lanzones[_iface0.lanzone_id].zone_type==E3VSWITCH_LAN_ZONE_TYPE_CUSTOMER: continue if not _next_lanzone_id or _edge_weight < _next_least_edge_weight: _next_lanzone_id = _immediate_lanzone_id _next_iface0_id = iface0_id _next_iface1_id = iface1_id _next_host_id = host_id _next_least_edge_weight = _edge_weight if not _next_lanzone_id: break #update g_degree for every edge if _next_lanzone_id not in g_degree: g_degree[_next_lanzone_id] = 1 else: g_degree[_next_lanzone_id] = g_degree[_next_lanzone_id] + 1 iface1 = interfaces[_next_iface1_id] if iface1.lanzone_id not in g_degree: g_degree[iface1.lanzone_id] = 1 else: g_degree[iface1.lanzone_id] = g_degree[iface1.lanzone_id] + 1 permanent_lanzone_set[_next_lanzone_id] = (_next_least_edge_weight, (_next_iface0_id, _next_host_id, _next_iface1_id)) if interfaces[ _next_iface0_id].lanzone_id not in lanzone_host_iface_mapping: lanzone_host_iface_mapping[ interfaces[_next_iface0_id].lanzone_id] = dict() if interfaces[ _next_iface1_id].lanzone_id not in lanzone_host_iface_mapping: lanzone_host_iface_mapping[ interfaces[_next_iface1_id].lanzone_id] = dict() lanzone_host_iface_mapping[interfaces[_next_iface0_id].lanzone_id][ interfaces[_next_iface0_id].host_id] = _next_iface0_id lanzone_host_iface_mapping[interfaces[_next_iface1_id].lanzone_id][ interfaces[_next_iface1_id].host_id] = _next_iface1_id temporary_lanzone_set.remove(_next_lanzone_id) e3loger.debug( 'add topology %s:%s' % (_next_lanzone_id, permanent_lanzone_set[_next_lanzone_id])) #remove redundant lanzones and edges while True: should_terminate = True degree = dict() for lanzone_id in permanent_lanzone_set: weight, path = permanent_lanzone_set[lanzone_id] iface0_id, host_id, iface1_id = path if not host_id: continue iface1 = interfaces[iface1_id] if lanzone_id not in degree: degree[lanzone_id] = 1 else: degree[lanzone_id] = degree[lanzone_id] + 1 if iface1.lanzone_id not in degree: degree[iface1.lanzone_id] = 1 else: degree[iface1.lanzone_id] = degree[iface1.lanzone_id] + 1 for lanzone_id in degree: lanzone = lanzones[lanzone_id] if degree[ lanzone_id] == 1 and lanzone.zone_type == E3VSWITCH_LAN_ZONE_TYPE_BACKBONE: del permanent_lanzone_set[lanzone_id] should_terminate = False if should_terminate: break for lanzone_id in permanent_lanzone_set: e3loger.debug('lanzone id:%s %s %s' % (lanzone_id, lanzones[lanzone_id].name, permanent_lanzone_set[lanzone_id])) iResult['permanent_lanzone_set'] = permanent_lanzone_set iResult['temporary_lanzone_set'] = temporary_lanzone_set iResult['start_lanzone_id'] = start_lanzone_id
def _create_ether_lan_topology(config, iResult): assert (len(iResult['initial_lanzones']) >= 2) iResult['operation'] = E_LAN_OPERATION_CREATION # #use Prim's algorithm to determine the minimum spanning tree aamong lanzones # e_lan = invt_get_vswitch_ether_service(iResult['service_id']) infinite_weight = 0x7fffffff lanzones = invt_list_vswitch_lan_zones() hosts = invt_list_vswitch_hosts() interfaces = invt_list_vswitch_interfaces() edges = invt_list_vswitch_topology_edges() iface_weight = dict() e3loger.debug('original lanzones set:') for lanzone_id in lanzones: e3loger.debug('\t%s' % (lanzones[lanzone_id])) e3loger.debug('original host set:') for host_id in hosts: e3loger.debug('\t%s' % (hosts[host_id])) e3loger.debug('original interface set:') for iface_id in interfaces: e3loger.debug('\t%s' % (interfaces[iface_id])) # #initialize the edge's weight #and calculate the weight of these interfaces which are already in the topology for iface_id in interfaces: iface_weight[iface_id] = 0 for edge_id in edges: edge = edges[edge_id] iface0 = edge.interface0 iface1 = edge.interface1 iface_weight[iface0] = iface_weight[iface0] + 1 iface_weight[iface1] = iface_weight[iface1] + 1 e3loger.debug('interface weight:') for iface_id in iface_weight: e3loger.debug('\t%s:%s' % (iface_id, iface_weight[iface_id])) # #remove the banned lanzones # for banned_lanzone in iResult['ban_lanzones']: assert (banned_lanzone in lanzones) e3loger.debug('banned lanzone:', banned_lanzone) # #remove the banned hosts # for banned_host in iResult['ban_hosts']: assert (banded_host in hosts) e3loger.debug('banned host:', banded_host) # #remove the banned Interface # for banned_iface in iResult['ban_interfaces']: assert (banned_iface in interfaces) e3loger.debug('banned interface:', banned_iface) # #to improve the efficiency to search interfaces with lanzone/host #split interfaces list into these two maps. note this will ve used several times # lanzone_2_iface = dict() host_2_iface = dict() for _iface_id in interfaces: iface = interfaces[_iface_id] lanzone_id = iface.lanzone_id host_id = iface.host_id if lanzone_id not in lanzone_2_iface: lanzone_2_iface[lanzone_id] = set() assert (lanzone_id in lanzone_2_iface) lanzone_2_iface[lanzone_id].add(_iface_id) if host_id not in host_2_iface: host_2_iface[host_id] = set() assert (host_id in host_2_iface) host_2_iface[host_id].add(_iface_id) e3loger.debug('lanzone to interface mapping:') for lanzone_id in lanzone_2_iface: e3loger.debug(' lanzone id:%s' % (lanzone_id)) for iface_id in lanzone_2_iface[lanzone_id]: e3loger.debug(' %s' % (iface_id)) e3loger.debug('host to interface mapping:') for host_id in host_2_iface: e3loger.debug(' host id:%s' % (host_id)) for iface_id in host_2_iface[host_id]: e3loger.debug(' %s' % (iface_id)) # #setup intermediate variables # permanent_lanzone_set = dict() temporary_lanzone_set = list() unused_lanzone_set = set() start_lanzone_id = config['initial_lanzones'][0] for lanzone_id in lanzones: lanzone = lanzones[lanzone_id] if lanzone.zone_type==E3VSWITCH_LAN_ZONE_TYPE_CUSTOMER and \ lanzone_id not in iResult['initial_lanzones']: unused_lanzone_set.add(lanzone_id) elif lanzone_id == start_lanzone_id: permanent_lanzone_set[lanzone_id] = (0, (None, None, None)) else: temporary_lanzone_set.append(lanzone_id) e3loger.debug('start lanzone id:%s' % (start_lanzone_id)) e3loger.debug('permanent lanzone set:%s' % (permanent_lanzone_set)) e3loger.debug('temporary lanzone set:%s' % (temporary_lanzone_set)) e3loger.debug('unused_lanzone_set:%s' % (unused_lanzone_set)) # #enter main loop of Prim'a algorithm #for each iteration, find the edge with least weight among all temporary neighbors debug_counter = 0 g_degree = dict() while True: _next_least_edge_weight = infinite_weight _next_lanzone_id = None _next_iface0_id = None _next_iface1_id = None _next_host_id = None e3loger.debug('enter round %s' % (debug_counter)) debug_counter = debug_counter + 1 for p_lanzone_id in permanent_lanzone_set: e3loger.debug('choose permanent lanzone:%s' % (p_lanzone_id)) #find the bottom half of the topology edge intermediate_host = dict() for _iface_id in lanzone_2_iface[p_lanzone_id]: if _iface_id in iResult['ban_interfaces']: continue iface = interfaces[_iface_id] if iface.host_id in iResult['ban_hosts']: continue if e_lan.link_type == E3NET_ETHER_SERVICE_LINK_EXCLUSIVE: if iface.interface_type!=E3VSWITCH_INTERFACE_TYPE_EXCLUSIVE or \ iface_weight[_iface_id]!=0: continue else: if iface.interface_type != E3VSWITCH_INTERFACE_TYPE_SHARED: continue if iface.host_id not in intermediate_host: intermediate_host[iface.host_id] = _iface_id elif iface_weight[_iface_id] < iface_weight[intermediate_host[ iface.host_id]]: intermediate_host[iface.host_id] = _iface_id e3loger.debug('intermediate_host:%s' % (intermediate_host)) #find the top half of the topology edge intermediate_lanzone = dict() for _host_id in intermediate_host: host = hosts[_host_id] for _iface_id in host_2_iface[_host_id]: iface = interfaces[_iface_id] if iface.lanzone_id not in temporary_lanzone_set or \ iface.lanzone_id in iResult['ban_lanzones']: continue if e_lan.link_type == E3NET_ETHER_SERVICE_LINK_EXCLUSIVE: if iface.interface_type!=E3VSWITCH_INTERFACE_TYPE_EXCLUSIVE or \ iface_weight[_iface_id]!=0: continue else: if iface.interface_type != E3VSWITCH_INTERFACE_TYPE_SHARED: continue if iface.lanzone_id not in intermediate_lanzone: intermediate_lanzone[iface.lanzone_id] = ( _iface_id, _host_id, intermediate_host[_host_id]) elif iface_weight[_iface_id]+iface_weight[intermediate_host[_host_id]]< \ iface_weight[intermediate_lanzone[iface.lanzone_id][0]]+ \ iface_weight[intermediate_lanzone[iface.lanzone_id][2]]: intermediate_lanzone[iface.lanzone_id] = ( _iface_id, _host_id, intermediate_host[_host_id]) e3loger.debug('intermediate_lanzone:%s' % (intermediate_lanzone)) #find the least weighted topology edge for p_lanzone_id for _immediate_lanzone_id in intermediate_lanzone: iface0_id, host_id, iface1_id = intermediate_lanzone[ _immediate_lanzone_id] _edge_weight = iface_weight[iface0_id] + iface_weight[iface1_id] #prevent customer lanzone from being a immediate backbone lanzone #i.e. if the customer lanzone is already in the permanent lanzone set, #skip it. _iface1 = interfaces[iface1_id] if _iface1.lanzone_id in g_degree and \ lanzones[_iface1.lanzone_id].zone_type==E3VSWITCH_LAN_ZONE_TYPE_CUSTOMER and \ g_degree[_iface1.lanzone_id]==1: continue #two customer lanzones can not constitute a topology edge _iface0 = interfaces[iface0_id] if lanzones[_iface1.lanzone_id].zone_type==E3VSWITCH_LAN_ZONE_TYPE_CUSTOMER and \ lanzones[_iface0.lanzone_id].zone_type==E3VSWITCH_LAN_ZONE_TYPE_CUSTOMER: continue if not _next_lanzone_id or \ _edge_weight<_next_least_edge_weight: _next_lanzone_id = _immediate_lanzone_id _next_iface0_id = iface0_id _next_iface1_id = iface1_id _next_host_id = host_id _next_least_edge_weight = _edge_weight if not _next_lanzone_id: break #update g_degree for every edge if _next_lanzone_id not in g_degree: g_degree[_next_lanzone_id] = 1 else: g_degree[_next_lanzone_id] = g_degree[_next_lanzone_id] + 1 iface1 = interfaces[_next_iface1_id] if iface1.lanzone_id not in g_degree: g_degree[iface1.lanzone_id] = 1 else: g_degree[iface1.lanzone_id] = g_degree[iface1.lanzone_id] + 1 permanent_lanzone_set[_next_lanzone_id] = (_next_least_edge_weight, (_next_iface0_id, _next_host_id, _next_iface1_id)) temporary_lanzone_set.remove(_next_lanzone_id) e3loger.debug( 'add topology %s:%s' % (_next_lanzone_id, permanent_lanzone_set[_next_lanzone_id])) # #remove those backbones to which no customer lanzones are attached, #we call these lanzones orphaned while True: should_terminate = True degree = dict() for lanzone_id in permanent_lanzone_set: weight, path = permanent_lanzone_set[lanzone_id] iface0_id, host_id, iface1_id = path if not host_id: continue iface1 = interfaces[iface1_id] if lanzone_id not in degree: degree[lanzone_id] = 1 else: degree[lanzone_id] = degree[lanzone_id] + 1 if iface1.lanzone_id not in degree: degree[iface1.lanzone_id] = 1 else: degree[iface1.lanzone_id] = degree[iface1.lanzone_id] + 1 for lanzone_id in degree: lanzone = lanzones[lanzone_id] if degree[ lanzone_id] == 1 and lanzone.zone_type == E3VSWITCH_LAN_ZONE_TYPE_BACKBONE: del permanent_lanzone_set[lanzone_id] should_terminate = False if should_terminate: break for lanzone_id in permanent_lanzone_set: e3loger.debug('lanzone id:%s %s %s' % (lanzone_id, lanzones[lanzone_id].name, permanent_lanzone_set[lanzone_id])) iResult['permanent_lanzone_set'] = permanent_lanzone_set iResult['temporary_lanzone_set'] = temporary_lanzone_set iResult['start_lanzone_id'] = start_lanzone_id
def _remove_lanzones_from_ether_lan(config, iResult): iResult['service_id'] = config['service_id'] assert (iResult['operation'] == E_LAN_OPERATION_REMOVAL) e_lan = invt_get_vswitch_ether_service(config['service_id']) lanzones = invt_list_vswitch_lan_zones() hosts = invt_list_vswitch_hosts() interfaces = invt_list_vswitch_interfaces() edges = invt_list_vswitch_topology_edges() topology_edges = dict() #filter the topology edge with the given service ID for _edge_id in edges: edge = edges[_edge_id] if edge.service_id == e_lan.id: topology_edges[_edge_id] = edge e3loger.debug('existing topology edges for service:%s' % (e_lan)) for _edge_id in topology_edges: e3loger.debug('\t%s' % (topology_edges[_edge_id])) #recover the algorithm environment permanent_lanzone_set = dict() _local_degree = dict() start_lanzone_id = None for _edge_id in topology_edges: edge = topology_edges[_edge_id] lanzone0_id = interfaces[edge.interface0].lanzone_id lanzone1_id = interfaces[edge.interface1].lanzone_id _local_degree[ lanzone0_id] = 1 if lanzone0_id not in _local_degree else _local_degree[ lanzone0_id] + 1 _local_degree[ lanzone1_id] = 1 if lanzone1_id not in _local_degree else _local_degree[ lanzone1_id] + 1 for _lanzone_id in _local_degree: if _local_degree[_lanzone_id] == 1: lanzone = lanzones[_lanzone_id] assert (lanzone.zone_type == E3VSWITCH_LAN_ZONE_TYPE_CUSTOMER) start_lanzone_id = _lanzone_id break assert (start_lanzone_id) permanent_lanzone_set[start_lanzone_id] = (0, (None, None, None)) while True: _should_terminate = True for _edge_id in topology_edges: edge = topology_edges[_edge_id] lanzone0_id = interfaces[edge.interface0].lanzone_id lanzone1_id = interfaces[edge.interface1].lanzone_id if lanzone0_id in permanent_lanzone_set and lanzone1_id in permanent_lanzone_set: continue if lanzone0_id in permanent_lanzone_set: host_id = interfaces[edge.interface0].host_id permanent_lanzone_set[lanzone1_id] = (0, (edge.interface1, host_id, edge.interface0)) _should_terminate = False elif lanzone1_id in permanent_lanzone_set: host_id = interfaces[edge.interface1].host_id permanent_lanzone_set[lanzone0_id] = (0, (edge.interface0, host_id, edge.interface1)) _should_terminate = False if _should_terminate: break for _lanzone_id in _local_degree: assert (_lanzone_id in permanent_lanzone_set) for _lanzone_id in iResult['initial_lanzones']: lanzone = lanzones[_lanzone_id] assert (lanzone.zone_type == E3VSWITCH_LAN_ZONE_TYPE_CUSTOMER) #in case the lanzone which is to be deleted are not in the topology assert (_lanzone_id in permanent_lanzone_set) deleted_path = list() #remove those lanzones that are supposed to be trimmed #before removing the redundant backbone lanzones, remove those lanzones in iResult.initial_lanzones for _lanzone_id in iResult['initial_lanzones']: weight, path = permanent_lanzone_set[_lanzone_id] iface0_id, host_id, iface1_id = path if not host_id: #special case that this lanzone previously is chosen as the source adjacent_lanzone_id = None for __lanzone_id in permanent_lanzone_set: __weight, __path = permanent_lanzone_set[__lanzone_id] __iface0_id, __host_id, __iface1_id = __path if not __host_id: continue __adjacent_lanzone0_id = interfaces[__iface0_id].lanzone_id __adjacent_lanzone1_id = interfaces[__iface1_id].lanzone_id assert (__adjacent_lanzone0_id == __lanzone_id) if __adjacent_lanzone1_id == _lanzone_id: adjacent_lanzone_id = __adjacent_lanzone0_id break assert (adjacent_lanzone_id) __, __path = permanent_lanzone_set[adjacent_lanzone_id] __iface0_id, __host_id, __iface1_id = __path deleted_path.append([__iface0_id, __iface1_id]) del permanent_lanzone_set[_lanzone_id] permanent_lanzone_set[adjacent_lanzone_id] = (0, (None, None, None)) start_lanzone_id = adjacent_lanzone_id else: lanzone0_id = interfaces[iface0_id].lanzone_id assert (lanzone0_id == _lanzone_id) deleted_path.append([iface0_id, iface1_id]) del permanent_lanzone_set[lanzone0_id] #remove those unused backbone lanzones while True: should_terminate = True degree = dict() for _lanzone_id in permanent_lanzone_set: _weight, _path = permanent_lanzone_set[_lanzone_id] _iface0_id, host_id, iface1_id = _path if not host_id: continue _iface1 = interfaces[iface1_id] degree[_lanzone_id] = 1 if _lanzone_id not in degree else degree[ _lanzone_id] + 1 degree[ _iface1. lanzone_id] = 1 if _iface1.lanzone_id not in degree else degree[ _iface1.lanzone_id] + 1 for _lanzone_id in degree: lanzone = lanzones[_lanzone_id] if degree[ _lanzone_id] == 1 and lanzone.zone_type == E3VSWITCH_LAN_ZONE_TYPE_BACKBONE: _, _path = permanent_lanzone_set[_lanzone_id] _iface0_id, host_id, _iface1_id = _path #bookmark here to replace the target lanzone entry if it's the start lanzone id if not host_id: adjacent_lanzone_id = None for __lanzone_id in permanent_lanzone_set: __, __path = permanent_lanzone_set[__lanzone_id] __iface0_id, __host_id, __iface1_id = __path if not __host_id: continue __adjacent_lanzone0_id = interfaces[ __iface0_id].lanzone_id __adjacent_lanzone1_id = interfaces[ __iface1_id].lanzone_id assert (__adjacent_lanzone0_id == __lanzone_id) if __adjacent_lanzone1_id == _lanzone_id: adjacent_lanzone_id = __adjacent_lanzone0_id break assert (adjacent_lanzone_id) __, __path = permanent_lanzone_set[adjacent_lanzone_id] __iface0_id, __host_id, __iface1_id = __path deleted_path.append([__iface0_id, __iface1_id]) del permanent_lanzone_set[_lanzone_id] permanent_lanzone_set[adjacent_lanzone_id] = (0, (None, None, None)) start_lanzone_id = adjacent_lanzone_id else: deleted_path.append([_iface0_id, _iface1_id]) del permanent_lanzone_set[_lanzone_id] should_terminate = False if should_terminate: break iResult['permanent_lanzone_set'] = permanent_lanzone_set iResult['start_lanzone_id'] = start_lanzone_id iResult['deleted_path'] = deleted_path
def _validate_ether_lan_topology(config, iResult): lanzones = invt_list_vswitch_lan_zones() hosts = invt_list_vswitch_hosts() interfaces = invt_list_vswitch_interfaces() start_lanzone_id = iResult['start_lanzone_id'] permanent_lanzone_set = iResult['permanent_lanzone_set'] initial_lanzone_set = iResult['initial_lanzones'] e_lan = invt_get_vswitch_ether_service(iResult['service_id']) iface_type = E3VSWITCH_INTERFACE_TYPE_EXCLUSIVE if e_lan.link_type != E3NET_ETHER_SERVICE_LINK_EXCLUSIVE: iface_type = E3VSWITCH_INTERFACE_TYPE_SHARED degree = dict() for lanzone_id in permanent_lanzone_set: weight, path = permanent_lanzone_set[lanzone_id] iface0_id, host_id, iface1_id = path if not host_id: continue iface0 = interfaces[iface0_id] iface1 = interfaces[iface1_id] host = hosts[host_id] assert (iface0.interface_type == iface_type) assert (iface1.interface_type == iface_type) assert (iface0.host_id == host_id) assert (iface1.host_id == host_id) assert (iface0.lanzone_id == lanzone_id) if iface0.lanzone_id not in degree: degree[iface0.lanzone_id] = 1 else: degree[iface0.lanzone_id] = degree[iface0.lanzone_id] + 1 if iface1.lanzone_id not in degree: degree[iface1.lanzone_id] = 1 else: degree[iface1.lanzone_id] = degree[iface1.lanzone_id] + 1 for lanzone_id in degree: lanzone = lanzones[lanzone_id] if lanzone.zone_type == E3VSWITCH_LAN_ZONE_TYPE_CUSTOMER: assert (degree[lanzone_id] == 1) else: assert (degree[lanzone_id] > 1) if iResult['operation'] == E_LAN_OPERATION_ADDITION or \ iResult['operation'] == E_LAN_OPERATION_CREATION: for lanzone_id in initial_lanzone_set: assert (lanzone_id in permanent_lanzone_set) elif iResult['operation'] == E_LAN_OPERATION_REMOVAL: for lanzone_id in initial_lanzone_set: assert (lanzone_id not in permanent_lanzone_set) #check whether a circle present #by search the path in Depth First manner vertext = dict() for _lanzone_id in permanent_lanzone_set: _, _path = permanent_lanzone_set[_lanzone_id] _iface0_id, _host_id, _iface1_id = _path if not _host_id: continue _lanzone0_id = interfaces[_iface0_id].lanzone_id _lanzone1_id = interfaces[_iface1_id].lanzone_id if _lanzone0_id not in vertext: vertext[_lanzone0_id] = set() vertext[_lanzone0_id].add(_lanzone1_id) if _lanzone1_id not in vertext: vertext[_lanzone1_id] = set() vertext[_lanzone1_id].add(_lanzone0_id) e3loger.debug('adjacency matrix:%s' % (vertext)) assert (start_lanzone_id in vertext) used = set() path_stack = list() path_stack.append(start_lanzone_id) used.add(start_lanzone_id) e3loger.debug('circle tedection: push lanzone:%s' % (start_lanzone_id)) next_lanzone_id = None while len(path_stack): current_lanzone_id = path_stack[-1] neighbors = vertext[current_lanzone_id] next_lanzone_id = None for _lanzone_id in neighbors: if _lanzone_id not in used: next_lanzone_id = _lanzone_id break if next_lanzone_id: assert (next_lanzone_id not in path_stack) path_stack.append(next_lanzone_id) used.add(next_lanzone_id) e3loger.debug('circle tedection: push lanzone:%s' % (next_lanzone_id)) else: poped_lanzone_id = path_stack.pop() e3loger.debug('circle tedection: pop lanzone:%s' % (poped_lanzone_id)) if iResult['operation'] == E_LAN_OPERATION_ADDITION or \ iResult['operation'] == E_LAN_OPERATION_CREATION: for _lanzone_id in initial_lanzone_set: assert (_lanzone_id in used) elif iResult['operation'] == E_LAN_OPERATION_REMOVAL: for _lanzone_id in initial_lanzone_set: assert (_lanzone_id not in used)
def _create_ether_line_topology(config, iResult): #if it's a solo customer lan zone,it's a NULL graphic if len(iResult['initial_lanzones']) == 1: return assert (len(iResult['initial_lanzones']) == 2) assert (len(config['initial_lanzones']) == 2) e_line = invt_get_vswitch_ether_service(iResult['service_id']) # #using Dijkstra Algorithm to determine the shortest path #between the two customer lan zones. # #let the tuple lanzone_id:<path_wright,<downstream_iface,host(vswitch),upstream_iface>> to #denote the lanzone-2-lanzone graphic edge infinite_weight = 0x7fffffff lanzones = invt_list_vswitch_lan_zones() hosts = invt_list_vswitch_hosts() interfaces = invt_list_vswitch_interfaces() edges = invt_list_vswitch_topology_edges() iface_weight = dict() permanent_lanzone_set = dict() permanent_host_set = list() temporary_lanzone_set = dict() start_lanzone = config['initial_lanzones'][0] end_lanzone = config['initial_lanzones'][1] # #initialize the edge's weight #and calculate the weight of these interfaces which are already in the topology for iface_id in interfaces: iface_weight[iface_id] = 0 for edge_id in edges: edge = edges[edge_id] iface0 = edge.interface0 iface1 = edge.interface1 iface_weight[iface0] = iface_weight[iface0] + 1 iface_weight[iface1] = iface_weight[iface1] + 1 # #remove the banned lanzones # for banned_lanzone in iResult['ban_lanzones']: assert (banned_lanzone in lanzones) e3loger.debug('banned lanzone:', banned_lanzone) # #remove the banned hosts # for banned_host in iResult['ban_hosts']: assert (banded_host in hosts) e3loger.debug('banned host:', banded_host) # #remove the banned Interface # for banned_iface in iResult['ban_interfaces']: assert (banned_iface in interfaces) e3loger.debug('banned interface:', banned_iface) # #initialize the temporary lanzone set, #with the format:lanzone_id:<path_wright,<iface0,node,iface1>> # for lanzone_id in lanzones: if lanzone_id != start_lanzone: temporary_lanzone_set[lanzone_id] = (infinite_weight, (None, None, None)) else: temporary_lanzone_set[lanzone_id] = (0, (None, None, None)) # #to improve the efficiency to search interfaces with lanzone/host #split interfaces list into these two maps. note this will ve used several times # lanzone_2_iface = dict() host_2_iface = dict() for _iface_id in interfaces: iface = interfaces[_iface_id] lanzone_id = iface.lanzone_id host_id = iface.host_id if lanzone_id not in lanzone_2_iface: lanzone_2_iface[lanzone_id] = set() assert (lanzone_id in lanzone_2_iface) lanzone_2_iface[lanzone_id].add(_iface_id) if host_id not in host_2_iface: host_2_iface[host_id] = set() assert (host_id in host_2_iface) host_2_iface[host_id].add(_iface_id) # #main loop to find shortest path fpr E-LINE service # while True: #find a lanzone from temporary lanzone set with least path weight target_lanzone_id = None for lanzone_id in temporary_lanzone_set: weight, path = temporary_lanzone_set[lanzone_id] if weight >= infinite_weight: continue if not target_lanzone_id: target_lanzone_id = lanzone_id elif temporary_lanzone_set[target_lanzone_id][0] > weight: target_lanzone_id = lanzone_id if not target_lanzone_id: break #now target_lanzone_id is the one that should go to permanent lanzone set weight, path = temporary_lanzone_set[target_lanzone_id] iface0, host, iface1 = path permanent_host_set.append(host) permanent_lanzone_set[target_lanzone_id] = (weight, path) del temporary_lanzone_set[target_lanzone_id] if target_lanzone_id == end_lanzone: break #update all the neighbors(which are still in the temporary set)' weight p_lanzone_id = target_lanzone_id #find the possible hosts in the path, and record their weight along with interfaces intermediate_host = dict() for _iface_id in lanzone_2_iface[p_lanzone_id]: if _iface_id in iResult['ban_interfaces']: continue iface = interfaces[_iface_id] if iface.host_id in permanent_host_set or \ iface.host_id in iResult['ban_hosts']: continue if e_line.link_type == E3NET_ETHER_SERVICE_LINK_EXCLUSIVE: if iface.interface_type!=E3VSWITCH_INTERFACE_TYPE_EXCLUSIVE or \ iface_weight[_iface_id]!=0: continue else: if iface.interface_type != E3VSWITCH_INTERFACE_TYPE_SHARED: continue if iface.host_id not in intermediate_host: intermediate_host[iface.host_id] = _iface_id elif iface_weight[_iface_id] < iface_weight[intermediate_host[ iface.host_id]]: intermediate_host[iface.host_id] = _iface_id #until now, the first part of the edge composition is finished #next ro do is to find the possible next lanzone in the path intermediate_lanzone = dict() for _host_id in intermediate_host: assert (_host_id not in permanent_host_set) host = hosts[_host_id] for _iface_id in host_2_iface[_host_id]: iface = interfaces[_iface_id] if iface.lanzone_id not in temporary_lanzone_set or \ iface.lanzone_id in iResult['ban_lanzones']: continue if e_line.link_type == E3NET_ETHER_SERVICE_LINK_EXCLUSIVE: if iface.interface_type!=E3VSWITCH_INTERFACE_TYPE_EXCLUSIVE or \ iface_weight[_iface_id]!=0: continue else: if iface.interface_type != E3VSWITCH_INTERFACE_TYPE_SHARED: continue if iface.lanzone_id not in intermediate_lanzone: intermediate_lanzone[iface.lanzone_id] = ( _iface_id, _host_id, intermediate_host[_host_id]) elif iface_weight[_iface_id]+iface_weight[intermediate_host[_host_id]]< \ iface_weight[intermediate_lanzone[iface.lanzone_id][0]]+ \ iface_weight[intermediate_lanzone[iface.lanzone_id][2]]: intermediate_lanzone[iface.lanzone_id] = ( _iface_id, _host_id, intermediate_host[_host_id]) #until now,let's update the neighbours's weight along with previous path for _lanzone_id in intermediate_lanzone: iface0_id = intermediate_lanzone[_lanzone_id][0] host_id = intermediate_lanzone[_lanzone_id][1] iface1_id = intermediate_lanzone[_lanzone_id][2] iface1 = interfaces[iface1_id] edge_weight = iface_weight[iface0_id] + iface_weight[iface1_id] _prev_lanzone_id = iface1.lanzone_id assert (_prev_lanzone_id == target_lanzone_id) _prev_weight, _ = permanent_lanzone_set[_prev_lanzone_id] _neighbor_weight, _ = temporary_lanzone_set[_lanzone_id] if _neighbor_weight > (_prev_weight + edge_weight): temporary_lanzone_set[_lanzone_id] = (_prev_weight + edge_weight, (iface0_id, host_id, iface1_id)) #dump the calculation footprint e3loger.debug('permanent lanzone set:') for lanzone_id in permanent_lanzone_set: weight, path = permanent_lanzone_set[lanzone_id] iface0, host, iface1 = path e3loger.debug('\tlanzone_id:%s' % (lanzone_id) + ':<weight:%d,<iface0:%s,host:%s,iface1:%s>>' % (weight, iface0, host, iface1)) e3loger.debug('temporary lanzone set:') for lanzone_id in temporary_lanzone_set: weight, path = temporary_lanzone_set[lanzone_id] iface0, host, iface1 = path e3loger.debug('\tlanzone_id:%s' % (lanzone_id) + ':<weight:%d,<iface0:%s,host:%s,iface1:%s>>' % (weight, iface0, host, iface1)) e3loger.debug('permanent host set:') for host_id in permanent_host_set: e3loger.debug('\thost_id:%s' % (host_id)) iResult['permanent_lanzone_set'] = permanent_lanzone_set iResult['temporary_lanzone_set'] = temporary_lanzone_set iResult['permanent_host_set'] = permanent_host_set