てくなべ (tekunabe)

ansible / network / automation

[Ansible][ACI] EPG に紐付けされている Contract 一覧を取得する(aci_epg_to_contract モジュール版)

■ はじめに

aci_epg_to_contract モジュール は、EPG に対して Contract を紐付けれられます。state オプションに query を指定することで、紐付けされている Contract 一覧を取得できます。

この記事では簡単なサンプルをもとにして説明します。

  • 環境
    • Cisco DevNet Sandbox (APIC 4.1)
    • Ansible 2.9.0

参考

aci_rest モジュール を利用する場合はこちら tekunabe.hatenablog.jp


APIC 側画面

f:id:akira6592:20191104110233p:plain:w400
EPG への Contract 紐付け設定画面
ある EPG

  • Provided Contract: c_sql、c_web
  • Consumed Contract: c_test

と設定されている状態を想定します。


■ Playbook

取得には、aci_epg_to_contract モジュールを利用します。state: query であっても contract_type のオプションの指定(provider / consumer)が必要です。そのため、タイプごとに取得することになります。(aci_rest モジュールを利用すればいっぺんに取得する方法ははこちら [Ansible][ACI] EPG に紐付けされている Contract 一覧を取得する(aci_rest モジュール版) - てくなべ (tekunabe)

Provided Contracts 取得時には fvRsProv が、Consumed Contracts 取得時には fvRsCons が返ってくるので、用途に合わせてキーを変えます。

---
- hosts: apic
  gather_facts: no

  tasks:
    # provided contracts
    - name: get provided contracts
      aci_epg_to_contract:
        host: "{{ ansible_host }}"
        username: "{{ username }}"
        password: "{{ password }}"
        validate_certs: no
        tenant: tenant1
        ap: ap1
        epg: epg1
        contract_type: provider  # provider / consumer の指定が必要
        output_level: debug
        state: query
      register: result_p

    - name: debug provided contracts
      debug:
        msg: "{{ item.fvRsProv.attributes.tnVzBrCPName }}"
      loop: "{{ result_p.current[0].fvAEPg.children | default([]) }}"
      loop_control:
        label: "{{ item.fvRsProv.attributes.tnVzBrCPName }}"

    # consumed contracts
    - name: get consumed contracts
      aci_epg_to_contract:
        host: "{{ ansible_host }}"
        username: "{{ username }}"
        password: "{{ password }}"
        validate_certs: no
        tenant: tenant1
        ap: ap1
        epg: epg1
        contract_type: consumer # provider / consumer の指定が必要
        output_level: debug
        state: query
      register: result_c

    - name: debug consumed contracts
      debug: 
        msg: "{{ item.fvRsCons.attributes.tnVzBrCPName }}"
      loop: "{{ result_c.current[0].fvAEPg.children | default([]) }}"
      loop_control:
        label: "{{ item.fvRsCons.attributes.tnVzBrCPName }}"

Contract の紐付け設定がない場合への対応

表示には、debug モジュールを利用します。Contract の紐付け設定がない場合は fvAEPgchildren がない結果になります。その場合に備えて、loop: "{{ result_p.current[0].fvAEPg.children | default([]) }}" のように、default フィルターを利用しています。よって、Contract の紐付け設定がない場合は、debug のループをしません。 他には、when: result.current[0].fvAEPg.children is defined という条件をつける方法もあります。


■ 実行

Playbook を実行します。

$ ansible-playbook -i ../../inventory.ini get_contracts.yml 

PLAY [apic] ************************************************************************************

TASK [get provided contracts] ******************************************************************

ok: [apic01]

TASK [debug provided contracts] ****************************************************************
ok: [apic01] => (item=c_sql) => {
    "msg": "c_sql" 
}
ok: [apic01] => (item=c_web) => {
    "msg": "c_web"
}

TASK [get consumed contracts] ******************************************************************
ok: [apic01]

TASK [debug consumed contracts] ****************************************************************
ok: [apic01] => (item=c_test) => {
    "msg": "c_test"
}

PLAY RECAP *************************************************************************************
apic01                     : ok=6    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

各 debug モジュールの取得で

  • Provided Contract: c_sql、c_web
  • Consumed Contract: c_test

となっていることを確認できました。

参考: query で取得したデータの全体

今回は、query した結果の中身の特定のキーを指定しています。参考のために query した結果の全体の中身も掲載します。 output_level: debug を指定した結果なので、filterurl なども含まれます。

取得した provided contracts のデータ

クリックして広げて見る

{
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "current": [
        {
            "fvAEPg": {
                "attributes": {
                    "annotation": "",
                    "childAction": "",
                    "configIssues": "",
                    "configSt": "applied",
                    "descr": "",
                    "dn": "uni/tn-tenant1/ap-ap1/epg-epg1",
                    "exceptionTag": "",
                    "extMngdBy": "",
                    "floodOnEncap": "disabled",
                    "fwdCtrl": "",
                    "hasMcastSource": "no",
                    "isAttrBasedEPg": "no",
                    "isSharedSrvMsiteEPg": "no",
                    "lcOwn": "local",
                    "matchT": "AtleastOne",
                    "modTs": "2019-11-03T14:54:44.955+00:00",
                    "monPolDn": "uni/tn-common/monepg-default",
                    "name": "epg1",
                    "nameAlias": "",
                    "pcEnfPref": "unenforced",
                    "pcTag": "32771",
                    "prefGrMemb": "exclude",
                    "prio": "unspecified",
                    "scope": "2555904",
                    "shutdown": "no",
                    "status": "",
                    "triggerSt": "triggerable",
                    "txId": "17293822569102705193",
                    "uid": "15374"
                },
                "children": [
                    {
                        "fvRsProv": {
                            "attributes": {
                                "annotation": "",
                                "childAction": "",
                                "ctrctUpd": "ctrct",
                                "extMngdBy": "",
                                "forceResolve": "yes",
                                "lcOwn": "local",
                                "matchT": "AtleastOne",
                                "modTs": "2019-11-04T01:39:51.572+00:00",
                                "monPolDn": "uni/tn-common/monepg-default",
                                "prio": "unspecified",
                                "rType": "mo",
                                "rn": "rsprov-c_sql",
                                "state": "formed",
                                "stateQual": "none",
                                "status": "",
                                "tCl": "vzBrCP",
                                "tContextDn": "",
                                "tDn": "uni/tn-tenant1/brc-c_sql",
                                "tRn": "brc-c_sql",
                                "tType": "name",
                                "tnVzBrCPName": "c_sql",
                                "triggerSt": "triggerable",
                                "uid": "15374",
                                "updateCollection": "no"
                            },
                            "children": [
                                {
                                    "fvCollectionCont": {
                                        "attributes": {
                                            "childAction": "deleteNonPresent",
                                            "collectionDn": "uni/tn-tenant1/brc-c_sql",
                                            "lcOwn": "local",
                                            "modTs": "2019-11-03T15:28:38.764+00:00",
                                            "monPolDn": "uni/tn-common/monepg-default",
                                            "name": "",
                                            "nameAlias": "",
                                            "rn": "collectionDn-[uni/tn-tenant1/brc-c_sql]",
                                            "status": ""
                                        }
                                    }
                                }
                            ]
                        }
                    },
                    {
                        "fvRsProv": {
                            "attributes": {
                                "annotation": "",
                                "childAction": "",
                                "ctrctUpd": "ctrct",
                                "extMngdBy": "",
                                "forceResolve": "yes",
                                "lcOwn": "local",
                                "matchT": "AtleastOne",
                                "modTs": "2019-11-04T01:39:51.572+00:00",
                                "monPolDn": "uni/tn-common/monepg-default",
                                "prio": "unspecified",
                                "rType": "mo",
                                "rn": "rsprov-c_web",
                                "state": "formed",
                                "stateQual": "none",
                                "status": "",
                                "tCl": "vzBrCP",
                                "tContextDn": "",
                                "tDn": "uni/tn-tenant1/brc-c_web",
                                "tRn": "brc-c_web",
                                "tType": "name",
                                "tnVzBrCPName": "c_web",
                                "triggerSt": "triggerable",
                                "uid": "15374",
                                "updateCollection": "no"
                            },
                            "children": [
                                {
                                    "fvCollectionCont": {
                                        "attributes": {
                                            "childAction": "deleteNonPresent",
                                            "collectionDn": "uni/tn-tenant1/brc-c_web",
                                            "lcOwn": "local",
                                            "modTs": "2019-11-03T15:16:07.253+00:00",
                                            "monPolDn": "uni/tn-common/monepg-default",
                                            "name": "",
                                            "nameAlias": "",
                                            "rn": "collectionDn-[uni/tn-tenant1/brc-c_web]",
                                            "status": ""
                                        }
                                    }
                                }
                            ]
                        }
                    }
                ]
            }
        }
    ],
    "failed": false,
    "filter_string": "?rsp-subtree-class=fvRsProv&rsp-subtree=full",
    "method": "GET",
    "proposed": {},
    "response": "OK (2348 bytes)",
    "sent": {},
    "status": 200,
    "url": "https://apic01/api/mo/uni/tn-tenant1/ap-ap1/epg-epg1.json",
    "warnings": [
        "Platform darwin on host apic01 is using the discovered Python interpreter at /usr/bin/python, but future installation of another Python interpreter could change this. See https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information."
    ]
}

取得した consumed contracts のデータ

クリックして広げて見る

{
    "changed": false,
    "current": [
        {
            "fvAEPg": {
                "attributes": {
                    "annotation": "",
                    "childAction": "",
                    "configIssues": "",
                    "configSt": "applied",
                    "descr": "",
                    "dn": "uni/tn-tenant1/ap-ap1/epg-epg1",
                    "exceptionTag": "",
                    "extMngdBy": "",
                    "floodOnEncap": "disabled",
                    "fwdCtrl": "",
                    "hasMcastSource": "no",
                    "isAttrBasedEPg": "no",
                    "isSharedSrvMsiteEPg": "no",
                    "lcOwn": "local",
                    "matchT": "AtleastOne",
                    "modTs": "2019-11-03T14:54:44.955+00:00",
                    "monPolDn": "uni/tn-common/monepg-default",
                    "name": "epg1",
                    "nameAlias": "",
                    "pcEnfPref": "unenforced",
                    "pcTag": "32771",
                    "prefGrMemb": "exclude",
                    "prio": "unspecified",
                    "scope": "2555904",
                    "shutdown": "no",
                    "status": "",
                    "triggerSt": "triggerable",
                    "txId": "17293822569102705193",
                    "uid": "15374"
                },
                "children": [
                    {
                        "fvRsCons": {
                            "attributes": {
                                "annotation": "",
                                "childAction": "",
                                "ctrctUpd": "ctrct",
                                "deplInfo": "",
                                "extMngdBy": "",
                                "forceResolve": "yes",
                                "lcOwn": "local",
                                "modTs": "2019-11-04T01:39:51.572+00:00",
                                "monPolDn": "uni/tn-common/monepg-default",
                                "prio": "unspecified",
                                "rType": "mo",
                                "rn": "rscons-c_test",
                                "state": "formed",
                                "stateQual": "none",
                                "status": "",
                                "tCl": "vzBrCP",
                                "tContextDn": "",
                                "tDn": "uni/tn-tenant1/brc-c_test",
                                "tRn": "brc-c_test",
                                "tType": "name",
                                "tnVzBrCPName": "c_test",
                                "triggerSt": "triggerable",
                                "uid": "15374",
                                "updateCollection": "no"
                            },
                            "children": [
                                {
                                    "fvCollectionCont": {
                                        "attributes": {
                                            "childAction": "deleteNonPresent",
                                            "collectionDn": "uni/tn-tenant1/brc-c_test",
                                            "lcOwn": "local",
                                            "modTs": "2019-11-04T01:39:51.572+00:00",
                                            "monPolDn": "uni/tn-common/monepg-default",
                                            "name": "",
                                            "nameAlias": "",
                                            "rn": "collectionDn-[uni/tn-tenant1/brc-c_test]",
                                            "status": ""
                                        }
                                    }
                                }
                            ]
                        }
                    }
                ]
            }
        }
    ],
    "failed": false,
    "filter_string": "?rsp-subtree-class=fvRsCons&rsp-subtree=full",
    "method": "GET",
    "proposed": {},
    "response": "OK (1514 bytes)",
    "sent": {},
    "status": 200,
    "url": "https://apic01/api/mo/uni/tn-tenant1/ap-ap1/epg-epg1.json"
}


■ まとめ

aci_epg_to_contract モジュール を利用して、EPG に紐付けれられている Contract の一覧を取得しました。 state: query を指定し、Provided Contract、Consumed Contract それぞれ取得しました。

参考

[Ansible][ACI] EPG に紐付けされている Contract 一覧を取得する(aci_rest モジュール版) - てくなべ (tekunabe)