如何移除Cisco配置输出尾随空格以通过Ansible断言验证
解决Ansible验证Cisco Policy-Map配置时的尾随空格问题
问题背景
需要用Ansible的assert模块验证Cisco设备的policy-maps配置,但设备返回的部分配置行存在尾随空格,导致断言匹配失败。尝试过trim、strip等过滤器但未生效,需找到正确的处理方式。
现有Playbook代码
- name: Get running class-map & policy-map config vars: ansible_connection: network_cli ios_command: commands: - 'show run | sec class-map|policy-map' register: show_policy - name: Print trim debug: var: show_policy.stdout_lines | trim - name: Ansible block with assert module block: - name: Validate running line ansible.builtin.assert: that: - "lookup('template', 'policy_desired.j2').splitlines() in show_policy.stdout_lines" success_msg: "TEST: {{ UNIT_HOSTNAME }}: VALIDATE RUNNING POLICY: PASSED" fail_msg: "TEST: {{ UNIT_HOSTNAME }}: VALIDATE RUNNING POLICY: FAILED"
输出示例
{ "show_policy.stdout_lines | trim": [ [ "class-map match-any CM-QOS-GENERIC-BESTEFFORT-MARK", " description Generic - Best Effort", " match access-group name ACL-QOS-GENERIC-BESTEFFORT", "class-map match-any CM-QOS-1P3Q-Q1", " match dscp cs4 cs5 ef ", <--- 注意此处的尾随空格 "class-map match-any CM-QOS-1P3Q-Q2", " match dscp cs6 cs7 ", "class-map match-any CM-QOS-1P3Q-Q3", " match dscp cs1 " ] ] }
已尝试的无效过滤器
- name: Print trim debug: var: show_policy.stdout_lines | trim - name: Print trim debug: var: show_policy.stdout_lines | strip - name: Print trim debug: var: show_policy.stdout_lines.strip() - name: Print trim debug: var: "{{ show_policy.stdout_lines | map('trim') }}" - name: Print trim debug: var: "{{ show_policy.stdout_lines | trim }}"
正确解决方案
问题根源
show_policy.stdout_lines是二维列表:外层列表对应每个执行的命令结果(此处仅一个命令),内层列表是具体的配置行。之前的过滤器未生效,是因为直接对整个二维列表操作,而非遍历内层列表的每一行字符串。
修改后的Playbook
方法1:先预处理配置行(推荐)
- name: Get running class-map & policy-map config vars: ansible_connection: network_cli ios_command: commands: - 'show run | sec class-map|policy-map' register: show_policy - name: 处理配置行,移除每行的首尾空格 set_fact: processed_policy_lines: "{{ show_policy.stdout_lines[0] | map('trim') | list }}" - name: Ansible block with assert module block: - name: Validate running line ansible.builtin.assert: that: - "lookup('template', 'policy_desired.j2').splitlines() in processed_policy_lines" success_msg: "TEST: {{ UNIT_HOSTNAME }}: VALIDATE RUNNING POLICY: PASSED" fail_msg: "TEST: {{ UNIT_HOSTNAME }}: VALIDATE RUNNING POLICY: FAILED"
方法2:直接在断言中处理
- name: Get running class-map & policy-map config vars: ansible_connection: network_cli ios_command: commands: - 'show run | sec class-map|policy-map' register: show_policy - name: Ansible block with assert module block: - name: Validate running line ansible.builtin.assert: that: - "lookup('template', 'policy_desired.j2').splitlines() in (show_policy.stdout_lines[0] | map('trim') | list)" success_msg: "TEST: {{ UNIT_HOSTNAME }}: VALIDATE RUNNING POLICY: PASSED" fail_msg: "TEST: {{ UNIT_HOSTNAME }}: VALIDATE RUNNING POLICY: FAILED"
说明
show_policy.stdout_lines[0]:取第一个命令的输出列表(因为只执行了一个show命令)map('trim'):遍历列表中的每一行,执行trim操作(移除首尾空格,包括尾随空格)| list:将map返回的迭代器转换为列表,方便后续断言匹配
内容的提问来源于stack exchange,提问作者C.AN5
相关产品推荐
相关产品推荐

