使用ansible tower 自动化运维juniper 交换机

2019-08-12  本文已影响0人  bjmingyang

一直准备把交换机的全部配置导入到gitlab 里,然后通过ansible 部署,但是这种玩意部署起来还是很多问题,真正用于企业部署的话,感觉和纯手工部署也没太大差别,以前玩了一两天的部署配置交换机的ansible network 模块
感觉实现功能比较单一,基本就是把配置全部导出,然后配置全部导入之类的。现在的模块比较多了,从配置,回滚,单行命令基本都有了,而且在junos上又多出了自动测试和审计等功能,(还没有去看其他交换机的配置文档),这样就适合企业级部署应用了.

首先要在juniper 交换机上打开netconf

set system services netconf ssh
commit

验证

ssh user@R1.example.com -p 830 -s netconf

如果出现password 就ok了,如果设置了sshkey,就直接登陆到交换机里面了

然后在ansible tower的服务器上安装依赖环境,具体看是否使用了python3,因为centos7 系统默认还是依赖python2的,所以红帽使用了scl 来隔离,切换到python3下可以使用

scl enable rh-python36 bash

下面是直接从history里粘出来的命令,直接拷贝就行,也可以直接切换到python3 的环境里执行,那就不用加上前面的scl enable rh-python36的字段了

yum install -y pip python-devel libxml2-devel libxslt-devel gcc openssl libffi-devel python-pip
scl enable rh-python36 "pip3 install ncclient"
scl enable rh-python36 "pip3 install junos-eznc"
scl enable rh-python36 "ansible-galaxy install Juniper.junos"
scl enable rh-python36 "pip install junos-eznc jxmlease wget jsnapy requests ipaddress cryptography "
scl enable rh-python36 "pip install jsnapy"

如果在python3 下面跑ansible 有可能会有找不到模块的问题
解决方式,要不切换到python3 模式下
要不在ansible playbook 里定义变量,要不在执行的时候 加入

 -e ansible_python_interpreter=/opt/rh/rh-python36/root/usr/bin/python

这里是我自己python3的路径
下面是ansible的一些应用

ansible

下面是jsnapy的一些应用,junapy主要是生成两份快照,分别叫pre.snap和post.snap
就是部署配置前的快照,和部署了配置之后的快照,然后跑测试用例,来判断配置是否和预期的一致,后续动作可以用ansible或者python,命令行触发,
因为本来jsnapy 就支持ansible模块,因此和ansible集成相当的简单
贴一个简单的收集配置的例子

---
- name: create configuration_backup directories
  hosts: localhost
  gather_facts: no
  tasks:

   - name: create configuration directory
     file:
       path: "{{playbook_dir}}/configuration"
       state: directory


   - name: create configuration subdirectories
     file:
       path: "{{playbook_dir}}/configuration/{{ item }}"
       state: directory
     with_items:
       - text
       - set

- name: Collect configuration from devices
  hosts: JUNOS
  connection: local
  gather_facts: no
  tasks:

  - name: Collect configuration in text format from devices
    junos_facts:
      gather_subset: config
      config_format: text
      provider: "{{ credentials }}"
    register: "result_text"

  - name: copy collected configuration in configuration/text directory
    copy:
      content: "{{ result_text.ansible_facts.ansible_net_config }}"
      dest: "{{ playbook_dir }}/configuration/text/{{ inventory_hostname }}.conf"

  - name: Collect configuration in set format from devices
    junos_facts:
      gather_subset: config
      config_format: set
      provider: "{{ credentials }}"
    register: "result_set"

  - name: copy collected configuration in configuration/set directory
    copy:
      content: "{{ result_set.ansible_facts.ansible_net_config }}"
      dest: "{{ playbook_dir }}/configuration/set/{{ inventory_hostname }}.set"

需要定义一个var 文件内容如下:

---
ADMUSER: root
ADMPASS: 123456

credentials:
  host: "{{ junos_host }}"
  username: root
  password: 123456
  timeout: 20

需要定义一个hosts 文件
内容如下

[JUNOS:children]
SRX
EX

[SRX]
SRX240h-14 junos_host=172.16.90.14
[EX]
EX4200-15  junos_host=172.16.90.15
EX4200-16  junos_host=172.16.90.16

以上的内容,也可以整合成一个playbook
然后就可以收集当前服务器的配置了,而且可以生成 text xml json set 4种格式,我这里只写了两种需要什么就用什么格式的字段替换就行了。

然后

jsnapy

jsnapy 快照的格式好像只能是xml,我这个没有特别具体的研究
生成快照

jsnapy --snap SNAP1 -f test-config-snap.conf

以上
snap 是动作
SNAP1 是tag
test-config-snap.conf 是写好的测试配置
test-config-snap.conf 的内容如下:

hosts:
  - include: device.yml
    group: EX

tests:
  - test-case-snap.yml

可以看到里面又包含了两个文件
device.yml 这个文件类似ansible inventory文件,就是交换机的列表文件内容如下:

EX:
  - 172.16.90.15:
     username: root
     passwd: xyzxyz
  - 172.16.90.16:
     username: root
     passwd: xyzxyz

test-case-snap.yml 这个文件是测试用例
文件内容如下:

tests_include:
   - test_show_config

test_show_config:
   - command: show configuration

通过上面的基本配置,就可以抓取交换机当前的配置,并生成快照文件了
(其实就是当前交换机的配置),然后修改交换机配置后,再次抓取交换机的配置文件生成快照,然后跑测试用例来测试配置是否达到预期,也可以通过命令来查看交换机修改的内容
命令如下:

jsnapy --dif SNAP1 NEW -f test-config-snap.yml #比较两个snap 文件的不同
jsnapy --snapcheck NEW -f test-config-snap.yml #测试snap文件的配置

如果符合预期,可以正式发布,如果不符合预期可以回滚,但是jsnapy 不具备这样的功能,因此整个流程化的部署就回到了ansible tower
具体假设我有一个交换机,我准备在上面划一个vlan id为42的vlan。那我的测试文件就是这样写的

test_phy:
 - rpc: get-config
 - kwargs:
     filter_xml: configuration/interfaces
 - iterate:
     id: ./name
     xpath: 'interfaces/interface'
     tests:
       - not-equal: name, ge-0/0/42
         info: "Interface does not exist"
         err: "-"

test_irb:
 - rpc: get-config
 - kwargs:
     filter_xml: configuration/interfaces
 - iterate:
     id: ./name
     xpath: 'interfaces/interface[name="irb"]/unit'
     tests:
       - not-equal: name, 42
         info: "Interface does not exist"
         err: "-"

test_vlan:
 - rpc: get-config
 - kwargs:
     filter_xml: configuration/vlans
 - iterate:
     id: ./vlan
     xpath: 'vlans/vlan'
     tests:
       - not-equal: name, DT
         info: "VLAN does not exist"
         err: "-"

具体就是要求再跑配置之前,首先确认当前的配置vlan 42这个号没有在当前的配置里被占用
然后用

jsnapy --snapcheck pre -f pre.yml

运行测试检查

如果做了更改,测试的文件如下:


test_phy:
  - rpc: get-config
  - kwargs:
      filter_xml: configuration/interfaces
  - item:
      id: ./name
      xpath: 'interfaces/interface[name="ge-0/0/42"]'
      tests:
        - is-equal: name, ge-0/0/42
          info: "Interface exists"
          err: "-"
 
test_irb:
  - rpc: get-config
  - kwargs:
      filter_xml: configuration/interfaces
  - item:
      id: ./name
      xpath: 'interfaces/interface[name="irb"]/unit[name="42"]'
      tests:
        - is-equal: name, 42
          info: "Interface exists"
          err: "-"
 
test_vlan:
  - rpc: get-config
  - kwargs:
      filter_xml: configuration/vlans
  - item:
      id: ./vlan
      xpath: 'vlans/vlan[name="DT"]'
      tests:
        - is-equal: name, DT
          info: "VLAN exists"
          err: "-"

用于测试配置之后,存在vlan 42 这个vlan。

jsnapy --snapcheck post -f post.yml

然后运行测试检查

具体实现可以用多种方法
可以用一个ansible playbook解决,也可以通过ansible job workflow template 来解决
基本思路都是首先生成一个golden config ,(即当前没有问题的配置),然后提交新的交换机配置,测试配置状态,如果正常,直接返回,如果不正常,提交golden config ,回滚配置
在中间插入通知模块,ansible tower 自带通知模块,鼠标点点就行,不用ansible tower的,可以写到playbook里面,jsnapy 也有邮件发送的选项,需要写到jsnapy的测试用例里

ansible 的代码大致如下

---
 - name: jsnapy
   hosts: AMS-EX4300
   connection: local
   gather_facts: no
   roles:
   - Juniper.junos

   tasks:

   - name: Collect Pre Snapshot
     junos_jsnapy:
       host: "{{ junos_host }}"
       user: "{{ credentials.username }}"
       passwd: "{{ credentials.password }}"
       action: "snap_pre"
       test_files: /etc/jsnapy/testfiles/test_file_check_lldp_states.yml

   - name: Collect Post Snapshot
     junos_jsnapy:
       host: "{{ junos_host }}"
       user: "{{ credentials.username }}"
       passwd: "{{ credentials.password }}"
       action: "snap_post"
       test_files: /etc/jsnapy/testfiles/test_file_check_lldp_states.yml

   - name: Compare snapshots
     junos_jsnapy:
       host: "{{ junos_host }}"
       user: "{{ credentials.username }}"
       passwd: "{{ credentials.password }}"
       action: "check"
       test_files: /etc/jsnapy/testfiles/test_file_check_lldp_states.yml
     register: test_check

   - name: Debug jsnapy
     debug: 
       msg: "{{ test_check }}"

   - name: Check JSNAPy tests results
     assert:
       that:
       - "test_check.passPercentage == 100"
       msg: "jsnapy test on {{ inventory_hostname }} failed"

ansible tower 抓图挺烦人,暂时挂在这里吧,具体就是在awx里面创建workflow的playbook
把我上面的代码拆开分成模块部署,
或者直接就是一个模块,上面的代码已经做了逻辑判断了,更简单
未完待续。。。。

上一篇 下一篇

猜你喜欢

热点阅读