def handle_raw_dispatch(self, raw): if 'routing-engine' in raw: raw = re.sub(r'<ok/>', '</routing-engine>\n<ok/>', raw) return raw # check if error is during capabilites exchange itself elif re.search('\<rpc-reply\>.*?\</rpc-reply\>.*\</hello\>?', raw, re.M | re.S): errs = re.findall('\<rpc-error\>.*?\</rpc-error\>', raw, re.M | re.S) err_list = [] if errs: add_ns = """ <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes"/> <xsl:template match="*"> <xsl:element name="{local-name()}" namespace="urn:ietf:params:xml:ns:netconf:base:1.0"> <xsl:apply-templates select="@*|node()"/> </xsl:element> </xsl:template> </xsl:stylesheet>""" for err in errs: doc = etree.ElementTree(etree.XML(err)) # Adding namespace using xslt xslt = etree.XSLT(etree.XML(add_ns)) transformed_xml = etree.XML(etree.tostring(xslt(doc))) err_list.append(RPCError(transformed_xml)) return RPCError( to_ele("<rpc-reply>" + ''.join(errs) + "</rpc-reply>"), err_list) else: return False
def rpc(self, cmd): """ Write the XML cmd and return the response as XML object. :cmd: <str> of the XML command. if the :cmd: is not XML, then this routine will perform the brackets; i.e. if given 'get-software-information', this routine will turn it into '<get-software-information/>' NOTES: The return XML object is the first child element after the <rpc-reply>. There is also no error-checking performing by this routine. """ if not cmd.startswith('<'): cmd = '<{}/>'.format(cmd) rpc = six.b('<rpc>{}</rpc>'.format(cmd)) logger.info('Calling rpc: %s' % rpc) self._tty.rawwrite(rpc) rsp = self._receive() rsp = rsp.decode('utf-8') if isinstance(rsp, bytes) else rsp reply = RPCReply(rsp) errors = reply.errors if len(errors) > 1: raise RPCError(to_ele(reply._raw), errs=errors) elif len(errors) == 1: raise reply.error return rsp
def test_validate(self): mock_validate = self.c.connection.validate self.assertTrue(self.c.validate()) mock_validate.assert_called_with() # RPC error mock_validate.side_effect = RPCError(mock.MagicMock()) self.assertFalse(self.c.validate())
def lock(self, source, lock_timeout): """ Lock the configuration system :param source: is the name of the configuration datastore accessed :param lock_timeout: timeout in seconds for holding the lock :return: (defeered) for RpcReply """ expire_time = time.time() + lock_timeout if source not in self._locked: self._locked[source] = None while self._locked[source] is not None: # Watch for lock timeout if time.time() >= self._locked[source]: self._locked[source] = None break yield asleep(0.1) if time.time() < expire_time: yield asleep(random.uniform(0.1, 0.5)) # Simulate NETCONF request delay self._locked[source] = expire_time returnValue( RPCReply(_dummy_xml ) if expire_time > time.time() else RPCError('TODO'))
def test_commit(self): mock_commit = self.c.connection.commit mock_commit.return_value = NCElement(good_reply, self.tr) self.assertTrue(self.c.commit()) # bad reply mock_commit.return_value = NCElement(bad_reply, self.tr) self.assertFalse(self.c.commit()) # RPC error mock_commit.side_effect = RPCError(mock.MagicMock()) self.assertFalse(self.c.commit())
def _mock_manager_3foobar_warnings(self, *args, **kwargs): cmd = """ <load-configuration action="set" format="text"> <configuration-set> delete interfaces ge-0/0/0 delete protocols ospf delete policy-options prefix-list foo </configuration-set> </load-configuration> """ rsp_string = """ <rpc-reply> <load-configuration-results> <rpc-error> <error-severity>warning</error-severity> <error-message> foo boom </error-message> </rpc-error> <rpc-error> <error-severity>warning</error-severity> <error-message> boom bar </error-message> </rpc-error> <rpc-error> <error-severity>warning</error-severity> <error-message> foo bar </error-message> </rpc-error> <ok/> </load-configuration-results> </rpc-reply> """ rsp = XML(rsp_string) errors = [] for err in rsp.findall('.//rpc-error'): errors.append(RPCError(err)) rpc_error = RPCError(rsp, errs=errors) raise RpcError(cmd=XML(cmd), rsp=rsp, errs=rpc_error)
def _mock_manager_3foobar_warnings(self, *args, **kwargs): cmd = """ <load-configuration action="set" format="text"> <configuration-set> delete interfaces ge-0/0/0 delete protocols ospf delete policy-options prefix-list foo </configuration-set> </load-configuration> """ rsp_string = """ <rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/16.1R4/junos" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:1f3dfa00-3434-414a-8aa8-0073590c5812"> <load-configuration-results> <rpc-error> <error-severity>warning</error-severity> <error-message> foo boom </error-message> </rpc-error> <rpc-error> <error-severity>warning</error-severity> <error-message> boom bar </error-message> </rpc-error> <rpc-error> <error-severity>warning</error-severity> <error-message> foo bar </error-message> </rpc-error> <ok/> </load-configuration-results> </rpc-reply> """ rsp = XML(rsp_string) errors = [] for err in rsp.findall('.//' + qualify('rpc-error')): errors.append(RPCError(err)) raise RPCError(rsp, errs=errors)
def _mock_manager_1snf_warning_1err(self, *args, **kwargs): cmd = """ <load-configuration action="set" format="text"> <configuration-set> delete interfaces ge-0/0/0 delete protcols ospf delete policy-options prefix-list foo </configuration-set> </load-configuration> """ rsp_string = """ <rpc-reply> <load-configuration-results> <rpc-error> <error-severity>warning</error-severity> <error-message> statement not found </error-message> </rpc-error> <rpc-error> <error-type>protocol</error-type> <error-tag>operation-failed</error-tag> <error-severity>error</error-severity> <error-message>syntax error</error-message> <error-info> <bad-element>protcols</bad-element> </error-info> </rpc-error> <ok/> </load-configuration-results> </rpc-reply> """ rsp = XML(rsp_string) errors = [] for err in rsp.findall('.//rpc-error'): errors.append(RPCError(err)) rpc_error = RPCError(rsp, errs=errors) raise RpcError(cmd=XML(cmd), rsp=rsp, errs=rpc_error)
def _mock_manager_1snf_warning_1err(self, *args, **kwargs): cmd = """ <load-configuration action="set" format="text"> <configuration-set> delete interfaces ge-0/0/0 delete protcols ospf delete policy-options prefix-list foo </configuration-set> </load-configuration> """ rsp_string = """ <rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/16.1R4/junos" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:1f3dfa00-3434-414a-8aa8-0073590c5812"> <load-configuration-results> <rpc-error> <error-severity>warning</error-severity> <error-message> statement not found </error-message> </rpc-error> <rpc-error> <error-type>protocol</error-type> <error-tag>operation-failed</error-tag> <error-severity>error</error-severity> <error-message>syntax error</error-message> <error-info> <bad-element>protcols</bad-element> </error-info> </rpc-error> <ok/> </load-configuration-results> </rpc-reply> """ rsp = XML(rsp_string) errors = [] for err in rsp.findall(".//" + qualify("rpc-error")): errors.append(RPCError(err)) raise RPCError(rsp, errs=errors)
def test_locking(self): # check lock self.c.connection.lock.return_value = NCElement(good_reply, self.tr) self.assertTrue(self.c._locking("lock")) self.assertTrue(self.c._configuration_lock) # check unlock self.c.connection.unlock.return_value = NCElement(good_reply, self.tr) self.assertTrue(self.c._locking("unlock")) self.assertFalse(self.c._configuration_lock) # check other action self.assertTrue(self.c._locking("test")) self.assertTrue(self.c._configuration_lock) # bad RCP reply lock self.c.connection.lock.return_value = NCElement(bad_reply, self.tr) self.assertFalse(self.c._locking("lock")) # bad RCP reply unlock self.c.connection.unlock.return_value = NCElement(bad_reply, self.tr) self.assertFalse(self.c._locking("unlock")) # check RPCError self.c.connection.lock.side_effect = RPCError(mock.MagicMock()) self.assertFalse(self.c._locking("lock")) self.c.connection.unlock.side_effect = RPCError(mock.MagicMock()) self.assertFalse(self.c._locking("unlock"))
def test_view(self): mock_cmd = self.c.connection.command self.assertEqual(self.c.view("test"), mock_cmd.return_value) # check tostring mock_cmd.return_value = mock.Mock() self.assertEqual(self.c.view("test", tostring=True), mock_cmd.return_value.tostring) # RPC error mock_cmd.side_effect = RPCError(mock.MagicMock()) with self.assertRaises(NetConfClientExecuteCmdError) as err: self.c.view("test") self.assertIn("Execute the view command 'test' error", str(err.exception)) # ignore RPC error with mock.patch('nocexec.NetConfClient._ignored_rpc_error') as mock_ig: mock_ig.return_value = True self.assertEqual(self.c.view("test"), None) mock_ig.assert_called_with(mock_cmd.side_effect)
def test_edit(self): mock_lc = self.c.connection.load_configuration self.assertEqual(self.c.edit("test"), mock_lc.return_value) mock_lc.assert_called_with(action='set', config=["test"]) # check tostring mock_lc.return_value = mock.Mock() self.assertEqual(self.c.edit("test", tostring=True), mock_lc.return_value.tostring) # RPC error mock_lc.side_effect = RPCError(mock.MagicMock()) with self.assertRaises(NetConfClientExecuteCmdError) as err: self.c.edit("test") self.assertIn("Executing the editing command 'test' error", str(err.exception)) # ignore RPC error with mock.patch('nocexec.NetConfClient._ignored_rpc_error') as mock_ig: mock_ig.return_value = True self.assertEqual(self.c.edit("test"), None) mock_ig.assert_called_with(mock_lc.side_effect)
def method(self, x): rpc_error = RPCError(XML('<foo/>'), errs=None) raise rpc_error