def delete_node_rpc(self, root: InstanceNode, rpc: RpcInfo) -> Tuple[InstanceNode, bool]: ii = self.parse_ii(rpc.path, rpc.path_format) n = root.goto(ii) # Deny any changes of NACM data for non-privileged users nacm_changed = False if (len(ii) > 0) and (isinstance(ii[0], MemberName)): # Not getting root ns_first = ii[0].namespace if ns_first == "ietf-netconf-acm": nacm_changed = True if rpc.username not in CONFIG_NACM["ALLOWED_USERS"]: raise NacmForbiddenError( rpc.username + " not allowed to modify NACM data") else: # Deleting root node # Check if NACM data are present in the datastore nacm_val = n.value.get("ietf-netconf-acm:nacm") if nacm_val is not None: nacm_changed = True if rpc.username not in CONFIG_NACM["ALLOWED_USERS"]: raise NacmForbiddenError( rpc.username + " not allowed to modify NACM data") # Evaluate NACM if self.nacm and not rpc.skip_nacm_check: nrpc = self.nacm.get_user_rules(rpc.username) if nrpc.check_data_node_permission( root, ii, Permission.NACM_ACCESS_DELETE) == Action.DENY: raise NacmForbiddenError() if len(ii) == 0: # Deleting entire datastore new_n = RootNode(ObjectValue({}), root.schema_node, datetime.now()) else: n_parent = n.up() last_isel = ii[-1] if isinstance(n_parent.value, ArrayValue): if isinstance(last_isel, EntryIndex): new_n = n_parent.delete_item(last_isel.index) elif isinstance(last_isel, EntryKeys): new_n = n_parent.delete_item(n.index) else: raise ValueError("Unknown node selector") elif isinstance(n_parent.value, ObjectValue): new_n = n_parent.delete_item( last_isel.namespace + ":" + last_isel.name if last_isel.namespace else last_isel.name) else: raise InstanceValueError(rpc.path, "Invalid target node type") return new_n.top(), nacm_changed
def test_xml_action(data_model): ''' Encodes known "raw data" Action input & outputs to an XML strings and back again. ''' output_obj = { "test:output" : { "leafL" : True } } output_xml_pretty = """ <output xmlns="http://example.com/test"> <leafL>true</leafL> </output> """ output_xml_stripped = strip_pretty(output_xml_pretty) # get the schema node for the 'action' sn_action = data_model.get_schema_node("/test:contA/listA/contD/acA") assert(type(sn_action) == RpcActionNode) ######### # INPUT # ######### # this 'action' has no input. ########## # OUTPUT # ########## # convert raw object to an InstanceValue # - an ObjectValue, not a RootNode as per DataModel.from_raw() output_inst_val = sn_action.from_raw(output_obj) assert(str(output_inst_val) == str(output_obj)) # convert InstanceValue to an Instance (a RootNode) output_inst = RootNode(output_inst_val, sn_action, data_model.schema_data, output_inst_val.timestamp) output_inst.validate(ctype=ContentType.all) assert(output_inst.raw_value() == output_obj) # convert Instance to an XML-encoded string and compare to known-good output_xml_et_obj = output_inst.to_xml() output_xml_text = ET.tostring(output_xml_et_obj).decode("utf-8") assert(output_xml_text == output_xml_stripped) # convert output's XML-encoded string back to an InstanceValue # - an ObjectValue, not a RootNode as per DataModel.from_xml() parser = XMLParser(output_xml_text) output_xml_et_obj2 = parser.root output_inst_val2 = sn_action.from_xml(output_xml_et_obj2) assert(output_inst_val2 == output_inst_val) # convert InstanceValue back to an Instance (a RootNode) output_inst2 = RootNode(output_inst_val2, sn_action, data_model.schema_data, output_inst_val2.timestamp) output_inst2.validate(ctype=ContentType.all) assert(output_inst2.raw_value() == output_obj) # convert Instance to raw value and ensure same output_rv2 = output_inst2.raw_value() assert(output_rv2 == output_obj)
def test_xml_rpc(data_model): ''' Encodes known "raw data" RPC input & outputs to an XML strings and back again. ''' input_obj = { "testb:input" : { "leafK" : 123 } } input_xml_pretty = """ <input xmlns="http://example.com/testb"> <leafK>123</leafK> </input> """ output_obj = { "testb:output" : { "llistC" : [True, False, True] } } output_xml_pretty = """ <output xmlns="http://example.com/testb"> <llistC>true</llistC> <llistC>false</llistC> <llistC>true</llistC> </output> """ input_xml_stripped = strip_pretty(input_xml_pretty) output_xml_stripped = strip_pretty(output_xml_pretty) # get the schema node for the RPC sn_rpc = data_model.get_schema_node("/testb:rpcA") # used by both tests assert(type(sn_rpc) == RpcActionNode) ######### # INPUT # ######### # convert raw object to an InstanceValue # - an ObjectValue, not a RootNode as per DataModel.from_raw() input_inst_val = sn_rpc.from_raw(input_obj) assert(str(input_inst_val) == str(input_obj)) # convert InstanceValue to an Instance (a RootNode) input_inst = RootNode(input_inst_val, sn_rpc, data_model.schema_data, input_inst_val.timestamp) input_inst.validate(ctype=ContentType.all) assert(input_inst.raw_value() == input_obj) # convert Instance to an XML-encoded string and compare to known-good input_xml_et_obj = input_inst.to_xml() input_xml_text = ET.tostring(input_xml_et_obj).decode("utf-8") assert(input_xml_text == input_xml_stripped) # convert input's XML-encoded string back to an InstanceValue # - an ObjectValue, not a RootNode as per DataModel.from_xml() parser = XMLParser(input_xml_text) input_xml_et_obj2 = parser.root input_inst_val2 = sn_rpc.from_xml(input_xml_et_obj2) assert(input_inst_val2 == input_inst_val) # convert InstanceValue back to an Instance (a RootNode) input_inst2 = RootNode(input_inst_val2, sn_rpc, data_model.schema_data, input_inst_val2.timestamp) input_inst2.validate(ctype=ContentType.all) assert(input_inst2.raw_value() == input_obj) # convert Instance to raw value and ensure same input_rv2 = input_inst2.raw_value() assert(input_rv2 == input_obj) ########## # OUTPUT # ########## # convert raw object to an InstanceValue # - an ObjectValue, not a RootNode as per DataModel.from_raw() output_inst_val = sn_rpc.from_raw(output_obj) assert(str(output_inst_val) == str(output_obj)) # convert InstanceValue to an Instance (a RootNode) output_inst = RootNode(output_inst_val, sn_rpc, data_model.schema_data, output_inst_val.timestamp) output_inst.validate(ctype=ContentType.all) assert(output_inst.raw_value() == output_obj) # convert Instance to an XML-encoded string and compare to known-good output_xml_et_obj = output_inst.to_xml() output_xml_text = ET.tostring(output_xml_et_obj).decode("utf-8") assert(output_xml_text == output_xml_stripped) # convert output's XML-encoded string back to an InstanceValue # - an ObjectValue, not a RootNode as per DataModel.from_xml() parser = XMLParser(output_xml_text) output_xml_et_obj2 = parser.root output_inst_val2 = sn_rpc.from_xml(output_xml_et_obj2) assert(output_inst_val2 == output_inst_val) # convert InstanceValue back to an Instance (a RootNode) output_inst2 = RootNode(output_inst_val2, sn_rpc, data_model.schema_data, output_inst_val2.timestamp) output_inst2.validate(ctype=ContentType.all) assert(output_inst2.raw_value() == output_obj) # convert Instance to raw value and ensure same output_rv2 = output_inst2.raw_value() assert(output_rv2 == output_obj)
def test_rpc(data_model, rpc_raw_output): sn = data_model.get_schema_node("/testb:rpcA") cooked = sn.from_raw(rpc_raw_output) inst = RootNode(cooked, sn, data_model.schema_data, cooked.timestamp) assert inst.raw_value() == rpc_raw_output assert inst.validate(ctype=ContentType.all) is None
def test_top_level_nodes(data_model): rv = {} # will an empty dict work? sn = data_model.get_schema_node("/") assert(type(sn) == SchemaTreeNode) cooked = sn.from_raw(rv) assert(type(cooked) == ObjectValue) rn = RootNode(cooked, sn, data_model.schema_data, cooked.timestamp) assert(type(rn) == RootNode) assert(type(rn.schema_node) == SchemaTreeNode) sn = data_model.get_schema_node("/testb:rpcA") assert(type(sn) == RpcActionNode) cooked = sn.from_raw(rv) assert(type(cooked) == ObjectValue) rn = RootNode(cooked, sn, data_model.schema_data, cooked.timestamp) assert(type(rn) == RootNode) assert(type(rn.schema_node) == RpcActionNode) sn = data_model.get_schema_node("/testb:rpcA/input") assert(type(sn) == InputNode) cooked = sn.from_raw(rv) assert(type(cooked) == ObjectValue) rn = RootNode(cooked, sn, data_model.schema_data, cooked.timestamp) assert(type(rn) == RootNode) assert(type(rn.schema_node) == InputNode) sn = data_model.get_schema_node("/testb:rpcA/output") assert(type(sn) == OutputNode) cooked = sn.from_raw(rv) assert(type(cooked) == ObjectValue) rn = RootNode(cooked, sn, data_model.schema_data, cooked.timestamp) assert(type(rn) == RootNode) assert(type(rn.schema_node) == OutputNode) sn = data_model.get_schema_node("/test:contA/listA/contD/acA") assert(type(sn) == RpcActionNode) cooked = sn.from_raw(rv) assert(type(cooked) == ObjectValue) rn = RootNode(cooked, sn, data_model.schema_data, cooked.timestamp) assert(type(rn) == RootNode) assert(type(rn.schema_node) == RpcActionNode) sn = data_model.get_schema_node("/test:contA/listA/contD/acA/input") assert(type(sn) == InputNode) cooked = sn.from_raw(rv) assert(type(cooked) == ObjectValue) rn = RootNode(cooked, sn, data_model.schema_data, cooked.timestamp) assert(type(rn) == RootNode) assert(type(rn.schema_node) == InputNode) sn = data_model.get_schema_node("/test:contA/listA/contD/acA/output") assert(type(sn) == OutputNode) cooked = sn.from_raw(rv) assert(type(cooked) == ObjectValue) rn = RootNode(cooked, sn, data_model.schema_data, cooked.timestamp) assert(type(rn) == RootNode) assert(type(rn.schema_node) == OutputNode) sn = data_model.get_schema_node("/testb:noA") assert(type(sn) == NotificationNode) cooked = sn.from_raw(rv) assert(type(cooked) == ObjectValue) rn = RootNode(cooked, sn, data_model.schema_data, cooked.timestamp) assert(type(rn) == RootNode) assert(type(rn.schema_node) == NotificationNode)
def test_xml_notification(data_model): ''' Encodes known "raw data" Notification to an XML string and back again. Work in progress (see Issue #78) ''' # get the schema node for the 'notiication' sn_notif = data_model.get_schema_node("/testb:noA") assert(type(sn_notif) == NotificationNode) ####### # NOA # ####### noA_obj = { "testb:leafO" : True } noA_xml_pretty = """ <leafO xmlns="http://example.com/testb">true</leafO> """ noA_xml_stripped = strip_pretty(noA_xml_pretty) # convert raw object to an InstanceValue # - an ObjectValue, not a RootNode as per DataModel.from_raw() noA_inst_val = sn_notif.from_raw(noA_obj, allow_nodata=True) assert(str(noA_inst_val) == str(noA_obj)) # convert InstanceValue to an Instance (a RootNode) noA_inst = RootNode(noA_inst_val, sn_notif, data_model.schema_data, noA_inst_val.timestamp) noA_inst.validate(ctype=ContentType.all) assert(noA_inst.raw_value() == noA_obj) # convert Instance to an XML-encoded string and compare to known-good noA_xml_et_obj = noA_inst.to_xml() noA_xml_text = ET.tostring(noA_xml_et_obj).decode("utf-8") assert(noA_xml_text == noA_xml_stripped) # convert noa's XML-encoded string back to an InstanceValue # - an ObjectValue, not a RootNode as per DataModel.from_xml() parser = XMLParser(noA_xml_text) noA_xml_et_obj2 = parser.root noA_inst_val2 = sn_notif.from_xml(noA_xml_et_obj2, isroot=True, allow_nodata=True) assert(noA_inst_val2 == noA_inst_val) # convert InstanceValue back to an Instance (a RootNode) noA_inst2 = RootNode(noA_inst_val2, sn_notif, data_model.schema_data, noA_inst_val2.timestamp) noA_inst2.validate(ctype=ContentType.all) assert(noA_inst2.raw_value() == noA_obj) # convert Instance to raw value and ensure same noA_rv2 = noA_inst2.raw_value() assert(noA_rv2 == noA_obj)