如何过滤Ansible的stdout_lines提取交换机端口并执行后续查询
Ansible 提取交换机MAC对应端口并过滤上行口的实现方案
完全可以实现你需要的逻辑,你可以通过Ansible内置的列表、字符串过滤器完成端口提取,以下是修改后的完整Playbook:
--- - name: Find mac address in sec-switches hosts: sec-switch gather_facts: false connection: local vars_prompt: - name: mac prompt: What is the mac address? private: no tasks: - name: 打印搜索提示 ansible.builtin.debug: msg: 'Searching for {{ mac }}' - name: 搜索MAC地址表 register: output ios_command: commands: - "show mac address-table | include {{ mac }}" # 无匹配MAC的交换机直接跳过后续任务 - name: 跳过无MAC匹配的交换机 meta: end_host when: output.stdout | length == 0 or output.stdout[0] | length == 0 - name: 提取端口列表并去重 ansible.builtin.set_fact: # 拆分每行取最后一个字段(端口号),也可替换为 map('index', 3) 精准取第4个字段 target_ports: "{{ output.stdout_lines | flatten | map('split') | map('last') | unique }}" - name: 检查端口描述排除上行口 ios_command: commands: - "show interfaces description | include {{ item }}" register: port_desc_results loop: "{{ target_ports }}" - name: 输出最终匹配的非上行端口信息 ansible.builtin.debug: msg: "MAC {{ mac }} 所在交换机:{{ inventory_hostname }},端口:{{ item.item }},端口描述:{{ item.stdout[0] }}" loop: "{{ port_desc_results.results }}" when: "'UPLINK' not in item.stdout[0]"
过滤器逻辑说明
flatten:将output.stdout_lines的嵌套列表压平为一维列表,每个元素为MAC地址表的单条记录map('split'):将每条记录按任意空白字符分割为字段列表map('last'):取每个字段列表的最后一个元素即端口号,若要精准取第4个字段可替换为map('index', 3)(索引从0开始计数)unique:对重复的端口号去重,避免同一端口多VLAN条目重复执行查询
执行效果说明
- 未查询到目标MAC的交换机会自动终止后续任务,不输出冗余信息
- 查询到MAC的交换机会自动过滤描述包含
UPLINK的上行端口,最终只输出实际接入终端的端口信息
内容的提问来源于stack exchange,提问作者Gerry Maddock
相关产品推荐
相关产品推荐

