借助Ansible捕获Dell交换机VLAN标签信息的问题求助
解决Dell OS9交换机接口VLAN信息的Ansible解析问题
问题背景
我是Ansible新手,需要捕获Dell交换机命令输出并整理为指定格式的字典:
执行命令:
show interfaces switchport | find Name: | except 802.1QTagged: | except 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
目标:将输出整理为字典,以接口名为键,对应值包含untagged(对应U行内容)和tagged(对应T行内容)。
原Playbook及问题
原Playbook代码:
--- - 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 }}"
运行后输出:
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" }
问题:循环中set_fact会持续覆盖变量,导致最后仅保留最后一次循环的结果,无法收集所有接口的对应信息。
解决方案
通过按接口分组处理,避免变量覆盖,逐步构建目标字典:
修改后的Playbook:
--- - 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: Parse output into interface groups set_fact: interface_groups: "{{ switchport_output.stdout[0] | split('\n\n\n\n') | map('trim') | select() | list }}" - name: Build interface VLAN dictionary set_fact: interface_vlans: "{{ interface_vlans | default({}) | combine({ intf_name: {'untagged': untagged_vlan, 'tagged': tagged_vlans} }) }}" loop: "{{ interface_groups }}" vars: lines: "{{ item.split('\n') | map('trim') | select() | list }}" intf_name: "{{ lines[0].split('Name: ')[1] }}" untagged_vlan: "{{ lines[1].split()[1] }}" tagged_vlans: "{{ lines[2].split()[1] }}" - name: Display interface VLAN details debug: var: interface_vlans
关键逻辑说明
- 接口块分组:用
split('\n\n\n\n')将原始输出按空行分割为单个接口的独立信息块,过滤掉空内容。 - 单接口信息提取:对每个接口块拆分每行内容,直接提取接口名、untagged VLAN、tagged VLAN列表。
- 字典构建:通过
combine方法逐步将每个接口的信息合并到interface_vlans字典中,避免变量被覆盖。
运行后将得到符合需求的字典结构:
{ "GigabitEthernet 1/1": { "untagged": "1641", "tagged": "1007,1076" }, "GigabitEthernet 1/2": { "untagged": "1641", "tagged": "1007,1076" }, "GigabitEthernet 1/3": { "untagged": "1641", "tagged": "1007,1076" } }
内容的提问来源于stack exchange,提问作者NetMan
相关产品推荐
相关产品推荐

