Skip to main content
Glama

NetBrain MCP

by NorthLaneMS
topology_discovery.cpython-312.pyc33.7 kB
� �C1h�o����ddlmZmZmZmZmZmZddlmZm Z ddl m Z ddl Z ddl Z ddlZddlZddlZddlZddlmZmZddlZGd�de j*�Ze j.e j0de j2e j4� �g� �e j6j8D]-Zeee j2�s�ej?ed���/e j@d �Z!dd l"m#Z#m$Z$m%Z%m&Z&dd l'm(Z(Gd�de �Z)Gd�de �Z*eGd�d��Z+eGd�d��Z,eGd�d��Z-eGd�d��Z.Gd�d�Z/de#de(de/fd�Z0y) �)�Dict�List�Optional�Any�Set�Tuple)� dataclass�field)�EnumN)�datetime� timedeltac�*��eZdZd�fd� Z�fd�Z�xZS)� JsonFormatterc�(��t�|�|||�y)N)�super�__init__)�self�fmt�datefmt�style� __class__s ��$F:\NetBrainMCP\topology_discovery.pyrzJsonFormatter.__init__s��� ����g�u�-�c�f��t�|�|�}|jdd��jd�S)N�utf-8�replace)�errors)r�format�encode�decode)r�record� log_recordrs �rrzJsonFormatter.formats2����W�^�F�+� �� � ��� �;�B�B�7�K�Kr)NN�%)�__name__� __module__� __qualname__rr� __classcell__)rs@rrrs���.�L�Lrrz4%(asctime)s - %(name)s - %(levelname)s - %(message)s)�stream)�levelr�handlers�topology_discovery)� DeviceManager� NetworkDevice� DeviceVendor� DeviceType)�ConnectionManagerc��eZdZdZdZdZdZy)�TopologyProtocolu拓扑发现协议枚举�cdp�lldp�unknownN)r$r%r&�__doc__�CDP�LLDP�UNKNOWN�rrr2r2)s��"� �C� �D��Grr2c�$�eZdZdZdZdZdZdZdZy)�ConnectionTypeu连接类型枚举�ethernet�serial�trunk�accessr5N) r$r%r&r6�ETHERNET�SERIAL�TRUNK�ACCESSr9r:rrr<r</s����H� �F� �E� �F��Grr<c���eZdZUdZeed<dZeeed<dZeeed<dZ eeed<dZ eed<dZ eed <dZ eeed <dZ eeed <dZeeed <d eeeffd�Zy)� InterfaceInfou 接口信息�nameN� description� ip_address� mac_addressr5�status�protocol�speed�duplex�vlan�returnc ���|j|j|j|j|j|j |j |j|jd� S)N� rGrHrIrJrKrLrMrNrOrR�rs r�to_dictzInterfaceInfo.to_dictDsO���I�I��+�+��/�/��+�+��k�k�� � ��Z�Z��k�k��I�I�  � r)r$r%r&r6�str�__annotations__rHrrIrJrKrLrMrNrOrrrTr:rrrFrF7s���� �I�!%�K��#��%� $�J��� �$�!%�K��#��%��F�C���H�c���E�8�C�=�� �F�H�S�M� ��D�(�3�-��  ��c�3�h��  rrFc���eZdZUdZeed<eed<eed<eed<ejZeed<e jZ e ed<e e j��Ze ed <e e j��Ze ed <d eeeffd �Zy )� TopologyLinku 拓扑链路�source_device_id�source_interface�target_device_id�target_interfacerL�connection_type��default_factory� discovered_at� last_seenrPc ��|j|j|j|j|jj |j j |jj�|jj�d�S)N�rYrZr[r\rLr]r`ra) rYrZr[r\rL�valuer]r`� isoformatrarSs rrTzTopologyLink.to_dict]sn�� $� 5� 5� $� 5� 5� $� 5� 5� $� 5� 5�� � �+�+�#�3�3�9�9�!�/�/�9�9�;����1�1�3�  � rN)r$r%r&r6rUrVr2r9rLr<r]r r �nowr`rarrrTr:rrrXrXQsx�����������!1�!9�!9�H��9�&4�&<�&<�O�^�<�#�H�L�L�A�M�8�A��� � �=�I�x�=�  ��c�3�h��  rrXc���eZdZUdZeed<eed<eed<eed<eed<ee��Ze e ed<d Z e e eefed <eej ��Zeed <eej ��Zeed <d e eeffd�Zy )� TopologyNodeu 拓扑节点� device_id� device_name� device_type�vendorrIr^� interfacesN�positionr`rarPc �H�|j|j|j|j|j|j D�cgc]}|j ���c}|j|jj�|jj�d� Scc}w)N� rirjrkrlrIrmrnr`ra) rirjrkrlrIrmrTrnr`rera)r�ifaces rrTzTopologyNode.to_dictvs~������+�+��+�+��k�k��/�/�8<���H��u�5�=�=�?��H�� � �!�/�/�9�9�;����1�1�3�  � �� Is�B)r$r%r&r6rUrVr �listrmrrFrnrr�floatr rfr`rarrTr:rrrhrhis�����N����� �K��O�&+�D�&A�J��]�#�A�+/�H�h�t�C��J�'�(�/�#�H�L�L�A�M�8�A��� � �=�I�x�=�  ��c�3�h��  rrhc���eZdZUdZee��Zeee fe d<ee ��Z e ee d<dZeee d<ee ��Ze ee d<de fd �Zd efd �Zd ed e efd�Zd eeeffd�Zy)�NetworkTopologyu 网络拓扑r^�nodes�linksN�last_discovery�discovery_scope�nodec�6�||j|j<y)u 添加节点N)rvri)rrzs r�add_nodezNetworkTopology.add_node�s��%)�� � �4�>�>�"r�linkc�P�|jD]|}|j|jk(s�|j|jk(s�7|j|jk(s�Q|j|jk(s�k|j |_y|jj |�y)u 添加链路N)rwrYrZr[r\ra�append)rr}� existing_links r�add_linkzNetworkTopology.add_link�s���"�Z�Z�M��.�.�$�2G�2G�G��.�.�$�2G�2G�G��.�.�$�2G�2G�G��.�.�$�2G�2G�G�*.�.�.� �'��(� � � ���$�rrirPc���t�}|jD]X}|j|k(r|j|j��.|j|k(s�>|j|j��Zt |�S)u#获取设备的邻居设备ID列表)�setrwrY�addr[rr)rri� neighborsr}s r�get_device_neighborsz$NetworkTopology.get_device_neighbors�sc���E� ��J�J�D��$�$� �1�� � �d�3�3�4��&�&�)�3�� � �d�3�3�4� � �I��rc�F�|jj�D��cic]\}}||j���c}}|jD�cgc]}|j���c}|jr|jj �nd|j d�Scc}}wcc}w)N)rvrwrxry)rv�itemsrTrwrxrery)r�node_idrzr}s rrTzNetworkTopology.to_dict�s���CG�:�:�CS�CS�CU�V�CU�-�'�4�g�t�|�|�~�-�CU�V�15���<���d�l�l�n��<�AE�AT�AT�d�1�1�;�;�=�Z^�#�3�3�  � ��V��<s �B� B)r$r%r&r6r �dictrvrrUrhrVrrrwrrXrxrr ryr|r�r�rrTr:rrruru�s����%*�4�%@�E�4��\�!� "�@� %�d� ;�E�4� � �;�)-�N�H�X�&�-�!&�t�!<�O�T�#�Y�<�*�\�*�  �\�  ��c��d�3�i�� ��c�3�h�� rruc �X�eZdZdZdedefd�Zd�Zd�Zde e de fd �Z d e dee ee efe effd �Zd e de efd �Zd e dede efd�Zd e de ee effd�Zd e de ee effd�Zd e de ee effd�Zd e dede ee effd�Zdee efdee fd�Zde fd�Zd�Zy)�TopologyDiscoveryu拓扑发现引擎�device_manager�connection_managerc� �||_||_t�|_d|_t j j|jd�|_t j|jd��|j�y)N�dataz topology.jsonT)�exist_ok) r�r�ru�topology�data_dir�os�path�join� topology_file�makedirs� load_topology)rr�r�s rrzTopologyDiscovery.__init__�s`��,���"4���'�)�� ��� ��W�W�\�\�$�-�-��I��� � � �D�M�M�D�1� ���rc�b� t|jdd��5}tj|jj �|dd��ddd�t jd|j���y#1swY�,xYw#t$r"}t jd |���Yd}~yd}~wwxYw) u保存拓扑数据到文件�wr��encodingF�)� ensure_ascii�indentNu拓扑数据已保存到: u保存拓扑数据失败: ) �openr��json�dumpr�rT�logger�info� Exception�error)r�f�es r� save_topologyzTopologyDiscovery.save_topology�s��� ;��d�(�(�#��@�A�� � �$�-�-�/�/�1�1�5�QR�S�A� �K�K�4�T�5G�5G�4H�I� J�A�@��� ;� �L�L�5�a�S�9� :� :�� ;�s.�B�2A7� *B�7B�<B� B.� B)�)B.c��tjj|j�stj d�y t |jdd��5}tj|�}ddd�t�|_ jdi�j�D]�\}}g}|jdg�D]}|jtdi|����t|d|d |d |d |d ||jd �t!j"|d�t!j"|d��� }|jj%|���|jdg�D]�}t'|d|d|d|dt)|d�t+|d�t!j"|d�t!j"|d���} |jj-| ���|jd�r't!j"|d�|j_|jdg�|j_tj dt3|jj4��dt3|jj6��d��y#1swY��2xYw#t8$r"} tj;d| ���Yd} ~ yd} ~ wwxYw) u从文件加载拓扑数据u3拓扑数据文件不存在,将创建新的拓扑N�rrr�rvrmrirjrkrlrIrnr`rarprwrYrZr[r\rLr]rcrxryu已加载拓扑数据:� 个节点,� 条链路u加载拓扑数据失败: r:)r�r��existsr�r�r�r�r��loadrur��getr�rrFrhr � fromisoformatr|rXr2r<r�rxry�lenrvrwr�r�) rr�r�r�� node_datarm� iface_datarz� link_datar}r�s rr�zTopologyDiscovery.load_topology�s����w�w�~�~�d�0�0�1� �K�K�M� N� �/ ;��d�(�(�#��@�A��y�y��|��A�,�-�D�M�'+�h�h�w��&;�&A�&A�&C�"���� �"+�-�-� �b�"A�J��%�%�m�&A�j�&A�B�#B�$�'� �4� )�-� 8� )�-� 8�$�X�.�(��6�)�&�]�]�:�6�"*�"8�"8��?�9S�"T�&�4�4�Y�{�5K�L� ��� � �&�&�t�,�!'D�&"�X�X�g�r�2� �#�%.�/A�%B�%.�/A�%B�%.�/A�%B�%.�/A�%B�-�i� �.C�D�$2�9�=N�3O�$P�"*�"8�"8��?�9S�"T�&�4�4�Y�{�5K�L� ��� � �&�&�t�,�3��x�x�(�)�/7�/E�/E�d�K[�F\�/]�� � �,�,0�H�H�5F��,K�D�M�M� )� �K�K�2�3�t�}�}�7J�7J�3K�2L�L�Y\�]a�]j�]j�]p�]p�Yq�Xr�r{�|� }�YA�@��Z� ;� �L�L�5�a�S�9� :� :�� ;�s1�J,�J�/H/J,�J)�$J,�, K�5K�K� device_idsrPc ��PK�tjdt|��d��t�}t|�}||j_|�r�|j �}||vr�tjd|���|jj|�}|stjd|����f |j|��d{���\}}t|j|j|jj|j j|j"|��}|jj%|�|D]�} |j'| ��d{���} | s�t)|| j+dd�| j| j+d d�t-| j+d d ��� �} |jj/| �| j|vs��|j1| j���|j1|�tjd |j�dt|��d��|r���t7j8�|j_|j=�tjdt|jj>��dt|jj@��d��|jS7��7��~#t2$r@} tj5d|j�d| ���|j1|�Yd} ~ ��d} ~ wwxYw�w)u!从指定设备开始发现拓扑u 开始从u个设备发现拓扑u正在发现设备拓扑: u设备不存在: N)rirjrkrlrIrm�local_interface��remote_interfacerLr5)rYrZr[r\rL�设备 u 发现完成,找到 � 个邻居� 发现设备 u 拓扑失败: u拓扑发现完成:r�r�)!r�r�r�r�r�ry�popr�� get_device�warning�discover_device_neighborsrh�idrGrkrdrlrIr|�find_or_create_neighbor_devicerXr�r2r�r�r�r�r rfrxr�rvrw) rr��discovered_devices�pending_devices�current_device_id�devicer�rmrz� neighbor_info�neighbor_devicer}r�s r�discover_topology_from_devicesz0TopologyDiscovery.discover_topology_from_devicess������ � �i��J��0�0E�F�G� �U���j�/��)3�� � �%�� /� 3� 3� 5� � �$6�6�� �K�K�4�5F�4G�H� I��(�(�3�3�4E�F�F�����!2�3D�2E�F�G��& :�.2�.L�.L�V�.T�(T�%� �:�$�$�i�i� &� � � &� 2� 2� 8� 8�!�=�=�.�.�%�0�0�)� ��� � �&�&�t�,�&/�M�,0�,O�,O�P]�,^�&^�O�&�+�->�-:�->�->�?P�RT�-U�-<�-?�-?�-:�->�->�?Q�SU�-V�%5�m�6G�6G� �T]�6^�%_�  ��� � �.�.�t�4�+�-�-�5G�G�+�/�/��0B�0B�C�&/�"#�&�&�'8�9�� � �g�f�k�k�]�2I�#�i�.�IY�Yc�d�e�a�n(0�|�|�~�� � �$� ����� � �+�C�� � �0C�0C�,D�+E�\�RU�VZ�Vc�Vc�Vi�Vi�Rj�Qk�kt�u�v��}�}��[)U��'_��&� :�� � �}�V�[�[�M����L�M�"�&�&�'8�9�9�� :�sj�B/L&�2K�K�BK�K�K�!A<K�AK�;L&�?BL&�K�K� L#�#6L�L&�L#�#L&r�c��tK�g}g}d}|jr%|jj|j�}|s'tj d|j �d��||fS |j j||��d{���\}}|satj d|j �d|���||f|j j|j|j��d{���S|j||��d{���}|jtjk(rW|j||��d{���}|j||��d{���}|j!|�|j!|�nt|jtj"k(r,|j||��d{���}|j!|�n+|j||��d{���}|j!|�|j j|j|j��d{���||fS7���7��G7��/7��7��7��7�`#t$$r/} tj d|j �d| ���Yd} ~ ��d} ~ wwxYw7�T#|j j|j|j��d{���7wxYw�w)u!发现单个设备的邻居信息Nr�u 没有关联的凭据u 连接设备 u 失败: r�u 邻居失败: )� credential_idr��get_credentialr�r�rGr��connect_device�disconnect_devicer��get_device_interfacesrlr.�CISCO�discover_cdp_neighbors�discover_lldp_neighbors�extend�HUAWEIr�) rr�r�rm� credential�successr�� cdp_neighbors�lldp_neighborsr�s rr�z+TopologyDiscovery.discover_device_neighborsIs_����� �� �� � � � ��,�,�;�;�F�<P�<P�Q�J�� �L�L�7�6�;�;�-�/E�F� G��j�(� (� V�#'�#:�#:�#I�#I�&�R\�#]�]�N�G�U��� � �}�V�[�[�M��5�'�J�K� �*�,�.�)�)�;�;�F�I�I�z�}�}�U� U� U�) $�9�9�&�*�M�M�J��}�}� � 2� 2�2�&*�&A�&A�&�*�&U� U� �'+�'C�'C�F�J�'W�!W��� � ��/�� � ��0����,�"5�"5�5�'+�'C�'C�F�J�'W�!W��� � ��0�(,�'C�'C�F�J�'W�!W��� � ��0� �)�)�;�;�F�I�I�z�}�}�U� U� U��*�$�$�9^��4 V��)N��!V��!W��"X��"X��� J� �L�L�=���� �_�Q�C�H� I� I�� J�� V��$�)�)�;�;�F�I�I�z�}�}�U� U� U�s��A!J8�$H=�H,�1H=�53J8�(H/�)J8�.H=�H2�6H=�:H5�;H=�H7�AH=�.H9�/+H=�H;�H=�03J8�#I8�$J8�,H=�/J8�2H=�5H=�7H=�9H=�;H=�= I5�%I0�+I:�0I5�5I:�8J8�:4J5�.J1�/J5�5J8c��K�g} |jtjk(rd}n"|jtjk(rd}nd}|jj |j |j |d���d{���\}}|rc|jrW|j|j|j�}tjd|j�dt|��d��|Stjd |j�d |��� |S7��#t$r0}tj!d |j�d |���Yd}~|Sd}~wwxYw�w) u获取设备接口信息zshow ip interface briefzdisplay ip interface brief�<��timeoutNr�u 发现 u 个接口� 获取设备 u 接口信息失败: u 接口信息异常: )rlr.r�r�r�� send_commandr�r��parse_interface_info�outputr�r�rGr�r�r�r�)rr�r�rm�command�resultr�r�s rr�z'TopologyDiscovery.get_device_interfacesws4����� � P��}�}� � 2� 2�2�3�����,�"5�"5�5�6��3��"&�"9�"9�"F�"F�� � �:�=�=�'�2�#G�#��M�F�E��&�.�.�!�6�6�v�}�}�f�m�m�T� �� � �g�f�k�k�]�(�3�z�?�:K�:�V�W��� ����v�{�{�m�;P�QV�PW�X�Y� ����� P� �L�L�=���� �5J�1�#�N� O� O���� P��N�E�A8D�>D�?A*D�)E�+%D�E�D� E�%E �E� E�Er�rlc �|�g} |j�jd�}|tjk(r�|ddD]z}|j�s�|j d�r�&|j�}t |�dk\s�Et |d|ddk7r|dnd|d|d � �}|j|��| |S|tjk(r�|D]�}|j�s�|j d �r�&|j d�r�8|j�}t |�d k\s�Wt |dt |�dkDr |dd k7r|dndt |�dkDr|dndt |�d kDr|d nd� �}|j|���|S#t$r#}tjd|���Yd}~|Sd}~wwxYw)u解析接口信息输出� �N�-�r� unassigned��)rGrIrKrL� Interface�z--r�r5u解析接口信息失败: ) �strip�splitr.r�� startswithr�rFrr�r�r�r�) rr�rlrm�lines�line�parts� interfacer�s rr�z&TopologyDiscovery.parse_interface_info�s���� � ;��L�L�N�(�(��.�E���+�+�+�!�!�"�I�D��z�z�|�D�O�O�C�,@� $� � � ���u�:��?�(5�%*�1�X�7<�Q�x�<�7O�5��8�UY�',�Q�x�).�q�� )�I� '�-�-�i�8�&�8��#�<�.�.�.�!�D��z�z�|�D�O�O�K�,H�QU�Q`�Q`�ad�Qe� $� � � ���u�:��?�(5�%*�1�X�7:�5�z�A�~�%�PQ�(�VZ�JZ�5��8�`d�36�u�:��>�u�Q�x�y�58��Z�!�^��q��� )�I� '�-�-�i�8�"����� ;� �L�L�5�a�S�9� :� :���� ;�sI�A F�F�!F�8F�;(F�$F�6F�F�'A&F� F;�F6�6F;c�� K�g} |jj|j|jdd���d{���\}}|rX|jrL|j |j �}t jd|j�dt|��d��|St jd|j�d |��� |S7��#t$r0}t jd |j�d |���Yd}~|Sd}~wwxYw�w) u发现CDP邻居zshow cdp neighbors detailr�r�Nr�u 通过CDP发现 r�r�u CDP邻居失败: r�u CDP邻居异常: ) r�r�r�r��parse_cdp_neighborsr�r�r�rGr�r�r�r�)rr�r�r�r�r�r�s rr�z(TopologyDiscovery.discover_cdp_neighbors�s������ � M�"&�"9�"9�"F�"F�� � �:�=�=�*E�r�#G�#��M�F�E��&�.�.� �4�4�V�]�]�C� �� � �g�f�k�k�]�2C�C� �N�CS�S]�^�_��� ����v�{�{�m�;M�e�W�U�V� ����� M� �L�L�=���� �5G��s�K� L� L���� M�sK�D�6C�C�AC�D�%C�D�C� D�%C<�6D�<D�Dc��g} tjd|�}|D�] }d|vs� ddi}tjd|�}|r|jd�|d<tjd|�}|r|jd�|d <tjd |�}|r"|jd�j �|d <tjd |�} | r| jd�|d <tjd|�} | r| jd�|d<d|vs��|j |��� |S#t $r#} tjd| ���Yd} ~ |Sd} ~ wwxYw)u解析CDP邻居信息z-{20,}z Device ID:rLr3zDevice ID:\s*(\S+)r�riz"IP address:\s*(\d+\.\d+\.\d+\.\d+)rIzPlatform:\s*([^,]+)�platformzInterface:\s*(\S+)r�z"Port ID \(outgoing port\):\s*(\S+)r�u解析CDP邻居信息失败: N) �rer��search�groupr�rr�r�r�) rr�r��entries�entry�neighbor�device_id_match�ip_match�platform_match�local_int_match�remote_int_matchr�s rr�z%TopologyDiscovery.parse_cdp_neighbors�si��� �% >��h�h�y�&�1�G� ���5�(� *�E�2�H�')�i�i�0E�u�&M�O�&�0?�0E�0E�a�0H���-� "�y�y�)N�PU�V�H��19����1B���.�&(�Y�Y�/E�u�%M�N�%�/=�/C�/C�A�/F�/L�/L�/N���,�')�i�i�0E�u�&M�O�&�6E�6K�6K�A�6N��!2�3�(*�y�y�1V�X]�'^�$�'�7G�7M�7M�a�7P��!3�4�"�h�.�!�(�(��2�=!�F���� >� �L�L�8���<� =� =���� >�s#� D/�C2D/�D/�/ E�8E�Ec��K�g} |jtjk(rd}n"|jtjk(rd}nd}|jj |j |j |d���d{���\}}|rc|jrW|j|j|j�}tjd|j�dt|��d��|Stjd |j�d |��� |S7��#t$r0}tj!d |j�d |���Yd}~|Sd}~wwxYw�w) u发现LLDP邻居zshow lldp neighbors detailzdisplay lldp neighbor verboser�r�Nr�u 通过LLDP发现 r�r�u LLDP邻居失败: r�u LLDP邻居异常: )rlr.r�r�r�r�r�r��parse_lldp_neighborsr�r�r�rGr�r�r�r�)rr�r�r�r�r�r�r�s rr�z)TopologyDiscovery.discover_lldp_neighbors�s4����� � N��}�}� � 2� 2�2�6�����,�"5�"5�5�9��6��"&�"9�"9�"F�"F�� � �:�=�=�'�2�#G�#��M�F�E��&�.�.� �5�5�f�m�m�V�]�]�S� �� � �g�f�k�k�]�2D�S��^�DT�T^�_�`��� ����v�{�{�m�;N�u�g�V�W� ����� N� �L�L�=���� �5H���L� M� M���� N�r�c���g} |tjk(�rtjd|�}|ddD]�}ddi}tjd|�}|r"|j d�j �|d<tjd|�}|r"|j d�j �|d <tjd |�} | r"| j d�j �|d <tjd |�} | r| j d�|d <d |vs��|j|��� |S|tjk(�rtjd|�}|ddD]�}ddi}tjd|�}|r|j d�|d<tjd|�}|r"|j d�j �|d <tjd|�} | r"| j d�j �|d <tjd|�} | r| j d�|d <d |vs��|j|���|S#t$r#} tjd| ���Yd} ~ |Sd} ~ wwxYw)u解析LLDP邻居信息z Local Intf:r�NrLr4z ^([^\n]+)r�zSystem Name:\s*([^\n]+)rizPort id:\s*([^\n]+)r�z2Management Addresses:\s*IP:\s*(\d+\.\d+\.\d+\.\d+)rIz!LLDP neighbor-information of portz(\S+):zSystem name\s*:\s*([^\n]+)zPort ID\s*:\s*([^\n]+)z-Management address\s*:\s*(\d+\.\d+\.\d+\.\d+)u解析LLDP邻居信息失败: ) r.r�r�r�r�r�r�rr�r�r�r�) rr�rlr�r�r�rr�sys_name_match� port_id_match�mgmt_addr_matchr�s rrz&TopologyDiscovery.parse_lldp_neighborssu��� �> ?���+�+�+��(�(�>�6�:��$�Q�R�[�E� *�F�3�H�')�i�i� �e�&D�O�&�6E�6K�6K�A�6N�6T�6T�6V��!2�3�&(�Y�Y�/I�5�%Q�N�%�0>�0D�0D�Q�0G�0M�0M�0O���-�%'�I�I�.D�e�$L�M�$�7D�7J�7J�1�7M�7S�7S�7U��!3�4�')�i�i�0e�gl�&m�O�&�1@�1F�1F�q�1I���.�"�h�.�!�(�(��2�1)�v��C�<�.�.�.��(�(�#G��P��$�Q�R�[�E� *�F�3�H�')�i�i� �5�&A�O�&�6E�6K�6K�A�6N��!2�3�&(�Y�Y�/L�e�%T�N�%�0>�0D�0D�Q�0G�0M�0M�0O���-�%'�I�I�.G��$O�M�$�7D�7J�7J�1�7M�7S�7S�7U��!3�4�')�i�i�0`�bg�&h�O�&�1@�1F�1F�q�1I���.�"�h�.�!�(�(��2�1)�:���� ?� �L�L�9�!��=� >� >���� ?�s+�DI �I �/DI �6I � I7�I2�2I7r�c��pK�|jd�r5|jj�D]}|j|dk(s�|cS|jdd�}|jj�D]}|j|k(s�|cS|jd��rddlm}m}m}m }ddl }|j} |jdd�j�} d| vr |j} nd | vr |j} |t|j!��|xsd |d��|d|j| |jdd�|j"d |jd d ��d���} |jj%| �t&j)d| j�d| j�d��| Sy�w)u查找或创建邻居设备rIrir�r)r-r/r.� DeviceStatusNr��cisco�huaweizUnknown-u 通过拓扑发现自动创建 (rLr5�))r�rGrIrkrlr�rKrHu创建新的邻居设备: z ()r�r�� list_devicesrIrG�network_devicesr-r/r.r �uuid�OTHER�lowerr�r�rU�uuid4r9� add_devicer�r�) rr�r�rir-r/r.r rrlr�� new_devices rr�z0TopologyDiscovery.find_or_create_neighbor_device^s����� � � �\� *��-�-�:�:�<���$�$� �l�(C�C�!�M�=� "�%�%�k�2�6� ��)�)�6�6�8�F��{�{�i�'�� �9� � � �\� *� ]� ]� �"�'�'�F�$�(�(��R�8�>�>�@�H��(�"�%�+�+���X�%�%�,�,��&��t�z�z�|�$��J�H�]�<�-H�,I�"J�(��6�&�,�,��&�*�*�:�r�:�#�+�+�>�}�?P�?P�Q[�]f�?g�>h�hi�j� �J� � � � *� *�:� 6� �K�K�4�Z�_�_�4E�R� �H]�H]�G^�^_�`� a�� ��s�AF6�AF6�D.F6c��|jS)u获取当前拓扑)r�rSs r� get_topologyzTopologyDiscovery.get_topology�s ���}�}�rc�l�t�|_|j�tj d�y)u清空拓扑数据u拓扑数据已清空N)rur�r�r�r�rSs r�clear_topologyz TopologyDiscovery.clear_topology�s%��'�)�� � ����� � �+�,rN)r$r%r&r6r,r0rr�r�rrUrur�r-rrrrFr�r�r.r�r�r�r�rrr�rrr:rrr�r��s���� �}� �J[� �;�5;�nG�t�C�y�G�_�G�R,%�m�,%��d�SW�X[�]`�X`�Sa�Nb�dh�iv�dw�Nw�Hx�,%�\�-��PT�Ub�Pc��8%�3�%� �%��m�I\�%�N�=��QU�VZ�[^�`c�[c�Vd�Qe��*+�#�+�$�t�C��H�~�2F�+�Z�M��RV�W[�\_�ad�\d�We�Rf��8D�3�D� �D��d�SV�X[�S[�n�I]�D�L+�$�s�C�x�.�+�U]�^k�Ul�+�Z�o��-rr�r�r�rPc��t||�S)u创建拓扑发现引擎实例)r�)r�r�s r�create_topology_discoveryr�s�� �^�-?� @�@r)1�typingrrrrrr� dataclassesr r �enumr �logging�sysr�r�r��asyncior r � ipaddress� Formatterr� basicConfig�INFO� StreamHandler�stdout�rootr*�handler� isinstance� setFormatter� getLoggerr�rr,r-r.r/�device_connectorr0r2r<rFrXrhrur�rr:rr�<module>r1st��8�8�(��� � � � ��(��L�G�%�%�L����� �,�,� A�����S�Z�Z�0����|�|�$�$�G��'�7�0�0�1����]�+a�b�c�%� �� � �/� 0��R�R�.��t�� �T�� � � � � �2 � � � � �. � � � � �2 �* �* � �* �Xc-�c-�LA�m�A�Qb�A�gx�Ar

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/NorthLaneMS/NetBrain_MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server