def applyEditToXMLNode(self, confignode, target): metaFile = "Modules/meta.xsl" try: # Generate a stylesheet equivalent to the edit-config df = InputSource.DefaultFactory editXMLRequest = df.fromString(util.convertNodeToString(confignode), 'urn:dummy') stylesheet = df.fromUri("file:" + C.YENCAP_HOME + "/" + metaFile, 'urn:sty') p = Processor.Processor() p.appendStylesheet(stylesheet) wr = DomWriter.DomWriter() p.run(editXMLRequest, writer=wr) generatedStyleSheet = wr.getResult() # Apply the generated stylesheet to the source document inputStyleSheet = df.fromString(util.convertNodeToString(generatedStyleSheet), 'urn:sty') inputDocument = df.fromString(util.convertNodeToString(target), 'urn:dummy') p = Processor.Processor() p.appendStylesheet(inputStyleSheet) wr = DomWriter.DomWriter() p.run(inputDocument, writer=wr) newXMLDoc = wr.getResult() # Return the transformed document return newXMLDoc except Exception,exp: moduleReply = ModuleReply( error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.OPERATION_FAILED, error_severity=ModuleReply.ERROR, error_message=str(exp)) return moduleReply
def editConfig(self, defaultoperation, testoption, erroroption, target, confignode, targetnode=None): """ Apply a edit-config request from the confignode to the targetnode. @type defaultoperation: MERGE_OPERATION | REPLACE_OPERATION | NONE_OPERATION @param defaultoperation : as specified in NETCONF protocol @type testoption : SET | TEST_AND_SET @param testoption : as specified in NETCONF protocol @type erroroption : STOP_ON_ERROR | IGNORE_ERROR | ROLL_BACK_ON_ERROR @param erroroption : as specified in NETCONF protocol @type target : RUNNING_TARGET | CANDIDATE_TARGET | STARTUP_TARGET @param target : as specified in NETCONF protocol @type targetnode : string @param targetnode : if the target is RUNNING_TARGET or STARTUP_TARGET it will be ignored otherwise should be the node of the CANDIDATE_TARGET that this module should procees @rtype: ModuleReply @return: It returns a success or error message. ** Relates to the netconf edit-config operation """ try: # Generate a stylesheet equivalent to the edit-config df = InputSource.DefaultFactory editXMLRequest = df.fromString( util.convertNodeToString(confignode), 'urn:dummy') stylesheet = df.fromUri("file:" + metaFile, 'urn:sty') p = Processor.Processor() p.appendStylesheet(stylesheet) wr = DomWriter.DomWriter() p.run(editXMLRequest, writer=wr) generatedStyleSheet = wr.getResult() # Apply the generated stylesheet to the source document inputStyleSheet = df.fromString( util.convertNodeToString(generatedStyleSheet), 'urn:sty') oldXMLDocument = self.getConfig(target).getXMLNodeReply() inputDocument = df.fromString( util.convertNodeToString(oldXMLDocument), 'urn:dummy') p = Processor.Processor() p.appendStylesheet(inputStyleSheet) wr = DomWriter.DomWriter() p.run(inputDocument, writer=wr) newXMLDoc = wr.getResult() # Copy the new document over the old one xmlReply = self.copyConfig("config", target, sourceNode=newXMLDoc) return xmlReply except Exception, exp: print str(exp) moduleReply = ModuleReply(error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.OPERATION_FAILED, error_severity=ModuleReply.ERROR, error_message=str(exp)) return moduleReply
def editConfig(self, defaultoperation, testoption, erroroption, target, confignode, targetnode=None): """ Apply a edit-config request from the confignode to the targetnode. @type defaultoperation: MERGE_OPERATION | REPLACE_OPERATION | NONE_OPERATION @param defaultoperation : as specified in NETCONF protocol @type testoption : SET | TEST_AND_SET @param testoption : as specified in NETCONF protocol @type erroroption : STOP_ON_ERROR | IGNORE_ERROR | ROLL_BACK_ON_ERROR @param erroroption : as specified in NETCONF protocol @type target : RUNNING_TARGET | CANDIDATE_TARGET | STARTUP_TARGET @param target : as specified in NETCONF protocol @type targetnode : string @param targetnode : if the target is RUNNING_TARGET or STARTUP_TARGET it will be ignored otherwise should be the node of the CANDIDATE_TARGET that this module should procees @rtype: ModuleReply @return: It returns a success or error message. ** Relates to the netconf edit-config operation """ try: # Generate a stylesheet equivalent to the edit-config df = InputSource.DefaultFactory editXMLRequest = df.fromString(util.convertNodeToString(confignode), 'urn:dummy') stylesheet = df.fromUri("file:"+metaFile, 'urn:sty') p = Processor.Processor() p.appendStylesheet(stylesheet) wr = DomWriter.DomWriter() p.run(editXMLRequest, writer=wr) generatedStyleSheet = wr.getResult() # Apply the generated stylesheet to the source document inputStyleSheet = df.fromString(util.convertNodeToString(generatedStyleSheet), 'urn:sty') oldXMLDocument = self.getConfig(target).getXMLNodeReply() inputDocument = df.fromString(util.convertNodeToString(oldXMLDocument), 'urn:dummy') p = Processor.Processor() p.appendStylesheet(inputStyleSheet) wr = DomWriter.DomWriter() p.run(inputDocument, writer=wr) newXMLDoc = wr.getResult() # Copy the new document over the old one xmlReply = self.copyConfig(C.CONFIG, target, sourceNode = newXMLDoc.documentElement) return xmlReply except Exception,exp: import traceback traceback.print_exc() moduleReply = ModuleReply( error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.OPERATION_FAILED, error_severity=ModuleReply.ERROR, error_message=str(exp)) return moduleReply
def processrequest(self, data): """ Forward the received message to the requestScanner and returns its reply @type data: string @param data: The message received from the client socket @rtype: string @return: The serialized XML reply to be sent back to the Netconf Manager """ self.netconfLock.acquire() try: # try to build the DOM, checking well-formness # http://madynes.loria.fr is there to avoid a warning... doc = NonvalidatingReader.parseString(data, 'http://madynes.loria.fr') # XML Schema validation #self.valid = util.validate(data,[C.NETCONF_SCHEMA_URI]) mainNode = doc.documentElement if mainNode.tagName == C.RPC: rpcRequest = Rpc(mainNode, self.session) response = rpcRequest.execute() elif mainNode.tagName == C.HELLO: response = '' else: moduleReply = ModuleReply( error_type=ModuleReply.PROTOCOL, error_tag=ModuleReply.UNKNOWN_ELEMENT, error_severity=ModuleReply.ERROR, error_message= "An element is not known. It should be an rpc or hello tag." ) moduleReply.addErrorInfo("bad-element", mainNode.tagName) nodeReply = moduleReply.getXMLNodeReply() response = util.convertNodeToString(nodeReply) except Exception, exp: moduleReply = ModuleReply( error_type=ModuleReply.PROTOCOL, error_tag=ModuleReply.UNKNOWN_ELEMENT, error_severity=ModuleReply.ERROR, error_message="The Netconf message is not well-formed." + str(exp)) nodeReply = moduleReply.getXMLNodeReply() response = util.convertNodeToString(nodeReply)
def processrequest(self, data): """ Forward the received message to the requestScanner and returns its reply @type data: string @param data: The message received from the client socket @rtype: string @return: The serialized XML reply to be sent back to the Netconf Manager """ self.netconfLock.acquire() try: # try to build the DOM, checking well-formness # http://madynes.loria.fr is there to avoid a warning... doc = NonvalidatingReader.parseString(data, 'http://madynes.loria.fr') # XML Schema validation #self.valid = util.validate(data,[C.NETCONF_SCHEMA_URI]) mainNode = doc.documentElement if mainNode.tagName == C.RPC: rpcRequest = Rpc(mainNode, self.session) response = rpcRequest.execute() elif mainNode.tagName == C.HELLO: response ='' else: moduleReply = ModuleReply( error_type=ModuleReply.PROTOCOL, error_tag=ModuleReply.UNKNOWN_ELEMENT, error_severity=ModuleReply.ERROR, error_message = "An element is not known. It should be an rpc or hello tag.") moduleReply.addErrorInfo("bad-element",mainNode.tagName) nodeReply = moduleReply.getXMLNodeReply() response = util.convertNodeToString(nodeReply) except Exception,exp: moduleReply = ModuleReply( error_type=ModuleReply.PROTOCOL, error_tag=ModuleReply.UNKNOWN_ELEMENT, error_severity=ModuleReply.ERROR, error_message="The Netconf message is not well-formed."+str(exp)) nodeReply = moduleReply.getXMLNodeReply() response = util.convertNodeToString(nodeReply)
def exchangeCapabilities(self, clientsock): """ Exchange the capabilities with the manager. First sends the agent capabilities. Then waits for the remote manager capabilities. Creates a Netconf session and returns it. @type clientsock: socket @param clientsock: The socket for the current client @rtype: session @return: The session created by the SessionManager. """ # Loading hello element along with static capabilities from hello.xml file helloRoot = NonvalidatingReader.parseUri(C.HELLO_URI) helloNode = helloRoot.documentElement # Finding a unique session-id for that session self.session = sessionManager.getInstance().createSession( clientsock, self.username) sessionId = self.session.getSessionId() LogManager.getInstance().logInfo( "opening Netconf session: (sessionId=%s)" % (self.session.getSessionId())) # Setup the session-id value within session-id node sessionIdNode = helloRoot.createElementNS(C.NETCONF_XMLNS, C.SESSION_ID) helloNode.appendChild(sessionIdNode) sessionIdNode.appendChild(helloRoot.createTextNode(str(sessionId))) # Get the unique instance of the singleton ModuleManager: moduleManager = ModuleManager.getInstance() # Add the capabilities related to the modules to the hello message: for node in helloNode.childNodes: if (node.nodeType == Node.ELEMENT_NODE and node.tagName == C.CAPABILITIES): for module in moduleManager.getModules(): capabNode = helloRoot.createElementNS( C.NETCONF_XMLNS, C.CAPABILITY) capabText = helloRoot.createTextNode(module.namespace) capabNode.appendChild(capabText) node.appendChild(capabNode) # Convert the hello element to String before sending hellostr = util.convertNodeToString(helloNode) # Sending capabilities along with a new session-id self.send(hellostr) # Receiving capabilities of the manager data = self.receive() # Printing Manager capabilities LogManager.getInstance().logInfo( "Manager capabilities received: (sessionId=%s)" % (self.session.getSessionId()))
def loop(self): # Loop until ending connection while 1: # Receving a new Netconf request data = self.receive() processeddata = "" if (data == -1): msg = "Problem while receiving message. Please check application protocol and options (sessionId=%s)" % ( self.session.getSessionId()) LogManager.getInstance().logError(msg) sessionManager.getInstance().closeSession(self.session) break elif (data == -2): # Remote socket was badly closed. Closing session. msg = "Remote socket seems closed: (sessionId=%s). Closing Netconf session..." % ( self.session.getSessionId()) LogManager.getInstance().logError(msg) sessionManager.getInstance().closeSession(self.session) break else: # Processing the Netconf request try: processeddata = self.processrequest(data) except Exception, exp: LogManager.getInstance().logError( "remote socket seems closed: (sessionId=%s,error=%s)" % (self.session.getSessionId(), str(exp))) if (processeddata == ''): moduleReply = ModuleReply( error_type=ModuleReply.PROTOCOL, error_tag=ModuleReply.UNKNOWN_ELEMENT, error_severity=ModuleReply.ERROR, error_message="The response is unexpectedly empty.") nodeReply = moduleReply.getXMLNodeReply() processeddata = util.convertNodeToString(nodeReply) # Sending the response self.send(processeddata) if self.session.mustBeClosed == 1: LogManager.getInstance().logInfo( "closing Netconf session: (sessionId=%s)" % (self.session.getSessionId())) sessionManager.getInstance().closeSession(self.session) break
def applyEditToXMLNode(self, confignode, target): metaFile = "Modules/meta.xsl" try: # Generate a stylesheet equivalent to the edit-config df = InputSource.DefaultFactory editXMLRequest = df.fromString( util.convertNodeToString(confignode), 'urn:dummy') stylesheet = df.fromUri("file:" + C.YENCAP_HOME + "/" + metaFile, 'urn:sty') p = Processor.Processor() p.appendStylesheet(stylesheet) wr = DomWriter.DomWriter() p.run(editXMLRequest, writer=wr) generatedStyleSheet = wr.getResult() # Apply the generated stylesheet to the source document inputStyleSheet = df.fromString( util.convertNodeToString(generatedStyleSheet), 'urn:sty') inputDocument = df.fromString(util.convertNodeToString(target), 'urn:dummy') p = Processor.Processor() p.appendStylesheet(inputStyleSheet) wr = DomWriter.DomWriter() p.run(inputDocument, writer=wr) newXMLDoc = wr.getResult() # Return the transformed document return newXMLDoc except Exception, exp: moduleReply = ModuleReply(error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.OPERATION_FAILED, error_severity=ModuleReply.ERROR, error_message=str(exp)) return moduleReply
def exchangeCapabilities(self, clientsock): """ Exchange the capabilities with the manager. First sends the agent capabilities. Then waits for the remote manager capabilities. Creates a Netconf session and returns it. @type clientsock: socket @param clientsock: The socket for the current client @rtype: session @return: The session created by the SessionManager. """ # Loading hello element along with static capabilities from hello.xml file helloRoot = NonvalidatingReader.parseUri(C.HELLO_URI) helloNode = helloRoot.documentElement # Finding a unique session-id for that session self.session = sessionManager.getInstance().createSession(clientsock, self.username) sessionId = self.session.getSessionId() LogManager.getInstance().logInfo("opening Netconf session: (sessionId=%s)" % (self.session.getSessionId())) # Setup the session-id value within session-id node sessionIdNode = helloRoot.createElementNS(C.NETCONF_XMLNS, C.SESSION_ID) helloNode.appendChild(sessionIdNode) sessionIdNode.appendChild(helloRoot.createTextNode(str(sessionId))) # Get the unique instance of the singleton ModuleManager: moduleManager = ModuleManager.getInstance() # Add the capabilities related to the modules to the hello message: for node in helloNode.childNodes: if (node.nodeType== Node.ELEMENT_NODE and node.tagName == C.CAPABILITIES): for module in moduleManager.getModules(): capabNode = helloRoot.createElementNS(C.NETCONF_XMLNS, C.CAPABILITY) capabText = helloRoot.createTextNode(module.namespace) capabNode.appendChild(capabText) node.appendChild(capabNode) # Convert the hello element to String before sending hellostr = util.convertNodeToString(helloNode) # Sending capabilities along with a new session-id self.send(hellostr) # Receiving capabilities of the manager data = self.receive() # Printing Manager capabilities LogManager.getInstance().logInfo("Manager capabilities received: (sessionId=%s)" % (self.session.getSessionId()))
def loop(self): # Loop until ending connection while 1 : # Receving a new Netconf request data = self.receive() processeddata = "" if (data == -1): msg = "Problem while receiving message. Please check application protocol and options (sessionId=%s)" % (self.session.getSessionId()) LogManager.getInstance().logError(msg) sessionManager.getInstance().closeSession(self.session) break elif (data == -2): # Remote socket was badly closed. Closing session. msg = "Remote socket seems closed: (sessionId=%s). Closing Netconf session..." % (self.session.getSessionId()) LogManager.getInstance().logError(msg) sessionManager.getInstance().closeSession(self.session) break else: # Processing the Netconf request try: processeddata = self.processrequest(data) except Exception,exp: LogManager.getInstance().logError("remote socket seems closed: (sessionId=%s,error=%s)" % (self.session.getSessionId() , str(exp))) if (processeddata == ''): moduleReply = ModuleReply( error_type=ModuleReply.PROTOCOL, error_tag=ModuleReply.UNKNOWN_ELEMENT, error_severity=ModuleReply.ERROR, error_message="The response is unexpectedly empty.") nodeReply = moduleReply.getXMLNodeReply() processeddata = util.convertNodeToString(nodeReply) # Sending the response self.send(processeddata) if self.session.mustBeClosed == 1: LogManager.getInstance().logInfo("closing Netconf session: (sessionId=%s)" % (self.session.getSessionId())) sessionManager.getInstance().closeSession(self.session) break
def applyXSLT(self, netconfReply): try: # Generate a stylesheet equivalent to the edit-config df = InputSource.DefaultFactory xmldoc = df.fromString(netconfReply, 'urn:dummy') xsldoc = df.fromUri("file:" + self.xsldocuri, 'urn:sty') p = Processor.Processor() p.appendStylesheet(xsldoc) wr = DomWriter.DomWriter() p.run(xmldoc, writer=wr) newHTMLDoc = wr.getResult() # Copy the new document over the old one return util.convertNodeToString(newHTMLDoc.documentElement) except Exception, exp: import traceback traceback.print_exc() return "Exception while applying XSLT of module %s: \n%s" % ( self.name, str(exp))
def editConfig(self, defaultoperation, testoption, erroroption, target, confignode, targetnode=None): """ Apply a edit-config request from the confignode to the targetnode. @type defaultoperation: MERGE_OPERATION | REPLACE_OPERATION | NONE_OPERATION @param defaultoperation : as specified in NETCONF protocol @type testoption : SET | TEST_AND_SET @param testoption : as specified in NETCONF protocol @type erroroption : STOP_ON_ERROR | IGNORE_ERROR | ROLL_BACK_ON_ERROR @param erroroption : as specified in NETCONF protocol @type target : RUNNING_TARGET | CANDIDATE_TARGET | STARTUP_TARGET @param target : as specified in NETCONF protocol @type targetnode : string @param targetnode : if the target is RUNNING_TARGET or STARTUP_TARGET it will be ignored otherwise should be the node of the CANDIDATE_TARGET that this module should procees @rtype: ModuleReply @return: It returns a success or error message. ** Relates to the netconf edit-config operation """ try: # Generate a stylesheet equivalent to the edit-config df = InputSource.DefaultFactory editXMLRequest = df.fromString( util.convertNodeToString(confignode), 'urn:dummy') stylesheet = df.fromUri("file:" + metaFile, 'urn:sty') p = Processor.Processor() p.appendStylesheet(stylesheet) wr = DomWriter.DomWriter() p.run(editXMLRequest, writer=wr) generatedStyleSheet = wr.getResult() # Apply the generated stylesheet to the source document inputStyleSheet = df.fromString( util.convertNodeToString(generatedStyleSheet), 'urn:sty') oldXMLDocument = self.getConfig(target).getXMLNodeReply() inputDocument = df.fromString( util.convertNodeToString(oldXMLDocument), 'urn:dummy') p = Processor.Processor() p.appendStylesheet(inputStyleSheet) wr = DomWriter.DomWriter() p.run(inputDocument, writer=wr) newXMLDoc = wr.getResult() newOLSRRootNode = newXMLDoc.childNodes[0] # Copy the data to the olsr config file file_generator = Generator(self.namespace) file_generator.transform(newOLSRRootNode) print "new OLSR config is \n" PrettyPrint(newXMLDoc.childNodes[0]) if (newOLSRRootNode != None): xmlreply = ModuleReply(replynode=newOLSRRootNode) else: xmlreply = ModuleReply( error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.OPERATION_NOT_SUPPORTED, error_severity=ModuleReply.ERROR, error_message= "Config generator from Module %s replied with None." % self.name) return xmlreply # (Re)start the olsr process on the device, if it is running # p = OLSR_System() # p.start_new_olsr_instance() # xmlReply = self.copyConfig("config", target, sourceNode = newXMLDoc) # return xmlReply except Exception, exp: print str(exp) moduleReply = ModuleReply(error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.OPERATION_FAILED, error_severity=ModuleReply.ERROR, error_message=str(exp)) return moduleReply