一直准备把交换机的全部配置导入到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
把我上面的代码拆开分成模块部署,
或者直接就是一个模块,上面的代码已经做了逻辑判断了,更简单
未完待续。。。。
网友评论