cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
6362
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.

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