Skip to content
This repository has been archived by the owner on May 15, 2019. It is now read-only.

Add args and kwargs support to method execution #69

Merged
merged 2 commits into from
Jul 3, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions docs/yang/parsers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -183,13 +183,15 @@ the device. For example::
parser: XMLParser
execute:
- method: _rpc
args:
args: []
Copy link
Member

@dbarrosop dbarrosop Jun 21, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need args. kwargs is probably enough.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both don't need to be specified in the YAML, but I think it might be wise to have the support in the future for args in the backend.

kwargs:
get: "<get-configuration/>"

* **execute** is a list of calls to do to from the device to extract the data.

* **method** is the method from the device to call.
* **args** are arguments that will be passed to the method.
* **args** are the numbered/ordered arguments for the method
* **kwargs** are the keyword arguments for the method

In addition, some methods like ``parse_config`` and ``parse_state`` may have mechanisms to pass the
information needed to the parser instead of relying on a live device to obtain it. For parsers, you
Expand Down
7 changes: 4 additions & 3 deletions docs/yang/writing_profiles.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,13 @@ If we check the content of the file ``vlan.yaml`` we can clearly see two parts:
processor: XMLParser
execute:
- method: _rpc
args:
args: []
kwargs:
get: "<get-configuration/>"

In this case we are using the ``XMLParser`` parser and in order to get the data we need from the
device we have to call the method ``_rpc`` with the ``args`` parameters. This is, by the way, an
RPC call for a junos device.
device we have to call the method ``_rpc`` with the ``args`` and ``kwargs`` parameters. This is,
by the way, an RPC call for a junos device.

* **vlan** - This is the part that follows the model specification. In this case is ``vlan`` but in
others it might be ``interfaces``, ``addressess`` or something else, this will be model dependent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ metadata:
processor: TextParser
execute:
- method: cli
args:
kwargs:
commands: ["show running-config all"]
interfaces:
_process: unnecessary
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ metadata:
processor: TextParser
execute:
- method: cli
args:
kwargs:
commands: ["show running-config all"]

network-instances:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ metadata:
processor: JSONParser
execute:
- method: "device.run_commands"
args:
kwargs:
commands: ["show interfaces", "show snmp mib ifmib ifindex"]

interfaces:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ metadata:
processor: TextParser
execute:
- method: cli
args:
kwargs:
commands: ["show running-config all"]
interfaces:
_process: unnecessary
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ metadata:
processor: XMLParser
execute:
- method: _rpc
args:
kwargs:
get: "<get-configuration/>"

interfaces:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ metadata:
processor: XMLParser
execute:
- method: _rpc
args:
kwargs:
get: "<get-configuration/>"

network-instances:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ metadata:
processor: XMLParser
execute:
- method: _rpc
args:
kwargs:
get: "<get-interface-information><extensive/></get-interface-information>"

interfaces:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ metadata:
parser:
execute:
- method:
args:
args: []
kwargs:
commands: [ ]

components:
Expand Down
8 changes: 7 additions & 1 deletion napalm_yang/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,15 @@ def _execute_methods(self, device, methods):
result = []
for m in methods:
attr = device
args = []
kwargs = {}
for p in m["method"].split("."):
attr = getattr(attr, p)
r = attr(**m["args"])
if isinstance(m.get("args", None), list):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't we default to an empty list/dict?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

defaults are set in lines 59/60 -- we just check if m has a valid dict/list to overwrite the default

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I see... I suggest doing this instead:

kwargs = m.get("kwargs", {})
if not isinstance(kwargs, dict):
    raise TypeError("kwargs has to be a dict")

Otherwise it seems like you are just ignoring invalid arguments without providing any feedback to the user.

args = m["args"]
if isinstance(m.get("kwargs", None), dict):
kwargs = m["kwargs"]
r = attr(*args, **kwargs)

if isinstance(r, dict) and all([isinstance(x, (str, unicode)) for x in r.values()]):
# Some vendors like junos return commands enclosed by a key
Expand Down