cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
6334
Views
40
Helpful
5
Replies

How do I make the -x query-target=children option for moquery display more than just one child object?

RedNectar
VIP
VIP

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]

Stage #1

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

Stage #2

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

Stage #3

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)

 

RedNectar aka Chris Welsh.
Forum Tips: 1. Paste images inline - don't attach. 2. Always mark helpful and correct answers, it helps others find what they need.
3 Accepted Solutions

Accepted Solutions

Marcel Zehnder
Spotlight
Spotlight

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

View solution in original post

Remi-Astruc
Cisco Employee
Cisco Employee

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"'

 

Remi Astruc

View solution in original post

Sergiu.Daniluk
VIP Alumni
VIP Alumni

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

View solution in original post

5 Replies 5

Marcel Zehnder
Spotlight
Spotlight

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

Remi-Astruc
Cisco Employee
Cisco Employee

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"'

 

Remi Astruc

Sergiu.Daniluk
VIP Alumni
VIP Alumni

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

RedNectar
VIP
VIP

Friends,

What a wonderful response I got. Thank you all so much.

  1. @Marcel Zehnder - thanks for confirming this is a bug. I don't think this code has been updated since 2014, so I guess it won't be now. Pity
  2. @Remi-Astruc - your solution actually worked for me, and helped me understand moquery a bit more. I guess strictly speaking, your answer was the most "correct", but
  3. @Sergiu.Daniluk - Sergui - what can I say? Thank you so much for you comprehensive answer and research into the source code itself. I'd be tempted to fix it if I thought it would ever be implemented, but I guess that is not likely to happen. I'm sure you answer will help others who end up here too

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.

 

RedNectar aka Chris Welsh.
Forum Tips: 1. Paste images inline - don't attach. 2. Always mark helpful and correct answers, it helps others find what they need.

RedNectar
VIP
VIP

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:

  1. Changed the -x option from query-target=children to rsp-subtree=children , and
  2. added a -c infraAccPortP option

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.

 

RedNectar aka Chris Welsh.
Forum Tips: 1. Paste images inline - don't attach. 2. Always mark helpful and correct answers, it helps others find what they need.
Getting Started

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:

Save 25% on Day-2 Operations Add-On License