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.
Find answers to your questions by entering keywords or phrases in the Search bar above. New here? Use these resources to familiarize yourself with the community: