跳转到主要内容

Python库,用于解析网络拓扑数据(例如:动态路由协议、NetJSON、CNML)并检测变更。

项目描述

CI build status https://coveralls.io/repos/openwisp/netdiff/badge.svg Dependency monitoring https://img.shields.io/gitter/room/nwjs/nw.js.svg?style=flat-square https://badge.fury.io/py/netdiff.svg downloads code style: black

Netdiff是一个简单的抽象层,用于解析开源动态路由协议或任何其他具有网络拓扑知识网络软件的网络拓扑数据。

它的目标是允许像openwisp-network-topology这样的应用程序收集、可视化和监控网络拓扑数据,而无需处理检索数据每个网络软件的详细信息。

特性:

https://raw.githubusercontent.com/openwisp/openwisp2-docs/master/assets/design/openwisp-logo-black.svg

从PyPI安装稳定版本

从PyPI安装

pip install netdiff

安装开发版本

安装tar包

pip install https://github.com/openwisp/netdiff/tarball/master

或者您也可以通过pip使用git进行安装

pip install -e git+git://github.com/openwisp/netdiff#egg=netdiff

如果您想贡献,请安装您克隆的分支

git clone git@github.com:<your_fork>/netdiff.git
cd netdiff
python setup.py develop

基本用法示例

计算OLSR 0.6.x拓扑的diff

from netdiff import OlsrParser
from netdiff import diff

old = OlsrParser(file="./stored-olsr.json")
new = OlsrParser(url="http://127.0.0.1:9090")
diff(old, new)

或者,您也可以使用减法运算符

from netdiff import OlsrParser
from netdiff import diff

old = OlsrParser(file="./stored-olsr.json")
new = OlsrParser(url="http://127.0.0.1:9090")
old - new

输出将是一个包含三个键的有序字典

  • 添加

  • 删除

  • 更改

每个键将包含一个与NetJSON NetworkGraph格式兼容的dict,分别表示

  • 已添加到拓扑中的节点和链接

  • 从拓扑中删除的节点和链接

  • 在两个拓扑中都存在,但它们的属性已更改的节点和链接

如果没有更改,键将包含None

因此,如果在旧版新版之间没有更改,结果将是

{"added": None, "removed": None, "changed": None}

而如果有更改,结果将如下所示

{
    "added": {
        "type": "NetworkGraph",
        "protocol": "OLSR",
        "version": "0.6.6",
        "revision": "5031a799fcbe17f61d57e387bc3806de",
        "metric": "ETX",
        "nodes": [
            {
                "id": "10.150.0.7",
                "label": "Node A",
                "local_addresses": [],
                "properties": {},
            },
            {
                "id": "10.150.0.6",
                "label": "Node B",
                "local_addresses": ["10.56.2.1"],
                "properties": {"hostname": "nodeb.lan"},
            },
        ],
        "links": [
            {
                "source": "10.150.0.3",
                "target": "10.150.0.7",
                "cost": 1.50390625,
                "cost_text": "",
                "properties": {},
            },
            {
                "source": "10.150.0.3",
                "target": "10.150.0.6",
                "cost": 1.0,
                "cost_text": "",
                "properties": {},
            },
        ],
    },
    "removed": {
        "type": "NetworkGraph",
        "protocol": "OLSR",
        "version": "0.6.6",
        "revision": "5031a799fcbe17f61d57e387bc3806de",
        "metric": "ETX",
        "nodes": [
            {
                "id": "10.150.0.8",
                "label": "Node C",
                "local_addresses": [],
                "properties": {},
            }
        ],
        "links": [
            {
                "source": "10.150.0.7",
                "target": "10.150.0.8",
                "cost": 1.0,
                "cost_text": "",
                "properties": {},
            }
        ],
    },
    "changed": {
        "type": "NetworkGraph",
        "protocol": "OLSR",
        "version": "0.6.6",
        "revision": "5031a799fcbe17f61d57e387bc3806de",
        "metric": "ETX",
        "nodes": [],
        "links": [
            {
                "source": "10.150.0.3",
                "target": "10.150.0.2",
                "cost": 1.0,
                "cost_text": "",
                "properties": {},
            }
        ],
    },
}

解析器

解析器是扩展netdiff.base.BaseParser的类,并实现了一个parse方法,该方法负责将Python数据结构转换为networkx.Graph对象并返回结果。

解析器还有一个json方法,该方法返回有效的NetJSON输出

可用的解析器有

初始化参数

数据可以通过以下3种方式提供,按优先级顺序

  • data:表示拓扑/图的字典或字符串

  • url:从URL获取数据的URL

  • file:检索数据的文件路径

其他可用参数

  • timeout:表示HTTP或telnet请求超时的秒数的整数,默认为None

  • verify:布尔值,表示请求库是否进行SSL证书验证[链接]

  • directed:布尔值,启用使用有向图(networkx.DiGraph),默认为False

初始化示例

本地文件示例

from netdiff import BatmanParser

BatmanParser(file="./my-stored-topology.json")

HTTP示例

from netdiff import NetJsonParser

url = "https://raw.githubusercontent.com/interop-dev/netjson/master/examples/network-graph.json"
NetJsonParser(url=url)

带有timeout的Telnet示例

from netdiff import OlsrParser

OlsrParser(url="telnet://127.0.1", timeout=5)

带有自签名SSL证书的HTTPS示例,使用verify=False

from netdiff import NetJsonParser

OlsrParser(
    url="https://myserver.mydomain.com/topology.json", verify=False
)

NetJSON输出

Netdiff解析器可以返回有效的NetJSON NetworkGraph对象

from netdiff import OlsrParser

olsr = OlsrParser(url="telnet://127.0.0.1:9090")

# will return a dict
olsr.json(dict=True)

# will return a JSON formatted string
print(olsr.json(indent=4))

输出

{
    "type": "NetworkGraph",
    "protocol": "OLSR",
    "version": "0.6.6",
    "revision": "5031a799fcbe17f61d57e387bc3806de",
    "metric": "ETX",
    "nodes": [
        {
            "id": "10.150.0.3"
        },
        {
            "id": "10.150.0.2"
        },
        {
            "id": "10.150.0.4"
        }
    ],
    "links": [
        {
            "source": "10.150.0.3",
            "target": "10.150.0.2",
            "cost": 2.4
        },
        {
            "source": "10.150.0.3",
            "target": "10.150.0.4",
            "cost": 1.0
        }
    ]
}

异常

所有异常都是netdiff.exceptions.NetdiffException的子类。

ConversionException

netdiff.exceptions.ConversionException

当netdiff无法识别传递给解析器的格式时抛出。

不一定是错误,应该捕获并管理以支持更多格式。

可以从“data”属性访问从网络/存储检索的数据,例如

def to_python(self, data):
    try:
        return super().to_python(data)
    except ConversionException as e:
        return self._txtinfo_to_jsoninfo(e.data)

ParserError

netdiff.exceptions.ParserError

当格式被识别但数据无效时抛出。

NetJsonError

netdiff.exceptions.NetJsonError

netdiff.parsers.BaseParserjson方法没有足够的数据符合NetJSON NetworkGraph规范时抛出。

TopologyRetrievalError

netdiff.exceptions.TopologyRetrievalError

当无法检索拓扑数据时抛出(例如:URL可能暂时不可达)。

特殊功能

OpenVPN

默认情况下,OpenVPN解析器使用通用名称来识别客户端,这是因为它如果使用公共IP地址,相同的客户端如果在不同的IP地址下连接,将不会被识别(由于许多ISP使用动态公共IP地址,这种情况非常可能)。

当VPN服务器配置允许不同客户端使用相同的通用名称时(通常不推荐这样做),这不起作用。

如果您需要支持配置了OpenVPN duplicate-cn功能的旧系统,您可以在初始化OpenvpnParser时传递duplicate_cn=True。这将更改解析器的行为,使每个客户端都通过它们的通用名称和IP地址(如果有多个具有相同通用名称和IP的客户端,则还包括使用的端口号)来识别。

已知问题

ConnectionError: BadStatusLine

如果您在向olsrd的jsoninfo插件(版本0.6到0.9)发出请求时遇到类似的错误,那么很可能是HTTP头被禁用了。

要修复它,请打开olsrd配置文件中的HTTP头,例如

LoadPlugin "olsrd_jsoninfo.so.0.0"
{
    PlParam "httpheaders" "yes"   # add this line
    PlParam "Port" "9090"
    PlParam "accept" "0.0.0.0"
}

运行测试

安装您的分叉仓库

git clone git://github.com/<your_fork>/netdiff
cd netdiff/
python setup.py develop

安装测试需求

pip install -r requirements-test.txt

使用以下命令运行测试

./runtests.py
./run-qa-checks

或者,您可以使用nose2命令(它有大量可用选项)

nose2
nose2 tests.test_olsr  # run only olsr related tests
nose2 tests/test_olsr.py  # variant form of the previous command
nose2 tests.test_olsr:TestOlsrParser  # variant form of the previous command
nose2 tests.test_olsr:TestOlsrParser.test_parse  # run specific test

使用以下命令查看测试覆盖率

coverage run --source=netdiff runtests.py && coverage report

贡献

请参阅OpenWISP贡献指南

支持

参阅OpenWISP支持渠道

变更日志

参阅CHANGES

许可证

参阅LICENSE

项目详情


下载文件

下载适用于您平台上的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源代码分发

netdiff-1.1.tar.gz (33.8 kB 查看哈希值)

上传时间 源代码

构建分发

netdiff-1.1-py2.py3-none-any.whl (21.4 kB 查看哈希值)

上传时间 Python 2 Python 3

支持