如何使用 Ansible 的 selectattr 过滤器筛选网络接口中的启用功能

在 Ansible 中,selectattr 是一个非常强大的 Jinja2 过滤器,用于根据对象的属性过滤序列。它允许你对复杂的数据结构进行筛选,提取符合特定条件的元素。

selectattr 过滤器简介

selectattr 过滤器可以根据对象的属性值应用测试条件,并选择符合条件的对象。如果没有指定测试条件,则属性的值将被当作布尔值进行评估。

语法:

{{ my_list | selectattr('attribute', 'test', 'value') }}
  • attribute:要筛选的对象属性。
  • test:可选的测试条件,默认为布尔测试。
  • value:测试条件的值。

示例:筛选网络接口中的启用功能

假设你想从 Ansible 收集的系统信息(facts)中筛选出网络接口 eth1 上启用的功能。以下是如何使用 selectattr 过滤器实现这一目标的示例。

Playbook 文件:selectattr.yml

---
- name: selectattr demo
  hosts: all
  gather_facts: true
  tasks:
    - name: all features
      ansible.builtin.debug:
        var: 'ansible_facts.eth1.features'

    - name: filter enabled
      ansible.builtin.debug:
        msg: "{{ (ansible_facts.eth1.features | dict2items | selectattr('value', 'match', 'on') ) }}"

执行命令

$ ansible-playbook -i virtualmachines/demo/inventory variables/selectattr.yml

执行结果

PLAY [selectattr demo] **********************************
TASK [Gathering Facts] **********************************
ok: [demo.example.com]
TASK [all features] *************************************
ok: [demo.example.com] => {
    "ansible_facts.eth1.features": {
        "esp_hw_offload": "off [fixed]",
        "esp_tx_csum_hw_offload": "off [fixed]",
        "fcoe_mtu": "off [fixed]",
        "generic_receive_offload": "on",
        "generic_segmentation_offload": "on",
        "highdma": "off [fixed]",
        "hw_tc_offload": "off [fixed]",
        "l2_fwd_offload": "off [fixed]",
        "large_receive_offload": "off [fixed]",
        "loopback": "off [fixed]",
        "netns_local": "off [fixed]",
        "ntuple_filters": "off [fixed]",
        "receive_hashing": "off [fixed]",
        "rx_all": "off",
        "rx_checksumming": "off",
        "rx_fcs": "off",
        "rx_gro_hw": "off [fixed]",
        "rx_gro_list": "off",
        "rx_udp_gro_forwarding": "off",
        "rx_udp_tunnel_port_offload": "off [fixed]",
        "rx_vlan_filter": "on [fixed]",
        "rx_vlan_offload": "on",
        "rx_vlan_stag_filter": "off [fixed]",
        "rx_vlan_stag_hw_parse": "off [fixed]",
        "scatter_gather": "on",
        "tcp_segmentation_offload": "on",
        "tls_hw_record": "off [fixed]",
        "tls_hw_rx_offload": "off [fixed]",
        "tls_hw_tx_offload": "off [fixed]",
        "tx_checksum_fcoe_crc": "off [fixed]",
        "tx_checksum_ip_generic": "on",
        "tx_checksum_ipv4": "off [fixed]",
        "tx_checksum_ipv6": "off [fixed]",
        "tx_checksum_sctp": "off [fixed]",
        "tx_checksumming": "on",
        "tx_esp_segmentation": "off [fixed]",
        "tx_fcoe_segmentation": "off [fixed]",
        "tx_gre_csum_segmentation": "off [fixed]",
        "tx_gre_segmentation": "off [fixed]",
        "tx_gso_list": "off [fixed]",
        "tx_gso_partial": "off [fixed]",
        "tx_gso_robust": "off [fixed]",
        "tx_ipxip4_segmentation": "off [fixed]",
        "tx_ipxip6_segmentation": "off [fixed]",
        "tx_lockless": "off [fixed]",
        "tx_nocache_copy": "off",
        "tx_scatter_gather": "on",
        "tx_scatter_gather_fraglist": "off [fixed]",
        "tx_sctp_segmentation": "off [fixed]",
        "tx_tcp6_segmentation": "off [fixed]",
        "tx_tcp_ecn_segmentation": "off [fixed]",
        "tx_tcp_mangleid_segmentation": "off",
        "tx_tcp_segmentation": "on",
        "tx_tunnel_remcsum_segmentation": "off [fixed]",
        "tx_udp_segmentation": "off [fixed]",
        "tx_udp_tnl_csum_segmentation": "off [fixed]",
        "tx_udp_tnl_segmentation": "off [fixed]",
        "tx_vlan_offload": "on [fixed]",
        "tx_vlan_stag_hw_insert": "off [fixed]",
        "vlan_challenged": "off [fixed]"
    }
}
TASK [filter enabled] ***********************************
ok: [demo.example.com] => {
    "msg": [
        {
            "key": "tx_checksumming",
            "value": "on"
        },
        {
            "key": "tx_checksum_ip_generic",
            "value": "on"
        },
        {
            "key": "scatter_gather",
            "value": "on"
        },
        {
            "key": "tx_scatter_gather",
            "value": "on"
        },
        {
            "key": "tcp_segmentation_offload",
            "value": "on"
        },
        {
            "key": "tx_tcp_segmentation",
            "value": "on"
        },
        {
            "key": "generic_segmentation_offload",
            "value": "on"
        },
        {
            "key": "generic_receive_offload",
            "value": "on"
        },
        {
            "key": "rx_vlan_offload",
            "value": "on"
        },
        {
            "key": "tx_vlan_offload",
            "value": "on [fixed]"
        },
        {
            "key": "rx_vlan_filter",
            "value": "on [fixed]"
        }
    ]
}
PLAY RECAP **********************************************
demo.example.com           : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

解释

  1. dict2items:将字典转换为键值对列表,以便进行过滤。
  2. selectattr:根据属性值筛选符合条件的元素。
    • selectattr('value', 'match', 'on'):筛选 value 属性中包含 on 的元素。

总结

  • selectattr 过滤器:用于根据对象的属性值进行筛选,非常适合处理复杂的数据结构。
  • dict2items:将字典转换为列表,以便使用 selectattr 过滤器。
  • 适用场景:当你需要从 Ansible 收集的系统信息(facts)中提取特定属性时,selectattr 是一个非常强大的工具。

通过 selectattr 过滤器,你可以轻松地从复杂的对象列表中提取符合特定条件的元素,从而实现更灵活的数据处理和自动化任务。