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 NoneNote1: 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 NoneNote1: 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