def test_process_router_throw_config_error(self): snip_name = 'CREATE_SUBINTERFACE' e_type = 'Fake error' e_tag = 'Fake error tag' params = {'snippet': snip_name, 'type': e_type, 'tag': e_tag} self.routing_helper._internal_network_added.side_effect = ( cfg_exceptions.CSR1kvConfigException(**params)) router, ports = prepare_router_data() ri = routing_svc_helper.RouterInfo(router['id'], router) self.assertRaises(cfg_exceptions.CSR1kvConfigException, self.routing_helper._process_router, ri)
def _check_response(self, rpc_obj, snippet_name, conf_str=None): """This function checks the rpc response object for status. This function takes as input the response rpc_obj and the snippet name that was executed. It parses it to see, if the last edit operation was a success or not. <?xml version="1.0" encoding="UTF-8"?> <rpc-reply message-id="urn:uuid:81bf8082-....-b69a-000c29e1b85c" xmlns="urn:ietf:params:netconf:base:1.0"> <ok /> </rpc-reply> In case of error, CSR1kv sends a response as follows. We take the error type and tag. <?xml version="1.0" encoding="UTF-8"?> <rpc-reply message-id="urn:uuid:81bf8082-....-b69a-000c29e1b85c" xmlns="urn:ietf:params:netconf:base:1.0"> <rpc-error> <error-type>protocol</error-type> <error-tag>operation-failed</error-tag> <error-severity>error</error-severity> </rpc-error> </rpc-reply> :return: True if the config operation completed successfully :raises: networking_cisco.plugins.cisco.cfg_agent.cfg_exceptions. CSR1kvConfigException """ LOG.debug("RPCReply for %(snippet_name)s is %(rpc_obj)s", { 'snippet_name': snippet_name, 'rpc_obj': rpc_obj.xml }) xml_str = rpc_obj.xml if "<ok />" in xml_str: # LOG.debug("RPCReply for %s is OK", snippet_name) LOG.info(_LI("%s was successfully executed"), snippet_name) return True # Not Ok, we throw a ConfigurationException e_type = rpc_obj._root[0][0].text e_tag = rpc_obj._root[0][1].text params = { 'snippet': snippet_name, 'type': e_type, 'tag': e_tag, 'dev_id': self.hosting_device['id'], 'ip': self._host_ip, 'confstr': conf_str } raise cfg_exc.CSR1kvConfigException(**params)
def _edit_running_config(self, conf_str, snippet): conn = self._get_connection() LOG.info( _LI("Config generated for [%(device)s] %(snip)s is:%(conf)s " "caller:%(caller)s"), { 'device': self.hosting_device['id'], 'snip': snippet, 'conf': conf_str, 'caller': self.caller_name() }) try: rpc_obj = conn.edit_config(target='running', config=conf_str) self._check_response(rpc_obj, snippet, conf_str=conf_str) except Exception as e: # Here we catch all exceptions caused by REMOVE_/DELETE_ configs # to avoid config agent to get stuck once it hits this condition. # This is needed since the current ncclient version (0.4.2) # generates an exception when an attempt to configure the device # fails by the device (ASR1K router) but it doesn't provide any # details about the error message that the device reported. # With ncclient 0.4.4 version and onwards the exception returns # also the proper error. Hence this code can be changed when the # ncclient version is increased. if re.search(r"REMOVE_|DELETE_", snippet): LOG.warning(_LW("Pass exception for %s"), snippet) pass elif isinstance(e, ncclient.operations.rpc.RPCError): e_tag = e.tag e_type = e.type params = { 'snippet': snippet, 'type': e_type, 'tag': e_tag, 'dev_id': self.hosting_device['id'], 'ip': self._host_ip, 'confstr': conf_str } raise cfg_exc.CSR1kvConfigException(**params)