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パッケージを使用できます。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 }}"

おすすめ記事