cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
922
Views
0
Helpful
2
Replies

NSO 6.1 Python API: Register two callpoints in same list

JennyW
Level 1
Level 1

Here is my yang module:

 

 

 

module pydp {
  namespace "http://tail-f.com/ns/example/pydp";
  prefix pydp; yang-version 1.1;

  import tailf-common {prefix tailf;}
  import ietf-inet-types {prefix inet;}

  list cont {
    key name;
    leaf name { type string; }
    container brief {
       tailf:callpoint mydp-cp-brief;
       config false;
       leaf status { type string; }
       leaf up-time { type string; }
    }
    container capabilities {
      tailf:callpoint mydp-cp-cap;
      config false;
      leaf test { type string; }
    }
  }
}

 

 

 

and my python:

 

 

 

import ncs 
import _ncs 
from ncs.experimental import DataCallbacks 

def dcb_start(state): 
  dcb = DataCallbacks(state.log)
  dcb.register('/mydp:cont', Handler())
  _ncs.dp.register_data_cb(state.ctx, 'mydp-cp-brief', dcb)
  _ncs.dp.register_data_cb(state.ctx, 'mydp-cp-cap', dcb)
  return state

def dcb_stop(start_state):
    pass

class Handler(object): 
    def get_object(self, tctx, kp, args): 
      cont_name = args.get("cont")
      with ncs.maapi.single_read_trans(tctx.uinfo.username, "passwd") as t: 
        root = ncs.maagic.get_root(t) 
        key = root.cont[device_name] 
        .... 
        return { 
          "brief": { 'status': 'value',  'up-time': 'value' }
        }

    def get_next(self, tctx, kp, args, next): 
      return None 

    def count(self): 
      return 0 

class Main(ncs.application.Application): 
  def setup(self): 
    ...
    self.register_fun(dcb_start, dcb_stop) 

  def teardown(self): 
    pass

 

 

 

I was hoping when get_object() in Handler class gets called, I can use kp to differentiate if it's for brief container or capabilities,  however, the kp was always /mydp:cont when I did "show cont brief" and "show cont capabilities". 

Now I wonder if it is possible to register multiple callpoints with same DataCallbacks instance. 

1 Accepted Solution

Accepted Solutions

tohagber
Cisco Employee
Cisco Employee

The low lever _ncs.X Python API documentation is not well documented. As a general comment i would recommend you to consult the c manual pages for the equivalent API functions https://developer.cisco.com/docs/nso/guides/#!ncs-man-pages-volume-3. The manpage states:
get_object()
...

The purpose of the callback is to return an entire object, i.e. a list entry, in one swoop. If the callback is not implemented, NSO will retrieve the whole object through a series of calls to get_elem().
...

By default, the callback will only be called for list entries - i.e. get_elem() is still needed for leafs that are not defined in a list, but if there are no such leafs in the part of the data model covered by a given callpoint, the get_elem() callback may be omitted when get_object() is registered. This has the drawback that NSO will have to invoke get_object() even if only a single leaf in a list entry is needed though, e.g. for the existence test mentioned for get_elem().

However, if the CONFD_DAEMON_FLAG_BULK_GET_CONTAINER flag is set via confd_set_daemon_flags(), get_object() will also be used for the toplevel ancestor container (if any) when no ancestor list node exists. I.e. in this case, get_elem() is only needed for toplevel leafs - if there are any such leafs in the part of the data model covered by a given callpoint.
...

So try to set the _ncs.dp.DAEMON_FLAG_BULK_GET_CONTAINER flag to verify that your get_object() will be invoked.

-Tommy


View solution in original post

2 Replies 2

tohagber
Cisco Employee
Cisco Employee

The low lever _ncs.X Python API documentation is not well documented. As a general comment i would recommend you to consult the c manual pages for the equivalent API functions https://developer.cisco.com/docs/nso/guides/#!ncs-man-pages-volume-3. The manpage states:
get_object()
...

The purpose of the callback is to return an entire object, i.e. a list entry, in one swoop. If the callback is not implemented, NSO will retrieve the whole object through a series of calls to get_elem().
...

By default, the callback will only be called for list entries - i.e. get_elem() is still needed for leafs that are not defined in a list, but if there are no such leafs in the part of the data model covered by a given callpoint, the get_elem() callback may be omitted when get_object() is registered. This has the drawback that NSO will have to invoke get_object() even if only a single leaf in a list entry is needed though, e.g. for the existence test mentioned for get_elem().

However, if the CONFD_DAEMON_FLAG_BULK_GET_CONTAINER flag is set via confd_set_daemon_flags(), get_object() will also be used for the toplevel ancestor container (if any) when no ancestor list node exists. I.e. in this case, get_elem() is only needed for toplevel leafs - if there are any such leafs in the part of the data model covered by a given callpoint.
...

So try to set the _ncs.dp.DAEMON_FLAG_BULK_GET_CONTAINER flag to verify that your get_object() will be invoked.

-Tommy


Thanks for the clarification. Really hope Cisco can update the Python API documentation.

Polls
AI-powered tools for network troubleshooting are likely to be part of everyone’s workflow sooner or later. What is the single biggest challenge or concern you see with adopting these tools in your organization?