如何在Python Fabric中运行EdgeOS配置命令

1 投票
2 回答
41 浏览
提问于 2025-04-14 17:21

我正在尝试用一个Python脚本来自动更新EdgeOS的配置。我使用fabric作为SSH客户端。https://docs.fabfile.org/en/latest/index.html

下面的“---原始问题---”描述了我遇到的问题,但我觉得我找到了问题的根源,但还没有找到解决办法。Fabric通过非交互模式连接到路由器,因此无法获取完整的bash配置。configure命令不可用,show命令也不可用,其他路由器管理命令也都不能用。路由器中的.bashrc文件是这样的:

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

# enable completion
source /etc/bash_completion.d/vyatta-cfg
source /etc/bash_completion.d/vyatta-op

unset HISTFILE

所以我发现我没有加载bash_completion文件。我尝试在Python中手动执行这个操作:c.run("source /etc/bash_completion.d/vyatta-cfg"),但似乎没有效果。我接下来最好的解决办法是找到这些命令的硬路径,但我不太确定该去哪里找。

---原始问题---

我想做的是进行一些小的配置更改,比如:

configure
set interfaces ethernet eth2 vif 20 disable
commit
save

但是,当我通过fabric运行configure命令时,它失败了。我注意到,当我在SSH会话中时,configure命令会创建一个新的子会话之类的。我不太确定这个术语。

$ configure
[edit]
#

到目前为止的脚本:

from fabric import Connection
c = Connection('routerip')
c.run("configure")

还有错误信息:

vbash: configure: command not found
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/me/opt/anaconda3/lib/python3.8/site-packages/decorator.py", line 231, in fun
    return caller(func, *(extras + args), **kw)
  File "/Users/me/opt/anaconda3/lib/python3.8/site-packages/fabric/connection.py", line 23, in opens
    return method(self, *args, **kwargs)
  File "/Users/me/opt/anaconda3/lib/python3.8/site-packages/fabric/connection.py", line 763, in run
    return self._run(self._remote_runner(), command, **kwargs)
  File "/Users/me/opt/anaconda3/lib/python3.8/site-packages/invoke/context.py", line 113, in _run
    return runner.run(command, **kwargs)
  File "/Users/me/opt/anaconda3/lib/python3.8/site-packages/fabric/runners.py", line 83, in run
    return super().run(command, **kwargs)
  File "/Users/me/opt/anaconda3/lib/python3.8/site-packages/invoke/runners.py", line 395, in run
    return self._run_body(command, **kwargs)
  File "/Users/me/opt/anaconda3/lib/python3.8/site-packages/invoke/runners.py", line 451, in _run_body
    return self.make_promise() if self._asynchronous else self._finish()
  File "/Users/me/opt/anaconda3/lib/python3.8/site-packages/invoke/runners.py", line 518, in _finish
    raise UnexpectedExit(result)
invoke.exceptions.UnexpectedExit: Encountered a bad command exit code!

Command: 'configure'

Exit code: 127

Stdout: already printed

Stderr: already printed

2 个回答

0

我发现从Python改变配置最简单的方法就是创建一个bash脚本,把它复制到路由器上,然后通过fabric来运行这个脚本。

这个脚本叫做turn-off-wifi.bash

#!/bin/vbash
source /opt/vyatta/etc/functions/script-template
configure
set interfaces ethernet $1 disable
commit
exit

还有一个叫toggle.py的文件

c = Connection(host="ubnt@192.168.1.1")
t = transfer.Transfer(c)
t.put("turn-off-wifi.bash")
c.run("chmod +x ./turn-off-wifi.bash && ./turn-off-wifi.bash %s" % (interfaceName))

(我在这里设置了以太网接口的名称作为参数)

1

如果你要使用配置命令,最好用绝对路径。

/path/to/configure
set interfaces ethernet eth2 vif 20 disable
commit
save

你可以通过你的交互式会话来获取这个路径。

type configure

如果进入了交互式会话,你可能需要以某种方式提供输入。

撰写回答