Repository: Juniper/py-junos-eznc

Issue:
Domain fact gathering not in try block, RPCerror uncaught.
Was using 1.1.0 until this morning with ssh key authentication.  After upgrade, connecting to the devices fails:

   
    from jnpr.junos import Device
    
    router = 'somerouter'
    username = 'netconf'
    path2keyfile = 'path2privatekey'
    
    dev = Device(router, user=username, ssh_private_key_file=path2keyfile)
    
    dev.open()
    


Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/jnpr/junos/device.py", line 494, in open
    self.facts_refresh()
  File "/usr/local/lib/python2.7/dist-packages/jnpr/junos/device.py", line 758, in facts_refresh
    gather(self, self._facts)
  File "/usr/local/lib/python2.7/dist-packages/jnpr/junos/facts/domain.py", line 16, in facts_domain
    domain = junos.rpc.get_config(domain_filter_xml)
  File "/usr/local/lib/python2.7/dist-packages/jnpr/junos/rpcmeta.py", line 43, in get_config
    return self._junos.execute(rpc)
  File "/usr/local/lib/python2.7/dist-packages/jnpr/junos/decorators.py", line 71, in wrapper
    return function(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/jnpr/junos/decorators.py", line 26, in wrapper
    return function(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/jnpr/junos/device.py", line 569, in execute
    raise e(cmd=rpc_cmd_e, rsp=rsp)
jnpr.junos.exception.PermissionError: PermissionError(severity: error, bad_element: system, message: permission denied)


rolled back to 1.1.0 to confirm, and authentication was successful. With both versions, the target router logs the following in 'messages':
    Jun 11 11:43:31  sshd[1258]: Accepted publickey for netconf from x.x.x.x port 40132 ssh2
    Jun 11 11:43:31  sshd[1258]: subsystem request for netconf by user netconf


I am able to login interactively with the username/key combination.


Discussion:

Patch:
diff --git a/lib/jnpr/junos/facts/domain.py b/lib/jnpr/junos/facts/domain.py
index ed104f01..92eb03ad 100644
--- a/lib/jnpr/junos/facts/domain.py
+++ b/lib/jnpr/junos/facts/domain.py
@@ -1,4 +1,5 @@
 from jnpr.junos.utils.fs import FS
+from jnpr.junos.exception import RpcError
 from lxml.builder import E
 
 
@@ -11,14 +12,17 @@ def facts_domain(junos, facts):
         facts['domain']
         facts['fqdn']
     """
-    # changes done to fix issue #332
-    domain_filter_xml = E('configuration', E('system', E('domain-name')))
-    domain = junos.rpc.get_config(domain_filter_xml)
-    domain_name = domain.xpath('.//domain-name')
-    if len(domain_name) > 0:
-        facts['domain'] = domain_name[0].text
-        facts['fqdn'] = facts['hostname'] + '.' + facts['domain']
-        return
+
+    try:
+        domain_filter_xml = E('configuration', E('system', E('domain-name')))
+        domain = junos.rpc.get_config(domain_filter_xml)
+        domain_name = domain.xpath('.//domain-name')
+        if len(domain_name) > 0:
+            facts['domain'] = domain_name[0].text
+            facts['fqdn'] = facts['hostname'] + '.' + facts['domain']
+            return
+    except RpcError:
+        pass
 
     fs = FS(junos)
     file_content = fs.cat('/etc/resolv.conf') or fs.cat('/var/etc/resolv.conf')


Test patch:
diff --git a/tests/unit/facts/test_domain.py b/tests/unit/facts/test_domain.py
index 62062557..e92a3313 100644
--- a/tests/unit/facts/test_domain.py
+++ b/tests/unit/facts/test_domain.py
@@ -8,6 +8,7 @@ from lxml import etree
 
 from jnpr.junos.facts.domain import facts_domain
 from jnpr.junos import Device
+from jnpr.junos.exception import RpcError
 
 
 @attr('unit')
@@ -61,3 +62,16 @@ class TestDomain(unittest.TestCase):
         facts_domain(self.dev, self.facts)
         self.assertEqual(self.facts['domain'], 'testing.net')
         self.assertEqual(self.facts['fqdn'], 'test.testing.net')
+
+    @patch('jnpr.junos.facts.domain.FS.cat')
+    def test_domain_rpc_error(self, mock_fs_cat):
+        self.dev.rpc.get_config = MagicMock(side_effect=RpcError)
+        mock_fs_cat.return_value =\
+            """# domain juniper.net
+        search englab.juniper.net spglab.juniper.net juniper.net jnpr.net
+        nameserver 10.11.12.13
+        """
+        self.facts['hostname'] = 'test'
+        facts_domain(self.dev, self.facts)
+        self.assertEqual(self.facts['domain'], 'juniper.net')
+        self.assertEqual(self.facts['fqdn'], 'test.juniper.net')