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