Ejemplo n.º 1
0
def remove_levels_by_params(
    topology_el: _Element,
    level=None,
    # TODO create a special type, so that it cannot accept any string
    target_type: Optional[str] = None,
    target_value=None,
    devices: Optional[Iterable[str]] = None,
    # TODO remove, deprecated backward compatibility layer
    ignore_if_missing: bool = False,
    # TODO remove, deprecated backward compatibility layer
    validate_device_ids: bool = True,
) -> ReportItemList:
    """
    Remove specified fencing level(s)

    topology_el -- etree element to remove the levels from
    int|string level -- level (index) of the fencing level to remove
    target_type -- the removed fencing level target value type
    mixed target_value -- the removed fencing level target value
    devices -- list of stonith devices of the removed fencing level
    ignore_if_missing -- when True, do not report if level not found
    """
    # Do not ever remove a fencing-topology element, even if it is empty. There
    # may be ACLs set in pacemaker which allow "write" for fencing-level
    # elements (adding, changing and removing) but not fencing-topology
    # elements. In such a case, removing a fencing-topology element would cause
    # the whole change to be rejected by pacemaker with a "permission denied"
    # message.
    # https://bugzilla.redhat.com/show_bug.cgi?id=1642514
    report_list: ReportItemList = []
    if target_type:
        report_list.extend(_validate_target_typewise(target_type))
        if has_errors(report_list):
            return report_list

    if validate_device_ids and devices is not None:
        for device_id in devices:
            validate_id(device_id,
                        description="stonith id",
                        reporter=report_list)

    level_el_list = _find_level_elements(topology_el, level, target_type,
                                         target_value, devices)

    if not level_el_list:
        if ignore_if_missing:
            return report_list
        report_list.append(
            ReportItem.error(
                reports.messages.CibFencingLevelDoesNotExist(
                    level,
                    target_type,
                    target_value,
                    sorted(devices) if devices else [],
                )))
    if has_errors(report_list):
        return report_list
    for el in level_el_list:
        el.getparent().remove(el)
    return report_list
Ejemplo n.º 2
0
def _validate_devices(
    reporter, resources_el, devices, force_device=False, allow_force=True
):
    if not devices:
        reporter.add(
            reports.required_option_is_missing(["stonith devices"])
        )
    invalid_devices = []
    for dev in devices:
        errors = reporter.errors_count
        validate_id(dev, description="device id", reporter=reporter)
        if reporter.errors_count > errors:
            continue
        # TODO use the new finding function
        if not is_stonith_resource(resources_el, dev):
            invalid_devices.append(dev)
    if invalid_devices:
        reporter.add(
            reports.stonith_resources_do_not_exist(
                invalid_devices,
                ReportItemSeverity.WARNING if force_device and allow_force
                    else ReportItemSeverity.ERROR
                ,
                None if force_device or not allow_force
                    else report_codes.FORCE_STONITH_RESOURCE_DOES_NOT_EXIST
            )
        )
Ejemplo n.º 3
0
def _validate_devices(
    reporter, resources_el, devices, force_device=False, allow_force=True
):
    if not devices:
        reporter.append(
            reports.required_option_is_missing(["stonith devices"])
        )
    invalid_devices = []
    for dev in devices:
        errors = reporter.errors_count
        validate_id(dev, description="device id", reporter=reporter)
        if reporter.errors_count > errors:
            continue
        # TODO use the new finding function
        if not is_stonith_resource(resources_el, dev):
            invalid_devices.append(dev)
    if invalid_devices:
        reporter.append(
            reports.stonith_resources_do_not_exist(
                invalid_devices,
                ReportItemSeverity.WARNING if force_device and allow_force
                    else ReportItemSeverity.ERROR
                ,
                None if force_device or not allow_force
                    else report_codes.FORCE_STONITH_RESOURCE_DOES_NOT_EXIST
            )
        )
Ejemplo n.º 4
0
 def validate(option_dict):
     value = ValuePair.get(option_dict[option_name])
     report_list = []
     validate_id(value.normalized, option_name_for_report, report_list)
     if id_provider is not None and not report_list:
         report_list.extend(id_provider.book_ids(value.normalized))
     return report_list
Ejemplo n.º 5
0
def _validate_devices(resources_el: _Element,
                      devices,
                      force_device=False,
                      allow_force=True) -> ReportItemList:
    report_list: ReportItemList = []
    if not devices:
        report_list.append(
            ReportItem.error(
                reports.messages.RequiredOptionsAreMissing(["stonith devices"
                                                            ])))
    invalid_devices = []
    for dev in devices:
        validate_id_report_list: ReportItemList = []
        validate_id(dev,
                    description="device id",
                    reporter=validate_id_report_list)
        report_list.extend(validate_id_report_list)
        if has_errors(validate_id_report_list):
            continue
        # TODO use the new finding function
        if not is_stonith_resource(resources_el, dev):
            invalid_devices.append(dev)
    if invalid_devices:
        report_list.append(
            ReportItem(
                severity=ReportItemSeverity(
                    level=(ReportItemSeverity.WARNING if force_device
                           and allow_force else ReportItemSeverity.ERROR),
                    force_code=(None if force_device or not allow_force else
                                report_codes.FORCE),
                ),
                message=reports.messages.StonithResourcesDoNotExist(
                    invalid_devices),
            ))
    return report_list
Ejemplo n.º 6
0
 def _validate_value(self, value: ValuePair) -> ReportItemList:
     report_list: ReportItemList = []
     validate_id(value.normalized, self._option_name_for_report,
                 report_list)
     if self._id_provider is not None and not report_list:
         report_list.extend(self._id_provider.book_ids(value.normalized))
     return report_list
Ejemplo n.º 7
0
    def test_invalid_character(self):
        desc = "test id"
        info = {
            "id": "",
            "id_description": desc,
            "invalid_character": "",
            "is_first_char": False,
        }
        report = (severity.ERROR, report_codes.INVALID_ID_BAD_CHAR, info)

        info["id"] = "dum:my"
        info["invalid_character"] = ":"
        assert_raise_library_error(lambda: lib.validate_id("dum:my", desc),
                                   report)

        info["id"] = "dummy:"
        info["invalid_character"] = ":"
        assert_raise_library_error(lambda: lib.validate_id("dummy:", desc),
                                   report)

        info["id"] = "dum?my"
        info["invalid_character"] = "?"
        assert_raise_library_error(lambda: lib.validate_id("dum?my", desc),
                                   report)

        info["id"] = "dummy?"
        info["invalid_character"] = "?"
        assert_raise_library_error(lambda: lib.validate_id("dummy?", desc),
                                   report)
Ejemplo n.º 8
0
def _validate_devices(resources_el,
                      devices,
                      force_device=False,
                      allow_force=True) -> ReportItemList:
    report_list: ReportItemList = []
    if not devices:
        report_list.append(
            reports.required_options_are_missing(["stonith devices"]))
    invalid_devices = []
    for dev in devices:
        validate_id_report_list: ReportItemList = []
        validate_id(dev,
                    description="device id",
                    reporter=validate_id_report_list)
        report_list.extend(validate_id_report_list)
        if has_errors(validate_id_report_list):
            continue
        # TODO use the new finding function
        if not is_stonith_resource(resources_el, dev):
            invalid_devices.append(dev)
    if invalid_devices:
        report_list.append(
            reports.stonith_resources_do_not_exist(
                invalid_devices, ReportItemSeverity.WARNING
                if force_device and allow_force else ReportItemSeverity.ERROR,
                None if force_device or not allow_force else
                report_codes.FORCE_STONITH_RESOURCE_DOES_NOT_EXIST))
    return report_list
Ejemplo n.º 9
0
 def validate(option_dict):
     value = ValuePair.get(option_dict[option_name])
     report_list = []
     validate_id(value.normalized, option_name_for_report, report_list)
     if id_provider is not None and not report_list:
         report_list.extend(
             id_provider.book_ids(value.normalized)
         )
     return report_list
Ejemplo n.º 10
0
def validate_clone_id(clone_id: str, id_provider: IdProvider) -> ReportItemList:
    """
    Validate that clone_id is a valid xml id and it is unique in the cib.

    clone_id -- identifier of clone element
    id_provider -- elements' ids generator
    """
    report_list: ReportItemList = []
    validate_id(clone_id, reporter=report_list)
    report_list.extend(id_provider.book_ids(clone_id))
    return report_list
Ejemplo n.º 11
0
 def validate_book_id(self, id_provider, id_description="id"):
     """
     Book element_id in the id_provider, return True if success
     """
     self._book_errors = []
     validate_id(self._element_id,
                 description=id_description,
                 reporter=self._book_errors)
     if not self._book_errors:
         self._book_errors += id_provider.book_ids(self._element_id)
     return len(self._book_errors) < 1
Ejemplo n.º 12
0
Archivo: tag.py Proyecto: mirecheck/pcs
def _validate_tag_id(tag_id: str, id_provider: IdProvider) -> ReportItemList:
    """
    Validate that tag_id is an valid xml id an it is uniqe in the cib.

    tag_id -- identifier of new tag
    id_provider -- elements' ids generator
    """
    report_list: ReportItemList = []
    validate_id(tag_id, reporter=report_list)
    report_list.extend(id_provider.book_ids(tag_id))
    return report_list
Ejemplo n.º 13
0
 def validate_book_id(self, id_provider, id_description="id"):
     """
     Book element_id in the id_provider, return True if success
     """
     self._book_errors = []
     validate_id(
         self._element_id,
         description=id_description,
         reporter=self._book_errors
     )
     if not self._book_errors:
         self._book_errors += id_provider.book_ids(self._element_id)
     return len(self._book_errors) < 1
Ejemplo n.º 14
0
 def test_invalid_empty(self):
     assert_raise_library_error(
         lambda: lib.validate_id("", "test id"),
         (
             severity.ERROR,
             report_codes.INVALID_ID_IS_EMPTY,
             {"id_description": "test id",},
         ),
     )
Ejemplo n.º 15
0
 def test_invalid_empty(self):
     assert_raise_library_error(
         lambda: lib.validate_id("", "test id"),
         (
             severity.ERROR,
             report_codes.EMPTY_ID,
             {
                 "id": "",
                 "id_description": "test id",
             }
         )
     )
Ejemplo n.º 16
0
    def test_invalid_first_character(self):
        desc = "test id"
        info = {
            "id": "",
            "id_description": desc,
            "invalid_character": "",
            "is_first_char": True,
        }
        report = (severity.ERROR, report_codes.INVALID_ID_BAD_CHAR, info)

        info["id"] = "0"
        info["invalid_character"] = "0"
        assert_raise_library_error(lambda: lib.validate_id("0", desc), report)

        info["id"] = "-"
        info["invalid_character"] = "-"
        assert_raise_library_error(lambda: lib.validate_id("-", desc), report)

        info["id"] = "."
        info["invalid_character"] = "."
        assert_raise_library_error(lambda: lib.validate_id(".", desc), report)

        info["id"] = ":"
        info["invalid_character"] = ":"
        assert_raise_library_error(lambda: lib.validate_id(":", desc), report)

        info["id"] = "0dummy"
        info["invalid_character"] = "0"
        assert_raise_library_error(
            lambda: lib.validate_id("0dummy", desc), report
        )

        info["id"] = "-dummy"
        info["invalid_character"] = "-"
        assert_raise_library_error(
            lambda: lib.validate_id("-dummy", desc), report
        )

        info["id"] = ".dummy"
        info["invalid_character"] = "."
        assert_raise_library_error(
            lambda: lib.validate_id(".dummy", desc), report
        )

        info["id"] = ":dummy"
        info["invalid_character"] = ":"
        assert_raise_library_error(
            lambda: lib.validate_id(":dummy", desc), report
        )
Ejemplo n.º 17
0
    def test_invalid_character(self):
        desc = "test id"
        info = {
            "id": "",
            "id_description": desc,
            "invalid_character": "",
            "is_first_char": False,
        }
        report = (severity.ERROR, report_codes.INVALID_ID, info)

        info["id"] = "dum:my"
        info["invalid_character"] = ":"
        assert_raise_library_error(
            lambda: lib.validate_id("dum:my", desc),
            report
        )

        info["id"] = "dummy:"
        info["invalid_character"] = ":"
        assert_raise_library_error(
            lambda: lib.validate_id("dummy:", desc),
            report
        )

        info["id"] = "dum?my"
        info["invalid_character"] = "?"
        assert_raise_library_error(
            lambda: lib.validate_id("dum?my", desc),
            report
        )

        info["id"] = "dummy?"
        info["invalid_character"] = "?"
        assert_raise_library_error(
            lambda: lib.validate_id("dummy?", desc),
            report
        )
Ejemplo n.º 18
0
def create_in_group(
    env,
    resource_id,
    resource_agent_name,
    group_id,
    operation_list,
    meta_attributes,
    instance_attributes,
    allow_absent_agent=False,
    allow_invalid_operation=False,
    allow_invalid_instance_attributes=False,
    use_default_operations=True,
    ensure_disabled=False,
    adjacent_resource_id=None,
    put_after_adjacent=False,
    wait=False,
    allow_not_suitable_command=False,
):
    # pylint: disable=too-many-arguments, too-many-locals
    """
    Create resource in a cib and put it into defined group

    LibraryEnvironment env provides all for communication with externals
    string resource_id is identifier of resource
    string resource_agent_name contains name for the identification of agent
    string group_id is identificator for group to put primitive resource inside
    list of dict operation_list contains attributes for each entered operation
    dict meta_attributes contains attributes for primitive/meta_attributes
    bool allow_absent_agent is a flag for allowing agent that is not installed
        in a system
    bool allow_invalid_operation is a flag for allowing to use operations that
        are not listed in a resource agent metadata
    bool allow_invalid_instance_attributes is a flag for allowing to use
        instance attributes that are not listed in a resource agent metadata
        or for allowing to not use the instance_attributes that are required in
        resource agent metadata
    bool use_default_operations is a flag for stopping stopping of adding
        default cib operations (specified in a resource agent)
    bool ensure_disabled is flag that keeps resource in target-role "Stopped"
    string adjacent_resource_id identify neighbor of a newly created resource
    bool put_after_adjacent is flag to put a newly create resource befor/after
        adjacent resource
    mixed wait is flag for controlling waiting for pacemaker idle mechanism
    bool allow_not_suitable_command -- flag for FORCE_NOT_SUITABLE_COMMAND
    """
    resource_agent = get_agent(
        env.report_processor,
        env.cmd_runner(),
        resource_agent_name,
        allow_absent_agent,
    )
    with resource_environment(
            env, wait, [resource_id],
            _ensure_disabled_after_wait(
                ensure_disabled
                or resource.common.are_meta_disabled(meta_attributes))
    ) as resources_section:
        id_provider = IdProvider(resources_section)
        _check_special_cases(env, resource_agent, resources_section,
                             resource_id, meta_attributes, instance_attributes,
                             allow_not_suitable_command)

        primitive_element = resource.primitive.create(
            env.report_processor,
            resources_section,
            id_provider,
            resource_id,
            resource_agent,
            operation_list,
            meta_attributes,
            instance_attributes,
            allow_invalid_operation,
            allow_invalid_instance_attributes,
            use_default_operations,
        )
        if ensure_disabled:
            resource.common.disable(primitive_element, id_provider)
        validate_id(group_id, "group name")
        resource.group.place_resource(
            resource.group.provide_group(resources_section, group_id),
            primitive_element,
            adjacent_resource_id,
            put_after_adjacent,
        )
Ejemplo n.º 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
    )
Ejemplo n.º 20
0
def check_new_id_applicable(tree, description, id):
    validate_id(id, description)
    validate_id_does_not_exist(tree, id)
Ejemplo n.º 21
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
    )
Ejemplo n.º 22
0
def create_in_group(
    env,
    stonith_id,
    stonith_agent_name,
    group_id,
    operations,
    meta_attributes,
    instance_attributes,
    allow_absent_agent=False,
    allow_invalid_operation=False,
    allow_invalid_instance_attributes=False,
    use_default_operations=True,
    ensure_disabled=False,
    adjacent_resource_id=None,
    put_after_adjacent=False,
    wait=False,
):
    # pylint: disable=too-many-arguments, too-many-locals
    """
    Create stonith as resource in a cib and put it into defined group.

    LibraryEnvironment env provides all for communication with externals
    string stonith_id is an identifier of stonith resource
    string stonith_agent_name contains name for the identification of agent
    string group_id is identificator for group to put stonith inside
    list of dict operations contains attributes for each entered operation
    dict meta_attributes contains attributes for primitive/meta_attributes
    dict instance_attributes contains attributes for
        primitive/instance_attributes
    bool allow_absent_agent is a flag for allowing agent that is not installed
        in a system
    bool allow_invalid_operation is a flag for allowing to use operations that
        are not listed in a stonith agent metadata
    bool allow_invalid_instance_attributes is a flag for allowing to use
        instance attributes that are not listed in a stonith agent metadata
        or for allowing to not use the instance_attributes that are required in
        stonith agent metadata
    bool use_default_operations is a flag for stopping stopping of adding
        default cib operations (specified in a stonith agent)
    bool ensure_disabled is flag that keeps resource in target-role "Stopped"
    string adjacent_resource_id identify neighbor of a newly created stonith
    bool put_after_adjacent is flag to put a newly create resource befor/after
        adjacent stonith
    mixed wait is flag for controlling waiting for pacemaker idle mechanism
    """
    stonith_agent = get_agent(
        env.report_processor,
        env.cmd_runner(),
        stonith_agent_name,
        allow_absent_agent,
    )
    if stonith_agent.get_provides_unfencing():
        meta_attributes["provides"] = "unfencing"

    with resource_environment(
            env,
            wait,
        [stonith_id],
            _ensure_disabled_after_wait(
                ensure_disabled or are_meta_disabled(meta_attributes), ),
    ) as resources_section:
        id_provider = IdProvider(resources_section)
        stonith_element = resource.primitive.create(
            env.report_processor,
            resources_section,
            id_provider,
            stonith_id,
            stonith_agent,
            operations,
            meta_attributes,
            instance_attributes,
            allow_invalid_operation,
            allow_invalid_instance_attributes,
            use_default_operations,
        )
        if ensure_disabled:
            resource.common.disable(stonith_element, id_provider)
        validate_id(group_id, "group name")
        resource.group.place_resource(
            resource.group.provide_group(resources_section, group_id),
            stonith_element,
            adjacent_resource_id,
            put_after_adjacent,
        )
Ejemplo n.º 23
0
def create_in_group(
    env: LibraryEnvironment,
    stonith_id: str,
    stonith_agent_name: str,
    group_id: str,
    operations: Iterable[Mapping[str, str]],
    meta_attributes: Mapping[str, str],
    instance_attributes: Mapping[str, str],
    allow_absent_agent: bool = False,
    allow_invalid_operation: bool = False,
    allow_invalid_instance_attributes: bool = False,
    use_default_operations: bool = True,
    ensure_disabled: bool = False,
    adjacent_resource_id: Optional[str] = None,
    put_after_adjacent: bool = False,
    wait: WaitType = False,
):
    # pylint: disable=too-many-arguments, too-many-locals
    """
    DEPRECATED
    Create stonith as resource in a cib and put it into defined group.

    env -- provides all for communication with externals
    stonith_id --an identifier of stonith resource
    stonith_agent_name -- contains name for the identification of agent
    group_id -- identificator for group to put stonith inside
    operations -- contains attributes for each entered operation
    meta_attributes -- contains attributes for primitive/meta_attributes
    instance_attributes -- contains attributes for primitive/instance_attributes
    allow_absent_agent -- a flag for allowing agent not installed in a system
    allow_invalid_operation -- a flag for allowing to use operations that
        are not listed in a stonith agent metadata
    allow_invalid_instance_attributes -- a flag for allowing to use instance
        attributes that are not listed in a stonith agent metadata or for
        allowing to not use the instance_attributes that are required in
        stonith agent metadata
    use_default_operations -- a flag for stopping of adding default cib
        operations (specified in a stonith agent)
    ensure_disabled -- flag that keeps resource in target-role "Stopped"
    adjacent_resource_id -- identify neighbor of a newly created stonith
    put_after_adjacent -- is flag to put a newly create resource befor/after
        adjacent stonith
    wait -- flag for controlling waiting for pacemaker idle mechanism
    """
    runner = env.cmd_runner()
    agent_factory = ResourceAgentFacadeFactory(runner, env.report_processor)
    stonith_agent = _get_agent_facade(
        env.report_processor,
        agent_factory,
        stonith_agent_name,
        allow_absent_agent,
    )
    if stonith_agent.metadata.provides_unfencing:
        meta_attributes = dict(meta_attributes, provides="unfencing")

    with resource_environment(
            env,
            wait,
        [stonith_id],
            _ensure_disabled_after_wait(
                ensure_disabled
                or resource.common.are_meta_disabled(meta_attributes), ),
    ) as resources_section:
        id_provider = IdProvider(resources_section)

        adjacent_resource_element = None
        if adjacent_resource_id:
            try:
                adjacent_resource_element = get_element_by_id(
                    get_root(resources_section), adjacent_resource_id)
            except ElementNotFound:
                # We cannot continue without adjacent element because
                # the validator might produce misleading reports
                if env.report_processor.report(
                        ReportItem.error(
                            reports.messages.IdNotFound(
                                adjacent_resource_id, []))).has_errors:
                    raise LibraryError() from None

        try:
            group_element = get_element_by_id(get_root(resources_section),
                                              group_id)
        except ElementNotFound:
            group_id_reports: List[ReportItem] = []
            validate_id(group_id,
                        description="group name",
                        reporter=group_id_reports)
            env.report_processor.report_list(group_id_reports)
            group_element = resource.group.append_new(resources_section,
                                                      group_id)

        stonith_element = resource.primitive.create(
            env.report_processor,
            resources_section,
            id_provider,
            stonith_id,
            stonith_agent,
            operations,
            meta_attributes,
            instance_attributes,
            allow_invalid_operation,
            allow_invalid_instance_attributes,
            use_default_operations,
        )
        if ensure_disabled:
            resource.common.disable(stonith_element, id_provider)

        if env.report_processor.report_list(
                resource.validations.validate_move_resources_to_group(
                    group_element,
                    [stonith_element],
                    adjacent_resource_element,
                )).has_errors:
            raise LibraryError()

        resource.hierarchy.move_resources_to_group(
            group_element,
            [stonith_element],
            adjacent_resource_element,
            put_after_adjacent,
        )
Ejemplo n.º 24
0
def create_in_group(
    env, resource_id, resource_agent_name, group_id,
    operations, meta_attributes, instance_attributes,
    allow_absent_agent=False,
    allow_invalid_operation=False,
    allow_invalid_instance_attributes=False,
    use_default_operations=True,
    ensure_disabled=False,
    adjacent_resource_id=None,
    put_after_adjacent=False,
    wait=False,
):
    """
    Create resource in a cib and put it into defined group

    LibraryEnvironment env provides all for communication with externals
    string resource_id is identifier of resource
    string resource_agent_name contains name for the identification of agent
    string group_id is identificator for group to put primitive resource inside
    list of dict operations contains attributes for each entered operation
    dict meta_attributes contains attributes for primitive/meta_attributes
    bool allow_absent_agent is a flag for allowing agent that is not installed
        in a system
    bool allow_invalid_operation is a flag for allowing to use operations that
        are not listed in a resource agent metadata
    bool allow_invalid_instance_attributes is a flag for allowing to use
        instance attributes that are not listed in a resource agent metadata
        or for allowing to not use the instance_attributes that are required in
        resource agent metadata
    bool use_default_operations is a flag for stopping stopping of adding
        default cib operations (specified in a resource agent)
    bool ensure_disabled is flag that keeps resource in target-role "Stopped"
    string adjacent_resource_id identify neighbor of a newly created resource
    bool put_after_adjacent is flag to put a newly create resource befor/after
        adjacent resource
    mixed wait is flag for controlling waiting for pacemaker iddle mechanism
    """
    resource_agent = get_agent(
        env.report_processor,
        env.cmd_runner(),
        resource_agent_name,
        allow_absent_agent,
    )
    with resource_environment(
        env, resource_id, wait,
        ensure_disabled or are_meta_disabled(meta_attributes),
    ) as resources_section:
        primitive_element = resource.primitive.create(
            env.report_processor, resources_section,
            resource_id, resource_agent,
            operations, meta_attributes, instance_attributes,
            allow_invalid_operation,
            allow_invalid_instance_attributes,
            use_default_operations,
            ensure_disabled,
        )
        validate_id(group_id, "group name")
        resource.group.place_resource(
            resource.group.provide_group(resources_section, group_id),
            primitive_element,
            adjacent_resource_id,
            put_after_adjacent,
        )
Ejemplo n.º 25
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
    )
Ejemplo n.º 26
0
def create_in_group(
    env, resource_id, resource_agent_name, group_id,
    operation_list, meta_attributes, instance_attributes,
    allow_absent_agent=False,
    allow_invalid_operation=False,
    allow_invalid_instance_attributes=False,
    use_default_operations=True,
    ensure_disabled=False,
    adjacent_resource_id=None,
    put_after_adjacent=False,
    wait=False,
    allow_not_suitable_command=False,
):
    # pylint: disable=too-many-arguments, too-many-locals
    """
    Create resource in a cib and put it into defined group

    LibraryEnvironment env provides all for communication with externals
    string resource_id is identifier of resource
    string resource_agent_name contains name for the identification of agent
    string group_id is identificator for group to put primitive resource inside
    list of dict operation_list contains attributes for each entered operation
    dict meta_attributes contains attributes for primitive/meta_attributes
    bool allow_absent_agent is a flag for allowing agent that is not installed
        in a system
    bool allow_invalid_operation is a flag for allowing to use operations that
        are not listed in a resource agent metadata
    bool allow_invalid_instance_attributes is a flag for allowing to use
        instance attributes that are not listed in a resource agent metadata
        or for allowing to not use the instance_attributes that are required in
        resource agent metadata
    bool use_default_operations is a flag for stopping stopping of adding
        default cib operations (specified in a resource agent)
    bool ensure_disabled is flag that keeps resource in target-role "Stopped"
    string adjacent_resource_id identify neighbor of a newly created resource
    bool put_after_adjacent is flag to put a newly create resource befor/after
        adjacent resource
    mixed wait is flag for controlling waiting for pacemaker idle mechanism
    bool allow_not_suitable_command -- flag for FORCE_NOT_SUITABLE_COMMAND
    """
    resource_agent = get_agent(
        env.report_processor,
        env.cmd_runner(),
        resource_agent_name,
        allow_absent_agent,
    )
    with resource_environment(
        env,
        wait,
        [resource_id],
        _ensure_disabled_after_wait(
            ensure_disabled
            or
            resource.common.are_meta_disabled(meta_attributes)
        )
    ) as resources_section:
        id_provider = IdProvider(resources_section)
        _check_special_cases(
            env,
            resource_agent,
            resources_section,
            resource_id,
            meta_attributes,
            instance_attributes,
            allow_not_suitable_command
        )

        primitive_element = resource.primitive.create(
            env.report_processor, resources_section, id_provider,
            resource_id, resource_agent,
            operation_list, meta_attributes, instance_attributes,
            allow_invalid_operation,
            allow_invalid_instance_attributes,
            use_default_operations,
        )
        if ensure_disabled:
            resource.common.disable(primitive_element, id_provider)
        validate_id(group_id, "group name")
        resource.group.place_resource(
            resource.group.provide_group(resources_section, group_id),
            primitive_element,
            adjacent_resource_id,
            put_after_adjacent,
        )
Ejemplo n.º 27
0
    def test_invalid_first_character(self):
        desc = "test id"
        info = {
            "id": "",
            "id_description": desc,
            "invalid_character": "",
            "is_first_char": True,
        }
        report = (severity.ERROR, report_codes.INVALID_ID, info)

        info["id"] = "0"
        info["invalid_character"] = "0"
        assert_raise_library_error(
            lambda: lib.validate_id("0", desc),
            report
        )

        info["id"] = "-"
        info["invalid_character"] = "-"
        assert_raise_library_error(
            lambda: lib.validate_id("-", desc),
            report
        )

        info["id"] = "."
        info["invalid_character"] = "."
        assert_raise_library_error(
            lambda: lib.validate_id(".", desc),
            report
        )

        info["id"] = ":"
        info["invalid_character"] = ":"
        assert_raise_library_error(
            lambda: lib.validate_id(":", desc),
            report
        )

        info["id"] = "0dummy"
        info["invalid_character"] = "0"
        assert_raise_library_error(
            lambda: lib.validate_id("0dummy", desc),
            report
        )

        info["id"] = "-dummy"
        info["invalid_character"] = "-"
        assert_raise_library_error(
            lambda: lib.validate_id("-dummy", desc),
            report
        )

        info["id"] = ".dummy"
        info["invalid_character"] = "."
        assert_raise_library_error(
            lambda: lib.validate_id(".dummy", desc),
            report
        )

        info["id"] = ":dummy"
        info["invalid_character"] = ":"
        assert_raise_library_error(
            lambda: lib.validate_id(":dummy", desc),
            report
        )
Ejemplo n.º 28
0
 def test_valid(self):
     self.assertEqual(None, lib.validate_id("dummy"))
     self.assertEqual(None, lib.validate_id("DUMMY"))
     self.assertEqual(None, lib.validate_id("dUmMy"))
     self.assertEqual(None, lib.validate_id("dummy0"))
     self.assertEqual(None, lib.validate_id("dum0my"))
     self.assertEqual(None, lib.validate_id("dummy-"))
     self.assertEqual(None, lib.validate_id("dum-my"))
     self.assertEqual(None, lib.validate_id("dummy."))
     self.assertEqual(None, lib.validate_id("dum.my"))
     self.assertEqual(None, lib.validate_id("_dummy"))
     self.assertEqual(None, lib.validate_id("dummy_"))
     self.assertEqual(None, lib.validate_id("dum_my"))
Ejemplo n.º 29
0
def check_new_id_applicable(tree, description, id):
    validate_id(id, description)
    validate_id_does_not_exist(tree, id)
Ejemplo n.º 30
0
def create_in_group(
    env, stonith_id, stonith_agent_name, group_id,
    operations, meta_attributes, instance_attributes,
    allow_absent_agent=False,
    allow_invalid_operation=False,
    allow_invalid_instance_attributes=False,
    use_default_operations=True,
    ensure_disabled=False,
    adjacent_resource_id=None,
    put_after_adjacent=False,
    wait=False,
):
    # pylint: disable=too-many-arguments, too-many-locals
    """
    Create stonith as resource in a cib and put it into defined group.

    LibraryEnvironment env provides all for communication with externals
    string stonith_id is an identifier of stonith resource
    string stonith_agent_name contains name for the identification of agent
    string group_id is identificator for group to put stonith inside
    list of dict operations contains attributes for each entered operation
    dict meta_attributes contains attributes for primitive/meta_attributes
    dict instance_attributes contains attributes for
        primitive/instance_attributes
    bool allow_absent_agent is a flag for allowing agent that is not installed
        in a system
    bool allow_invalid_operation is a flag for allowing to use operations that
        are not listed in a stonith agent metadata
    bool allow_invalid_instance_attributes is a flag for allowing to use
        instance attributes that are not listed in a stonith agent metadata
        or for allowing to not use the instance_attributes that are required in
        stonith agent metadata
    bool use_default_operations is a flag for stopping stopping of adding
        default cib operations (specified in a stonith agent)
    bool ensure_disabled is flag that keeps resource in target-role "Stopped"
    string adjacent_resource_id identify neighbor of a newly created stonith
    bool put_after_adjacent is flag to put a newly create resource befor/after
        adjacent stonith
    mixed wait is flag for controlling waiting for pacemaker idle mechanism
    """
    stonith_agent = get_agent(
        env.report_processor,
        env.cmd_runner(),
        stonith_agent_name,
        allow_absent_agent,
    )
    if stonith_agent.get_provides_unfencing():
        meta_attributes["provides"] = "unfencing"

    with resource_environment(
        env,
        wait,
        [stonith_id],
        _ensure_disabled_after_wait(
            ensure_disabled or are_meta_disabled(meta_attributes),
        )
    ) as resources_section:
        id_provider = IdProvider(resources_section)
        stonith_element = resource.primitive.create(
            env.report_processor, resources_section, id_provider,
            stonith_id, stonith_agent,
            operations, meta_attributes, instance_attributes,
            allow_invalid_operation,
            allow_invalid_instance_attributes,
            use_default_operations,
        )
        if ensure_disabled:
            resource.common.disable(stonith_element, id_provider)
        validate_id(group_id, "group name")
        resource.group.place_resource(
            resource.group.provide_group(resources_section, group_id),
            stonith_element,
            adjacent_resource_id,
            put_after_adjacent,
        )
Ejemplo n.º 31
0
 def test_valid(self):
     self.assertEqual(None, lib.validate_id("dummy"))
     self.assertEqual(None, lib.validate_id("DUMMY"))
     self.assertEqual(None, lib.validate_id("dUmMy"))
     self.assertEqual(None, lib.validate_id("dummy0"))
     self.assertEqual(None, lib.validate_id("dum0my"))
     self.assertEqual(None, lib.validate_id("dummy-"))
     self.assertEqual(None, lib.validate_id("dum-my"))
     self.assertEqual(None, lib.validate_id("dummy."))
     self.assertEqual(None, lib.validate_id("dum.my"))
     self.assertEqual(None, lib.validate_id("_dummy"))
     self.assertEqual(None, lib.validate_id("dummy_"))
     self.assertEqual(None, lib.validate_id("dum_my"))
Ejemplo n.º 32
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,
    )