0
点赞
收藏
分享

微信扫一扫

network_cli及初探playbook

将网络设备所独有的connection——network_cli

之前我们调用raw模块执行了一条命令,将version 信息回显成功。我们都知道是通过ssh登录上的设备。其实这里面也是可以讲很多的。我们展开来讲讲,因为这关系到你能不能登录上设备,很多人按照网上系统的ansible脚本去改,或者有些特殊的网络模块它的连接方式都是不同的,有讲究的。

网络设备的connection方式


├── buildah.py
 ├── chroot.py
 ├── docker.py
 ├── funcd.py
 ├── httpapi.py
 ├── iocage.py
 ├── jail.py
 ├── kubectl.py
 ├── libvirt_lxc.py
 ├── local.py
 ├── lxc.py
 ├── lxd.py
 ├── napalm.py
 ├── netconf.py
 ├── network_cli.py
 ├── oc.py
 ├── paramiko_ssh.py
 ├── persistent.py
 ├── podman.py
 ├── psrp.py
 ├── qubes.py
 ├── saltstack.py
 ├── ssh.py
 ├── vmware_tools.py
 ├── winrm.py
 └── zone.py

在hosts中,我们配置 ansible_connection字段即可。

可以使用变量配置,更快捷。

[cisco_nxos]
 sbx-nxos-mgmt.cisco.com
 
 [cisco_ios]
 sbx-iosxr-mgmt.cisco.com
 
 [cisco_nxos:vars]
 ansible_connection=network_cli
 ansible_network_os=nxos
 ansible_port=8181
 ansible_user=admin
 ansible_password=XXX
 
 [cisco_ios:vars]
 ansible_connection=network_cli
 ansible_port=8181
 ansible_user=admin
 ansible_password=XXX

常用的connection方式。

常用的几个我们来讲讲:

local是指在我们使用ansible的服务器本地执行命令,这点一定注意,它是在服务器本地执行,所以大部分情况下你连接网络设备执行show 会报错 /bin/bash 不支持show命令,是因为在服务器本地执行,而不是网络设备。

ssh是基于OpenSSH执行ssh,同时版本够新的话会有一些特有的技术可以加速ssh连接,共享ssh隧道。

paramiko是基于Python的一个ssh包

description:

   - Use the python ssh implementation (Paramiko) to connect to targets

   - The paramiko transport is provided because many distributions, in particular EL6 and before do not support ControlPersist

    in their SSH implementations.

   - This is needed on the Ansible control machine to be reasonably efficient with connections.

    Thus paramiko is faster for most users on these platforms.

    Users with ControlPersist capability can consider using -c ssh or configuring the transport in the configuration file.

   - This plugin also borrows a lot of settings from the ssh plugin as they both cover the same protocol.

主要是openssh的版本不够,不支持隧道加速就会用paramiko(我是这么理解的)

network_cli就是专门给网络设备准备的一个ssh模块。

description:

- This connection plugin provides a connection to remote devices over the

SSH and implements a CLI shell. This connection plugin is typically used by

network devices for sending and receiving CLi commands to network devices.

但是使用network_cli必须制定网络设备的平台系统,network_os字段,根据不同的平台,会配置一些ssh的提示符,或者开始就取消分页,保证自动化执行的顺畅。常见的网络设备它都有对应的os,但是国产的里面,华为的有人(不知道是不是华为自己还是ansible官方还是民间,反正点个赞)提交到了ansible官方,其他的我是没看到。如果国产的话,我觉得还是需要进行简单的适配,一会讲讲适配的思路,也提倡各厂商能够自己适配放到github或者国内的git上,不嫌弃,我也可以友情支持。

另外大家也可以关注 httpapi、netconf、napalm,这些也是和网络相关的一些connection方法。

network_cli

刚才我们简单减少了几种连接方式,network_cli是我们连接网络设备的首选,原因是它在调用的时候结合network_os字段,会去内置的配置里查找到该网络设备ssh 提示符的各种情况。

network_os:

description:

- Configures the device platform network operating system. This value is

   used to load the correct terminal and cliconf plugins to communicate

   with the remote device.

从以上描述我们可以看出,它会调用正确的terminal配置文件,以及对应的cliconf 的配置,来与网络设备交互。cliconf是一个内置的类,在对应的一些模块可以去发送命令获取设备的一些基本信息,它不是一个可以在命令行里或者playbook里被调用的模块,大家了解即可。

terminal

我们先来看terminal,位于python3.8/dist-packages/ansible/plugins/terminal/位置,我们看看都有哪些文件

├── aireos.py├── aruba.py├── asa.py├── bigip.py├── ce.py├── cnos.py├── custom_os.py├── dellos10.py├── dellos6.py├── dellos9.py├── edgeos.py├── edgeswitch.py├── enos.py├── eos.py├── eric_eccli.py├── exos.py├── frr.py├── icx.py├── ios.py├── iosxr.py├── ironware.py├── junos.py├── netvisor.py├── nos.py├── nxos.py├── onyx.py├── routeros.py├── slxos.py├── sros.py├── voss.py└── vyos.py

以上每一个文件都是对应的一个network_cli的network_os。

这些可以直接通过一个cli_command模块对接,实现show和config命令。

我们打开一个看看(来选ce.py吧)。

class TerminalModule(TerminalBase):
 
     terminal_stdout_re = [
         re.compile(br'[\r\n]?<.+>(?:\s*)$'),
         re.compile(br'[\r\n]?\[.+\](?:\s*)$'),
     ]
     #: terminal initial prompt
     #: The password needs to be changed. Change now? [Y/N]:
     terminal_initial_prompt = br'Change\s*now\s*\?\s*\[Y\/N\]\s*:'
 
     #: terminal initial answer
     #: do not change password when it is asked to change with initial connection.
     terminal_initial_answer = b'N'
     terminal_stderr_re = [
         re.compile(br"% ?Error: "),
         re.compile(br"^% \w+", re.M),
         re.compile(br"% ?Bad secret"),
         re.compile(br"invalid input", re.I),
         re.compile(br"(?:incomplete|ambiguous) command", re.I),
         re.compile(br"connection timed out", re.I),
         re.compile(br"[^\r\n]+ not found", re.I),
         re.compile(br"'[^']' +returned error code: ?\d+"),
         re.compile(br"syntax error"),
         re.compile(br"unknown command"),
         re.compile(br"Error\[\d+\]: ", re.I),
         re.compile(br"Error:", re.I)
     ]
 
     def on_open_shell(self):
         try:
             self._exec_cli_command('screen-length 0 temporary')
         except AnsibleConnectionFailure:
             raise AnsibleConnectionFailure('unable to set terminal parameters')

简单理解下就是用正则描述了各类情况下的提示符,这样见招拆招就可以与设备交互了,如果遇到国产设备,我们可以自己命名一个os文件名, 模仿这个去重写

TerminalBase 类即可。有分页的一定要注意在最开始的时候输入取消分页的命令。这个父类里还有升级用户权限的函数等等。同时在cliconf的目录下写一个对应的同名的os文件,模仿其他os的cliconf去写一个,这个文件里写的是如何获取设备的一些基础信息,查看与配置的相关函数。这段有时间我们再细细讲,很多国产的设备如果不给你对应的ansible包,大家可能都需要去写。如果只是调用命令行,我还是建议使用Netmiko这个包,而不是ansible,ansible调用层级太多,嵌套太深,而且有时候都是去动态调用,梳理代码逻辑的时候需要一定功底,我上述讲的,我暂时没在其他地方看到过类似的博文。

cliconf的目录

network_cli及初探playbook_网络设备

华为的ce.py(cliconf包下),在terminal底下还有一个ce.py用于处理交互的提示符的,区别开。定制的时候要改这两个。

network_cli及初探playbook_ico_02

如果你不是开发,这段就跳过去了,我们赶紧讲使用了。

cli_command

我们用ssh 和raw实际上是可以简单与设备交互的,但是如果变更或者分页的时候,这个操作就不是很顺畅,所以我们需要使用cli_command这个模块,它可以进行命令执行(建议只执行show命令,对于config,在同目录下有一个cli_config模块),cli_command底层搭配network_cli及相应的network_os的terminal和cliconf的时候,才可以使用。

cli_command简单用法

ansible -i hosts cisco_nxos -m cli_command -a "command='show version'"

network_cli及初探playbook_网络设备_03

各厂商自己的command模块

我们以思科的nxos为例,很多厂商(或者是ansible)也客制化了一些的command模块。他们根据情况,connection可以选择local和network_cli。选择local在本地执行命令的时候,他们底层会在本地ssh到远程设备,也可以实现一些功能模块。但是我建议调用的时候还是用network_cli。

network_cli及初探playbook_ico_04

比如思科的nxos_command模块,通过传递参数commands就可以批量执行一些命令(还是show),对应的有一个nxos_config可以执行配置的相关命令。

network_cli及初探playbook_ios_05

我们可以在这些模块的描述里找到对应的使用方法(ansible-doc或者查看原文件)。

network_cli及初探playbook_ico_06

有描述说明使用方法、参数,也有一些贴心的例子。

这些例子我们发现,是不是我们熟悉的命令行,这个就是playbook(其实是部分内容)

我们简单引入playbook,执行更多的命令,放更多的参数进去。,编写更复杂的逻辑。

playbook

很多自动化工具都喜欢用一些比喻来描述它的各个组件,比如chef喜欢用菜谱,把菜谱发给每个虚机、系统,让他们自己cook做菜。

ansible也喜欢来这一套,它的逻辑是剧本playbook,一个剧本里面有很多幕,每一幕里的人有很多的任务(task),每个人都有自己的action(就是咱们说的模块),模块里需要参数。甚至每个设备都可以有自己的角色(这个暂时不会深入去讲)。

  • playbook剧本,即一个yaml文件,yaml大家可以去网上搜搜,后续我会单独拿一节出来分享。
  • 每个幕就是一组特定目的的task
  • 每个task就是一个action,完成一个具体的动作、功能,调用一个模块。

我们简单写一个show多个信息的playbook。

--- # 以三个'-'开始
 
 - name: first show # 剧本的第一部分
   hosts: cisco_nxos # 筛选网络设备,可以是all,前提是他们都支持这个调用的模块
   gather_facts: no # 收集设备的一些基础信息。比如端口、版本、平台等等,耗费时间,大家都选择不调用
   tasks: # 复数,是一个列表,内含多个action task
     - name: 1.1、show version
       nxos_command:
         commands: show version
       register: result1 # 将结果注册到变量result1中
     - name: 1.2、show int bri
       nxos_command:
         commands: show int bri
       register: result2 # 将结果注册到变量result2中
 
 
 - name: second show # 剧本的第二部分
   hosts: cisco_nxos
   gather_facts: no
   tasks:
     - name: 2.1 show
       nxos_command:
         commands: show version

yaml对缩进非常严格,它和json还有xml是可以转换的,它的优点是对人的可读性非常好。

我们执行命令可以检查一下这个剧本是不是有语法错误。

执行ansible-playbook -i hosts playbook.yml --syntax-check检查剧本,会告诉你错在哪行。

network_cli及初探playbook_ico_07

执行剧本 ansible-playbook -i hosts playbook.yml

network_cli及初探playbook_ico_08

绿色代表执行成功没配置变化(这个时候是正常的了,不会像raw那样抽风),如果我们先回显show的内容,需要加一个额外的debug ,将output注册上去,就可以显示了。

yml文件

--- # 以三个'-'开始
 
 - name: first show # 剧本的第一部分
   hosts: cisco_nxos # 筛选网络设备,可以是all,前提是他们都支持这个调用的模块
   gather_facts: no # 收集设备的一些基础信息。比如端口、版本、平台等等,耗费时间,大家都选择不调用
   tasks: # 复数,是一个列表,内含多个action task
     - name: 1.1、show version
       nxos_command:
         commands: show version
       register: result1 # 将结果注册到变量result1中
     - name: 1.2、show int bri
       nxos_command:
         commands: show int bri
       register: result2 # 将结果注册到变量result2中
 
     - name: Dispaly result 1
       debug: msg="{{result1}}"
 
     - name: Dispaly result 2
       debug: msg="{{result2}}"
 
 
 - name: second show # 剧本的第二部分
   hosts: cisco_nxos
   gather_facts: no
   tasks:
     - name: 2.1 show
       nxos_command:
         commands: show version

network_cli及初探playbook_ico_09

总结

今天我们讲了 connection究竟是什么东西,以及网络专属的network_cli连接方式,顺便简单讲了适配的思路。简单讲了playbook,写了一个show的例子。

其实config也就很简单了。包括对端口、vlan的配置也水到渠成,与nxos_command的调用几乎一样。找模块,传参数,执行坐等结果。

但是有几点说明

local对于网络设备来说是一个很危险的连接方式,有些容易混淆的地方,它说是在本地,但是调用网络的模块是可行的,因为模块底层会做一些操作,使之可行。但是我们执行raw的时候,你会发现不可行,它就是在本地调用命令,并没有ssh到设备。大家要小心这个坑。

网络设备的ansible比较麻烦的地方在于适配,很多国内厂商都很难找到适配的驱动(对应os模块或者其他功能模块)。然后网上又很少有人讲如何去适配网络设备。想象一下,其实是有技术难度的,因为封装的过于深刻,一个具备开发技能的网工发现其中的逻辑也是有点困难的。客观说,我也是花了很长时间,做了很多测试,用了各种方法,才找到其中门路,本人从11年研究生才是真正的去写代码,到现在9年有余,感谢我的导师,尤其感谢带我的师兄大树:)。国内想用这个又能去适配的又告诉大家方法的,我觉得确实很难找到。

ansible的很多模块很有营养,比如terminal中整理了很多厂商的一些正则,我们如果觉得ansible重,想自己开发或者是写类似的ssh工具的时候,可以参考这些正则。它的很多模块都带有参数-》配置,配置-》解析后的参数的模块,可以复用。


以上就是今天的分享,限于时间篇幅,难免有遗漏,大家如果有疑问可以私信我,感谢大家看完。后续会讲讲如何配置一个设备,以及传入的命令带有变化。



举报

相关推荐

0 条评论