def _run_one(netconf, message_id, operation, netconf_namespace, data, xmlns): """run one call by netconf connection""" # rpc ctx.logger.info("rpc call") parent = utils.rpc_gen(message_id, operation, netconf_namespace, data, xmlns) # send rpc rpc_string = etree.tostring(parent, pretty_print=True, xml_declaration=True, encoding='UTF-8') ctx.logger.info("i sent: " + rpc_string) response = netconf.send(rpc_string) ctx.logger.info("i recieved:" + response) response_dict = _parse_response(xmlns, netconf_namespace, response) ctx.logger.info("package will be :" + str(response_dict)) return response_dict
def _run_one( netconf, message_id, operation, netconf_namespace, data, xmlns ): """run one call by netconf connection""" # rpc ctx.logger.info("rpc call") parent = utils.rpc_gen( message_id, operation, netconf_namespace, data, xmlns ) # send rpc rpc_string = etree.tostring( parent, pretty_print=True, xml_declaration=True, encoding='UTF-8' ) ctx.logger.info("i sent: " + rpc_string) response = netconf.send(rpc_string) ctx.logger.info("i recieved:" + response) response_dict = _parse_response( xmlns, netconf_namespace, response ) ctx.logger.info("package will be :" + str(response_dict)) return response_dict
def run(**kwargs): """main entry point for all calls""" calls = kwargs.get('calls', []) if not calls: ctx.logger.info("No calls") return # credentials properties = ctx.node.properties ip = properties.get('netconf_auth', {}).get('ip') user = properties.get('netconf_auth', {}).get('user') password = properties.get('netconf_auth', {}).get('password') key_content = properties.get('netconf_auth', {}).get('key_content') if not ip or not user or (not password and not key_content): raise cfy_exc.NonRecoverableError("please check your credentials") # some random initial message id, for have different between calls message_id = int((time.time() * 100) % 100 * 1000) # xml namespaces and capabilities xmlns = properties.get('metadata', {}).get('xmlns', {}) # override by system namespaces xmlns = _merge_ns(xmlns, properties.get('base_xmlns', {})) netconf_namespace, xmlns = utils.update_xmlns(xmlns) capabilities = properties.get('metadata', {}).get('capabilities') # connect ctx.logger.info("use %s@%s for login" % (user, ip)) hello_string = _generate_hello(xmlns, netconf_namespace, capabilities) ctx.logger.info("i sent: " + hello_string) netconf = netconf_connection.connection() capabilities = netconf.connect(ip, user, hello_string, password, key_content) ctx.logger.info("i recieved: " + capabilities) if _server_support_1_1(xmlns, netconf_namespace, capabilities): ctx.logger.info("i will use version 1.1 of netconf protocol") netconf.current_level = netconf_connection.NETCONF_1_1_CAPABILITY if 'lock' in kwargs: message_id = message_id + 1 for name in kwargs['lock']: _lock(name, True, netconf, message_id, netconf_namespace, xmlns) if 'back_database' in kwargs and 'front_database' in kwargs: message_id = message_id + 1 _copy(kwargs['front_database'], kwargs['back_database'], netconf, message_id, netconf_namespace, xmlns) # recheck before real send for call in calls: operation = call.get('action') if not operation: continue data = call.get('payload', {}) # gen xml for check parent = utils.rpc_gen(message_id, operation, netconf_namespace, data, xmlns) # validate rpc validation = call.get('validation', {}) xpath = validation.get('xpath') if xpath: ctx.logger.info("We have some validation rules for " + str(xpath)) rng = validation.get('rng') sch = validation.get('sch') utils.xml_validate(parent, xmlns, xpath, rng, sch) # we can have several calls in one session, # like lock, edit-config, unlock for call in calls: operation = call.get('action') if not operation: ctx.logger.info("No operations") continue data = call.get('payload', {}) message_id = message_id + 1 if "@" not in operation: operation = "_@" + operation _update_data(data, operation, netconf_namespace, kwargs.get('back_database')) response_dict = _run_one(netconf, message_id, operation, netconf_namespace, data, xmlns) # save results to runtime properties save_to = call.get('save_to') if save_to: ctx.instance.runtime_properties[save_to] = response_dict ctx.instance.runtime_properties[save_to + "_ns"] = xmlns if 'back_database' in kwargs and 'front_database' in kwargs: message_id = message_id + 1 _copy(kwargs['back_database'], kwargs['front_database'], netconf, message_id, netconf_namespace, xmlns) if 'lock' in kwargs: message_id = message_id + 1 for name in kwargs['lock']: _lock(name, False, netconf, message_id, netconf_namespace, xmlns) # goodbye ctx.logger.info("connection close") message_id = message_id + 1 goodbye_string = _generate_goodbye(xmlns, netconf_namespace, message_id) ctx.logger.info("i sent: " + goodbye_string) response = netconf.close(goodbye_string) ctx.logger.info("i recieved: " + response)
def run(**kwargs): """main entry point for all calls""" calls = kwargs.get('calls', []) if not calls: ctx.logger.info("No calls") return # credentials properties = ctx.node.properties ip = properties.get('netconf_auth', {}).get('ip') user = properties.get('netconf_auth', {}).get('user') password = properties.get('netconf_auth', {}).get('password') key_content = properties.get('netconf_auth', {}).get('key_content') port = properties.get('netconf_auth', {}).get('port', 830) if not ip or not user or (not password and not key_content): raise cfy_exc.NonRecoverableError( "please check your credentials" ) # some random initial message id, for have different between calls message_id = int((time.time() * 100) % 100 * 1000) # xml namespaces and capabilities xmlns = properties.get('metadata', {}).get('xmlns', {}) # override by system namespaces xmlns = _merge_ns(xmlns, properties.get('base_xmlns', {})) netconf_namespace, xmlns = utils.update_xmlns( xmlns ) capabilities = properties.get('metadata', {}).get('capabilities') # connect ctx.logger.info("use %s@%s for login" % (user, ip)) hello_string = _generate_hello( xmlns, netconf_namespace, capabilities ) ctx.logger.info("i sent: " + hello_string) netconf = netconf_connection.connection() capabilities = netconf.connect( ip, user, hello_string, password, key_content, port ) ctx.logger.info("i recieved: " + capabilities) if _server_support_1_1(xmlns, netconf_namespace, capabilities): ctx.logger.info("i will use version 1.1 of netconf protocol") netconf.current_level = netconf_connection.NETCONF_1_1_CAPABILITY if 'lock' in kwargs: message_id = message_id + 1 for name in kwargs['lock']: _lock( name, True, netconf, message_id, netconf_namespace, xmlns ) if 'back_database' in kwargs and 'front_database' in kwargs: message_id = message_id + 1 _copy( kwargs['front_database'], kwargs['back_database'], netconf, message_id, netconf_namespace, xmlns ) # recheck before real send for call in calls: operation = call.get('action') if not operation: continue data = call.get('payload', {}) # gen xml for check parent = utils.rpc_gen( message_id, operation, netconf_namespace, data, xmlns ) # try to validate validate_xml = call.get('validate_xml', True) if validate_xml: # validate rpc rng, sch, xpath = _gen_relaxng_with_schematron( properties.get('metadata', {}).get('dsdl'), call.get('action') ) else: xpath = None if xpath: ctx.logger.info( "We have some validation rules for '{}'".format( str(xpath) ) ) utils.xml_validate( parent, xmlns, xpath, rng, sch ) # we can have several calls in one session, # like lock, edit-config, unlock for call in calls: operation = call.get('action') if not operation: ctx.logger.info("No operations") continue data = call.get('payload', {}) message_id = message_id + 1 if "@" not in operation: operation = "_@" + operation _update_data( data, operation, netconf_namespace, kwargs.get('back_database') ) response_dict = _run_one( netconf, message_id, operation, netconf_namespace, data, xmlns ) # save results to runtime properties save_to = call.get('save_to') if save_to: ctx.instance.runtime_properties[save_to] = response_dict ctx.instance.runtime_properties[save_to + "_ns"] = xmlns if 'back_database' in kwargs and 'front_database' in kwargs: message_id = message_id + 1 _copy( kwargs['back_database'], kwargs['front_database'], netconf, message_id, netconf_namespace, xmlns ) if 'lock' in kwargs: message_id = message_id + 1 for name in kwargs['lock']: _lock( name, False, netconf, message_id, netconf_namespace, xmlns ) # goodbye ctx.logger.info("connection close") message_id = message_id + 1 goodbye_string = _generate_goodbye( xmlns, netconf_namespace, message_id ) ctx.logger.info("i sent: " + goodbye_string) response = netconf.close(goodbye_string) ctx.logger.info("i recieved: " + response)