cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
2018
Views
7
Helpful
10
Replies

CRUD read operation returns None

Anton Abik
Level 4
Level 4

Hello,

I am playing with ydk and it works like charm for my IOS-XR devices. I created several applications and they all works. Then I tried to generate python API/Sphinx docs for Junos Yang models, that also worked like charm.

However I cannot run a single application against Junos devices and I dont know why. I am trying to get syslog configuration from device but all the values are None, however device is properly configured. In attachment (debug.txt) you can find output when I run the application with debuging on (verbose mode). Everything passed and you can even see correct values in the xml data (for example <log-rotate-frequency>10</log-rotate-frequency>)  but seems crud read operations doesnt pass these values to python object. My code is in attachment application.py

Can you please help me how can I troubleshoot further? thanks a lot

1 Accepted Solution

Accepted Solutions

Thanks for the attachment. I notice that there is some weird inconsistencies in the namespaces being used in the YANG model, the <get> RPC request and the RPC reply.

I see two separate namespaces for these:

  1. in the yang model (from which the YDK model API is generated): 'http://yang.juniper.net/yang/1.1/jc'
  2. in the <get> RPC request (from your debug log): 'http://yang.juniper.net/yang/1.1/jc'
  3. in the RPC reply (from your debug log): 'http://xml.juniper.net/xnm/1.1/xnm'

However, per the netconf/yang RFCs, the namespaces should remain consistent across all the above. For some reason, junos seems to diverge from the standard. This is likely the reason why YDK is not able to populate the python object.

View solution in original post

10 Replies 10

einarnn
Cisco Employee
Cisco Employee

Anton,

In this line in your .py file I noticed a typo:

print (syslog_configuration.__dic__)

It should be __dict__, I think. Can you fix that and see if it changes anything?

Apart from that, I have no further suggestions for now. Others might.

Cheers,

Einar

abhirame
Cisco Employee
Cisco Employee

Hi Anton,

From looking at the log, it seems that the server is returning the XML data and YDK is decoding the XML data into a python object, which you are trying to print out as <obj>.__dict__

Perhaps, a better way to process the YDK python object would be to iterate through it and print out the children. See this CRUD read sample for an example.

Another option could be to encode the YDK python object back into XML using the codec service. See this sample for example.

Anton Abik
Level 4
Level 4

Thanks a lot guys for your replies. Seems I attached the code with a typo I fixed later (the __dict__), so thats not the issue but thanks a lot for noticing.

I tried to iterate through all the objects in the hierarchy one by one but none of it is iterable. And again I see all the data in xml haha

EDIT: I added also the configuration.py. Its python compiled Junos Yang model.

Hi Anton,

Your application2.py looks great. I just have a couple comments/suggestions. In your app, you are reading the entire device configuration. So, the result of the crud read operation will be instances of the class: ydk.models.configuration.Configuration(). To know what the attributes of this class are, you can either look at the documentation, which you can generate using generate.py, or look at the class itself (configuration.py) which contains docstrings with information about the class attributes and types of each attribute. Then you can print out the data in a human readable format, which is what your app is presumably trying to do.

For example, try the below code and modify it as you desire to print the read data:

def testJunos(configuration):

    # Print attributes

    print ('Configuration version: {}'.format(configuration.version)) # System version

    print ('System host name: {}'.format(configuration.system.host_name)) # Hostname

    print ('System login message: {}'.format(configuration.system.login.message)) # Login message


    print()


    # Iterate the configuration.system.login.user YList and print out members

    for user in configuration.system.login.user:

        print('User name: {}'.format(user.name))

        print('User uid: {}'.format(user.uid))

        print('User class: {}'.format(user.class_))


    print()

   

    # By default all the attributes are set to None, so you may need to check for this

    if configuration.system.syslog.log_rotate_frequency is not None:

        print('Syslog log rotate frequency: {}'.format(configuration.system.syslog.log_rotate_frequency))


    # Iterate the configuration.system.syslog.user YList and print out members  

    for syslog_user in configuration.system.syslog.user:

        print('Syslog user name: {}'.format(syslog_user.name))

        for contents in syslog_user.contents:

            print('Syslog contents name: {}'.format(contents.name))

            print('Syslog contents emergency? {}'.format(contents.emergency == None))

Hello,

thank you very much for your answer.  I think that the issue here is that the crud.read object (syslog_configuration in my code) is just empty no matter what I do. Seems like the XML is not parsed back to python even though we can see from the debuging output that the XML data are sent properly. I wrote several applications for XR (using xr models) with YDK and that works just great. With the Junos generated yang models the data is not there. I dont have any explanation why its always empty. I am already using the documentation I generated with ydk-gen for Junos, thats not the issue, but thanks for noticing. I included it to attachment (maybe someone can use it haha, but beware extracted size is 1.1 GB)

Do you have please some other ideas how can I troubleshoot the CRUD object if it reads the xml?

Thanks a lot

Thanks for your reply. Can you please attach the python bundle tar file you generated using generate.py at this step? This will help me in reproducing the issue.

Anton Abik
Level 4
Level 4

Thanks a lot! In attachment also output from the server when I generated the junos API.

Thanks for the attachment. I notice that there is some weird inconsistencies in the namespaces being used in the YANG model, the <get> RPC request and the RPC reply.

I see two separate namespaces for these:

  1. in the yang model (from which the YDK model API is generated): 'http://yang.juniper.net/yang/1.1/jc'
  2. in the <get> RPC request (from your debug log): 'http://yang.juniper.net/yang/1.1/jc'
  3. in the RPC reply (from your debug log): 'http://xml.juniper.net/xnm/1.1/xnm'

However, per the netconf/yang RFCs, the namespaces should remain consistent across all the above. For some reason, junos seems to diverge from the standard. This is likely the reason why YDK is not able to populate the python object.

Anton Abik
Level 4
Level 4

Thank you very much abhirame you are genius! I edited the _yang_ns.py under "/usr/local/lib/python3.5/dist-packages/ydk/models/junos" to value the junos device returns and now it works like charm.

Maybe can be good to implement some exception for this? Just an idea.

Agreed.  YDK-Cpp should already throw an exception in this scenario.  YDK-Py should do the same in the next minor release.