cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
2326
Views
0
Helpful
1
Replies

Python/YANG tailf:cli-completion-actionpoint example

mohamkh7
Cisco Employee
Cisco Employee

Hi All,

 

I am looking for Python/YANG tailf:cli-completion-actionpoint example where custom list can be displayed in CLI mode from a completion action callback.

I tried the below example:

 

YANG Pseudo code where actionpoint is defined

        leaf interface {
          tailf:info "Endpoint Port";
          type string;
          tailf:cli-completion-actionpoint if-action;
          mandatory true;
        }

 

Python Code where Application and Callback is implemented

 

# -*- mode: python; python-indent: 4 -*-
from ncs.dp import Daemon
from ncs.maapi import Maapi
from _ncs.dp import register_action_cbs, action_reply_completion

# ----------------------
# L3VPN ACTION CALLBACKS
# ----------------------
class ActionCallbacks(object):
    def __init__(self, log):
        self.log = log
        self.logPrefix = 'ActionCallbacks:'
        self.daemon = Daemon("l3vpn-cli-completion-daemon", log=log)
        self.maapi = Maapi()
        self.log.info(self.logPrefix, 'register_action_cbs start')
        register_action_cbs(self.daemon.ctx(), 'if-action', self)
        self.daemon.start()
        self.log.info(self.logPrefix, 'register_action_cbs end')

    def cb_init(self, tctx):
        self.log.info(self.logPrefix, 'cb_init')
        self.maapi.attach(tctx)
        trans_set_fd(tctx, self.daemon._wsock)

    def cb_abort(self, uinfo):
        self.log.info(self.logPrefix, 'cb_abort')
        self.maapi.detach(tctx)

    def cb_action(self, uinfo, name, kp, params):
        self.log.info(self.logPrefix, 'cb_action')

    def cb_command(self, uinfo, path, argv):
        self.log.info(self.logPrefix, 'cb_command')

    def cb_completion(self, uinfo, cli_style, token, completion_char,
                      kp, cmdpath, cmdparam_id, simpleType, extra):
        self.log.info(self.logPrefix, 'cb_completion({},{},{},{},{},{},{},{},{})'.format(
            uinfo, cli_style, token, completion_char, kp, cmdpath, cmdparam_id, simpleType, extra))

        if_list = [(0, 'ge-0/1', None), (0, 'fe-0/0', None),
                   (0, 'ge-0/2', None)]
        action_reply_completion(uinfo, if_list)


# ---------------------------------------------
# COMPONENT THREAD THAT WILL BE STARTED BY NCS.
# ---------------------------------------------
class L3VPN(ncs.application.Application):
    def setup(self):
        self.log.info('L3VPN RUNNING')

        self.acb = ActionCallbacks(self.log)
        self.register_service('l3vpn-servicepoint', ServiceCallbacks)

def teardown(self): self.log.info('L3VPN FINISHED')

Some of the code is ommited for simplicity.

 

From CLI when i hit tab on interface I don't see any custom list of interfaces

For each tab hit i see cb_init is called (printed in the log) but cb_completion callback never called.

 

Here is the log

<INFO> 07-May-2019::14:07:50.305 l3vpn ComponentThread:l3vpn: - ActionCallbacks:register_action_cbs start
<INFO> 07-May-2019::14:07:50.306 l3vpn ComponentThread:l3vpn: - ActionCallbacks:register_action_cbs end
<INFO> 07-May-2019::14:09:18.904 l3vpn l3vpn-cli-completion-daemon: - ActionCallbacks:cb_init
<INFO> 07-May-2019::14:09:22.950 l3vpn l3vpn-cli-completion-daemon: - ActionCallbacks:cb_init
<INFO> 07-May-2019::14:09:23.964 l3vpn l3vpn-cli-completion-daemon: - ActionCallbacks:cb_init
<INFO> 07-May-2019::14:09:26.696 l3vpn l3vpn-cli-completion-daemon: - ActionCallbacks:cb_init
<INFO> 07-May-2019::14:09:28.917 l3vpn l3vpn-cli-completion-daemon: - ActionCallbacks:cb_init

Any help is highly appreciated.

 

Thanks

Zahid

 

1 Accepted Solution

Accepted Solutions

mohamkh7
Cisco Employee
Cisco Employee

I solved the problem, Here are the changes in Callback class

 

 

 

class ActionCallbacks(object):
    def __init__(self, log):
        self.log = log
        self.logPrefix = 'ActionCallbacks:'
        self.daemon = Daemon("l3vpn-cli-completion-daemon", log=log)
        self.completion_action = 'if-action'
        register_action_cbs(self.daemon.ctx(), self.completion_action, self)
        self.daemon.start()

    def cb_init(self, uinfo):
        self.log.info(self.logPrefix, 'cb_init')
        self.log.info(self.logPrefix, 'cb_init daemon alive :',
                      self.daemon.isAlive())
        name = 'usid-{0}-{1}'.format(uinfo.usid, self.completion_action)
        key = '{0}-{1}'.format(id(self), uinfo.usid)
        wsock = ncs.dp.take_worker_socket(self.daemon, name, key)
        # dp.action_set_timeout(unifo, 2)
        _tm.dp.action_set_fd(uinfo, wsock)
        self.log.info(self.logPrefix, 'cb_init', ' complete')

    def cb_abort(self, uinfo):
        self.log.info(self.logPrefix, 'cb_abort')

    def cb_action(self, uinfo, name, kp, params):
        self.log.info(self.logPrefix, 'cb_action')

    def cb_command(self, uinfo, path, argv):
        self.log.info(self.logPrefix, 'cb_command')

    def cb_completion(self, uinfo, cli_style, token, completion_char,
                      kp, cmdpath, cmdparam_id, simpleType, extra):
        self.log.info(self.logPrefix, 'cb_completion({},{},{},{},{},{},{},{},{})'.format(
            uinfo, cli_style, token, completion_char, kp, cmdpath, cmdparam_id, simpleType, extra))

        if_list = [(0, 'ge-0/1', None), (0, 'fe-0/0', None),
                   (0, 'ge-0/2', None)]
        action_reply_completion(uinfo, if_list)

 

 

View solution in original post

1 Reply 1

mohamkh7
Cisco Employee
Cisco Employee

I solved the problem, Here are the changes in Callback class

 

 

 

class ActionCallbacks(object):
    def __init__(self, log):
        self.log = log
        self.logPrefix = 'ActionCallbacks:'
        self.daemon = Daemon("l3vpn-cli-completion-daemon", log=log)
        self.completion_action = 'if-action'
        register_action_cbs(self.daemon.ctx(), self.completion_action, self)
        self.daemon.start()

    def cb_init(self, uinfo):
        self.log.info(self.logPrefix, 'cb_init')
        self.log.info(self.logPrefix, 'cb_init daemon alive :',
                      self.daemon.isAlive())
        name = 'usid-{0}-{1}'.format(uinfo.usid, self.completion_action)
        key = '{0}-{1}'.format(id(self), uinfo.usid)
        wsock = ncs.dp.take_worker_socket(self.daemon, name, key)
        # dp.action_set_timeout(unifo, 2)
        _tm.dp.action_set_fd(uinfo, wsock)
        self.log.info(self.logPrefix, 'cb_init', ' complete')

    def cb_abort(self, uinfo):
        self.log.info(self.logPrefix, 'cb_abort')

    def cb_action(self, uinfo, name, kp, params):
        self.log.info(self.logPrefix, 'cb_action')

    def cb_command(self, uinfo, path, argv):
        self.log.info(self.logPrefix, 'cb_command')

    def cb_completion(self, uinfo, cli_style, token, completion_char,
                      kp, cmdpath, cmdparam_id, simpleType, extra):
        self.log.info(self.logPrefix, 'cb_completion({},{},{},{},{},{},{},{},{})'.format(
            uinfo, cli_style, token, completion_char, kp, cmdpath, cmdparam_id, simpleType, extra))

        if_list = [(0, 'ge-0/1', None), (0, 'fe-0/0', None),
                   (0, 'ge-0/2', None)]
        action_reply_completion(uinfo, if_list)

 

 

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?