■ はじめに
aci_epg_to_contract
モジュール は、EPG に対して Contract を紐付けれられます。state
オプションに query
を指定することで、紐付けされている Contract 一覧を取得できます。
この記事では簡単なサンプルをもとにして説明します。
参考
aci_rest
モジュール を利用する場合はこちら
tekunabe.hatenablog.jp
■ APIC 側画面
- 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 の紐付け設定がない場合は fvAEPg
に children
がない結果になります。その場合に備えて、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
を指定した結果なので、filter
や url
なども含まれます。
取得した 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)