Example #1
0
def prepare_options_plain(cib, options, ticket, resource_id):
    options = options.copy()

    report = _validate_options_common(options)

    if not ticket:
        report.append(reports.required_option_is_missing(['ticket']))
    options["ticket"] = ticket

    if not resource_id:
        report.append(reports.required_option_is_missing(['rsc']))
    options["rsc"] = resource_id

    if "rsc-role" in options:
        if options["rsc-role"]:
            resource_role = options["rsc-role"].lower().capitalize()
            if resource_role not in ATTRIB_PLAIN["rsc-role"]:
                report.append(
                    reports.invalid_option_value("rsc-role",
                                                 options["rsc-role"],
                                                 ATTRIB_PLAIN["rsc-role"]))
            options["rsc-role"] = resource_role
        else:
            del options["rsc-role"]

    if report:
        raise LibraryError(*report)

    return constraint.prepare_options(
        tuple(list(ATTRIB) + list(ATTRIB_PLAIN)), options,
        partial(_create_id, cib, options["ticket"], resource_id,
                options.get("rsc-role", "")),
        partial(tools.check_new_id_applicable, cib, DESCRIPTION))
Example #2
0
def initialize_block_devices(lib_env, device_list, option_dict):
    """
    Initialize SBD devices in device_list with options_dict.

    lib_env -- LibraryEnvironment
    device_list -- list of strings
    option_dict -- dictionary
    """
    report_item_list = []
    if not device_list:
        report_item_list.append(reports.required_option_is_missing(["device"]))

    supported_options = sbd.DEVICE_INITIALIZATION_OPTIONS_MAPPING.keys()

    report_item_list += names_in(supported_options, option_dict.keys())
    validator_list = [
        value_nonnegative_integer(key)
        for key in supported_options
    ]

    report_item_list += run_collection_of_option_validators(
        option_dict, validator_list
    )

    lib_env.report_processor.process_list(report_item_list)
    sbd.initialize_block_devices(
        lib_env.report_processor, lib_env.cmd_runner(), device_list, option_dict
    )
Example #3
0
    def validate_parameters(
        self, parameters,
        parameters_type="resource",
        allow_invalid=False,
        update=False
    ):
        forceable = report_codes.FORCE_OPTIONS if not allow_invalid else None
        severity = (
            ReportItemSeverity.ERROR if not allow_invalid
            else ReportItemSeverity.WARNING
        )

        report_list = []
        bad_opts, missing_req_opts = self.validate_parameters_values(
            parameters
        )

        if bad_opts:
            report_list.append(reports.invalid_options(
                bad_opts,
                sorted([attr["name"] for attr in self.get_parameters()]),
                parameters_type,
                severity=severity,
                forceable=forceable,
            ))

        if not update and missing_req_opts:
            report_list.append(reports.required_option_is_missing(
                missing_req_opts,
                parameters_type,
                severity=severity,
                forceable=forceable,
            ))

        return report_list
Example #4
0
def create_alert(
    lib_env,
    alert_id,
    path,
    instance_attribute_dict,
    meta_attribute_dict,
    description=None
):
    """
    Create new alert.
    Raises LibraryError if path is not specified, or any other failure.

    lib_env -- LibraryEnvironment
    alert_id -- id of alert to be created, if None it will be generated
    path -- path to script for alert
    instance_attribute_dict -- dictionary of instance attributes
    meta_attribute_dict -- dictionary of meta attributes
    description -- alert description description
    """
    if not path:
        raise LibraryError(reports.required_option_is_missing(["path"]))

    cib = lib_env.get_cib(REQUIRED_CIB_VERSION)

    alert_el = alert.create_alert(cib, alert_id, path, description)
    alert.update_instance_attributes(alert_el, instance_attribute_dict)
    alert.update_meta_attributes(alert_el, meta_attribute_dict)

    lib_env.push_cib(cib)
Example #5
0
def add_recipient(lib_env,
                  alert_id,
                  recipient_value,
                  instance_attribute_dict,
                  meta_attribute_dict,
                  recipient_id=None,
                  description=None,
                  allow_same_value=False):
    """
    Add new recipient to alert witch id alert_id.

    lib_env -- LibraryEnvironment
    alert_id -- id of alert to which new recipient should be added
    recipient_value -- value of new recipient
    instance_attribute_dict -- dictionary of instance attributes to update
    meta_attribute_dict -- dictionary of meta attributes to update
    recipient_id -- id of new recipient, if None it will be generated
    description -- recipient description
    allow_same_value -- if True unique recipient value is not required
    """
    if not recipient_value:
        raise LibraryError(reports.required_option_is_missing(["value"]))

    cib = lib_env.get_cib(REQUIRED_CIB_VERSION)
    recipient = alert.add_recipient(lib_env.report_processor,
                                    cib,
                                    alert_id,
                                    recipient_value,
                                    recipient_id=recipient_id,
                                    description=description,
                                    allow_same_value=allow_same_value)
    alert.update_instance_attributes(recipient, instance_attribute_dict)
    alert.update_meta_attributes(recipient, meta_attribute_dict)

    lib_env.push_cib(cib)
Example #6
0
def create_alert(
    lib_env,
    alert_id,
    path,
    instance_attribute_dict,
    meta_attribute_dict,
    description=None
):
    """
    Create new alert.
    Raises LibraryError if path is not specified, or any other failure.

    lib_env -- LibraryEnvironment
    alert_id -- id of alert to be created, if None it will be generated
    path -- path to script for alert
    instance_attribute_dict -- dictionary of instance attributes
    meta_attribute_dict -- dictionary of meta attributes
    description -- alert description description
    """
    if not path:
        raise LibraryError(reports.required_option_is_missing(["path"]))


    alert_el = alert.create_alert(
        lib_env.get_cib(REQUIRED_CIB_VERSION),
        alert_id,
        path,
        description
    )
    alert.update_instance_attributes(alert_el, instance_attribute_dict)
    alert.update_meta_attributes(alert_el, meta_attribute_dict)

    lib_env.push_cib()
Example #7
0
def initialize_block_devices(lib_env, device_list, option_dict):
    """
    Initialize SBD devices in device_list with options_dict.

    lib_env -- LibraryEnvironment
    device_list -- list of strings
    option_dict -- dictionary
    """
    report_item_list = []
    if not device_list:
        report_item_list.append(reports.required_option_is_missing(["device"]))

    supported_options = sbd.DEVICE_INITIALIZATION_OPTIONS_MAPPING.keys()

    report_item_list += names_in(supported_options, option_dict.keys())
    validator_list = [
        value_nonnegative_integer(key)
        for key in supported_options
    ]

    report_item_list += run_collection_of_option_validators(
        option_dict, validator_list
    )

    lib_env.report_processor.process_list(report_item_list)
    sbd.initialize_block_devices(
        lib_env.report_processor, lib_env.cmd_runner(), device_list, option_dict
    )
Example #8
0
def set_message(lib_env, device, node_name, message):
    """
    Set message on device for node_name.

    lib_env -- LibrayEnvironment
    device -- string, absolute path to device
    node_name -- string
    message -- string, mesage type, should be one of settings.sbd_message_types
    """
    report_item_list = []
    missing_options = []
    if not device:
        missing_options.append("device")
    if not node_name:
        missing_options.append("node")
    if missing_options:
        report_item_list.append(
            reports.required_option_is_missing(missing_options)
        )
    supported_messages = settings.sbd_message_types
    if message not in supported_messages:
        report_item_list.append(
            reports.invalid_option_value("message", message, supported_messages)
        )
    lib_env.report_processor.process_list(report_item_list)
    sbd.set_message(lib_env.cmd_runner(), device, node_name, message)
Example #9
0
 def validate(option_dict):
     if option_name not in option_dict:
         return [reports.required_option_is_missing(
             [option_name],
             option_type,
         )]
     return []
Example #10
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
            )
        )
Example #11
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
            )
        )
Example #12
0
    def validate_parameters_create(self, parameters, force=False):
        # This is just a basic validation checking that required parameters are
        # set and all set parameters are known to an agent. Missing checks are:
        # 1. values checks - if a param is an integer, then "abc" is not valid
        # 2. warnings should be emitted when a deprecated param is set
        # 3. errors should be emitted when a deprecated parameter and a
        #    parameter obsoleting it are set at the same time
        # 4. possibly some other checks
        # All of these have been missing in pcs since ever (ad 1. agents have
        # never provided enough info for us to do such validations, ad 2. and
        # 3. there were no deprecated parameters before). The checks should be
        # implemented in agents themselves, so I'm not adding them now either.
        report_items = []

        # report unknown parameters
        report_items.extend(
            validate.names_in(
                {param["name"]
                 for param in self.get_parameters()}, parameters.keys(),
                self._agent_type_label, report_codes.FORCE_OPTIONS, force))

        # report missing required parameters
        missing_parameters = self._find_missing_required_parameters(parameters)
        if missing_parameters:
            forcible, severity = self._validate_report_forcible_severity(force)
            report_items.append(
                reports.required_option_is_missing(
                    sorted(missing_parameters),
                    self._agent_type_label,
                    severity=severity,
                    forceable=forcible,
                ))

        return report_items
Example #13
0
def set_message(lib_env, device, node_name, message):
    """
    Set message on device for node_name.

    lib_env -- LibrayEnvironment
    device -- string, absolute path to device
    node_name -- string
    message -- string, mesage type, should be one of settings.sbd_message_types
    """
    report_item_list = []
    missing_options = []
    if not device:
        missing_options.append("device")
    if not node_name:
        missing_options.append("node")
    if missing_options:
        report_item_list.append(
            reports.required_option_is_missing(missing_options)
        )
    supported_messages = settings.sbd_message_types
    if message not in supported_messages:
        report_item_list.append(
            reports.invalid_option_value("message", message, supported_messages)
        )
    lib_env.report_processor.process_list(report_item_list)
    sbd.set_message(lib_env.cmd_runner(), device, node_name, message)
Example #14
0
    def validate_parameters(
        self, parameters,
        parameters_type="resource agent parameter",
        allow_invalid=False
    ):
        forceable = report_codes.FORCE_OPTIONS if not allow_invalid else None
        severity = (
            ReportItemSeverity.ERROR if not allow_invalid
            else ReportItemSeverity.WARNING
        )

        report_list = []
        bad_opts, missing_req_opts = self.validate_parameters_values(
            parameters
        )

        if bad_opts:
            report_list.append(reports.invalid_option(
                bad_opts,
                sorted([attr["name"] for attr in self.get_parameters()]),
                parameters_type,
                severity=severity,
                forceable=forceable,
            ))

        if missing_req_opts:
            report_list.append(reports.required_option_is_missing(
                missing_req_opts,
                parameters_type,
                severity=severity,
                forceable=forceable,
            ))

        return report_list
Example #15
0
    def validate_parameters_update(
        self,
        current_parameters,
        new_parameters,
        force=False
    ):
        # This is just a basic validation checking that required parameters are
        # set and all set parameters are known to an agent. Missing checks are:
        # 1. values checks - if a param is an integer, then "abc" is not valid
        # 2. warnings should be emitted when a deprecated param is set
        # 3. errors should be emitted when a deprecated parameter and a
        #    parameter obsoleting it are set at the same time
        # 4. possibly some other checks
        # All of these have been missing in pcs since ever (ad 1. agents have
        # never provided enough info for us to do such validations, ad 2. and
        # 3. there were no deprecated parameters before). The checks should be
        # implemented in agents themselves, so I'm not adding them now either.
        report_items = []

        # get resulting set of agent's parameters
        final_parameters = dict(current_parameters)
        for name, value in new_parameters.items():
            if value:
                final_parameters[name] = value
            else:
                if name in final_parameters:
                    del final_parameters[name]

        # report unknown parameters
        report_items.extend(
            validate.names_in(
                {param["name"] for param in self.get_parameters()},
                # Do not report unknown parameters already set in the CIB. They
                # have been reported already when the were added to the CIB.
                set(new_parameters.keys()) - set(current_parameters.keys()),
                self._agent_type_label,
                report_codes.FORCE_OPTIONS,
                force
            )
        )

        # report missing or removed required parameters
        missing_parameters = self._find_missing_required_parameters(
            final_parameters
        )
        if missing_parameters:
            forcible, severity = self._validate_report_forcible_severity(force)
            report_items.append(reports.required_option_is_missing(
                sorted(missing_parameters),
                self._agent_type_label,
                severity=severity,
                forceable=forcible,
            ))

        return report_items
Example #16
0
    def validate_parameters_update(self,
                                   current_parameters,
                                   new_parameters,
                                   force=False):
        # This is just a basic validation checking that required parameters are
        # set and all set parameters are known to an agent. Missing checks are:
        # 1. values checks - if a param is an integer, then "abc" is not valid
        # 2. warnings should be emitted when a deprecated param is set
        # 3. errors should be emitted when a deprecated parameter and a
        #    parameter obsoleting it are set at the same time
        # 4. possibly some other checks
        # All of these have been missing in pcs since ever (ad 1. agents have
        # never provided enough info for us to do such validations, ad 2. and
        # 3. there were no deprecated parameters before). The checks should be
        # implemented in agents themselves, so I'm not adding them now either.
        report_items = []

        # get resulting set of agent's parameters
        final_parameters = dict(current_parameters)
        for name, value in new_parameters.items():
            if len(value) < 1:
                if name in final_parameters:
                    del final_parameters[name]
            else:
                final_parameters[name] = value

        # report unknown parameters
        report_items.extend(
            validate.names_in(
                {param["name"]
                 for param in self.get_parameters()},
                # Do not report unknown parameters already set in the CIB. They
                # have been reported already when the were added to the CIB.
                set(new_parameters.keys()) - set(current_parameters.keys()),
                self._agent_type_label,
                report_codes.FORCE_OPTIONS,
                force))

        # report missing or removed required parameters
        missing_parameters = self._find_missing_required_parameters(
            final_parameters)
        if missing_parameters:
            forcible, severity = self._validate_report_forcible_severity(force)
            report_items.append(
                reports.required_option_is_missing(
                    sorted(missing_parameters),
                    self._agent_type_label,
                    severity=severity,
                    forceable=forcible,
                ))

        return report_items
Example #17
0
def prepare_options_plain(cib, options, ticket, resource_id):
    options = options.copy()

    report = _validate_options_common(options)

    if not ticket:
        report.append(reports.required_option_is_missing(['ticket']))
    options["ticket"] = ticket

    if not resource_id:
        report.append(reports.required_option_is_missing(['rsc']))
    options["rsc"] = resource_id

    if "rsc-role" in options:
        if options["rsc-role"]:
            resource_role = options["rsc-role"].lower().capitalize()
            if resource_role not in ATTRIB_PLAIN["rsc-role"]:
                report.append(reports.invalid_option_value(
                    "rsc-role", options["rsc-role"], ATTRIB_PLAIN["rsc-role"]
                ))
            options["rsc-role"] = resource_role
        else:
            del options["rsc-role"]

    if report:
        raise LibraryError(*report)

    return constraint.prepare_options(
        tuple(list(ATTRIB) + list(ATTRIB_PLAIN)),
        options,
        partial(
            _create_id,
            cib,
            options["ticket"],
            resource_id,
            options.get("rsc-role", "")
        ),
        partial(tools.check_new_id_applicable, cib, DESCRIPTION)
    )
Example #18
0
def prepare_options_with_set(cib, options, resource_set_list):
    options = constraint.prepare_options(
        tuple(ATTRIB.keys()),
        options,
        create_id_fn=partial(constraint.create_id, cib, TAG_NAME,
                             resource_set_list),
        validate_id=partial(tools.check_new_id_applicable, cib, DESCRIPTION),
    )
    report = _validate_options_common(options)
    if "ticket" not in options or not options["ticket"].strip():
        report.append(reports.required_option_is_missing(['ticket']))
    if report:
        raise LibraryError(*report)
    return options
Example #19
0
def prepare_options_with_set(cib, options, resource_set_list):
    options = constraint.prepare_options(
        tuple(ATTRIB.keys()),
        options,
        create_id_fn=partial(
            constraint.create_id, cib, TAG_NAME, resource_set_list
        ),
        validate_id=partial(tools.check_new_id_applicable, cib, DESCRIPTION),
    )
    report = _validate_options_common(options)
    if "ticket" not in options or not options["ticket"].strip():
        report.append(reports.required_option_is_missing(['ticket']))
    if report:
        raise LibraryError(*report)
    return options
Example #20
0
def add_recipient(
    lib_env,
    alert_id,
    recipient_value,
    instance_attribute_dict,
    meta_attribute_dict,
    recipient_id=None,
    description=None,
    allow_same_value=False
):
    """
    Add new recipient to alert witch id alert_id.

    lib_env -- LibraryEnvironment
    alert_id -- id of alert to which new recipient should be added
    recipient_value -- value of new recipient
    instance_attribute_dict -- dictionary of instance attributes to update
    meta_attribute_dict -- dictionary of meta attributes to update
    recipient_id -- id of new recipient, if None it will be generated
    description -- recipient description
    allow_same_value -- if True unique recipient value is not required
    """
    if not recipient_value:
        raise LibraryError(
            reports.required_option_is_missing(["value"])
        )

    cib = lib_env.get_cib(REQUIRED_CIB_VERSION)
    id_provider = IdProvider(cib)
    recipient = alert.add_recipient(
        lib_env.report_processor,
        cib,
        alert_id,
        recipient_value,
        recipient_id=recipient_id,
        description=description,
        allow_same_value=allow_same_value
    )
    arrange_first_instance_attributes(
        recipient, instance_attribute_dict, id_provider
    )
    arrange_first_meta_attributes(
        recipient, meta_attribute_dict, id_provider
    )

    lib_env.push_cib()
Example #21
0
    def __validate_quorum_device_model_net_options(
        self, model_options, need_required, force=False
    ):
        required_options = frozenset(["host", "algorithm"])
        optional_options = frozenset([
            "connect_timeout",
            "force_ip_version",
            "port",
            "tie_breaker",
        ])
        allowed_options = required_options | optional_options
        model_options_names = frozenset(model_options.keys())
        missing_options = []
        report_items = []
        severity = (
            ReportItemSeverity.WARNING if force else ReportItemSeverity.ERROR
        )
        forceable = None if force else report_codes.FORCE_OPTIONS

        if need_required:
            missing_options += required_options - model_options_names

        for name, value in sorted(model_options.items()):
            if name not in allowed_options:
                report_items.append(reports.invalid_options(
                    [name],
                    allowed_options,
                    "quorum device model",
                    severity=severity,
                    forceable=forceable
                ))
                continue

            if value == "":
                # do not allow to remove required options
                if name in required_options:
                    missing_options.append(name)
                else:
                    continue

            if name == "algorithm":
                allowed_values = ("ffsplit", "lms")
                if value not in allowed_values:
                    report_items.append(reports.invalid_option_value(
                        name,
                        value,
                        allowed_values,
                        severity=severity,
                        forceable=forceable
                    ))

            if name == "connect_timeout":
                minimum, maximum = 1000, 2*60*1000
                if not (value.isdigit() and minimum <= int(value) <= maximum):
                    min_max = "{min}-{max}".format(min=minimum, max=maximum)
                    report_items.append(reports.invalid_option_value(
                        name,
                        value,
                        min_max,
                        severity=severity,
                        forceable=forceable
                    ))

            if name == "force_ip_version":
                allowed_values = ("0", "4", "6")
                if value not in allowed_values:
                    report_items.append(reports.invalid_option_value(
                        name,
                        value,
                        allowed_values,
                        severity=severity,
                        forceable=forceable
                    ))

            if name == "port":
                minimum, maximum = 1, 65535
                if not (value.isdigit() and minimum <= int(value) <= maximum):
                    min_max = "{min}-{max}".format(min=minimum, max=maximum)
                    report_items.append(reports.invalid_option_value(
                        name,
                        value,
                        min_max,
                        severity=severity,
                        forceable=forceable
                    ))

            if name == "tie_breaker":
                node_ids = [node.id for node in self.get_nodes()]
                allowed_nonid = ["lowest", "highest"]
                if value not in allowed_nonid + node_ids:
                    allowed_values = allowed_nonid + ["valid node id"]
                    report_items.append(reports.invalid_option_value(
                        name,
                        value,
                        allowed_values,
                        severity=severity,
                        forceable=forceable
                    ))

        if missing_options:
            report_items.append(
                reports.required_option_is_missing(sorted(missing_options))
            )

        return report_items
Example #22
0
    def __validate_quorum_device_model_net_options(
        self, model_options, need_required, force=False
    ):
        required_options = frozenset(["host", "algorithm"])
        optional_options = frozenset([
            "connect_timeout",
            "force_ip_version",
            "port",
            "tie_breaker",
        ])
        allowed_options = required_options | optional_options
        model_options_names = frozenset(model_options.keys())
        missing_options = []
        report_items = []
        severity = (
            ReportItemSeverity.WARNING if force else ReportItemSeverity.ERROR
        )
        forceable = None if force else report_codes.FORCE_OPTIONS

        if need_required:
            missing_options += required_options - model_options_names

        for name, value in sorted(model_options.items()):
            if name not in allowed_options:
                report_items.append(reports.invalid_option(
                    [name],
                    allowed_options,
                    "quorum device model",
                    severity,
                    forceable
                ))
                continue

            if value == "":
                # do not allow to remove required options
                if name in required_options:
                    missing_options.append(name)
                else:
                    continue

            if name == "algorithm":
                allowed_values = ("ffsplit", "lms")
                if value not in allowed_values:
                    report_items.append(reports.invalid_option_value(
                        name, value, allowed_values, severity, forceable
                    ))

            if name == "connect_timeout":
                minimum, maximum = 1000, 2*60*1000
                if not (value.isdigit() and minimum <= int(value) <= maximum):
                    min_max = "{min}-{max}".format(min=minimum, max=maximum)
                    report_items.append(reports.invalid_option_value(
                        name, value, min_max, severity, forceable
                    ))

            if name == "force_ip_version":
                allowed_values = ("0", "4", "6")
                if value not in allowed_values:
                    report_items.append(reports.invalid_option_value(
                        name, value, allowed_values, severity, forceable
                    ))

            if name == "port":
                minimum, maximum = 1, 65535
                if not (value.isdigit() and minimum <= int(value) <= maximum):
                    min_max = "{min}-{max}".format(min=minimum, max=maximum)
                    report_items.append(reports.invalid_option_value(
                        name, value, min_max, severity, forceable
                    ))

            if name == "tie_breaker":
                node_ids = [node.id for node in self.get_nodes()]
                allowed_nonid = ["lowest", "highest"]
                if value not in allowed_nonid + node_ids:
                    allowed_values = allowed_nonid + ["valid node id"]
                    report_items.append(reports.invalid_option_value(
                        name, value, allowed_values, severity, forceable
                    ))

        if missing_options:
            report_items.append(
                reports.required_option_is_missing(sorted(missing_options))
            )

        return report_items