Exemple #1
0
    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
Exemple #2
0
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)
Exemple #3
0
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)
Exemple #4
0
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
Exemple #5
0
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)
Exemple #6
0
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)