04-07-2020 10:58 PM - edited 04-11-2020 12:16 AM
Hi experts,
Special call out to all those who have played with moquery like @lindawa , @Marcel Zehnder , @Remi Astruc - can one of you tell me how to make the -x query-target=children option for moquery display more than just one child object?
TBH - I think it is a bug with moquery, (in which case will one of you please report it) but bear with me.
I have created a Leaf Profile called T3:L102_LeafProf and an Interface Profile called T3:L102_IntProf
T3:L102_IntProf is linked to T3:L102_LeafProf
[Edit: I discovered after posting this question (mostly due to the answers I received) that I should have been using -x rsp-subtree=children. See my addendum below https://community.cisco.com/t5/application-centric/how-do-i-make-the-x-query-target-children-option-for-moquery/m-p/4063843/highlight/true#M8194]
Although this Interface Profile has been linked to a Leaf Profile, no Interface selectors have been assigned.
Running moquery on the DN with the -x query-target=children option yields what you would expect, a single Rt type child object.
apic1# moquery -d uni/infra/accportprof-T3:L102_IntProf -x query-target=children Total Objects shown: 1 # infra.RtAccPortP tDn : uni/infra/nprof-T3:L102_LeafProf childAction : dn : uni/infra/rtaccPortP-[uni/infra/nprof-T3:L102_LeafProf] lcOwn : local modTs : 2020-04-08T15:10:05.256 rn : rtaccPortP-[uni/infra/nprof-T3:L102_LeafProf] status : tCl : infraNodeP
I add an Interface Selector to the Interface Profile and run the precise same query again:
apic1# moquery -d uni/infra/accportprof-T3:L102_IntProf -x query-target=children Total Objects shown: 1 # infra.HPortS name : 1:18_IntSel type : range annotation : childAction : descr : dn : uni/infra/hports-1:18_IntSel-typ-range extMngdBy : lcOwn : local modTs : 2020-04-08T15:16:07.006 monPolDn : uni/fabric/monfab-default nameAlias : ownerKey : ownerTag : rn : hports-1:18_IntSel-typ-range status : uid : 15374
For some reason, the # infra.RtAccPortP child object is not shown - just the recently created Interface Selector
I add another Interface Selector to the Interface Profile and run the precise same query again: I won't bore you with the details, but it is exactly the same as above - one object displayed. (The same selector FWIW)
Compare this with the same output from the API (taken from visore), which shows all three child objects
/api/node/mo/uni/infra/accportprof-T3:L102_IntProf.json?query-target=children { "totalCount": "3", "imdata": [ { "infraHPortS": { "attributes": { "annotation": "", "childAction": "", "descr": "", "dn": "uni/infra/accportprof-T3:L102_IntProf/hports-1:18_IntSel-typ-range", "extMngdBy": "", "lcOwn": "local", "modTs": "2020-04-08T15:16:07.006", "monPolDn": "uni/fabric/monfab-default", "name": "1:18_IntSel", "nameAlias": "", "ownerKey": "", "ownerTag": "", "status": "", "type": "range", "uid": "15374" } } }, { "infraHPortS": { "attributes": { "annotation": "", "childAction": "", "descr": "", "dn": "uni/infra/accportprof-T3:L102_IntProf/hports-1:15_IntSel-typ-range", "extMngdBy": "", "lcOwn": "local", "modTs": "2020-04-08T15:20:26.235", "monPolDn": "uni/fabric/monfab-default", "name": "1:15_IntSel", "nameAlias": "", "ownerKey": "", "ownerTag": "", "status": "", "type": "range", "uid": "15374" } } }, { "infraRtAccPortP": { "attributes": { "childAction": "", "dn": "uni/infra/accportprof-T3:L102_IntProf/rtaccPortP-[uni/infra/nprof-T3:L102_LeafProf]", "lcOwn": "local", "modTs": "2020-04-08T15:10:05.256", "status": "", "tCl": "infraNodeP", "tDn": "uni/infra/nprof-T3:L102_LeafProf" } } } ] }
So back to my question.
Can one of you tell me how to make the -x query-target=children option for moquery display more than just one child object?
I notice I get a similar situation using the -x query-target=subtree option - at Stage#2 above with one Interface selector defined, I get one object in the response. At Stage#3, with two interface selectors defined, I still only get one object in the response.
I'd love someone to shine some light on this.
Techincal information:
apic1# show version Role Pod Node Name Version ---------- ---------- ---------- ------------------------ -------------------- controller 1 1 apic1 4.2(3l)
Solved! Go to Solution.
04-07-2020 11:40 PM - edited 04-07-2020 11:41 PM
Hi Chris
Same here. I also think it's a moquery-bug - I see this behaviour in 4.2 and 5.0 (EFT) code and I think it's also the case for 3.2.
So if you don't have access via HTTP/HTTPs to query the API and you need to get this information via APIC-CLI you may use icurl and python (for pretty printing):
apic# icurl -g 'http://localhost:7777/api/mo/<DN>.json?query-target=children' | python -m json.tool
Marcel
04-08-2020 02:33 AM
Hi @RedNectar and @Marcel Zehnder ,
Definitely a bit crazy, but here it is. Moving a step higher and filter on child.
moquery -c infraInfra -x 'query-target=children target-subtree-class=infraAccPortP rsp-subtree=children' -f 'infra.AccPortP.name=="T3:L102_IntProf"'
04-08-2020 02:53 AM - edited 04-08-2020 02:54 AM
Hi Chris,
RtAccPortP is a target relation to the interface profile:
So my first thought was that moquery is filtering relations from children list when querying by DN.
Looking at the moquery code (which is written in python) there is a difference on how the query by class and query by DN is implemented:
def handleClassQuery(session, classNames, parentDn=None, pfilter=None, opts={}): moDir = MoDirectory(session=session) allMos = [] classNames = classNames.split(',') for className in classNames: mos = moDir.lookupByClass(className, parentDn=parentDn, pfilter=pfilter, **opts) allMos.extend(mos) return allMos def handleDnQuery(session, dn, opts={}): moDir = MoDirectory(session=session) mo = moDir.lookupByDn(dn, **opts) if mo: return [mo] return None
Note1: the code can be found here:
admin@apic1:~> which moquery /controller/bin/moquery
Note2: the MoDirectory is a class in insieme.mit.access.
I haven't looked yet at how exactly are written the two lookup methods, but because of the slight in the two moquery functions, I tried querying by class and filtering by DN:
apic1# moquery -c infraAccPortP -d uni/infra/accportprof-ansible_101 -x query-target=children -x target-subtree-class=infraRtAccPortP Total Objects shown: 1 # infra.RtAccPortP tDn : uni/infra/nprof-ansible-101 childAction : dn : uni/infra/accportprof-ansible_101/rtaccPortP-[uni/infra/nprof-ansible-101] lcOwn : local modTs : 2020-04-08T09:15:27.793+03:00 rn : rtaccPortP-[uni/infra/nprof-ansible-101] status : tCl : infraNodeP
And it returns what you are looking for.
When I will have more time, I will look over the two lookup methods and see if I could see why the infraRtAccPortP is filtered out.
Hope it helps.
Regards,
Sergiu
04-07-2020 11:40 PM - edited 04-07-2020 11:41 PM
Hi Chris
Same here. I also think it's a moquery-bug - I see this behaviour in 4.2 and 5.0 (EFT) code and I think it's also the case for 3.2.
So if you don't have access via HTTP/HTTPs to query the API and you need to get this information via APIC-CLI you may use icurl and python (for pretty printing):
apic# icurl -g 'http://localhost:7777/api/mo/<DN>.json?query-target=children' | python -m json.tool
Marcel
04-08-2020 02:33 AM
Hi @RedNectar and @Marcel Zehnder ,
Definitely a bit crazy, but here it is. Moving a step higher and filter on child.
moquery -c infraInfra -x 'query-target=children target-subtree-class=infraAccPortP rsp-subtree=children' -f 'infra.AccPortP.name=="T3:L102_IntProf"'
04-08-2020 02:53 AM - edited 04-08-2020 02:54 AM
Hi Chris,
RtAccPortP is a target relation to the interface profile:
So my first thought was that moquery is filtering relations from children list when querying by DN.
Looking at the moquery code (which is written in python) there is a difference on how the query by class and query by DN is implemented:
def handleClassQuery(session, classNames, parentDn=None, pfilter=None, opts={}): moDir = MoDirectory(session=session) allMos = [] classNames = classNames.split(',') for className in classNames: mos = moDir.lookupByClass(className, parentDn=parentDn, pfilter=pfilter, **opts) allMos.extend(mos) return allMos def handleDnQuery(session, dn, opts={}): moDir = MoDirectory(session=session) mo = moDir.lookupByDn(dn, **opts) if mo: return [mo] return None
Note1: the code can be found here:
admin@apic1:~> which moquery /controller/bin/moquery
Note2: the MoDirectory is a class in insieme.mit.access.
I haven't looked yet at how exactly are written the two lookup methods, but because of the slight in the two moquery functions, I tried querying by class and filtering by DN:
apic1# moquery -c infraAccPortP -d uni/infra/accportprof-ansible_101 -x query-target=children -x target-subtree-class=infraRtAccPortP Total Objects shown: 1 # infra.RtAccPortP tDn : uni/infra/nprof-ansible-101 childAction : dn : uni/infra/accportprof-ansible_101/rtaccPortP-[uni/infra/nprof-ansible-101] lcOwn : local modTs : 2020-04-08T09:15:27.793+03:00 rn : rtaccPortP-[uni/infra/nprof-ansible-101] status : tCl : infraNodeP
And it returns what you are looking for.
When I will have more time, I will look over the two lookup methods and see if I could see why the infraRtAccPortP is filtered out.
Hope it helps.
Regards,
Sergiu
04-09-2020 05:01 AM
Friends,
What a wonderful response I got. Thank you all so much.
Finally, I must say that I really was overwhelmed by your great responses. I was actually preparing a blog post at the time on moquery, and getting a little frustrated. Anyway, that job's done and your responses really helped. Thanks again.
04-11-2020 12:08 AM - edited 10-28-2022 12:51 PM
FWIW - working on @Remi-Astruc's answer above I went back to my original query:
apic1# moquery -d uni/infra/accportprof-T3:L102_IntProf -x query-target=children
and made two changes:
So the final construction:
apic1# moquery -c infraAccPortP -d uni/infra/accportprof-T3:L102_IntProf -x rsp-subtree=children
returns the exact same output, and is just a little less convulted than Remi's
apic1# moquery -c infraInfra -x 'query-target=children target-subtree-class=infraAccPortP rsp-subtree=children' -f 'infra.AccPortP.name=="T3:L102_IntProf"'
... but given the question was about the "-x query-target=children" option, my solution doesn't realy answer the question, but changes the question so the answer fits. I should become a politician.
Anyway - added this to help others who are looking.
Discover and save your favorite ideas. Come back to expert answers, step-by-step guides, recent topics, and more.
New here? Get started with these tips. How to use Community New member guide