我是 Ansible 新手,我需要有关我正在编写的代码的帮助。我需要捕获此戴尔交换机命令的输出:
显示接口交换机端口 |查找名称:| 802.1Q 除外标记: |除了VLAN
这会产生这个:
Name: GigabitEthernet 1/1
U 1641
T 1007,1076
Name: GigabitEthernet 1/2
U 1641
T 1007,1076
Name: GigabitEthernet 1/3
U 1641
T 1007,1076
并将这些内容放入字典中,其中键是接口名称,其中值未标记为 U 的内容,标记为 T 的内容
这是我正在运行的剧本:
---
- hosts: [dellos9]
connection: network_cli
gather_facts: no
tasks:
- name: Include secrets and vars
include_vars: dell_vars.yml
- name: "Get Dell EMC OS9 VLAN info"
dellos9_command:
commands:
- 'show interfaces switchport | find Name: | except 802.1QTagged: | except Vlan'
register: switchport_output
- name: Parsing Command_9 output
set_fact:
output_items: "{{ switchport_output.stdout_lines[0] | map('regex_findall','[\\S]+') | list | select() }}"
when: switchport_output.stdout_lines is defined
- name: Process output_items and set variables
set_fact:
my_int: "{{ item.1 + ' ' + item.2 if item.0 == 'Name:' }}"
my_untagged: "{{ item.1 if item.0 == 'U' }}"
my_tagged: "{{ item.1 if item.0 == 'T' }}"
loop: "{{ output_items }}"
- name: Display interface details
debug:
msg: "Interface: {{ my_int }} Untagged: {{ my_untagged }} Tagged: {{ my_tagged }}"
希望有经验的人可以帮助我。 TIA
这是我运行剧本得到的输出:
ok: [switch] => (item=['Name:', 'GigabitEthernet', '1/1'])
ok: [switch] => (item=['U', '1641'])
ok: [switch] => (item=['T', '1007,1076'])
ok: [switch] => (item=['Name:', 'GigabitEthernet', '1/2'])
ok: [switch] => (item=['U', '1641'])
ok: [switch] => (item=['T', '1007,1076'])
ok: [switch] => (item=['Name:', 'GigabitEthernet', '1/3'])
ok: [switch] => (item=['U', '1641'])
ok: [switch] => (item=['T', '1007,1076'])
TASK [Display interface details] **********************************************************************************************************************************
ok: [switch] => {
"msg": "Interface: Untagged: Tagged: 1007,1076"
}
输入数据的结构使得这是一个仅用 Ansible 来解决的相对棘手的问题。如果将解析逻辑移至 Python 过滤器中,您的生活将会变得更加轻松。如果我们将以下内容放入
filter_plugins.filter.py
:
def parse_interfaces(v):
interfaces = {}
for line in v:
if line.startswith("Name"):
name = line.split(": ")[1]
interfaces[name] = {}
elif line.startswith("U"):
interfaces[name]["untagged"] = line.split()[1].split(",")
elif line.startswith("T"):
interfaces[name]["tagged"] = line.split()[1].split(",")
return interfaces
class FilterModule:
def filters(self):
return {"parse_interfaces": parse_interfaces}
然后我们可以写一个这样的剧本:
- hosts: localhost
gather_facts: no
vars:
raw_output: |
Name: GigabitEthernet 1/1
U 1641
T 1007,1076
Name: GigabitEthernet 1/2
U 1641
T 1007,1076
Name: GigabitEthernet 1/3
U 1641
T 1007,1076
switchport_output:
stdout_lines:
- "{{ raw_output.splitlines() }}"
tasks:
- set_fact:
switch_interfaces: "{{ switchport_output.stdout_lines[0] | parse_interfaces }}"
- debug:
var: switch_interfaces
并得到这个输出:
TASK [debug] *******************************************************************
ok: [localhost] => {
"switch_interfaces": {
"GigabitEthernet 1/1": {
"tagged": [
"1007",
"1076"
],
"untagged": [
"1641"
]
},
"GigabitEthernet 1/2": {
"tagged": [
"1007",
"1076"
],
"untagged": [
"1641"
]
},
"GigabitEthernet 1/3": {
"tagged": [
"1007",
"1076"
],
"untagged": [
"1641"
]
}
}
}
PLAY RECAP *********************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0