def setParameters(self, operation): """ Set the parameters @type operation: Node @param operation: The operation node of the current Netconf request. """ for child in operation.childNodes: if child.nodeType==Node.ELEMENT_NODE: if child.tagName == "command": for node in child.childNodes: if node.nodeType==Node.ELEMENT_NODE: if node.tagName in ["install","update","remove"]: self.command = node.tagName else: moduleReply = ModuleReply( error_type = ModuleReply.PROTOCOL, error_tag = ModuleReply.BAD_ELEMENT, error_severity = ModuleReply.ERROR, error_message = "An element value is not correct.") moduleReply.addErrorInfo("bad-element",node.tagName) self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return elif child.tagName == "packages": for node in child.childNodes: if node.nodeType==Node.ELEMENT_NODE: if node.tagName == "package": pkgName = node.childNodes[0].nodeValue self.packages.append(pkgName)
def getConfig(self, configName): """ the getConfig operation retrieves configuration data only """ if configName in [C.STARTUP, C.RUNNING]: configFileParser = OLSR_Parser.Parser(self.namespace) get_config = configFileParser.parse() # print "[debug] =========parsed config===========" # PrettyPrint(get_config) if (get_config != None): xmlreply = ModuleReply(replynode=get_config.documentElement) else: xmlreply = ModuleReply( error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.OPERATION_NOT_SUPPORTED, error_severity=ModuleReply.ERROR, error_message="Parser from Module %s replied with None." % self.name) else: print "in getConfig: configuration is %s" % configName xmlreply = ModuleReply( error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.OPERATION_NOT_SUPPORTED, error_severity=ModuleReply.ERROR, error_message= "OPERATION-NOT-SUPPORTED: Module %s only supports startup configuration." % self.name) return xmlreply
def getConfig(self, configName): """ Generate the device's XML configuration of the current module. @rtype: ModuleReply @return: It should return the device's configuration or an error ** Relates to the netconf get-config operation """ if configName == C.STARTUP: get_config = self.parser.parse() if (get_config != None): xmlreply = ModuleReply(replynode=get_config.documentElement) else: xmlreply = ModuleReply( error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.OPERATION_NOT_SUPPORTED, error_severity=ModuleReply.ERROR, error_message="Parser from Module %s replied with None." % self.name) else: xmlreply = ModuleReply( error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.OPERATION_NOT_SUPPORTED, error_severity=ModuleReply.ERROR, error_message= "OPERATION-NOT-SUPPORTED: Module %s only supports startup configuration." % self.name) return xmlreply
def execute(self): """ Execute the copy-config operation. """ if self.operationReply.isError(): return self.operationReply sessionId = sessionManager.getInstance().getLockOwnerSessionId( C.CANDIDATE) if sessionId >= 0 and sessionId != self.session.getSessionId(): # Somebody else locked the target. moduleReply = ModuleReply( error_type=ModuleReply.PROTOCOL, error_tag=ModuleReply.LOCK_DENIED, error_severity=ModuleReply.ERROR, error_message= "The running datastore is locked by another entity.") moduleReply.addErrorInfo("session-id", sessionId) self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return self.operationReply # Just do a copy-config from running to candidate op = Copy_config_operation() op.setOperationReply() op.setSession(self.session) op.source = C.RUNNING op.target = C.CANDIDATE # Execute the command operationReply = op.execute() return operationReply
def deactivate(self, session, roles): for role in roles: if (role in session.roles): session.roles.remove(role) moduleReply = ModuleReply() return moduleReply.getXMLNodeReply()
def execute(self): """ Execute the copy-config operation. """ if self.operationReply.isError(): return self.operationReply sessionId = sessionManager.getInstance().getLockOwnerSessionId(C.CANDIDATE) if sessionId >= 0 and sessionId != self.session.getSessionId(): # Somebody else locked the target. moduleReply = ModuleReply( error_type = ModuleReply.PROTOCOL, error_tag = ModuleReply.LOCK_DENIED, error_severity = ModuleReply.ERROR, error_message = "The running datastore is locked by another entity.") moduleReply.addErrorInfo("session-id",sessionId) self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return self.operationReply # Just do a copy-config from running to candidate op = Copy_config_operation() op.setOperationReply() op.setSession(self.session) op.source = C.RUNNING op.target = C.CANDIDATE # Execute the command operationReply = op.execute() return operationReply
def applyFilter(self): """ initialNode will not be modified. A clone will be produced. """ selectedNodes = self.selectNodes() if len(selectedNodes) == 0: moduleReply = ModuleReply( error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.UNKNOWN_ELEMENT, error_severity=ModuleReply.ERROR, error_message= "XPathFilter: the node set (selected with XPath expressions) is empty." ) return moduleReply if self.initialNode in selectedNodes: clone = self.resultDocument.importNode(self.initialNode, True) self.resultDocument.replaceChild( clone, self.resultDocument.documentElement) return ModuleReply(self.resultDocument.documentElement) parentNodes = self.selectParents(selectedNodes) # Let's clone the selected nodes (deeply) clonedSelectedNodes = [] for node in selectedNodes: clone = self.resultDocument.importNode(node, True) clonedSelectedNodes.append(clone) # Let's clone their parent's nodes (not deeply) clonedParentNodes = [] for node in parentNodes: clone = self.resultDocument.importNode(node, False) clonedParentNodes.append(clone) if node == self.initialNode: self.resultDocument.replaceChild( clone, self.resultDocument.documentElement) # Now linking the clones together # 1. First, link the selected nodes to their cloned parents for i in range(0, len(selectedNodes)): selectedNode = selectedNodes[i] if selectedNode.parentNode != None and selectedNode.parentNode in parentNodes: index = parentNodes.index(selectedNode.parentNode) clonedParentNodes[index].appendChild(clonedSelectedNodes[i]) # 2. Second, link the parents together for i in range(0, len(parentNodes)): parentNode = parentNodes[i] if (parentNode.parentNode != None and parentNode.parentNode in parentNodes): index = parentNodes.index(parentNode.parentNode) clonedParentNodes[index].appendChild(clonedParentNodes[i]) # Why 0 ? because this is the clone of self.initialNode which is the "root" node return ModuleReply(clonedParentNodes[0])
def copyConfiguration(self, sourceName, targetName): try: id = self.vty_conex.stablishConnection() id, text = self.vty_conex.copyConfiguration(id, sourceName, targetName) self.vty_conex.closeConnection(id) print text print text.startswith("copy") print text.startswith("copy running-config startup-config") print text.startswith("copy running-config startup-config \nConfiguration sa") if text.find("Configuration saved to") != -1: xmlreply = ModuleReply() else: xmlreply = ModuleReply( error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.RESOURCE_DENIED, error_severity=ModuleReply.ERROR, error_message= text+"\n") except ConnectError , exp : import traceback traceback.print_exc() xmlreply = ModuleReply( error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.RESOURCE_DENIED, error_severity=ModuleReply.ERROR, error_tag_app=exp.getError(), error_message=str(exp))
def getConfig(self, configName): """ Generate the BGP device's XML configuration. Note that for every request it opens a new connection to the device, this behaivor allows multiple request at the same time. To avoid problems of concurrency, this implementation relies over the lock provided by the device, in this case the Quagga software. @rtype: ModuleReply @return: the main node of the BGP protocol if it success or the error ocurred. ** Relates to the netconf get-config operation """ if configName in [C.RUNNING, C.STARTUP]: try : id = self.deviceConnection.stablishConnection() id,config = self.deviceConnection.getConfiguration(id, self.protocol, configName) self.deviceConnection.closeConnection(id) parserstruct = self.parse("Parser",config) confdoc = self.XMLConstructor.construct_XML(parserstruct) modulereply = ModuleReply(replynode=confdoc.documentElement) except ConnectError , exp : modulereply = ModuleReply( error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.RESOURCE_DENIED, error_severity=ModuleReply.ERROR, error_tag_app=exp.getError(), error_message=str(exp)) except Exception,exp: modulereply = ModuleReply( error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.OPERATION_FAILED, error_severity=ModuleReply.ERROR, error_message=str(exp))
def checkInternalNestingValidity(self, selectedNodes): for elem in selectedNodes: deepvalue = elem.getAttributeNS( "urn:ietf:params:xml:ns:netconf:base:1.0", "operation") tmp = elem while (tmp.parentNode != elem.ownerDocument.documentElement): if tmp.parentNode in selectedNodes: # It means that elem is a child (direct or not) of another SelectedNode highvalue = tmp.parentNode.getAttributeNS( "urn:ietf:params:xml:ns:netconf:base:1.0", "operation") if highvalue != "merge": moduleReply = ModuleReply( error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.MISSING_ELEMENT, error_severity=ModuleReply.ERROR, error_message= "%s can not have %s operation in its subelements." % (highvalue, deepvalue)) self.operationReply.setError() self.operationReply.setNode( moduleReply.getXMLNodeReply()) return #return "%s can not have %s operation in its subelements." % (highvalue, deepvalue) else: tmp = tmp.parentNode
def makeRequest(self, parentnode,structnode, followcommand): """ Create the list of commands made for the issueNode into the parentnode @type parentnode: cDomelette @param parentnode: where the request take place @type structnode: cDomelette @param structnode: the equivalent node of parentNode but in the XML Language Translation @type followcommand : Command @param followcommand: The command generated by the envelop that should be appended at the beginning of every command generated by makeRequest @rtype: boolean @return: if the request was acomplish (i.e. if it was a create request and the node allready exists it return false) """ requestmade = True requestNodes = self.requestNodes(parentnode, structnode) if (self.operationType == C.CREATE): if(requestNodes == []): nodecommands = self.makeNode(self.issueNode,structnode, followcommand,True,True,False) self.commands.appendCommands(nodecommands) else : requestmade = False elif (self.operationType == C.MERGE): if(requestNodes != []): nodecommands = self.makeNode(self.issueNode,structnode, followcommand,True,True,False) self.commands.appendCommands(nodecommands) else : requestmade = False elif (self.operationType == C.REPLACE): if(requestNodes == []): requestmade = False else: for requestnode in requestNodes: nodecommands = self.makeNode(requestnode,structnode, followcommand,False,False,True) self.commands.appendCommands(nodecommands) nodecommands = self.makeNode(self.issueNode,structnode, followcommand,True,True,False) self.commands.appendCommands(nodecommands) elif (self.operationType == C.DELETE): if(requestNodes == []): requestmade = False else : for requestnode in requestNodes: nodecommands = self.makeNode(requestnode,structnode, followcommand,False,False,True) self.commands.appendCommands(nodecommands) else : reply = ModuleReply( error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.BAD_ATTRIBUTE, error_severity=ModuleReply.ERROR, error_message="Attribute value unknown") reply.addErrorInfo(ModuleReply.BAD_ATTRIBUTE_INFO,C.OPERATION) reply.addErrorInfo(ModuleReply.BAD_ELEMENT_INFO,self.operationType) raise XML_Interpreter_Exception(reply) return requestmade
def unlock(self, session, target): """ Try to unlock a target configuration (One of RUNNING, CANDIDATE, STARTUP) @type session: Session @param session: The current session that tries to acquire the lock @type target: String @param target: The target to unlock @rtype: moduleReply @return: A module reply """ sessionId = self.getLockOwnerSessionId(target) if sessionId == session.getSessionId() : session.unlock(str(target)) moduleReply = ModuleReply() elif sessionId < 0: moduleReply = ModuleReply( error_type = ModuleReply.PROTOCOL, error_tag = ModuleReply.OPERATION_FAILED, error_severity = ModuleReply.ERROR, error_message = "The specified target (%s) is not locked." % str(target)) elif sessionId != session.getSessionId : moduleReply = ModuleReply( error_type = ModuleReply.PROTOCOL, error_tag = ModuleReply.OPERATION_FAILED, error_severity = ModuleReply.ERROR, error_message = "Unlock failed, another session holds the lock.") moduleReply.addErrorInfo(C.SESSION_ID,str(sessionId)) return moduleReply.getXMLNodeReply()
def deleteConfig(self, targetName): if (targetName in [C.CANDIDATE, C.STARTUP]): try: os.system("rm %s" % (self.files[targetName])) moduleReply = ModuleReply() except Exception, exp: moduleReply = ModuleReply( error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.OPERATION_FAILED, error_severity=ModuleReply.ERROR, error_message=str(exp))
def execute(self): """ Execute the close-session operation. """ if self.operationReply.isError(): return self.operationReply self.session.mustBeClosed = 1 moduleReply = ModuleReply() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return self.operationReply
def makeEnvelop(self, structnode, followcommand,nodes): """ Create the list of commands for generated the envelop (i.e. generates the commands to get to the path for apply the actual request) @type structnode: cDomelette @param structnode: The current node of the XML Translation Language equivalent to the node where the request will be apply. @type followcommand : Command @param followcommand: The command that should be appended at the beginning of every command generated by it. @type nodes: [cDomelette] @param nodes: The ancestors nodes in the Device's XML Configuration of the node where the request will be aplied @rtype: (cDomelette,Command) @return: The first elemet of the tuple is the current offset of the XML Translation Language and the second if the followcommand created by the envelop if any. """ for node in nodes: if (structnode != None): structnode = structnode.xpath(node.nodeName) if (structnode == []): structnode = None else: structnode = structnode[0] if (structnode != None and structnode.childNodes != []): commands = self.makeCommand(node,structnode,self.COMMAND_ITEM) if (commands != None): for subcommand in commands: subcommand.setHeading(followcommand) self.commands.addCommand(subcommand) commands = self.makeCommand(node,structnode,self.FOLLOWCOMMAND_ITEM) if (commands != None and commands != []): commands[0].setHeading(followcommand) followcommand = commands[0] commands = self.makeCommand(node,structnode,self.EXITCOMMAND_ITEM,absolutepathdefault=True) if (commands != None): for subcommand in commands: subcommand.setHeading(followcommand) self.commands.addCommand(leavingcommand=subcommand) structnode = structnode.xpath("childs") if (structnode != []): structnode = structnode[0] else: structnode = None else: reply = ModuleReply(error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.BAD_ELEMENT, error_severity=ModuleReply.ERROR, error_message="The element not belong to this protocol") reply.addErrorInfo(ModuleReply.BAD_ATTRIBUTE_INFO,node.nodeName) raise XML_Interpreter_Exception(reply) return structnode, followcommand
def get(self, configName): if self.files.has_key(configName): doc = NonvalidatingReader.parseUri("file:" + self.files[configName]) moduleReply = ModuleReply(replynode=doc.documentElement) else: moduleReply = ModuleReply(error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.OPERATION_FAILED, error_severity=ModuleReply.ERROR, error_message="Unknown source: " + configName) return moduleReply
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 setParameters(self, operation, NSS = None): """ Set the parameters @type operation: Node @param operation: The operation node of the current Netconf request. """ for child in operation.childNodes: if child.nodeType==Node.ELEMENT_NODE: if child.tagName == C.SESSION_ID: for node in child.childNodes: if node.nodeType==Node.TEXT_NODE: try: self.sessionId = int(node.nodeValue) except Exception,exp: moduleReply = ModuleReply( error_type = ModuleReply.APPLICATION, error_tag = ModuleReply.INVALID_VALUE, error_severity = ModuleReply.ERROR, error_message = "This is not a valid format for session-id parameter.") moduleReply.addErrorInfo("bad-element",str(node.nodeValue)) self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return else: moduleReply = ModuleReply( error_type = ModuleReply.PROTOCOL, error_tag = ModuleReply.UNKNOWN_ELEMENT, error_severity = ModuleReply.ERROR, error_message = "An element is not known.") moduleReply.addErrorInfo("bad-element",child.tagName) self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return
def filterResponse(self): # Creating the XML response filter moduleReply = None abstractFilter = None if self.filterType == C.SUBTREE: if self.subtree != None: abstractFilter = SubtreeFilter(self.operationReply.getNode(), self.subtree) moduleReply = abstractFilter.applyFilter() else: moduleReply = ModuleReply(replynode=self.operationReply.getNode()) elif self.filterType == C.XPATH: abstractFilter = XpathFilter(self.operationReply.getNode(), [self.xpathrequest], self.prefixes) moduleReply = abstractFilter.applyFilter() if moduleReply.isError(): self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return else: self.operationReply.setNode(moduleReply.getXMLNodeReply()) rm = rbacManager.getInstance() if rm.isActive(): moduleReply = rm.filterNode(self.operationReply.getNode(), self.session) if moduleReply.isError(): self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return else: self.operationReply.setNode(moduleReply.getXMLNodeReply())
def getConfig(self, sourceName): doc = self.datastoreManager.getConfig(sourceName, "config") if doc == None: moduleReply = ModuleReply( error_type=ModuleReply.PROTOCOL, error_tag=ModuleReply.UNKNOWN_ELEMENT, error_severity=ModuleReply.ERROR, error_message="%s configuration does not exist." % sourceName) self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return else: self.operationReply.setNode(doc)
def activate(self, session, roles): moduleReply = None allowedRoles = self.getAllowedRoles(session.user) for role in roles: if (role in allowedRoles): if (role not in session.roles): session.roles.append(role) else: moduleReply = ModuleReply( error_type = ModuleReply.PROTOCOL, error_tag = ModuleReply.PARTIAL_OPERATION, error_severity = ModuleReply.WARNING, error_message = "Role " + role.name + " is already active. Some other roles may have been activated.") moduleReply.addErrorInfo("bad-element",role.name) else: moduleReply = ModuleReply( error_type = ModuleReply.PROTOCOL, error_tag = ModuleReply.PARTIAL_OPERATION, error_severity = ModuleReply.WARNING, error_message = "User "+ session.user.login +" can not activate role " + role.name + ". Some other roles may have been activated.") moduleReply.addErrorInfo("bad-element",role.name) if moduleReply == None: moduleReply = ModuleReply() return moduleReply.getXMLNodeReply()
def getConfig(self, sourceName): doc = self.datastoreManager.getConfig(sourceName, "state") if doc == None: moduleReply = ModuleReply( error_type = ModuleReply.PROTOCOL, error_tag = ModuleReply.UNKNOWN_ELEMENT, error_severity = ModuleReply.ERROR, error_message = "%s configuration does not exist." % sourceName) self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return else: self.operationReply.setNode(doc.documentElement)
def execute(self): """ Execute the close-session operation. """ if self.operationReply.isError(): return self.operationReply sessionToKill = sessionManager.getInstance().getSessionFromId(self.sessionId) if sessionToKill == None: moduleReply = ModuleReply( error_type = ModuleReply.APPLICATION, error_tag = ModuleReply.INVALID_VALUE, error_severity = ModuleReply.ERROR, error_message = "No Netconf session has this session-id.") moduleReply.addErrorInfo("bad-element",str(self.sessionId)) self.operationReply.setError() elif sessionToKill == self.session: moduleReply = ModuleReply( error_type = ModuleReply.APPLICATION, error_tag = ModuleReply.INVALID_VALUE, error_severity = ModuleReply.ERROR, error_message = "A Netconf session can not kill itself.") moduleReply.addErrorInfo("bad-element",str(self.sessionId)) self.operationReply.setError() else: sessionManager.getInstance().closeSession(sessionToKill) moduleReply = ModuleReply() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return self.operationReply
def setParameters(self, operation, NSS=None): """ Set the target parameter @type operation: Node @param operation: The operation node of the current Netconf request. """ for child in operation.childNodes: if child.nodeType == Node.ELEMENT_NODE: if child.tagName == C.TARGET: for node in child.childNodes: if node.nodeType == Node.ELEMENT_NODE: if node.tagName in [C.CANDIDATE, C.STARTUP]: self.target = node.tagName elif node.tagName == C.URL: self.urlTarget = string.strip(str(node.childNodes[0].nodeValue)) elif node.tagName == C.RUNNING: moduleReply = ModuleReply( error_type=ModuleReply.PROTOCOL, error_tag=ModuleReply.INVALID_VALUE, error_severity=ModuleReply.ERROR, error_message="The running configuration can not be deleted.", ) self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return else: moduleReply = ModuleReply( error_type=ModuleReply.PROTOCOL, error_tag=ModuleReply.UNKNOWN_ELEMENT, error_severity=ModuleReply.ERROR, error_message="An element is not known.", ) moduleReply.addErrorInfo("bad-element", node.tagName) self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return else: moduleReply = ModuleReply( error_type=ModuleReply.PROTOCOL, error_tag=ModuleReply.UNKNOWN_ELEMENT, error_severity=ModuleReply.ERROR, error_message="An element is not known.", ) moduleReply.addErrorInfo("bad-element", child.tagName) self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return
def copyConfig(self, sourceName, targetName, sourceNode=None): """ Copy the sourceNode's XML configuration of the current module to the targenName. @type targetName: string @param targetName: the target datastore (running, candidate, startup) @rtype: ModuleReply @return: It should return a success or error message. ** Relates to the netconf copy-config operation """ if (targetName in [C.URL, C.RUNNING]): xmlreply = ModuleReply( error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.OPERATION_NOT_SUPPORTED, error_severity=ModuleReply.ERROR, error_message="OPERATION-NOT-SUPPORTED") return xmlreply #candidate or startup configurations are supported as sources. if sourceName in [C.CANDIDATE, C.STARTUP]: if os.path.exists(C.YENCAP_HOME + '/Modules/VERMONT_Module/' + sourceName + '.xml'): try: sourcefile = file( C.YENCAP_HOME + '/Modules/VERMONT_Module/' + sourceName + '.xml', 'r') sourcexml = sourcefile.read() targetfile = file( C.YENCAP_HOME + '/Modules/VERMONT_Module/' + targetName + '.xml', 'w') targetfile.write(sourcexml) sourcefile.close() targetfile.close() except: xmlreply = ModuleReply( error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.OPERATION_FAILED, error_severity=ModuleReply.ERROR, error_message="copying failed") return xmlreply modulereply = ModuleReply() return modulereply if sourceName == C.CONFIG: print "sourceNode in Copyconfig" print sourceNode return self.editConfig(C.REPLACE, C.SET, C.STOP_ON_ERROR, targetName, sourceNode)
def execute(self): """ Execute the operation. """ print "restart Operation executed" module = self.moduleManager.getModuleFromName(self.targetModule) if module == None: moduleReply = ModuleReply( error_type = ModuleReply.PROTOCOL, error_tag = ModuleReply.BAD_ELEMENT, error_severity = ModuleReply.ERROR, error_message = "No Module s% ."%self.targetModule) else: moduleReply = module.restart() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return self.operationReply
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 copyConfig(self, sourceName, targetName, sourceNode=None): if (targetName in [C.RUNNING, C.CANDIDATE, C.STARTUP]): if sourceName in [C.RUNNING, C.CANDIDATE, C.STARTUP]: moduleReply = self.getConfig(sourceName) if moduleReply.isError(): return moduleReply else: util.printNodeToFile(moduleReply.getXMLNodeReply(), self.files[targetName]) return ModuleReply() elif sourceName in [C.CONFIG, C.URL]: util.printNodeToFile(sourceNode, self.files[targetName]) return ModuleReply() moduleReply = ModuleReply() return moduleReply
def getInvolvedNodes(self,defaultoperation,targetnode,editnode): """ Look for the parent, in targetnode, of every node that match the editnode request ignoring the node with the 'operation' attribute. @type defaultoperation : Module.MERGE_OPERATION | Module.REPLACE_OPERATION | Module.NONE_OPERATION @type targetnode: cDomelette @param targetnode : Where the editnode should be look for. @type editnode: cDomelette @param editnode: The editconfig node representing the request @rtype : [cDomelette] @return: the list of parent matching the editnode in the targetnode or None in case the matching were in the root node. """ operationNode = editnode.xpath("//*[@*[local-name() ='"+C.OPERATION +"' and namespace-uri()='"+C.NETCONF_XMLNS+"']]") if (len(operationNode) == 0): self.issueNode = editnode self.operationType = defaultoperation matchnodes = [None] elif (len(operationNode) > 1): reply = ModuleReply( error_type=ModuleReply.APLICATION, error_tag=ModuleReply.BAD_ATTRIBUTE, error_severity=ModuleReply.ERROR, error_message="Exists more than one node with attribute 'operation'") reply.addErrorInfo(ModuleReply.BAD_ATTRIBUTE_INFO, C.OPERATION) for node in operationNode: reply.addErrorInfo(ModuleReply.BAD_ELEMENT_INFO,node.nodeName) raise XML_Interpreter_Exception(reply) else: self.issueNode = operationNode[0] self.operationType = self.issueNode.getAttributeNS(C.NETCONF_XMLNS, C.OPERATION) xpath = "" parent = self.issueNode ignorechild = None while (parent != editnode): ignorechild = parent parent = parent.parentNode xpath = "/" + self.getXpathFromXMLNode(parent,ignoreChilds=[ignorechild]) + xpath xpath = ".." + xpath matchnodes = targetnode.xpath(xpath,{"ns":self.namespaceURI}) return matchnodes
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 lock(self, session, target): """ Try to lock a target configuration (One of RUNNING, CANDIDATE, STARTUP) @type session: Session @param session: The current session that tries to acquire the lock @type target: String @param target: The target to lock @rtype: moduleReply @return: A module reply """ sessionId = self.getLockOwnerSessionId(target) if sessionId >= 0 : moduleReply = ModuleReply( error_type = ModuleReply.PROTOCOL, error_tag = ModuleReply.IN_USE, error_severity = ModuleReply.ERROR, error_message = "Lock failed, lock is already held") moduleReply.addErrorInfo(C.SESSION_ID,str(sessionId)) else: session.lock(target) moduleReply = ModuleReply() return moduleReply.getXMLNodeReply()
def getConfig(self, configDatastore): #xmlFile = open(C.YENCAP_HOME + '/Modules/VERMONT_Module/running.xml') #doc = parse(xmlFile) dataFile = C.YENCAP_HOME + '/Modules/VERMONT_Module/' + configDatastore + '.xml' doc = NonvalidatingReader.parseUri("file:" + dataFile) modulereply = ModuleReply(replynode=doc.documentElement) return modulereply
def setParameters(self, operation, NSS=None): """ Set the parameters @type operation: Node @param operation: The operation node of the current Netconf request. """ for child in operation.childNodes: if child.nodeType == Node.ELEMENT_NODE: moduleReply = ModuleReply( error_type=ModuleReply.PROTOCOL, error_tag=ModuleReply.UNKNOWN_ELEMENT, error_severity=ModuleReply.ERROR, error_message="An element is not known.") moduleReply.addErrorInfo("bad-element", child.tagName) self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return
def setParameters(self, operation, NSS = None): """ Set the parameters @type operation: Node @param operation: The operation node of the current Netconf request. """ for child in operation.childNodes: if child.nodeType==Node.ELEMENT_NODE: moduleReply = ModuleReply( error_type = ModuleReply.PROTOCOL, error_tag = ModuleReply.UNKNOWN_ELEMENT, error_severity = ModuleReply.ERROR, error_message = "An element is not known.") moduleReply.addErrorInfo("bad-element",child.tagName) self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return
def copyConfig(self, sourceName, targetName, sourceNode = None): """ Copy the sourceName configuration of the current module to the targetName configuration. @type targetName: string @param targetName: "running", "startup", "candidate" configuration datastore @rtype: ModuleReply @return: It should return the device's configuration or an error ** Relates to the netconf copy-config operation """ if (sourceName in [C.RUNNING, C.STARTUP] and targetName in [C.RUNNING, C.STARTUP]): try: id = self.deviceConnection.stablishConnection() id, text = self.deviceConnection.copyConfiguration(id, sourceName, targetName) self.deviceConnection.closeConnection(id) if text.find("Configuration saved to") != -1: xmlreply = ModuleReply() else: xmlreply = ModuleReply( error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.RESOURCE_DENIED, error_severity=ModuleReply.ERROR, error_message= text+"\n") except ConnectError , exp : import traceback traceback.print_exc() xmlreply = ModuleReply( error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.RESOURCE_DENIED, error_severity=ModuleReply.ERROR, error_tag_app=exp.getError(), error_message=str(exp)) except Exception,exp: import traceback traceback.print_exc() xmlreply = ModuleReply( error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.OPERATION_FAILED, error_severity=ModuleReply.ERROR, error_message=str(exp))
def getConfig(self, configName): if self.ipVersion == "6": self.routeManager = RouteManagerV6(self.namespace) elif self.ipVersion == "4": self.routeManager = RouteManagerV4(self.namespace) #else: # through exception... modulereply = ModuleReply(replynode=self.routeManager.serialize()) return modulereply
def execute(self): """ Execute the delete-config operation. """ if self.operationReply.isError(): return self.operationReply # Check access here if self.rbacManager.isActive(): operation_allowed = self.rbacManager.checkAccessDeleteConfig(self.session) if not operation_allowed: moduleReply = ModuleReply( error_type=ModuleReply.PROTOCOL, error_tag=ModuleReply.ACCESS_DENIED, error_severity=ModuleReply.ERROR, error_message="Access denied.", ) self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return self.operationReply if self.target in [C.CANDIDATE, C.STARTUP]: moduleReply = self.datastoreManager.removeConfig(self.target, "config") elif self.target == C.URL: # BUG : should delete the specified url (e.g. on a ftp server) moduleReply = ModuleReply( error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.OPERATION_NOT_SUPPORTED, error_severity=ModuleReply.ERROR, error_message="Cannot delete the document at the specified url.", ) if moduleReply.isError(): self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return self.operationReply
def checkInternalNestingValidity(self, selectedNodes): for elem in selectedNodes: deepvalue = elem.getAttributeNS("urn:ietf:params:xml:ns:netconf:base:1.0", "operation") tmp = elem while (tmp.parentNode != elem.ownerDocument.documentElement): if tmp.parentNode in selectedNodes: # It means that elem is a child (direct or not) of another SelectedNode highvalue = tmp.parentNode.getAttributeNS("urn:ietf:params:xml:ns:netconf:base:1.0", "operation") if highvalue != "merge": moduleReply = ModuleReply( error_type = ModuleReply.APPLICATION, error_tag = ModuleReply.MISSING_ELEMENT, error_severity = ModuleReply.ERROR, error_message = "%s can not have %s operation in its subelements." % (highvalue, deepvalue)) self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return #return "%s can not have %s operation in its subelements." % (highvalue, deepvalue) else: tmp = tmp.parentNode
def execute(self): """ Execute the yum operation. """ stringCmd = "/etc/init.d/" + self.service + " " + self.command res = os.popen3(stringCmd) resultat = res[1].read() print "-----" print resultat resultat = res[2].read() print "-----" print resultat #doc = implementation.createDocument(C.NETCONF_XMLNS, "report", None) #nameNode = doc.createElementNS(None,module.name) #modulesNode.appendChild(nameNode) moduleReply = ModuleReply() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return self.operationReply
def rollBack(self): """ It restablish the last state of the device's configuration. Note that the last editConfig should had received erroroption equal to ROLL_BACK_ON_ERROR in order to achived this request, otherwise returns in error. @rtype: ModuleReply @return: It returns a success or error message. """ try: if (self.oldconfig != None): xmlreply = ModuleReply( error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.OPERATION_NOT_SUPPORTED, error_severity=ModuleReply.ERROR, error_message="The %s Module doesn't support rollback." % self.name) return xmlreply # It is necessary to delete the new configuration in order to push the old one, # there is no command yet in the # quagga soft to do it, and to delete by hand the quagga soft crash id = self.deviceConnection.stablishConnection() id = self.deviceConnection.setConfigureState(id,True) id = self.deviceConnection.sendCommand(id,self.oldconfig) xmlreply = ModuleReply() id = self.deviceConnection.setConfigureState(id,False) self.deviceConnection.closeConnection(id) else : xmlreply = ModuleReply( error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.ROLL_BACK, error_severity=ModuleReply.ERROR, error_message="It is not specified what to rollback") except ConnectError , exp : xmlreply = ModuleReply( error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.RESOURCE_DENIED, error_severity=ModuleReply.ERROR, error_tag_app=exp.getError(), error_message=str(exp))
def setParameters(self, operation, NSS=None): """ Set the parameters @type operation: Node @param operation: The operation node of the current Netconf request. """ for child in operation.childNodes: if child.nodeType == Node.ELEMENT_NODE: if child.tagName == C.SESSION_ID: for node in child.childNodes: if node.nodeType == Node.TEXT_NODE: try: self.sessionId = int(node.nodeValue) except Exception, exp: moduleReply = ModuleReply( error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.INVALID_VALUE, error_severity=ModuleReply.ERROR, error_message= "This is not a valid format for session-id parameter." ) moduleReply.addErrorInfo( "bad-element", str(node.nodeValue)) self.operationReply.setError() self.operationReply.setNode( moduleReply.getXMLNodeReply()) return else: moduleReply = ModuleReply( error_type=ModuleReply.PROTOCOL, error_tag=ModuleReply.UNKNOWN_ELEMENT, error_severity=ModuleReply.ERROR, error_message="An element is not known.") moduleReply.addErrorInfo("bad-element", child.tagName) self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return
def deleteConfig(self, targetName): if (targetName in [C.URL, C.RUNNING]): xmlreply = ModuleReply( error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.OPERATION_NOT_SUPPORTED, error_severity=ModuleReply.ERROR, error_message="OPERATION-NOT-SUPPORTED") return xmlreply if os.path.exists(C.YENCAP_HOME + '/Modules/VERMONT_Module/' + targetName + '.xml'): os.remove(C.YENCAP_HOME + '/Modules/VERMONT_Module/' + targetName + '.xml') xmlreply = ModuleReply() return xmlreply else: xmlreply = ModuleReply(error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.OPERATION_FAILED, error_severity=ModuleReply.ERROR, error_message="Datastore is already empty.") return xmlreply
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 setParameters(self, operation, NSS=None): """ Set the source parameter and the config parameter, config then contains the configuration to validate. @type operation: Node @param operation: The operation node of the current Netconf request. """ for child in operation.childNodes: if child.nodeType == Node.ELEMENT_NODE: if child.tagName == C.SOURCE: for node in child.childNodes: if node.nodeType == Node.ELEMENT_NODE: if node.tagName in [C.CANDIDATE, C.STARTUP, C.RUNNING]: self.target = node.tagName elif node.tagName == C.CONFIG: self.target = node.tagName for blub in node.childNodes: if blub.nodeType == Node.ELEMENT_NODE: if blub.localName == "netconf" and blub.namespaceURI == C.YENCAP_XMLNS: # We build a new document containing the "filter" to compare more easily self.config = implementation.createDocument(C.YENCAP_XMLNS, "netconf", None) clone = self.config.importNode(blub, True) # self.config is a document which documentElement is "netconf" self.config.replaceChild(clone, self.config.documentElement) return else: moduleReply = ModuleReply( error_type=ModuleReply.PROTOCOL, error_tag=ModuleReply.UNKNOWN_ELEMENT, error_severity=ModuleReply.ERROR, error_message="An element is not known.", ) moduleReply.addErrorInfo("bad-element", child.tagName) self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return
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 checkNestingValidity(self, prefixes): prefixes["xc"] = C.NETCONF_XMLNS xpathRequest = "//*[@xc:operation]" ctx = Context(self.config, processorNss = prefixes) selectedNodes = Evaluate(xpathRequest, ctx) if self.defaultOperation == "replace": if len(selectedNodes) != 0: #print "When default operation is replace, no other operation attribute is allowed." moduleReply = ModuleReply( error_type = ModuleReply.APPLICATION, error_tag = ModuleReply.UNKNOWN_ELEMENT, error_severity = ModuleReply.ERROR, error_message = "When default operation is replace, no other operation attribute is allowed.") moduleReply.addErrorInfo("bad-element",selectedNodes[0]) self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return else: return elif self.defaultOperation == "none": if len(selectedNodes) == 0: #print "When default operation is none, at least one operation attribute must appear." moduleReply = ModuleReply( error_type = ModuleReply.APPLICATION, error_tag = ModuleReply.MISSING_ELEMENT, error_severity = ModuleReply.ERROR, error_message = "When default operation is none, at least one operation attribute must appear.") self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return else: # Check the internal nestings, independently of default operation. self.checkInternalNestingValidity(selectedNodes) elif self.defaultOperation == "merge": # Check the internal nestings, independently of default operation. valid = self.checkInternalNestingValidity(selectedNodes)
def execute(self): """ Execute the validate operation. """ if self.operationReply.isError(): return self.operationReply # Execute validate if self.target in [C.CANDIDATE, C.STARTUP, C.RUNNING]: moduleReply = None for module in self.moduleManager.getModules(): moduleReply = module.validate(self.target) if moduleReply.isError(): self.operationReply.setNode(moduleReply.getXMLNodeReply()) return self.operationReply self.operationReply.setNode(moduleReply.getXMLNodeReply()) return self.operationReply elif self.target == C.CONFIG: moduleReply = None for module in self.moduleManager.getModules(): currentPath = module.path # Finding the nodes (related to the current module) # in the received configuration ctx = Context(self.config, processorNss=self.moduleManager.getPrefixes()) nodeList = Evaluate(currentPath, ctx) # Distributing the nodes to the current module if len(nodeList) > 1: moduleReply = ModuleReply( error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.UNKNOWN_ELEMENT, error_severity=ModuleReply.ERROR, error_message="More than one node found in the received data for the same module" + module.name, ) self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return self.operationReply elif len(nodeList) == 1: # Get the configuration to validate. node = nodeList[0] # Send the operation to the module. moduleReply = module.validate(self.target, self.config) if moduleReply.isError(): self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return self.operationReply if moduleReply == None: moduleReply = ModuleReply( error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.UNKNOWN_ELEMENT, error_severity=ModuleReply.ERROR, error_message="Not any module matched", ) self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return self.operationReply # If somebody has the strange idea to try this: elif self.target == C.URL: xmlreply = ModuleReply( error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.OPERATION_NOT_SUPPORTED, error_severity=ModuleReply.ERROR, error_message="OPERATION-NOT-SUPPORTED", ) self.operationReply.setNode(xmlReply.getXMLNodeReply()) return self.operationReply
def setParameters(self, operation, NSS = None): """ Set the target parameter @type operation: Node @param operation: The operation node of the current Netconf request. """ for child in operation.childNodes: if child.nodeType==Node.ELEMENT_NODE: if child.tagName in [C.ACTIVATE,C.DEACTIVATE]: self.action = child.tagName for node in child.childNodes: if node.nodeType==Node.ELEMENT_NODE: if node.tagName in C.ROLES: for nodeee in node.childNodes: if nodeee.nodeType==Node.ELEMENT_NODE: if nodeee.tagName in C.ROLE: tmpval = nodeee.childNodes[0].nodeValue roleName = string.strip(str(tmpval)) role = rbacManager.getInstance().getRoleFromName(roleName) if role == None: moduleReply = ModuleReply( error_type = ModuleReply.PROTOCOL, error_tag = ModuleReply.UNKNOWN_ELEMENT, error_severity = ModuleReply.ERROR, error_message = "Role " + roleName + " does not exist.") moduleReply.addErrorInfo("bad-element", roleName) self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return else: self.roles.append(role) else: moduleReply = ModuleReply( error_type = ModuleReply.PROTOCOL, error_tag = ModuleReply.UNKNOWN_ELEMENT, error_severity = ModuleReply.ERROR, error_message = "An element is not known.") moduleReply.addErrorInfo("bad-element",nodeee.tagName) self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return else: moduleReply = ModuleReply( error_type = ModuleReply.PROTOCOL, error_tag = ModuleReply.UNKNOWN_ELEMENT, error_severity = ModuleReply.ERROR, error_message = "An element is not known.") moduleReply.addErrorInfo("bad-element",node.tagName) self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return else: moduleReply = ModuleReply( error_type = ModuleReply.PROTOCOL, error_tag = ModuleReply.UNKNOWN_ELEMENT, error_severity = ModuleReply.ERROR, error_message = "An element is not known.") moduleReply.addErrorInfo("bad-element",child.tagName) self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return
def setParameters(self, operation, NSS = None): """ Set the source and filter parameters @type operation: Node @param operation: The operation node of the current Netconf request. """ self.prefixes = NSS for child in operation.childNodes: if child.nodeType==Node.ELEMENT_NODE: if child.tagName == C.SOURCE: for node in child.childNodes: if node.nodeType==Node.ELEMENT_NODE: if node.tagName in [C.RUNNING, C.CANDIDATE, C.STARTUP]: self.source = node.tagName else: moduleReply = ModuleReply( error_type = ModuleReply.PROTOCOL, error_tag = ModuleReply.BAD_ELEMENT, error_severity = ModuleReply.ERROR, error_message = "An element value is not correct.") moduleReply.addErrorInfo("bad-element",node.tagName) self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return elif child.tagName == C.FILTER: self.filter = child for att in self.filter.attributes.values(): if att.name == "type": if att.value == C.SUBTREE: self.filterType = C.SUBTREE elif att.value == C.XPATH: self.filterType = C.XPATH else: moduleReply = ModuleReply( error_type = ModuleReply.PROTOCOL, error_tag = ModuleReply.BAD_ATTRIBUTE, error_severity = ModuleReply.ERROR, error_message = "An attribute value is not correct") moduleReply.addErrorInfo("bad-attribute",att.name) moduleReply.addErrorInfo("bad-element",child.tagName) self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return else: moduleReply = ModuleReply( error_type = ModuleReply.PROTOCOL, error_tag = ModuleReply.UNKNOWN_ATTRIBUTE, error_severity = ModuleReply.ERROR, error_message = "An unexpected attribute is present") moduleReply.addErrorInfo("bad-attribute",att.name) moduleReply.addErrorInfo("bad-element",child.tagName) self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return if self.filterType == C.XPATH: tmpval = self.filter.childNodes[0].nodeValue self.xpathrequest = string.strip(str(tmpval)) if self.xpathrequest == "": moduleReply = ModuleReply( error_type = ModuleReply.PROTOCOL, error_tag = ModuleReply.INVALID_VALUE, error_severity = ModuleReply.ERROR, error_message = "The request specifies an unacceptable value for one or more parameters.") self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return elif self.filterType == C.SUBTREE: for node in self.filter.childNodes: if (node.nodeType==Node.ELEMENT_NODE): self.subtree = node else: moduleReply = ModuleReply( error_type = ModuleReply.PROTOCOL, error_tag = ModuleReply.UNKNOWN_ELEMENT, error_severity = ModuleReply.ERROR, error_message = "An element is not known.") moduleReply.addErrorInfo("bad-element",child.tagName) self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return if self.filter == None: self.subtree = implementation.createDocument(C.YENCAP_XMLNS, 'netconf', None).documentElement
def setParameters(self, operation, NSS = None): """ Set the source and filter parameters @type operation: Node @param operation: The operation node of the current Netconf request. """ self.prefixes = NSS for child in operation.childNodes: if child.nodeType==Node.ELEMENT_NODE: if child.tagName == C.FILTER: self.filter = child for att in self.filter.attributes.values(): if att.name == "type": if att.value == C.SUBTREE: self.filterType = C.SUBTREE elif att.value == C.XPATH: self.filterType = C.XPATH else: moduleReply = ModuleReply( error_type = ModuleReply.PROTOCOL, error_tag = ModuleReply.BAD_ATTRIBUTE, error_severity = ModuleReply.ERROR, error_message = "An attribute value is not correct") moduleReply.addErrorInfo("bad-attribute",att.name) moduleReply.addErrorInfo("bad-element",child.tagName) self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return else: moduleReply = ModuleReply( error_type = ModuleReply.PROTOCOL, error_tag = ModuleReply.UNKNOWN_ATTRIBUTE, error_severity = ModuleReply.ERROR, error_message = "An unexpected attribute is present") moduleReply.addErrorInfo("bad-attribute",att.name) moduleReply.addErrorInfo("bad-element",child.tagName) self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return if self.filterType == C.XPATH: tmpval = self.filter.childNodes[0].nodeValue self.xpathrequest = string.strip(str(tmpval)) elif self.filterType == C.SUBTREE: for node in self.filter.childNodes: if (node.nodeType==Node.ELEMENT_NODE): self.subtree = node else: moduleReply = ModuleReply( error_type = ModuleReply.PROTOCOL, error_tag = ModuleReply.UNKNOWN_ELEMENT, error_severity = ModuleReply.ERROR, error_message = "An element is not known.") moduleReply.addErrorInfo("bad-element",child.tagName) self.operationReply.setError() self.operationReply.setNode(moduleReply.getXMLNodeReply()) return
def makeNode(self,node, structnode, followcommand,stepping, creating,deleting): """ Creates the device's command for the node paramiters, the commands created will de could be to delete, create or making the envelop for the node in the device. @type node: cDomelette @param node: Issue Node @type structnode: cDomelette @param structnode: It is the equivalent node of "node" but in the XML Translation Language @type followcommand: Command @param followcommand: It is the command that will be appended to the beginning of all the commands generated by this function. @type stepping : boolean @param stepping: If set to true, it will just look for the <command> and <followcommand> nodes in the structnode, this is the case for generating the envelop. @type creating: boolean @param creating: If set to true, it will look for the <creatingcommand> nodes in the structnode, if any , otherwise will use the <command> node to generated the commands @type deleting: boolean @param deleting: If set to true, it will look for the <deletingcommand> nodes in the structnode, if any , otherwise will negate the <command> node and use it to generated the commands """ commandlist = CommandList() if (structnode != None): structnode = structnode.xpath(node.nodeName) if(structnode != []): structnode = structnode[0] else: structnode = None if (structnode != None): deletingvar = deleting steppingvar = stepping creatingvar = creating while (deletingvar or steppingvar or creatingvar): if (deletingvar): deletingvar = False followrecursion = False commandstr = self.DELETINGCOMMAND_ITEM elif (creatingvar): creatingvar = False followrecursion = False commandstr = self.CREATINGCOMMAND_ITEM elif (steppingvar): steppingvar = False followrecursion = True commandstr = self.COMMAND_ITEM commands = self.makeCommand(node,structnode,commandstr,recursiondefault=False) commandadd = False if (commands != None): commandadd = True for subcommand in commands: followrecursion = followrecursion or subcommand.getRecursion() subcommand.setHeading(followcommand) commandlist.addCommand(subcommand) commands = self.makeCommand(node,structnode,"exit"+commandstr,absolutepathdefault=True,recursiondefault=False) if (commands != None): commandadd = True for subcommand in commands: followrecursion = followrecursion or subcommand.getRecursion() subcommand.setHeading(followcommand) commandlist.addCommand(leavingcommand=subcommand) if (not commandadd and not stepping): commands = self.makeCommand(node,structnode,self.COMMAND_ITEM) if (commands != None): if(deleting): tempfollowcommand = followcommand.clone() tempfollowcommand.neg() else: tempfollowcommand = followcommand for subcommand in commands: followrecursion = followrecursion or subcommand.getRecursion() subcommand.setHeading(tempfollowcommand) commandlist.addCommand(subcommand) else: followrecursion = True if (followrecursion): tempfollowcommand = self.makeCommand(node,structnode,self.FOLLOWCOMMAND_ITEM) if (tempfollowcommand != None and tempfollowcommand != []): tempfollowcommand[0].setHeading(followcommand) tempfollowcommand = tempfollowcommand[0] else: tempfollowcommand = followcommand if (structnode.childNodes != []): structchild = structnode.xpath("childs") if (structchild != []): structchild = structchild[0] else : structchild = None for child in node.childNodes : if (child.nodeName != TEXT_NODE_NAME): commandlistchild = self.makeNode(child, structchild, tempfollowcommand, stepping, creating,deleting) commandlist.appendCommands(commandlistchild) commandlist.newList() else: reply = ModuleReply(error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.BAD_ELEMENT, error_severity=ModuleReply.ERROR, error_message="The element not belong to this protocol") reply.addErrorInfo(ModuleReply.BAD_ATTRIBUTE_INFO,node.nodeName) raise XML_Interpreter_Exception(reply) return commandlist
def requestNodes(self,node, structnode): """ Using the key items from strucnode and the values of them in the editconfig request, it search for the nodes that match them in the node paramiter. Also the if the acceptXPathTag is set to true it checks for the xpath attribute tags. @type node: cDomelette @param node: The node where the search will be apply @type strucnode: cDomelette @param strucnode: The current node from XML Translation Language equivalent to node. Return a list of nodes that are childs from 'node' and the key elements match with the ones from 'self.issueNode' """ requestNodes = None if (structnode != None): structnode = structnode.xpath(self.issueNode.nodeName) if (structnode == []): reply = ModuleReply( error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.BAD_ELEMENT, error_severity=ModuleReply.ERROR, error_message="The element not belong to this protocol") reply.addErrorInfo(ModuleReply.BAD_ELEMENT_INFO,node.nodeName) raise XML_Interpreter_Exception(reply) else: structnode = structnode[0] if("true" == structnode.getAttributeNS(EMPTY_NAMESPACE,self.KEY_TAG)): reply = ModuleReply( error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.BAD_ATTRIBUTE, error_severity=ModuleReply.ERROR, error_message="Attemp to do an operation over a key node") reply.addErrorInfo(ModuleReply.BAD_ELEMENT_INFO,self.issueNode.nodeName) reply.addErrorInfo(ModuleReply.BAD_ATTRIBUTE_INFO,self.operationType) raise XML_Interpreter_Exception(reply) keynodes = structnode.xpath("childs/*[@"+self.KEY_TAG+"='true']") allowfields = [] for keynode in keynodes: if self.namespaceURI == None : allowfields.extend(self.issueNode.xpath("*[local-name()='"+keynode.nodeName+"']")) else: allowfields.extend(self.issueNode.xpath("*[local-name()='"+keynode.nodeName+"' and namespace-uri()='"+self.namespaceURI+"']")) xpath =self.getXpathFromXMLNode(self.issueNode,allowChilds=allowfields) requestNodes = node.xpath(xpath,{"ns":self.namespaceURI}) else: reply = ModuleReply( error_type=ModuleReply.APPLICATION, error_tag=ModuleReply.BAD_ELEMENT, error_severity=ModuleReply.ERROR, error_message="The element not belong to this protocol") reply.addErrorInfo(ModuleReply.BAD_ELEMENT_INFO,node.nodeName) raise XML_Interpreter_Exception(reply) return requestNodes