---
- hosts: leaf-1, leaf-2
vars_files:
- /vars/all.yml
tasks:
- name: collect the vlan databse
raw: "show vlan brief"
register: vlan_db
- name: compare vlan_id(.*)Ports against the vlan_db
set_fact:
fact1: "{{ item.1.vlan_id }}"
fact2: "{{ item.1.sap.inventory_hostname | join(', ') }}"
fact3: "{{ fact1 }}(.*){{ fact2 }}"
failed_when: not vlan_db.stdout is regex(fact3)
when: inventory_hostname in item.1.sap
with_subelements:
- "{{ customers }}"
- services我从一个交换机( "services.sap"
中列出。
我想我可以用以下方法来完成这个任务:when: inventory_hostname in item.1.sap
如果上面的检查为真,我希望在第一个任务的stdout和fact3之间进行regex比较,如果第一个任务的stdout中没有regex,则引发失败:
set_fact: fact1: "{{ item.1.vlan_id }}" fact2: "{{ item.1.sap.inventory_hostname | join(', ') }}" fact3: "{{ fact1 }}(.*){{ fact2 }}" failed_when: not vlan_db.stdout is regex(fact3)
这就像嵌套循环和条件在一起。有没有办法让Ansible做这件事?我做错什么了?
为了确保我的意图是明确的:
通过客户列表中的项目循环,通过每个customer
/vars/all.yml如下所示:
customers:
- name: "cust-1"
l3_vni: "101"
services:
- vlan_id: "10"
vni: "1010"
gw: "10.0.0.254/24"
sap:
leaf-1: ["Eth3"]
leaf-2: ["Eth3"]
- vlan_id: "11"
vni: "1011"
gw: "10.0.1.254/24"
sap:
leaf-1: ["Eth3"]
leaf-2: ["Eth3"]
- name: "cust-2"
l3_vni: "102"
services:
- vlan_id: "20"
vni: "1020"
gw: "20.0.0.254/24"
sap:
leaf-3: ["Eth3", "Eth4"]
leaf-4: ["Eth3"]
- vlan_id: "21"
vni: "1021"
gw: "20.0.1.254/24"
sap:
leaf-3: ["Eth3"]
leaf-4: ["Eth3"]
```
a switch vlan database usually looks like this:
```
leaf-1#show vlan brief
VLAN Name Status Ports
---- -------------------------------- --------- ----------------------
1 default active Eth5
10 cust-1 active Eth3, Eth4
20 cust-2 active Eth1, Eth2
```
error log:致命:叶-1:失败!=> { "msg":“任务包含一个带有未定义变量的选项。错误是:'fact1‘是未定义的\n\n,错误出现在’/迷走区/Ansible文件夹fact1第23行,第7列,但可能\n在文件的其他地方,这取决于确切的语法问题。\n\n,违规行似乎是:\n\n\n-名称:比较vlan_id(.*)端口和vlan_db\n ^ here\n“}
发布于 2019-12-07 14:38:34
这里有几个问题。
首先,您的剧本在语法上是无效的:它根本无法运行。如果出现错误,它将失败:
ERROR! unexpected parameter type in action: <class 'ansible.parsing.yaml.objects.AnsibleSequence'>这是因为set_fact的内容应该是字典,而不是列表:
- name: "compare vlan_id(.*)Ports against the vlan_db"
set_fact:
fact1: "{{ item.1.vlan_id }}"
fact2: "{{ item.1.sap.inventory_hostname | join(', ') }}"
fact3: "{{ fact1 }}(.*){{ fact2 }}"
failed_when: not vlan_db.stdout is regex(fact3)
when: inventory_hostname in item.1.sap
with_subelements:
- "{{ customers }}"
- services但是,这里还有另一个问题:在set_fact任务运行之前,您的事实是不可用的,所以检查is regex(fact3)的条件永远不会正确匹配。如果要使用该表达式的值,则需要将该值公开为变量。
但在我们看这个之前,还有另外一个问题:当你写:
fact2: "{{ item.1.sap.inventory_hostname | join(', ') }}"您要在inventory_hostname字典中查找一个名为“sap”的文字键。请记住,当您编写foo.bar.baz时,这实际上是foo["bar"]["baz"]的缩写。相反,你需要:
fact2: "{{ item.1.sap[inventory_hostname] | join(', ') }}"所以,回到变量。如果您想在条件中使用fact3的值,有几种方法可以做到这一点。一种选择是在任务上使用vars块,这将创建任务持续时间内存在的新变量。我在这里使用了一个debug任务来演示正在发生的事情;如果在任务完成后需要持久化一些或所有这些变量,显然可以用set_fact任务替换它:
- name: "compare vlan_id(.*)Ports against the vlan_db"
debug:
msg:
- "{{ fact1 }}"
- "{{ fact2 }}"
- "{{ fact3 }}"
vars:
fact1: "{{ item.1.vlan_id }}"
fact2: "{{ item.1.sap[inventory_hostname] | join(', ') }}"
fact3: "{{ fact1 }}(.*){{ fact2 }}"
failed_when: not vlan_db.stdout is regex(fact3)
when: inventory_hostname in item.1.sap
with_subelements:
- "{{ customers }}"
- services希望这足以为你指明正确的方向。如果我能澄清什么,请告诉我。
发布于 2019-12-07 16:01:16
谢谢各位。经过一番努力,我才能用下面的游戏达到我的目标。我还必须更改failed_when语法。
- hosts: leaf-1
gather_facts: no
tags: [ verify ]
vars_files:
- ../Step2-config/roles/services_config/vars/main.yml
tasks:
- name: collect the vlan databse
raw: "show vlan brief"
register: vlan_db
- debug:
var: vlan_db.stdout
var: inventory_hostname, vlan_db
- name: compare vlan_id(.*)Ports against the vlan_db
set_fact:
fact1: "{{ item.1.vlan_id }}"
fact2: "{{ item.0.name }}"
fact3: "{{ item.1.sap[inventory_hostname] | join('.*')}}"
when: "inventory_hostname in item.1.sap"
failed_when: not vlan_db.stdout_lines is regex(fact1 + '.*' + fact2 + '.*' + fact3)
with_subelements:
- "{{ customers }}"
- serviceshttps://stackoverflow.com/questions/59211880
复制相似问题