Skip to content

Commit

Permalink
Merge pull request Juniper#403 from vnitinv/json-support
Browse files Browse the repository at this point in the history
for JSON support
  • Loading branch information
vnitinv committed Sep 29, 2015
2 parents 99384d3 + 36b0006 commit c7f2532
Showing 3 changed files with 196 additions and 3 deletions.
15 changes: 15 additions & 0 deletions lib/jnpr/junos/device.py
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@
import socket
import datetime
import time
import json

# 3rd-party packages
from lxml import etree
@@ -572,6 +573,20 @@ def execute(self, rpc_cmd, **kvargs):
warnings.warn("An unknown exception occured - please report.", RuntimeWarning)
raise

# From 14.2 onward, junos supports JSON, so now code can be written as
# dev.rpc.get_route_engine_information({'format': 'json'})

if rpc_cmd_e.attrib.get('format') in ['json', 'JSON']:
if self._facts == {}:
self.facts_refresh()
ver_info = self._facts['version_info']
if ver_info.major[0] >= 15 or \
(ver_info.major[0] == 14 and ver_info.major[1] >= 2):
return json.loads(rpc_rsp_e.text)
else:
warnings.warn("Native JSON support is only from 14.2 onwards",
RuntimeWarning)

# This section is here for the possible use of something other than ncclient
# for RPCs that have embedded rpc-errors, need to check for those now

120 changes: 120 additions & 0 deletions tests/unit/rpc-reply/get-system-users-information.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<rpc-reply message-id="urn:uuid:986c395e-2f84-11e5-ac45-b8e85604f858">
{
"system-users-information" : [
{
"attributes" : {"xmlns" : "http://xml.juniper.net/junos/15.1I0/junos"},
"uptime-information" : [
{
"date-time" : [
{
"data" : "4:43AM",
"attributes" : {"junos:seconds" : "1437468224"}
}
],
"up-time" : [
{
"data" : "48 days, 22:58",
"attributes" : {"junos:seconds" : "4229925"}
}
],
"active-user-count" : [
{
"data" : "2",
"attributes" : {"junos:format" : "2 users"}
}
],
"load-average-1" : [
{
"data" : "0.00"
}
],
"load-average-5" : [
{
"data" : "0.02"
}
],
"load-average-15" : [
{
"data" : "0.00"
}
],
"user-table" : [
{
"user-entry" : [
{
"user" : [
{
"data" : "regress"
}
],
"tty" : [
{
"data" : "p0"
}
],
"from" : [
{
"data" : "172.29.227.10"
}
],
"login-time" : [
{
"data" : "4:28AM",
"attributes" : {"junos:seconds" : "1437467296"}
}
],
"idle-time" : [
{
"data" : "-",
"attributes" : {"junos:seconds" : "24"}
}
],
"command" : [
{
"data" : "cli"
}
]
},
{
"user" : [
{
"data" : "regress"
}
],
"tty" : [
{
"data" : "p2"
}
],
"from" : [
{
"data" : "bng-junos-d051.juniper.net"
}
],
"login-time" : [
{
"data" : "03Jun15",
"attributes" : {"junos:seconds" : "1433314876"}
}
],
"idle-time" : [
{
"data" : "47days",
"attributes" : {"junos:seconds" : "4143714"}
}
],
"command" : [
{
"data" : "gdb /b/"
}
]
}
]
}
]
}
]
}
]
}
</rpc-reply>
64 changes: 61 additions & 3 deletions tests/unit/test_rpcmeta.py
Original file line number Diff line number Diff line change
@@ -2,20 +2,28 @@
__credits__ = "Jeremy Schulman"

import unittest
import os
from nose.plugins.attrib import attr

from jnpr.junos.device import Device
from jnpr.junos.rpcmeta import _RpcMetaExec
from jnpr.junos.facts.swver import version_info
from ncclient.manager import Manager, make_device_handler
from ncclient.transport import SSHSession

from mock import patch
from mock import patch, MagicMock, call
from lxml import etree


@attr('unit')
class Test_RpcMetaExec(unittest.TestCase):

def setUp(self):
self.dev = Device(host='1.1.1.1')
@patch('ncclient.manager.connect')
def setUp(self, mock_connect):
mock_connect.side_effect = self._mock_manager
self.dev = Device(host='1.1.1.1', user='rick', password='password123',
gather_facts=False)
self.dev.open()
self.rpc = _RpcMetaExec(self.dev)

def test_rpcmeta_constructor(self):
@@ -79,3 +87,53 @@ def test_rpcmeta_get_config(self, mock_execute_fn):
self.rpc.get_config(root)
self.assertEqual(mock_execute_fn.call_args[0][0].tag,
'get-configuration')

def test_rpcmeta_exec_rpc_format_json_14_2(self):
self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
self.dev._facts['version_info'] = version_info('14.2X46-D15.3')
op = self.rpc.get_system_users_information(dict(format='json'))
self.assertEqual(op['system-users-information'][0]
['uptime-information'][0]['date-time'][0]['data'],
u'4:43AM')

def test_rpcmeta_exec_rpc_format_json_gt_14_2(self):
self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
self.dev._facts['version_info'] = version_info('15.1X46-D15.3')
op = self.rpc.get_system_users_information(dict(format='json'))
self.assertEqual(op['system-users-information'][0]
['uptime-information'][0]['date-time'][0]['data'],
u'4:43AM')

@patch('jnpr.junos.device.warnings')
def test_rpcmeta_exec_rpc_format_json_lt_14_2(self, mock_warn):
self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager)
self.dev._facts['version_info'] = version_info('13.1X46-D15.3')
self.rpc.get_system_users_information(dict(format='json'))
mock_warn.assert_has_calls(call.warn(
'Native JSON support is only from 14.2 onwards', RuntimeWarning))

def _mock_manager(self, *args, **kwargs):
if kwargs:
if 'normalize' in kwargs and args:
return self._read_file(args[0].tag + '.xml')
device_params = kwargs['device_params']
device_handler = make_device_handler(device_params)
session = SSHSession(device_handler)
return Manager(session, device_handler)

if args:
return self._read_file(args[0].tag + '.xml')

def _read_file(self, fname):
from ncclient.xml_ import NCElement

fpath = os.path.join(os.path.dirname(__file__),
'rpc-reply', fname)
foo = open(fpath).read()
if fname == 'get-system-users-information.xml':
return NCElement(foo,
self.dev._conn._device_handler.transform_reply())
rpc_reply = NCElement(foo, self.dev._conn.
_device_handler.transform_reply())\
._NCElement__doc[0]
return rpc_reply

0 comments on commit c7f2532

Please sign in to comment.