示例#1
0
def db_update_ether_service(service_id):
    agent = get_host_agent()
    ether_service_stub = get_stub(agent.current_controller,
                                  agent.controller_port,
                                  ether_service_rpc_service)
    session = db_sessions[DB_NAME]()
    try:
        ether_service_guard.write_lock()
        session.begin()
        local_service = session.query(agent_ether_service).filter(
            agent_ether_service.id == service_id).first()
        if local_service:
            return local_service.clone()
        local_service = agent_ether_service()
        shadow_service = rpc_client_get_ether_service(ether_service_stub,
                                                      service_id)
        local_service.id = shadow_service.id
        local_service.name = shadow_service.name
        local_service.service_type = shadow_service.service_type
        local_service.tenant_id = shadow_service.tenant_id
        local_service.created_at = shadow_service.created_at
        local_service.link_type = shadow_service.link_type
        session.add(local_service)
        session.commit()
        return local_service.clone()
    finally:
        session.close()
        ether_service_guard.write_unlock()
def synchronize_topology_label(iResult):
    agent = get_host_agent()
    local_host_id = agent.vswitch_host.id
    interface_neighbor_mapping = iResult['interface_neighbor_mapping']
    host_interface_mappping = iResult['host_interface_mappping']
    rechability_mapping = iResult['rechability_mapping']
    service_id = iResult['service_id']
    service = iResult['service']
    interfaces = iResult['interfaces']
    lanzones = iResult['lanzones']
    hosts = iResult['hosts']
    edges = iResult['edges']
    interfaces_in_topology = [iface for iface in interface_neighbor_mapping if \
        interfaces[iface].host_id == local_host_id]
    backbone_interfaces = list()
    for _iface_id in interfaces_in_topology:
        _iface = interfaces[_iface_id]
        _lanzone_id = _iface.lanzone_id
        _lanzone = lanzones[_lanzone_id]
        if _lanzone.zone_type == E3VSWITCH_LAN_ZONE_TYPE_CUSTOMER:
            continue
        backbone_interfaces.append(_iface_id)
    labels_in_vswitch = db_list_topology_labels(service_id)
    labels_to_apply = dict()
    for _lanzone_id in rechability_mapping:
        _nexthop = rechability_mapping[_lanzone_id]
        _lanzone = lanzones[_lanzone_id]
        if _lanzone.zone_type == E3VSWITCH_LAN_ZONE_TYPE_BACKBONE:
            continue
        for _adjacent_iface_id in backbone_interfaces:
            if _adjacent_iface_id == _nexthop:
                continue
            neighbor = get_topology_neighbor_by_interfaces(_adjacent_iface_id,
                interface_neighbor_mapping[_adjacent_iface_id])
            label = db_update_topology_label(customer_lanzone = _lanzone_id,
                interface_id = _adjacent_iface_id,
                neighbor_id = neighbor.id,
                direction = LABEL_DIRECTION_INGRESS,
                service_id = service_id)
            labels_to_apply[label.id] = label
    for _iface_id in backbone_interfaces:
        neighbor = get_topology_neighbor_by_interfaces(_iface_id,
            interface_neighbor_mapping[_iface_id])
        label = db_update_topology_label(customer_lanzone = DUMMY_MULTICAST_LANZONE,
            interface_id = _iface_id,
            neighbor_id = neighbor.id,
            direction = LABEL_DIRECTION_INGRESS,
            service_id = service_id)
        labels_to_apply[label.id] = label
    labels_to_add = dict()
    labels_to_del = dict()
    for _label_id in labels_to_apply:
        if _label_id not in [label.id for label in labels_in_vswitch]:
            labels_to_add[_label_id] = labels_to_apply[_label_id]
    for _label in labels_in_vswitch:
        if _label.id not in list(labels_to_apply.keys()):
            labels_to_del[_label.id] = _label
    print('labels to add :', labels_to_add)
    print('labels to del :', labels_to_del)
def retrieve_topology_elements(service_id, iResult):
    agent = get_host_agent()
    topology_edge_stub = get_stub(agent.current_controller,
        agent.controller_port,
        topology_edge_rpc_service)
    vswitch_interface_stub = get_stub(agent.current_controller,
        agent.controller_port,
        vswitch_interface_rpc_service)
    vswitch_lanzone_stub = get_stub(agent.current_controller,
        agent.controller_port,
        vswitch_lanzone_rpc_service)
    vswitch_host_stub = get_stub(agent.current_controller,
        agent.controller_port,
        vswitch_host_rpc_service)
    e3loger.info('applying service: %s' % (service_id))
    _edges = rpc_client_list_topology_edges_for_services(topology_edge_stub, [service_id])
    edges = {_edge.id : _edge for _edge in _edges}

    _iface_list = set()
    _ifaces = list()
    for _edge_id in edges:
        _edge = edges[_edge_id]
        _iface_list.add(_edge.interface0)
        _iface_list.add(_edge.interface1)
    if len(_iface_list):
        _ifaces = rpc_client_list_vswitch_interfaces(vswitch_interface_stub, _iface_list)
    ifaces = {_iface.id : _iface for _iface in _ifaces}

    _lanzone_list = set()
    _host_list = set()
    _lanzones = list()
    _hosts = list()
    for _iface_id in ifaces:
        _iface = ifaces[_iface_id]
        _lanzone_list.add(_iface.lanzone_id)
        _host_list.add(_iface.host_id)
    if len(_lanzone_list):
        _lanzones = rpc_client_list_vswitch_lanzones(vswitch_lanzone_stub, uuid_list = _lanzone_list)
    lanzones = {_lanzone.id : _lanzone for _lanzone in _lanzones}
    if len(_host_list):
        _hosts = rpc_client_list_vswitch_hosts(vswitch_host_stub, uuid_list = _host_list)
    hosts = {_host.id : _host for _host in _hosts}
    iResult['edges'] = edges
    iResult['interfaces'] = ifaces
    iResult['lanzones'] = lanzones
    iResult['hosts'] = hosts
    iResult['service_id'] = service_id
    iResult['service'] = db_update_ether_service(service_id)
def resolve_rechability_information(iResult):
    edges = iResult['edges']
    lanzones = iResult['lanzones']
    interfaces = iResult['interfaces']
    hosts = iResult['hosts']
    agent = get_host_agent()
    initial_edge_id = None
    local_host_id = agent.vswitch_host.id
    local_iface_ids = [agent.interfaces[_iface_name].vswitch_interface.id \
        for _iface_name in agent.interfaces]
    #map lanzone to interfaces
    lanzone_to_interface = dict()
    for _edge_id in edges:
        _edge = edges[_edge_id]
        _iface0_id = _edge.interface0
        _iface1_id = _edge.interface1
        _lanzone0_id = interfaces[_iface0_id].lanzone_id
        _lanzone1_id = interfaces[_iface1_id].lanzone_id
        if _lanzone0_id not in lanzone_to_interface:
            lanzone_to_interface[_lanzone0_id] = set()
        if _lanzone1_id not in lanzone_to_interface:
            lanzone_to_interface[_lanzone1_id] = set()
        lanzone_to_interface[_lanzone0_id].add(_iface0_id)
        lanzone_to_interface[_lanzone1_id].add(_iface1_id)
    #hostinterface_mapping
    host_interface_mappping = dict()
    for _edge_id in edges:
        _edge = edges[_edge_id]
        _iface0_id = _edge.interface0
        _iface1_id = _edge.interface1
        assert (interfaces[_iface0_id].host_id == interfaces[_iface1_id].host_id)
        _host_id = interfaces[_iface0_id].host_id
        if not initial_edge_id and local_host_id == _host_id:
            initial_edge_id = _edge_id
        if _host_id not in host_interface_mappping:
            host_interface_mappping[_host_id] = set()
        host_interface_mappping[_host_id].add(_iface0_id)
        host_interface_mappping[_host_id].add(_iface1_id)
    #interfaces neighbor mapping
    interface_neighbor_mapping = dict()
    for _lanzone_id in lanzone_to_interface:
        if len(lanzone_to_interface[_lanzone_id]) == 1:
            continue
        assert (len(lanzone_to_interface[_lanzone_id]) == 2)
        iface_lst = list(lanzone_to_interface[_lanzone_id])
        _iface0_id = iface_lst[0]
        _iface1_id = iface_lst[1]
        interface_neighbor_mapping[_iface0_id] = _iface1_id
        interface_neighbor_mapping[_iface1_id] = _iface0_id
    for _iface_id in interface_neighbor_mapping:
        _iface = interfaces[_iface_id]
        if _iface.host_id == local_host_id:
            register_topology_neighbor(_iface_id, interface_neighbor_mapping[_iface_id])
    #calculate the reachability information
    rechability_mapping = dict()
    used_edges = set()
    iface_stack = list()
    assert(initial_edge_id)
    used_edges.add(initial_edge_id)
    initial_edge = edges[initial_edge_id]
    initial_iface0_id = initial_edge.interface0
    initial_iface1_id = initial_edge.interface1
    lanzone0_id = interfaces[initial_iface0_id].lanzone_id
    lanzone1_id = interfaces[initial_iface1_id].lanzone_id
    rechability_mapping[lanzone0_id] = initial_iface0_id
    rechability_mapping[lanzone1_id] = initial_iface1_id
    iface_stack.append(initial_iface0_id)
    iface_stack.append(initial_iface1_id)
    next_iface = None
    while len(iface_stack):
        current_iface = iface_stack.pop()
        if interfaces[current_iface].host_id == local_host_id:
            next_iface = current_iface
        #find a free edge which is connected to current_iface
        current_lanzone = interfaces[current_iface].lanzone_id
        next_edge = None
        for _edge_id in edges:
            if _edge_id in used_edges:
                continue
            _edge = edges[_edge_id]
            _iface0_id = _edge.interface0
            _iface1_id = _edge.interface1
            _lanzone0_id = interfaces[_iface0_id].lanzone_id
            _lanzone1_id = interfaces[_iface1_id].lanzone_id
            if current_lanzone == _lanzone0_id or \
                current_lanzone == _lanzone1_id:
                next_edge = _edge
                break
        if next_edge:
            used_edges.add(next_edge.id)
            iface0_id = next_edge.interface0
            iface1_id = next_edge.interface1
            lanzone0_id = interfaces[iface0_id].lanzone_id
            lanzone1_id = interfaces[iface1_id].lanzone_id
            if lanzone0_id == current_lanzone:
                iface_stack.append(iface0_id)
                iface_stack.append(iface1_id)
                rechability_mapping[lanzone1_id] = iface1_id if \
                    interfaces[iface1_id].host_id == local_host_id else \
                    next_iface
            elif lanzone1_id == current_lanzone:
                iface_stack.append(iface1_id)
                iface_stack.append(iface0_id)
                rechability_mapping[lanzone0_id] = iface0_id if \
                    interfaces[iface0_id].host_id == local_host_id else \
                    next_iface
            else:
                assert(False)
    nexthop_ifaces = set(rechability_mapping.values())
    for _iface_id in nexthop_ifaces:
        assert (_iface_id in local_iface_ids)
    for lanzone_id in rechability_mapping:
        lanzone = lanzones[lanzone_id]
        if lanzone.zone_type == E3VSWITCH_LAN_ZONE_TYPE_BACKBONE:
            assert (rechability_mapping[lanzone_id] in interface_neighbor_mapping)
    iResult['interface_neighbor_mapping'] = interface_neighbor_mapping
    iResult['rechability_mapping'] = rechability_mapping
    iResult['host_interface_mappping'] = host_interface_mappping
def e3neta_agent_connect():
    agent = get_host_agent()
    if agent.connected == True:
        return
    vswitch_host_stub = get_stub(agent.current_controller,
                                 agent.controller_port, 'vswitch_host')
    vswitch_iface_stub = get_stub(agent.current_controller,
                                  agent.controller_port, 'vswitch_interface')
    vswitch_lanzone_stub = get_stub(agent.current_controller,
                                    agent.controller_port, 'vswitch_lanzone')
    vswitch_host = None
    vswitch_ifaces = None
    try:
        vswitch_host = rpc_client_get_vswitch_host(vswitch_host_stub,
                                                   agent.hostname, False)
    except grpc.RpcError as e:
        e3neta_intercept_exception(agent, e)
        if e.user_error and e.user_exception == E3_EXCEPTION_NOT_FOUND:
            vswitch_host = rpc_client_register_vswitch_host(
                vswitch_host_stub,
                name=agent.hostname,
                host_ip=agent.local_ip,
                description=agent.description,
                host_status=E3VSWITCH_HOST_STATUS_ACTIVE)
    assert (vswitch_host)
    if agent.hostname != vswitch_host.name or \
        agent.local_ip != vswitch_host.host_ip or \
        agent.description != vswitch_host.description or \
        vswitch_host.host_status != E3VSWITCH_HOST_STATUS_ACTIVE:
        vswitch_host = rpc_client_update_vswitch_host(
            vswitch_host_stub,
            uuid=vswitch_host.id,
            name=agent.hostname,
            host_ip=agent.local_ip,
            description=agent.description,
            host_status=E3VSWITCH_HOST_STATUS_ACTIVE)
    agent.vswitch_host = vswitch_host
    vswitch_ifaces = rpc_client_list_vswitch_interfaces_for_hosts(
        vswitch_iface_stub, [vswitch_host.id])
    local_devs = {
        agent.interfaces[_iface].dev_address: agent.interfaces[_iface]
        for _iface in agent.interfaces
    }
    registered_devs = list()
    for viface in vswitch_ifaces:
        assert (viface.host_id == vswitch_host.id)
        if viface.dev_address in local_devs:
            local_dev = local_devs[viface.dev_address]
            registered_devs.append(viface.dev_address)
            lanzone = rpc_client_get_vswitch_lanzone(
                vswitch_lanzone_stub, local_devs[viface.dev_address].lanzone,
                False)
            iface = viface
            if viface.interface_type != local_dev.iface_type or \
                viface.lanzone_id != lanzone.id or \
                viface.interface_status != E3VSWITCH_INTERFACE_STATUS_ACTIVE:
                iface = rpc_client_update_vswitch_interface(
                    vswitch_iface_stub,
                    viface.id,
                    interface_status=E3VSWITCH_INTERFACE_STATUS_ACTIVE,
                    interface_type=local_dev.iface_type,
                    lanzone_id=lanzone.id)
            for _iface in agent.interfaces:
                if agent.interfaces[_iface].dev_address == viface.dev_address:
                    agent.interfaces[_iface].vswitch_interface = iface
        else:
            #delete the viface if it's not in local-dev list
            rpc_client_unregister_vswitch_interface(vswitch_iface_stub,
                                                    viface.id)
    #register those who are not registered yet
    for dev in local_devs:
        if dev in registered_devs:
            continue
        lanzone = rpc_client_get_vswitch_lanzone(vswitch_lanzone_stub,
                                                 local_devs[dev].lanzone,
                                                 False)
        iface = rpc_client_register_vswitch_interface(
            vswitch_iface_stub,
            host_id=vswitch_host.id,
            dev_address=dev,
            lanzone_id=lanzone.id,
            interface_status=E3VSWITCH_INTERFACE_STATUS_ACTIVE,
            interface_type=local_devs[dev].iface_type)
        for _iface in agent.interfaces:
            if agent.interfaces[_iface].dev_address == dev:
                agent.interfaces[_iface].vswitch_interface = iface