用于解析和比较RouterOS配置文件的工具。可以生成配置文件补丁。
项目描述
为您的Mikrotik路由器创建配置补丁
安装
使用您喜欢的Python包管理器进行安装。例如
pip install routeros-diff
获取差异
routeros_diff
(别名ros_diff
)命令将取两个RouterOS文件并进行比较
routeros_diff old_config.rsc new_config.rsc
或者使用Python
from routeros_diff.parser import RouterOSConfig
new = RouterOSConfig.parse(new_config_string)
old = RouterOSConfig.parse(old_config_string)
print(new.diff(old))
示例
首先是一个简单的示例
# Old:
/routing ospf instance
add name=core router-id=100.127.0.1
# New:
/routing ospf instance
add name=core router-id=100.127.0.99
# Diff:
/routing ospf instance
set [ find name=core ] router-id=100.127.0.99
下面是一个更复杂的示例,我们使用自定义ID以保持表达式顺序(有关详细信息,请参阅下面的“自然键和ID”)
# Old:
/ip firewall nat
add chain=a comment="Example text [ ID:block-smtp ]"
add chain=c comment="[ ID:block-smb ]"
# New:
/ip firewall nat
add chain=a comment="Example text [ ID:block-smtp ]"
add chain=b comment="[ ID:block-nfs ]"
add chain=c comment="[ ID:block-smb ]"
# Diff:
/ip firewall nat
add chain=b comment="[ ID:block-nfs ]" place-before=[ find where comment~ID:block-smb ]
使用和限制
本过程的目的是在有限范围内运行良好。配置格式本身就是一个完整的脚本语言,因此这个库无法合理地希望解析任何任意输入。作为一般规则,这个库应该能够比较由/export
产生的任何内容。
高级使用
RouterOSConfig.parse
还接受一个可选的第二个参数,如下所示
from routeros_diff.parser import RouterOSConfig
new = RouterOSConfig.parse(new_config_string)
old = RouterOSConfig.parse(old_config_string)
# Produced using: /export verbose
old_verbose = RouterOSConfig.parse(old_verbose_config_string)
print(new.diff(old, old_verbose))
提供old_verbose
可以使比较算法在产生的比较中更智能。当提供old_verbose
时,算法可以自动避免设置它知道未更改的某些值。这仅适用于以下情况:a)新的配置将参数设置回其默认值,b)旧的配置已经将参数设置为相同的值。
虽然这个特性不是生成有效比较所必需的,但它确实使生成没有不必要的表达式的比较变得更容易。换句话说,如果您想确保两个功能上相等的配置产生一个空比较,请使用此方法。
章节和表达式
以下内容不支持
## NOT SUPPORTED, DONT DO THIS ##
/routing ospf instance add name=core router-id=100.127.0.1
相反,必须将它们格式化为不同的行上的单独的'章节'和'表达式'。例如
/routing ospf instance
add name=core router-id=100.127.0.1
本例中的章节是 /routing ospf instance
,表达式是 add name=core router-id=100.127.0.1
。每个章节可以包含多个表达式(就像您从 /export
看到的输出一样)。
自然键与ID
解析器会尝试唯一地标识每个表达式。这使得解析器在添加、修改、删除和排序方面更加智能。
解析器将这些唯一标识称为自然键和自然ID。例如
add name=core router-id=100.127.0.1
在这里,自然键是 name
,自然ID是 core
。解析器假定 name
将是自然键,但在某些情况下配置为使用其他键。
此外,您可以选择手动将您自己的ID添加到表达式中。这是通过注释实现的。例如
add chain=a comment="[ ID:1 ]"
这些基于注释的ID将优先于解析器可能使用的任何其他ID。如果您使用注释ID,请确保您为该章节中的所有表达式设置了它们。
这对于防火墙规则特别有用。防火墙规则的顺序很重要,它们没有明显的自然键/ID。使用注释ID对您的防火墙规则进行注释可以让解析器智能地维护顺序。例如
# Old:
/ip firewall nat
add chain=a comment="Example text [ ID:block-smtp ]"
add chain=c comment="[ ID:block-smb ]"
# New:
/ip firewall nat
add chain=a comment="Example text [ ID:block-smtp ]"
add chain=b comment="[ ID:block-nfs ]"
add chain=c comment="[ ID:block-smb ]"
# Diff:
/ip firewall nat
add chain=b comment="[ ID:block-nfs ]" place-before=[ find where comment~ID:block-smb ]
请注意,解析器使用 place-before
正确放置新的防火墙规则。
如果不使用注释ID,解析器将不得不删除并重新创建所有防火墙规则。 这在安全性和可靠性方面都不是理想的选择。
报告错误
在您的diff输出中看到了奇怪的内容?请提供以下信息报告错误
- 输入
- 实际输出
- 您认为的输出应该是
请尽可能缩小这些数据的大小。问题示例越小、越具体,我们找到解决方案就越容易。
美化
routeros_prettify
(别名 ros_prettify
)命令将解析现有配置,并以标准格式重新打印它,其中常见章节已折叠
routeros_prettify old_config.rsc new_config.rsc
或者使用Python
from routeros_diff.parser import RouterOSConfig
config = RouterOSConfig.parse(config_string)
print(config)
您还可以按照以下方式生成配置的语法高亮HTML版本(查看示例CSS)
from routeros_diff.parser import RouterOSConfig
config = RouterOSConfig.parse(config_string)
print(config.__html__())
设置
您可以通过两种方式之一自定义设置。
最简单的方法是将设置传递给 RouterOSConfig.parse() 方法
RouterOSConfig.parse(s=my_config, settings=dict(
# Natural keys for each section name.
# 'name' will be used if none is found below
# (and only if the 'name' value is available)
natural_keys={
"/ip address": "address",
...
},
# Don't perform deletions in these sections
no_deletions={
"/interface ethernet",
...
},
# Don't perform creations in these sections
no_creations={
"/interface ethernet",
...
},
# Ordering is important in these sections. Ensure
# entities maintain their order. Natural keys/ids must be
# present in sections listed here
expression_order_important={
"/ip firewall*",
...
},
))
请注意,可以使用 '*' 通配符指定章节路径。例如,/ip firewall*
。
或者,您可以通过扩展此类并重写其方法来自定义此类。如果需要,您可以在此处实现更复杂的逻辑。在这种情况下,您可以将自定义类传递给解析器,如下所示
RouterOSConfig.parse(my_config, settings=MyCustomSettings())
概念
这是一个路径为 /ip address
的 章节,包含两个表达式
/ip address
add address=1.2.3.4
add address=5.6.7.8
这是一个具有 add 命令的 表达式,键值参数为 address=1.2.3.4
add address=1.2.3.4
发布流程
export VERSION=a.b.c
poetry version $VERSION
dephell convert
black setup.py
git add .
git commit -m "Releasing version $VERSION"
git tag "v$VERSION"
git branch "v$VERSION"
git push origin \
refs/tags/"v$VERSION" \
refs/heads/"v$VERSION" \
main
# Wait for CI to pass
poetry publish --build
项目详情
下载文件
下载您平台上的文件。如果您不确定选择哪个,请了解更多关于 安装软件包 的信息。
源代码分发
构建版本
routeros-diff-0.5.3.tar.gz的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 3d06321caff053f16cc370986f8ce6edbed202a111bfbd0ad168ceece652e105 |
|
MD5 | cf897dfdd98ea01f219c4c404161207a |
|
BLAKE2b-256 | 206e146947c770aa6089ab0f5676a2aaf3915b8daee41cb8b54cc08c39545383 |
routeros_diff-0.5.3-py3-none-any.whl的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 7ab21a776a7d673c2dffe5d06467956755641596e38e652083eaddba71b4a173 |
|
MD5 | bce61b6b2af1a103c1525b1337a57910 |
|
BLAKE2b-256 | f8587781c5ba169e981621d49bdc42cc5e8734268a08146ae658f3f1b91dfc01 |