Ansible - 将字符串与列表中的项目匹配

Ansible - 将字符串与列表中的项目匹配

我正在尝试迭代 Ansible 中的列表并在其中的每个项目中搜索字符串,然后将匹配的项目分配给变量。更具体地说,我将每个节点上的所有 MAC 地址提取到一个列表中,并在每个接口中查找特定的制造商前缀。

该列表是根据 Ansible 事实创建的 - 我在游戏开始时创建它:

  vars:
    mac_addresses: []

然后将发现的事实添加到其中:

- name: Find MAC addresses
    shell: "echo {{ ansible_facts[item]['macaddress']|default(None) }}"
    register: mac_addresses
    with_items:
    - "{{ ansible_interfaces }}"

然后我尝试迭代该列表 - 我尝试使用以下match方法:

  - name: Find correct MAC address
    debug:
      msg: "{{ item }} is the correct NIC"
    when: "{{ item }}" is match("*[mac prefix]*")
    with_items:
    - "{{ mac_addresses }}"
    

我还尝试将前缀注册到变量并使用条件,将上面的when行替换为:

when: correct_prefix in mac_addresses

两者都无法运行或产生不需要的结果。

我将如何在列表中查找字符串并将结果注册到变量中?我浏览了互联网和文档,但无法弄清楚 - 任何帮助将不胜感激。

谢谢!

编辑:上面的代码找到的MAC地址产生了一个数组或结果,由于这里的答案,我从中提取了标准输出:https://stackoverflow.com/questions/29512443/register-variables-in-with-items-loop-in-ansible-playbook

使用弗拉基米尔下面的答案,我得出以下结论:

  - debug: var="mac_addresses"
  - debug: msg="item.item={{item.item}}, item.stdout={{item.stdout}}, item.changed={{item.changed}}"
    with_items: "{{ mac_addresses.results }}"
  - debug:
      msg: "{{ item.stdout }} is the correct NIC"
    loop: "{{ mac_addresses.results }}"
    when: item[0:8] in mac_prefix

...即使在变量中设置了所需的前缀之后,我也无法开始工作。任何澄清将不胜感激 - 我什至不确定要寻找哪些文档。

谢谢!

答案1

问:在每个接口中查找特定的制造商前缀。

答:制造商前缀由前三个八位字节组成。例如,下面的声明

mac_vendor_prefix:
  '00:22:64': HP
  '00:23:B2': Intel
  '00:A0:C6': Qualcomm
mac_prefix: "{{ mac_vendor_prefix.keys()|list }}"

mac_prefix:
  - 00:22:64
  - 00:23:B2
  - 00:A0:C6

清单中的项目mac_前缀是字符串。项目的长度为 8(六个十六进制数字和两个冒号)。

给定用于测试的 MAC 地址列表,例如

mac_addresses:
  - 00:22:64:12:34:5A
  - 00:22:64:12:34:5B
  - 00:23:B2:12:34:5A
  - 00:23:B2:12:34:5B
  - 00:A0:C6:12:34:5A
  - 00:A0:C6:12:34:5B
  - FF:FF:FF:FF:FF:FA
  - FF:FF:FF:FF:FF:FB

该任务测试 MAC 的供应商前缀是否在列表中mac_前缀

    - debug:
        msg: "{{ item }} is the correct NIC"
      loop: "{{ mac_addresses }}"
      when: item[0:8] in mac_prefix

给出(删节)

msg: 00:22:64:12:34:5A is the correct NIC
msg: 00:22:64:12:34:5B is the correct NIC
msg: 00:23:B2:12:34:5A is the correct NIC
msg: 00:23:B2:12:34:5B is the correct NIC
msg: 00:A0:C6:12:34:5A is the correct NIC
msg: 00:A0:C6:12:34:5B is the correct NIC
skipping: [localhost] => (item=FF:FF:FF:FF:FF:FB)
skipping: [localhost] => (item=FF:FF:FF:FF:FF:FB)

下一个任务显示供应商

    - debug:
        msg: "{{ item }} {{ mac_vendor_prefix[item[0:8]]|
                            d('Prefix is not registered') }}"
      loop: "{{ mac_addresses }}"

给出(删节)

msg: 00:22:64:12:34:5A HP
msg: 00:22:64:12:34:5B HP
msg: 00:23:B2:12:34:5A Intel
msg: 00:23:B2:12:34:5B Intel
msg: 00:A0:C6:12:34:5A Qualcomm
msg: 00:A0:C6:12:34:5B Qualcomm
msg: FF:FF:FF:FF:FF:FA Prefix is not registered
msg: FF:FF:FF:FF:FF:FB Prefix is not registered

用于测试的完整剧本示例

- hosts: localhost

  vars:

    mac_addresses:
      - 00:22:64:12:34:5A
      - 00:22:64:12:34:5B
      - 00:23:B2:12:34:5A
      - 00:23:B2:12:34:5B
      - 00:A0:C6:12:34:5A
      - 00:A0:C6:12:34:5B
      - FF:FF:FF:FF:FF:FA
      - FF:FF:FF:FF:FF:FB

    mac_vendor_prefix:
      '00:22:64': HP
      '00:23:B2': Intel
      '00:A0:C6': Qualcomm
    mac_prefix: "{{ mac_vendor_prefix.keys()|list }}"

  tasks:

    - debug:
        var: mac_prefix

    - debug:
        msg: "{{ item }} is the correct NIC"
      loop: "{{ mac_addresses }}"
      when: item[0:8] in mac_prefix

    - debug:
        msg: "{{ item }} {{ mac_vendor_prefix[item[0:8]]|
                            default('Prefix is not registered') }}"
      loop: "{{ mac_addresses }}"

维护数据库不太现实mac_供应商_前缀靠你自己。您可以找到此类数据库的来源或使用 Python 包mac 供应商查找。该软件包包含 IEEE 的 OUI 前缀列表的本地副本。安装此包并创建过滤器

shell> cat plugins/filter/mac-vendor-lookup.py
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

from ansible.errors import AnsibleFilterError
from ansible.module_utils.six import string_types
from mac_vendor_lookup import MacLookup


def mac_vendor_lookup(mac):
    if not isinstance(mac, string_types):
        raise AnsibleFilterError('The argument for mac_lookup must be string. %s is %s' %
                                 (mac, type(mac)))
    try:
        vendor = MacLookup().lookup(mac)
    except KeyError:
        vendor = 'Prefix is not registered'

    return vendor


class FilterModule(object):
    ''' Ansible wrapper for Mac Vendor Lookup '''

    def filters(self):
        return {
            'mac_vendor_lookup': mac_vendor_lookup,
        }

然后,任务显示供应商

    - debug:
        msg: "{{ item }} {{ item|mac_vendor_lookup }}"
      loop: "{{ mac_addresses }}"

给出(删节)

msg: 00:22:64:12:34:5A Hewlett Packard
msg: 00:22:64:12:34:5B Hewlett Packard
msg: 00:23:B2:12:34:5A Intelligent Mechatronic Systems Inc
msg: 00:23:B2:12:34:5B Intelligent Mechatronic Systems Inc
msg: 00:A0:C6:12:34:5A Qualcomm Inc.
msg: 00:A0:C6:12:34:5B Qualcomm Inc.
msg: FF:FF:FF:FF:FF:FA Prefix is not registered
msg: FF:FF:FF:FF:FF:FB Prefix is not registered

用于测试的完整剧本示例

- hosts: localhost

  vars:

    mac_addresses:
      - 00:22:64:12:34:5A
      - 00:22:64:12:34:5B
      - 00:23:B2:12:34:5A
      - 00:23:B2:12:34:5B
      - 00:A0:C6:12:34:5A
      - 00:A0:C6:12:34:5B
      - FF:FF:FF:FF:FF:FA
      - FF:FF:FF:FF:FF:FB

  tasks:

    - debug:
        msg: "{{ item }} {{ item|mac_vendor_lookup }}"
      loop: "{{ mac_addresses }}"

相关内容