Beispiel #1
0
 def test_nonexisting_id(self):
     self.fixture_add_primitive_with_id("myId")
     self.assertFalse(lib.does_id_exist(self.cib.tree, "otherId"))
     self.assertFalse(lib.does_id_exist(self.cib.tree, "myid"))
     self.assertFalse(lib.does_id_exist(self.cib.tree, " myId"))
     self.assertFalse(lib.does_id_exist(self.cib.tree, "myId "))
     self.assertFalse(lib.does_id_exist(self.cib.tree, "my Id"))
Beispiel #2
0
 def test_nonexisting_id(self):
     self.fixture_add_primitive_with_id("myId")
     self.assertFalse(lib.does_id_exist(self.cib.tree, "otherId"))
     self.assertFalse(lib.does_id_exist(self.cib.tree, "myid"))
     self.assertFalse(lib.does_id_exist(self.cib.tree, " myId"))
     self.assertFalse(lib.does_id_exist(self.cib.tree, "myId "))
     self.assertFalse(lib.does_id_exist(self.cib.tree, "my Id"))
Beispiel #3
0
 def test_ignore_acl_role_references(self):
     self.cib.append_to_first_tag_name(
         "configuration", """
         <acls>
             <acl_target id="target1">
                 <role id="role1"/>
                 <role id="role2"/>
             </acl_target>
         </acls>
         """)
     self.assertFalse(lib.does_id_exist(self.cib.tree, "role1"))
     self.assertFalse(lib.does_id_exist(self.cib.tree, "role2"))
Beispiel #4
0
 def test_ignore_acl_role_references(self):
     self.cib.append_to_first_tag_name(
         "configuration",
         """
         <acls>
             <acl_target id="target1">
                 <role id="role1"/>
                 <role id="role2"/>
             </acl_target>
         </acls>
         """
     )
     self.assertFalse(lib.does_id_exist(self.cib.tree, "role1"))
     self.assertFalse(lib.does_id_exist(self.cib.tree, "role2"))
Beispiel #5
0
def validate_permissions(tree, permission_info_list):
    """
    Validate given permission list.
    Raise LibraryError if any of permission is not valid.

    tree -- cib tree
    permission_info_list -- list of tuples like this:
        ("read|write|deny", "xpath|id", <id-or-xpath-string>)
    """
    report_items = []
    allowed_permissions = ["read", "write", "deny"]
    allowed_scopes = ["xpath", "id"]
    for permission, scope_type, scope in permission_info_list:
        if not permission in allowed_permissions:
            report_items.append(reports.invalid_option_value(
                "permission",
                permission,
                allowed_permissions
            ))

        if not scope_type in allowed_scopes:
            report_items.append(reports.invalid_option_value(
                "scope type",
                scope_type,
                allowed_scopes
            ))

        if scope_type == 'id' and not does_id_exist(tree, scope):
            report_items.append(reports.id_not_found(scope, "id"))

    if report_items:
        raise LibraryError(*report_items)
Beispiel #6
0
def validate_permissions(tree, permission_info_list):
    """
    Validate given permission list.
    Raise LibraryError if any of permission is not valid.

    tree -- cib tree
    permission_info_list -- list of tuples like this:
        ("read|write|deny", "xpath|id", <id-or-xpath-string>)
    """
    report_items = []
    allowed_permissions = ["read", "write", "deny"]
    allowed_scopes = ["xpath", "id"]
    for permission, scope_type, scope in permission_info_list:
        if not permission in allowed_permissions:
            report_items.append(
                reports.invalid_option_value("permission", permission,
                                             allowed_permissions))

        if not scope_type in allowed_scopes:
            report_items.append(
                reports.invalid_option_value("scope type", scope_type,
                                             allowed_scopes))

        if scope_type == 'id' and not does_id_exist(tree, scope):
            report_items.append(reports.id_not_found(scope, ["id"]))

    if report_items:
        raise LibraryError(*report_items)
Beispiel #7
0
def append_new_operation(operations_element, options):
    """
    Create op element and apend it to operations_element.
    etree operations_element is the context element
    dict options are attributes of operation
    """
    attribute_map = dict((key, value) for key, value in options.items()
                         if key not in OPERATION_NVPAIR_ATTRIBUTES)
    if "id" in attribute_map:
        if does_id_exist(operations_element, attribute_map["id"]):
            raise LibraryError(reports.id_already_exists(attribute_map["id"]))
    else:
        attribute_map.update({
            "id":
            create_id(operations_element.getparent(), options["name"],
                      options["interval"])
        })
    op_element = etree.SubElement(
        operations_element,
        "op",
        attribute_map,
    )
    nvpair_attribute_map = dict((key, value) for key, value in options.items()
                                if key in OPERATION_NVPAIR_ATTRIBUTES)

    if nvpair_attribute_map:
        append_new_instance_attributes(op_element, nvpair_attribute_map)

    return op_element
Beispiel #8
0
 def test_ignore_acl_target(self):
     self.cib.append_to_first_tag_name(
         "configuration", """
         <acls>
             <acl_target id="target1"/>
         </acls>
         """)
     self.assertFalse(lib.does_id_exist(self.cib.tree, "target1"))
Beispiel #9
0
 def test_ignore_acl_target(self):
     self.cib.append_to_first_tag_name(
         "configuration",
         """
         <acls>
             <acl_target id="target1"/>
         </acls>
         """
     )
     self.assertFalse(lib.does_id_exist(self.cib.tree, "target1"))
Beispiel #10
0
def validate_conflicts(tree, existing_nodes_names, existing_nodes_addrs,
                       node_name, options):
    report_list = []
    if (does_id_exist(tree, node_name) or node_name in existing_nodes_names or
        ("remote-addr" not in options and node_name in existing_nodes_addrs)):
        report_list.append(reports.id_already_exists(node_name))

    if ("remote-addr" in options
            and options["remote-addr"] in existing_nodes_addrs):
        report_list.append(reports.id_already_exists(options["remote-addr"]))
    return report_list
Beispiel #11
0
def validate_conflicts(tree, nodes, node_name, options):
    report_list = []
    if (does_id_exist(tree, node_name)
            or node_addresses_contain_name(nodes, node_name)
            or ("remote-addr" not in options
                and node_addresses_contain_host(nodes, node_name))):
        report_list.append(reports.id_already_exists(node_name))

    if ("remote-addr" in options
            and node_addresses_contain_host(nodes, options["remote-addr"])):
        report_list.append(reports.id_already_exists(options["remote-addr"]))
    return report_list
Beispiel #12
0
def __validate_role_id_for_create(tree, role_id):
    validate_id(role_id, 'ACL role')
    if tree.find('.//acl_role[@id="{0}"]'.format(role_id)) is not None:
        raise LibraryError(ReportItem.error(
            error_codes.ACL_ROLE_ALREADY_EXISTS,
            'role {id} already exists',
            info={'id': role_id}
        ))
    if does_id_exist(tree, role_id):
        raise LibraryError(ReportItem.error(
            error_codes.ID_ALREADY_EXISTS,
            '{id} already exists',
            info={'id': role_id}
        ))
Beispiel #13
0
 def test_find_remote_node_pacemaker_internal_id(self):
     tree = etree.fromstring("""
         <cib>
             <configuration>
                 <resources>
                     <primitive id="b">
                         <meta_attributes>
                             <nvpair name="remote-node" value="a"/>
                         </meta_attributes>
                     </primitive>
                 </resources>
             </configuration>
         </cib>
     """)
     self.assertTrue(lib.does_id_exist(tree, "a"))
Beispiel #14
0
 def test_find_remote_node_pacemaker_internal_id(self):
     tree = etree.fromstring("""
         <cib>
             <configuration>
                 <resources>
                     <primitive id="b">
                         <meta_attributes>
                             <nvpair name="remote-node" value="a"/>
                         </meta_attributes>
                     </primitive>
                 </resources>
             </configuration>
         </cib>
     """)
     self.assertTrue(lib.does_id_exist(tree, "a"))
Beispiel #15
0
 def test_ignore_status_section(self):
     self.cib.append_to_first_tag_name("status", """
         <elem1 id="status-1">
             <elem1a id="status-1a">
                 <elem1aa id="status-1aa"/>
                 <elem1ab id="status-1ab"/>
             </elem1a>
             <elem1b id="status-1b">
                 <elem1ba id="status-1ba"/>
                 <elem1bb id="status-1bb"/>
             </elem1b>
         </elem1>
     """)
     self.assertFalse(lib.does_id_exist(self.cib.tree, "status-1"))
     self.assertFalse(lib.does_id_exist(self.cib.tree, "status-1a"))
     self.assertFalse(lib.does_id_exist(self.cib.tree, "status-1aa"))
     self.assertFalse(lib.does_id_exist(self.cib.tree, "status-1ab"))
     self.assertFalse(lib.does_id_exist(self.cib.tree, "status-1b"))
     self.assertFalse(lib.does_id_exist(self.cib.tree, "status-1ba"))
     self.assertFalse(lib.does_id_exist(self.cib.tree, "status-1bb"))
Beispiel #16
0
 def test_ignore_status_section(self):
     self.cib.append_to_first_tag_name("status", """
         <elem1 id="status-1">
             <elem1a id="status-1a">
                 <elem1aa id="status-1aa"/>
                 <elem1ab id="status-1ab"/>
             </elem1a>
             <elem1b id="status-1b">
                 <elem1ba id="status-1ba"/>
                 <elem1bb id="status-1bb"/>
             </elem1b>
         </elem1>
     """)
     self.assertFalse(lib.does_id_exist(self.cib.tree, "status-1"))
     self.assertFalse(lib.does_id_exist(self.cib.tree, "status-1a"))
     self.assertFalse(lib.does_id_exist(self.cib.tree, "status-1aa"))
     self.assertFalse(lib.does_id_exist(self.cib.tree, "status-1ab"))
     self.assertFalse(lib.does_id_exist(self.cib.tree, "status-1b"))
     self.assertFalse(lib.does_id_exist(self.cib.tree, "status-1ba"))
     self.assertFalse(lib.does_id_exist(self.cib.tree, "status-1bb"))
Beispiel #17
0
def __validate_permissions(tree, permission_info_list):
    report = []
    allowed_permissions = ["read", "write", "deny"]
    allowed_scopes = ["xpath", "id"]
    for permission, scope_type, scope in permission_info_list:
        if not permission in allowed_permissions:
            report.append(ReportItem.error(
                error_codes.BAD_ACL_PERMISSION,
                'bad permission "{permission}, expected {allowed_values}',
                info={
                    'permission': permission,
                    'allowed_values_raw': allowed_permissions,
                    'allowed_values': ' or '.join(allowed_permissions)
                },
            ))

        if not scope_type in allowed_scopes:
            report.append(ReportItem.error(
                error_codes.BAD_ACL_SCOPE_TYPE,
                'bad scope type "{scope_type}, expected {allowed_values}',
                info={
                    'scope_type': scope_type,
                    'allowed_values_raw': allowed_scopes,
                    'allowed_values': ' or '.join(allowed_scopes)
                },
            ))

        if scope_type == 'id' and not does_id_exist(tree, scope):
            report.append(ReportItem.error(
                error_codes.ID_NOT_FOUND,
                'id "{id}" does not exist.',
                info={'id': scope },
            ))

    if report:
        raise LibraryError(*report)
Beispiel #18
0
def __validate_permissions(tree, permission_info_list):
    report_items = []
    allowed_permissions = ["read", "write", "deny"]
    allowed_scopes = ["xpath", "id"]
    for permission, scope_type, scope in permission_info_list:
        if not permission in allowed_permissions:
            report_items.append(reports.invalid_option_value(
                "permission",
                permission,
                allowed_permissions
            ))

        if not scope_type in allowed_scopes:
            report_items.append(reports.invalid_option_value(
                "scope type",
                scope_type,
                allowed_scopes
            ))

        if scope_type == 'id' and not does_id_exist(tree, scope):
            report_items.append(reports.id_not_found(scope, "id"))

    if report_items:
        raise LibraryError(*report_items)
Beispiel #19
0
def create(
    report_processor, resources_section, resource_id, resource_agent,
    raw_operation_list=None, meta_attributes=None, instance_attributes=None,
    allow_invalid_operation=False,
    allow_invalid_instance_attributes=False,
    use_default_operations=True,
    resource_type="resource"
):
    """
    Prepare all parts of primitive resource and append it into cib.

    report_processor is a tool for warning/info/error reporting
    etree.Element resources_section is place where new element will be appended
    string resource_id is id of new resource
    lib.resource_agent.CrmAgent resource_agent
    list of dict raw_operation_list specifies operations of resource
    dict meta_attributes specifies meta attributes of resource
    dict instance_attributes specifies instance attributes of resource
    bool allow_invalid_operation is flag for skipping validation of operations
    bool allow_invalid_instance_attributes is flag for skipping validation of
        instance_attributes
    bool use_default_operations is flag for completion operations with default
        actions specified in resource agent
    string resource_type -- describes the resource for reports
    """
    if raw_operation_list is None:
        raw_operation_list = []
    if meta_attributes is None:
        meta_attributes = {}
    if instance_attributes is None:
        instance_attributes = {}

    if does_id_exist(resources_section, resource_id):
        raise LibraryError(reports.id_already_exists(resource_id))
    validate_id(resource_id, "{0} name".format(resource_type))

    operation_list = prepare_operations(
        report_processor,
        raw_operation_list,
        resource_agent.get_cib_default_actions(
            necessary_only=not use_default_operations
        ),
        [operation["name"] for operation in resource_agent.get_actions()],
        allow_invalid=allow_invalid_operation,
    )

    report_processor.process_list(
        resource_agent.validate_parameters(
            instance_attributes,
            parameters_type=resource_type,
            allow_invalid=allow_invalid_instance_attributes,
        )
    )

    return append_new(
        resources_section,
        resource_id,
        resource_agent.get_standard(),
        resource_agent.get_provider(),
        resource_agent.get_type(),
        instance_attributes=instance_attributes,
        meta_attributes=meta_attributes,
        operation_list=operation_list
    )
Beispiel #20
0
def create(
    report_processor: ReportProcessor,
    resources_section,
    id_provider,
    resource_id,
    resource_agent,
    raw_operation_list=None,
    meta_attributes=None,
    instance_attributes=None,
    allow_invalid_operation=False,
    allow_invalid_instance_attributes=False,
    use_default_operations=True,
    resource_type="resource",
    do_not_report_instance_attribute_server_exists=False # TODO remove this arg
):
    # pylint: disable=too-many-arguments
    """
    Prepare all parts of primitive resource and append it into cib.

    report_processor is a tool for warning/info/error reporting
    etree.Element resources_section is place where new element will be appended
    IdProvider id_provider -- elements' ids generator
    string resource_id is id of new resource
    lib.resource_agent.CrmAgent resource_agent
    list of dict raw_operation_list specifies operations of resource
    dict meta_attributes specifies meta attributes of resource
    dict instance_attributes specifies instance attributes of resource
    bool allow_invalid_operation is flag for skipping validation of operations
    bool allow_invalid_instance_attributes is flag for skipping validation of
        instance_attributes
    bool use_default_operations is flag for completion operations with default
        actions specified in resource agent
    string resource_type -- describes the resource for reports
    bool do_not_report_instance_attribute_server_exists -- dirty fix due to
        suboptimal architecture, TODO: fix the architecture and remove the param
    """
    if raw_operation_list is None:
        raw_operation_list = []
    if meta_attributes is None:
        meta_attributes = {}
    if instance_attributes is None:
        instance_attributes = {}

    if does_id_exist(resources_section, resource_id):
        raise LibraryError(reports.id_already_exists(resource_id))
    validate_id(resource_id, "{0} name".format(resource_type))

    operation_list = prepare_operations(
        report_processor,
        raw_operation_list,
        resource_agent.get_cib_default_actions(
            necessary_only=not use_default_operations
        ),
        [operation["name"] for operation in resource_agent.get_actions()],
        allow_invalid=allow_invalid_operation,
    )

    if report_processor.report_list(
        validate_resource_instance_attributes_create(
            resource_agent,
            instance_attributes,
            resources_section,
            force=allow_invalid_instance_attributes,
            do_not_report_instance_attribute_server_exists=(
                do_not_report_instance_attribute_server_exists
            )
        )
    ).has_errors:
        raise LibraryError()

    return append_new(
        resources_section,
        id_provider,
        resource_id,
        resource_agent.get_standard(),
        resource_agent.get_provider(),
        resource_agent.get_type(),
        instance_attributes=instance_attributes,
        meta_attributes=meta_attributes,
        operation_list=operation_list
    )
Beispiel #21
0
 def test_existing_id(self):
     self.fixture_add_primitive_with_id("myId")
     self.assertTrue(lib.does_id_exist(self.cib.tree, "myId"))
Beispiel #22
0
 def test_ignore_sections_directly_under_cib(self):
     #this is side effect of current implementation but is not problem since
     #id attribute is not allowed for elements directly under cib
     tree = etree.fromstring('<cib><direct id="a"/></cib>')
     self.assertFalse(lib.does_id_exist(tree, "a"))
Beispiel #23
0
 def test_ignore_sections_directly_under_cib(self):
     #this is side effect of current implementation but is not problem since
     #id attribute is not allowed for elements directly under cib
     tree = etree.fromstring('<cib><direct id="a"/></cib>')
     self.assertFalse(lib.does_id_exist(tree, "a"))
Beispiel #24
0
 def test_existing_id(self):
     self.fixture_add_primitive_with_id("myId")
     self.assertTrue(lib.does_id_exist(self.cib.tree, "myId"))
Beispiel #25
0
 def test_find_id_when_cib_is_not_root_element(self):
     #for example we have only part of xml
     tree = etree.fromstring('<root><direct id="a"/></root>')
     self.assertTrue(lib.does_id_exist(tree, "a"))
Beispiel #26
0
def create(
    report_processor: reports.ReportProcessor,
    resources_section: _Element,
    id_provider: IdProvider,
    resource_id: str,
    resource_agent_facade: ResourceAgentFacade,
    raw_operation_list: Optional[Iterable[ResourceOperationIn]] = None,
    meta_attributes: Optional[Mapping[str, str]] = None,
    instance_attributes: Optional[Mapping[str, str]] = None,
    allow_invalid_operation: bool = False,
    allow_invalid_instance_attributes: bool = False,
    use_default_operations: bool = True,
    resource_type: str = "resource",
    # TODO remove this arg
    do_not_report_instance_attribute_server_exists: bool = False,
):
    # pylint: disable=too-many-arguments
    # pylint: disable=too-many-locals
    """
    Prepare all parts of primitive resource and append it into cib.

    report_processor -- a tool for warning/info/error reporting
    resources_section -- a place where the new resource will be appended
    id_provider -- elements' ids generator
    resource_id -- id of the new resource
    resource_agent_facade -- resource agent
    raw_operation_list -- specifies operations of the resource
    meta_attributes -- specifies meta attributes of the resource
    instance_attributes -- specifies instance attributes of the resource
    allow_invalid_operation -- flag for skipping validation of operations
    allow_invalid_instance_attributes -- flag for skipping validation of
        instance_attributes
    use_default_operations -- flag for completion operations with default
        actions specified in resource agent
    resource_type -- describes the resource for reports
    do_not_report_instance_attribute_server_exists -- dirty fix due to
        suboptimal architecture, TODO: fix the architecture and remove the param
    """
    if raw_operation_list is None:
        raw_operation_list = []
    if meta_attributes is None:
        meta_attributes = {}
    if instance_attributes is None:
        instance_attributes = {}

    filtered_raw_operation_list = []
    for op in raw_operation_list:
        filtered_raw_operation_list.append(
            {name: "" if value is None else value for name, value in op.items()}
        )

    if does_id_exist(resources_section, resource_id):
        raise LibraryError(
            reports.ReportItem.error(
                reports.messages.IdAlreadyExists(resource_id)
            )
        )
    validate_id(resource_id, "{0} name".format(resource_type))

    agent_metadata = resource_agent_facade.metadata

    operation_list = prepare_operations(
        report_processor,
        filtered_raw_operation_list,
        get_default_operations(
            agent_metadata, necessary_only=not use_default_operations
        ),
        [operation.name for operation in agent_metadata.actions],
        are_new_role_names_supported(resources_section),
        allow_invalid=allow_invalid_operation,
    )

    report_items = validate_resource_instance_attributes_create(
        resource_agent_facade,
        instance_attributes,
        resources_section,
        force=allow_invalid_instance_attributes,
    )
    # TODO remove this "if", see pcs.lib.cib.remote_node.create for details
    if do_not_report_instance_attribute_server_exists:
        for report_item in report_items:
            if isinstance(report_item.message, reports.messages.InvalidOptions):
                report_msg = cast(
                    reports.messages.InvalidOptions, report_item.message
                )
                report_item.message = reports.messages.InvalidOptions(
                    report_msg.option_names,
                    sorted(
                        [
                            value
                            for value in report_msg.allowed
                            if value != "server"
                        ]
                    ),
                    report_msg.option_type,
                    report_msg.allowed_patterns,
                )
    report_processor.report_list(report_items)

    if report_processor.has_errors:
        raise LibraryError()

    return append_new(
        resources_section,
        id_provider,
        resource_id,
        agent_metadata.name.standard,
        agent_metadata.name.provider,
        agent_metadata.name.type,
        instance_attributes=instance_attributes,
        meta_attributes=meta_attributes,
        operation_list=operation_list,
    )
Beispiel #27
0
 def test_find_id_when_cib_is_not_root_element(self):
     #for example we have only part of xml
     tree = etree.fromstring('<root><direct id="a"/></root>')
     self.assertTrue(lib.does_id_exist(tree, "a"))
Beispiel #28
0
def create(
    report_processor, resources_section, resource_id, resource_agent,
    raw_operation_list=None, meta_attributes=None, instance_attributes=None,
    allow_invalid_operation=False,
    allow_invalid_instance_attributes=False,
    use_default_operations=True,
    ensure_disabled=False,
):
    """
    Prepare all parts of primitive resource and append it into cib.

    report_processor is a tool for warning/info/error reporting
    etree.Element resources_section is place where new element will be appended
    string resource_id is id of new resource
    lib.resource_agent.CrmAgent resource_agent
    list of dict raw_operation_list specifies operations of resource
    dict meta_attributes specifies meta attributes of resource
    dict instance_attributes specifies instance attributes of resource
    bool allow_invalid_operation is flag for skipping validation of operations
    bool allow_invalid_instance_attributes is flag for skipping validation of
        instance_attributes
    bool use_default_operations is flag for completion operations with default
        actions specified in resource agent
    bool ensure_disabled is flag for completion meta_attributes with attribute
        causing disabling resource
    """
    if raw_operation_list is None:
        raw_operation_list = []
    if meta_attributes is None:
        meta_attributes = {}
    if instance_attributes is None:
        instance_attributes = {}

    if does_id_exist(resources_section, resource_id):
        raise LibraryError(reports.id_already_exists(resource_id))
    validate_id(resource_id, "resource name")

    operation_list = prepare_operations(
        report_processor,
        raw_operation_list,
        resource_agent.get_cib_default_actions(
            necessary_only=not use_default_operations
        ),
        [operation["name"] for operation in resource_agent.get_actions()],
        allow_invalid=allow_invalid_operation,
    )

    if ensure_disabled:
        meta_attributes = disable_meta(meta_attributes)

    report_processor.process_list(
        resource_agent.validate_parameters(
            instance_attributes,
            parameters_type="resource",
            allow_invalid=allow_invalid_instance_attributes,
        )
    )

    return append_new(
        resources_section,
        resource_id,
        resource_agent.get_standard(),
        resource_agent.get_provider(),
        resource_agent.get_type(),
        instance_attributes=instance_attributes,
        meta_attributes=meta_attributes,
        operation_list=operation_list
    )