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 주소는 배열 또는 결과를 생성하며 여기에 대한 답변 덕분에 stdout을 추출했습니다.https://stackoverflow.com/questions/29512443/register-variables-in-with-items-loop-in-ansible-playbook

아래 Vladimir의 답변을 사용하여 다음과 같은 결론에 도달했습니다.

  - 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

묻다:"각 인터페이스에서 특정 제조업체 접두어를 찾아보세요."

답변: 제조업체 접두사는 처음 3개의 옥텟으로 구성됩니다. 예를 들어, 다음 명령문은

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_prefix문자열입니다. 항목의 길이는 8(16진수 6자리와 콜론 2개)입니다.

테스트를 위한 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_prefix

    - 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_vendor_prefix스스로. 해당 데이터베이스의 소스를 찾거나 Python 패키지를 사용할 수 있습니다.맥 공급업체 검색. 이 패키지에는 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 }}"

관련 정보