예제 #1
0
    def test_search_for_base_class_with_gaps(self):
        mapper = ExceptionMapper()
        expected_message = "RuntimeError message"

        mapper.message_map[RuntimeError] = (expected_message, mapper.format_default)
        err = MyRuntimeError("Logged Only")
        self.assertEquals(expected_message, mapper.get_message(err))
    def test_single_mapped_exception(self):
        expected_message = "Single Exception Message"
        mapper = ExceptionMapper()
        mapper.message_map[RuntimeError] = (expected_message, mapper.format_default)

        err = RuntimeError("Testing")
        self.assertEqual(expected_message, mapper.get_message(err))
예제 #3
0
    def test_can_support_old_style_classes(self):
        expected_message = "Old style class"
        mapper = ExceptionMapper()
        mapper.message_map[OldStyleClass] = (expected_message, mapper.format_default)

        err = OldStyleClass()
        self.assertEquals(expected_message, mapper.get_message(err))
예제 #4
0
    def test_single_mapped_exception(self):
        expected_message = "Single Exception Message"
        mapper = ExceptionMapper()
        mapper.message_map[RuntimeError] = (expected_message, mapper.format_default)

        err = RuntimeError("Testing")
        self.assertEquals(expected_message, mapper.get_message(err))
예제 #5
0
    def test_subclass_mapped_by_base_class(self):
        expected_message = "Single Exception Message"
        mapper = ExceptionMapper()
        mapper.message_map[RuntimeError] = (expected_message, mapper.format_default)

        err = MyRuntimeError("Testing base class")
        self.assertEquals(expected_message, mapper.get_message(err))
    def test_search_for_base_class_with_gaps(self):
        mapper = ExceptionMapper()
        expected_message = "RuntimeError message"

        mapper.message_map[RuntimeError] = (expected_message, mapper.format_default)
        err = MyRuntimeError("Logged Only")
        self.assertEqual(expected_message, mapper.get_message(err))
    def test_can_support_old_style_classes(self):
        expected_message = "Old style class"
        mapper = ExceptionMapper()
        mapper.message_map[OldStyleClass] = (expected_message, mapper.format_default)

        err = OldStyleClass()
        self.assertEqual(expected_message, mapper.get_message(err))
    def test_subclass_mapped_by_base_class(self):
        expected_message = "Single Exception Message"
        mapper = ExceptionMapper()
        mapper.message_map[RuntimeError] = (expected_message, mapper.format_default)

        err = MyRuntimeError("Testing base class")
        self.assertEqual(expected_message, mapper.get_message(err))
예제 #9
0
    def test_restlib_exception_uses_custom_message(self):
        expected_message = "Expected MESSAGE"
        mapper = ExceptionMapper()

        err = RestlibException(404, expected_message)
        self.assertEqual("HTTP error code 404: %s" % expected_message,
                         mapper.get_message(err))
    def test_subclass_preferred_over_base_class(self):
        expected_message = "Subclass Exception Message"
        mapper = ExceptionMapper()
        mapper.message_map[RuntimeError] = ("RuntimeError message", mapper.format_default)
        mapper.message_map[MyRuntimeErrorBase] = ("MyRuntimeErrorBase message", mapper.format_default)
        mapper.message_map[MyRuntimeError] = (expected_message, mapper.format_default)

        err = MyRuntimeError("Logged Only")
        self.assertEqual(expected_message, mapper.get_message(err))
    def test_can_map_middle_sub_class(self):
        expected_message = "MyRuntimeErrorBase message"
        mapper = ExceptionMapper()
        mapper.message_map[RuntimeError] = ("RuntimeError message", mapper.format_default)
        mapper.message_map[MyRuntimeErrorBase] = (expected_message, mapper.format_default)
        mapper.message_map[MyRuntimeError] = ("MyRuntimeError message", mapper.format_default)

        err = MyRuntimeErrorBase("Logged Only")
        self.assertEqual(expected_message, mapper.get_message(err))
예제 #12
0
    def _do_command(self):
        self._validate_options()
        try:
            # If we have a username/password, we're going to use that, otherwise
            # we'll use the identity certificate. We already know one or the other
            # exists:
            if self.options.token:
                self.cp = self.cp_provider.get_keycloak_auth_cp(
                    self.options.token)
            elif self.options.username and self.options.password:
                self.cp_provider.set_user_pass(self.username, self.password)
                self.cp = self.cp_provider.get_basic_auth_cp()
            elif not self.is_registered() and self.options.show:
                pass
            else:
                # get an UEP as consumer
                self.cp = self.cp_provider.get_consumer_auth_cp()
        except connection.RestlibException as re:
            log.exception(re)
            log.error(
                "Error: Unable to retrieve service levels: {re}".format(re=re))

            mapped_message: str = ExceptionMapper().get_message(re)
            system_exit(os.EX_SOFTWARE, mapped_message)
        except Exception as e:
            handle_exception(_("Error: Unable to retrieve service levels."), e)
        else:
            try:
                if self.options.unset:
                    self.unset()
                elif self.options.set is not None:
                    self.set()
                elif self.options.list:
                    self.list_service_levels()
                elif self.options.show:
                    self.show()
                else:
                    self.show()
            except UnauthorizedException as uex:
                handle_exception(_(str(uex)), uex)
            except connection.GoneException as ge:
                raise ge
            except connection.RestlibException as re_err:
                log.exception(re_err)
                log.error(
                    "Error: Unable to retrieve service levels: {err}".format(
                        err=re_err))

                mapped_message: str = ExceptionMapper().get_message(re_err)
                system_exit(os.EX_SOFTWARE, mapped_message)
            except ProxyException:
                system_exit(
                    os.EX_UNAVAILABLE,
                    _("Proxy connection failed, please check your settings."),
                )
예제 #13
0
def handle_gui_exception(e, msg, parent, format_msg=True, log_msg=None):
    """
    Handles an exception for the gui by logging the stack trace and
    displaying a user-friendly internationalized message.

    e = either an exception or a tuple returned from sys.exc_info()
    msg = User friendly message to display in GUI.
    parent = Parent window where the error originates.
    log_msg = Optional message to be logged in addition to stack trace.
    format_msg = if true, string sub the exception error in the msg
    """
    if isinstance(e, tuple):
        if not log_msg:
            log_msg = str(e[1])

        log.error(log_msg, exc_info=e)
        # Get the class instance of the exception
        e = e[1]
    else:
        if log_msg:
            log.error(log_msg)
        log.exception(e)

    exception_mapper = ExceptionMapper()
    mapped_message = exception_mapper.get_message(e)
    if mapped_message:
        if isinstance(e, connection.RestlibException):
            # If this exception's code is in the 200 range (such as 202 ACCEPTED)
            # we're going to ignore the message we were given and just display
            # the message from the server as an info dialog. (not an error)
            if 200 < int(e.code) < 300:
                message = linkify(mapped_message)
                messageWindow.InfoDialog(messageWindow.wrap_text(message))

            else:
                try:
                    if format_msg:
                        message = msg % linkify(mapped_message)
                    else:
                        message = linkify(mapped_message)
                except Exception:
                    message = msg

                show_error_window(message, parent=parent)
        else:
            show_error_window(mapped_message, parent)
    else:
        #catch-all, try to interpolate and if it doesn't work out, just display the message
        try:
            interpolated_str = msg % e
            show_error_window(interpolated_str, parent=parent)
        except Exception:
            show_error_window(msg, parent=parent)
예제 #14
0
def handle_gui_exception(e, msg, parent, format_msg=True, log_msg=None):
    """
    Handles an exception for the gui by logging the stack trace and
    displaying a user-friendly internationalized message.

    e = either an exception or a tuple returned from sys.exc_info()
    msg = User friendly message to display in GUI.
    parent = Parent window where the error originates.
    log_msg = Optional message to be logged in addition to stack trace.
    format_msg = if true, string sub the exception error in the msg
    """
    if isinstance(e, tuple):
        if not log_msg:
            log_msg = str(e[1])

        log.error(log_msg, exc_info=e)
        # Get the class instance of the exception
        e = e[1]
    else:
        if log_msg:
            log.error(log_msg)
        log.exception(e)

    exception_mapper = ExceptionMapper()
    mapped_message = exception_mapper.get_message(e)
    if mapped_message:
        if isinstance(e, connection.RestlibException):
            # If this exception's code is in the 200 range (such as 202 ACCEPTED)
            # we're going to ignore the message we were given and just display
            # the message from the server as an info dialog. (not an error)
            if 200 < int(e.code) < 300:
                message = linkify(mapped_message)
                messageWindow.InfoDialog(messageWindow.wrap_text(message))

            else:
                try:
                    if format_msg:
                        message = msg % linkify(mapped_message)
                    else:
                        message = linkify(mapped_message)
                except Exception:
                    message = msg

                show_error_window(message, parent=parent)
        else:
            show_error_window(mapped_message, parent)
    else:
        #catch-all, try to interpolate and if it doesn't work out, just display the message
        try:
            interpolated_str = msg % e
            show_error_window(interpolated_str, parent=parent)
        except Exception:
            show_error_window(msg, parent=parent)
예제 #15
0
def format_exception(e, msg, format_msg=True, log_msg=None):
    if isinstance(e, tuple):
        log.error(log_msg, exc_info=e)
        # Get the class instance of the exception
        e = e[1]
    message = None
    exception_mapper = ExceptionMapper()
    mapped_message = exception_mapper.get_message(e)
    if mapped_message:
        message = format_mapped_message(e, msg, mapped_message, format_msg=format_msg)
    else:
        message = format_interpolated_message(e, msg, mapped_message, format_msg=format_msg)

    return message
예제 #16
0
def format_exception(e, msg, format_msg=True, log_msg=None):
    if isinstance(e, tuple):
        log.error(log_msg, exc_info=e)
        # Get the class instance of the exception
        e = e[1]
    message = None
    exception_mapper = ExceptionMapper()
    mapped_message = exception_mapper.get_message(e)
    if mapped_message:
        message = format_mapped_message(e, msg, mapped_message, format_msg=format_msg)
    else:
        message = format_interpolated_message(e, msg, mapped_message, format_msg=format_msg)

    return message
예제 #17
0
 def _get_valid_fields(self):
     """
     Try to get valid fields from server
     :return: Dictionary with valid fields
     """
     valid_fields = {}
     if self.is_registered():
         # When system is registered, then try to get valid fields from cache file
         try:
             valid_fields = get_syspurpose_valid_fields(uep=self.cp, identity=self.identity)
         except ProxyException:
             system_exit(os.EX_UNAVAILABLE, _("Proxy connection failed, please check your settings."))
     elif self.options.username and self.options.password and self.cp is not None:
         # Try to get current organization key. It is property of OrgCommand.
         # Every Syspurpose command has to be subclass of OrgCommand too
         # must have used credentials in command if not registered to proceed
         try:
             org_key = self.org
             server_response = self.cp.getOwnerSyspurposeValidFields(org_key)
         except connection.RestlibException as rest_err:
             log.warning(
                 "Unable to get list of valid fields using REST API: {rest_err}".format(rest_err=rest_err)
             )
             mapped_message: str = ExceptionMapper().get_message(rest_err)
             system_exit(os.EX_SOFTWARE, mapped_message)
         except ProxyException:
             system_exit(os.EX_UNAVAILABLE, _("Proxy connection failed, please check your settings."))
         else:
             if "systemPurposeAttributes" in server_response:
                 server_response = post_process_received_data(server_response)
                 valid_fields = server_response["systemPurposeAttributes"]
     return valid_fields
예제 #18
0
    def _do_command(self):
        self.assert_should_be_registered()
        try:
            # Also remove the content access mode cache to be sure we display
            # SCA or regular mode correctly
            content_access_mode = inj.require(inj.CONTENT_ACCESS_MODE_CACHE)
            if content_access_mode.exists():
                content_access_mode.delete_cache()

            if self.options.force is True:
                # get current consumer identity
                consumer_identity = inj.require(inj.IDENTITY)
                # Force a regen of the entitlement certs for this consumer
                if not self.cp.regenEntitlementCertificates(consumer_identity.uuid, True):
                    log.debug(
                        "Warning: Unable to refresh entitlement certificates; service likely unavailable"
                    )

            self.entcertlib.update()

            log.debug("Refreshed local data")
            print(_("All local data refreshed"))
        except connection.RestlibException as re:
            log.error(re)

            mapped_message: str = ExceptionMapper().get_message(re)
            system_exit(os.EX_SOFTWARE, mapped_message)
        except Exception as e:
            handle_exception(
                _("Unable to perform refresh due to the following exception: {e}").format(e=e), e
            )

        self._request_validity_check()
예제 #19
0
    def _do_command(self):
        self._validate_options()
        facts = inj.require(inj.FACTS)

        if self.options.list:
            facts_dict = facts.get_facts()
            facts_keys = sorted(facts_dict.keys())

            for key in facts_keys:
                value = facts_dict[key]
                if str(value).strip() == "":
                    value = _("Unknown")
                print("{key}: {value}".format(key=key, value=value))

        if self.options.update:
            identity = inj.require(inj.IDENTITY)
            try:
                facts.update_check(self.cp, identity.uuid, force=True)
            except connection.GoneException as ge:
                raise ge
            except connection.RestlibException as re:
                log.exception(re)

                mapped_message: str = ExceptionMapper().get_message(re)
                system_exit(os.EX_SOFTWARE, mapped_message)
            log.debug("Succesfully updated the system facts.")
            print(_("Successfully updated the system facts."))
예제 #20
0
    def _do_auto_attach(self, consumer):
        """
        Try to do auto-attach, when it was requested using --auto-attach CLI option
        :return: None
        """

        # Do not try to do auto-attach, when simple content access mode is used
        # Only print info message to stdout
        if is_simple_content_access(uep=self.cp, identity=self.identity):
            self._print_ignore_auto_attach_mesage()
            return

        if "serviceLevel" not in consumer and self.options.service_level:
            system_exit(
                os.EX_UNAVAILABLE,
                _(
                    "Error: The --servicelevel option is not supported "
                    "by the server. Did not complete your request."
                ),
            )
        try:
            # We don't call auto_attach with self.option.service_level, because it has been already
            # set during service.register() call
            attach.AttachService(self.cp).attach_auto(service_level=None)
        except connection.RestlibException as rest_lib_err:
            mapped_message: str = ExceptionMapper().get_message(rest_lib_err)
            print_error(mapped_message)
        except Exception:
            log.exception("Auto-attach failed")
            raise
예제 #21
0
    def _do_command(self):
        self._validate_options()
        supported_resources = get_supported_resources()
        if "environments" not in supported_resources:
            system_exit(os.EX_UNAVAILABLE,
                        _("Error: Server does not support environments."))
        try:
            if self.options.token:
                self.cp = self.cp_provider.get_keycloak_auth_cp(
                    self.options.token)
            else:
                if not self.options.enabled:
                    if self.options.username is None or self.options.password is None:
                        print(_("This operation requires user credentials"))
                    self.cp_provider.set_user_pass(self.username,
                                                   self.password)
                    self.cp = self.cp_provider.get_basic_auth_cp()
            self.identity = require(IDENTITY)
            if self.options.set:
                self._set_environments()
            else:
                self._list_environments()
        except connection.RestlibException as re:
            log.exception(re)
            log.error(
                "Error: Unable to retrieve environment list from server: {re}".
                format(re=re))

            mapped_message: str = ExceptionMapper().get_message(re)
            system_exit(os.EX_SOFTWARE, mapped_message)
        except Exception as e:
            handle_exception(
                _("Error: Unable to retrieve environment list from server"), e)
예제 #22
0
    def _do_command(self):
        self._validate_options()

        self.cp = None
        try:
            # If we have a username/password, we're going to use that, otherwise
            # we'll use the identity certificate. We already know one or the other
            # exists:
            if self.options.token:
                try:
                    self.cp = self.cp_provider.get_keycloak_auth_cp(self.options.token)
                except Exception as err:
                    log.error(
                        'unable to connect to candlepin server using token: "{token}", err: {err}'.format(
                            token=self.options.token, err=err
                        )
                    )
                    print(_("Unable to connect to server using token"))
            elif self.options.username and self.options.password:
                self.cp_provider.set_user_pass(self.options.username, self.options.password)
                self.cp = self.cp_provider.get_basic_auth_cp()
            else:
                # get an UEP as consumer
                if self.is_registered():
                    self.cp = self.cp_provider.get_consumer_auth_cp()
        except connection.RestlibException as err:
            log.exception(err)
            if getattr(self.options, "list", None):
                log.error(
                    "Error: Unable to retrieve {attr} from server: {err}".format(attr=self.attr, err=err)
                )
                mapped_message: str = ExceptionMapper().get_message(err)
                system_exit(os.EX_SOFTWARE, mapped_message)
            else:
                log.debug(
                    "Error: Unable to retrieve {attr} from server: {err}".format(attr=self.attr, err=err)
                )
        except Exception as err:
            log.debug("Error: Unable to retrieve {attr} from server: {err}".format(attr=self.attr, err=err))

        self.store = SyncedStore(uep=self.cp, consumer_uuid=self.identity.uuid)

        if getattr(self.options, "unset", None):
            self.unset()
        elif getattr(self.options, "set", None):
            self.set()
        elif hasattr(self.options, "to_add") and len(self.options.to_add) > 0:
            self.add()
        elif hasattr(self.options, "to_remove") and len(self.options.to_remove) > 0:
            self.remove()
        elif getattr(self.options, "list", None):
            self.list()
        elif getattr(self.options, "show", None):
            self.show()
        else:
            self.show()
예제 #23
0
def handle_exception(msg, ex):
    # On Python 2.4 and earlier, sys.exit triggers a SystemExit exception,
    # which can land us into this block of code. We do not want to handle
    # this or print any messages as the caller would already have done so,
    # so just re-throw and let Python have at it.
    if isinstance(ex, SystemExit):
        raise ex

    # GoneException will be handled uniformly for every command except unregister.
    if isinstance(ex, connection.GoneException):
        raise ex

    log.error(msg)
    log.exception(ex)

    exception_mapper = ExceptionMapper()

    mapped_message: str = exception_mapper.get_message(ex)
    system_exit(os.EX_SOFTWARE, mapped_message)
예제 #24
0
    def test_subclass_preferred_over_base_class(self):
        expected_message = "Subclass Exception Message"
        mapper = ExceptionMapper()
        mapper.message_map[RuntimeError] = ("RuntimeError message", mapper.format_default)
        mapper.message_map[MyRuntimeErrorBase] = ("MyRuntimeErrorBase message", mapper.format_default)
        mapper.message_map[MyRuntimeError] = (expected_message, mapper.format_default)

        err = MyRuntimeError("Logged Only")
        self.assertEquals(expected_message, mapper.get_message(err))
예제 #25
0
    def test_can_map_middle_sub_class(self):
        expected_message = "MyRuntimeErrorBase message"
        mapper = ExceptionMapper()
        mapper.message_map[RuntimeError] = ("RuntimeError message", mapper.format_default)
        mapper.message_map[MyRuntimeErrorBase] = (expected_message, mapper.format_default)
        mapper.message_map[MyRuntimeError] = ("MyRuntimeError message", mapper.format_default)

        err = MyRuntimeErrorBase("Logged Only")
        self.assertEquals(expected_message, mapper.get_message(err))
예제 #26
0
    def list_service_levels(self):
        if self.is_registered():
            org_key = self.cp.getOwner(self.identity.uuid)["key"]
        else:
            org_key = self.org

        try:
            slas = self.cp.getServiceLevelList(org_key)
            if len(slas):
                print("+-------------------------------------------+")
                print("           {label}".format(
                    label=_("Available Service Levels")))
                print("+-------------------------------------------+")
                for sla in slas:
                    print(sla)
            else:
                print(
                    _('There are no available values for the system purpose "{syspurpose_attr}" '
                      "from the available subscriptions in this "
                      "organization.").format(syspurpose_attr="service_level"))
        except UnauthorizedException as e:
            raise e
        except connection.RemoteServerException:
            system_exit(
                os.EX_UNAVAILABLE,
                _("Error: The service-level command is not supported by the server."
                  ))
        except connection.GoneException as ge:
            raise ge
        except connection.RestlibException as e:
            if e.code == 404 and e.msg.find("/servicelevels") > 0:
                system_exit(
                    os.EX_UNAVAILABLE,
                    _("Error: The service-level command is not supported by the server."
                      ))
            elif e.code == 404:
                mapped_message: str = ExceptionMapper().get_message(e)
                system_exit(os.EX_DATAERR, mapped_message)
            else:
                raise e
예제 #27
0
    def _do_command(self):

        try:
            # get a UEP
            if self.options.token:
                self.cp = self.cp_provider.get_keycloak_auth_cp(
                    self.options.token)
            else:
                self.cp_provider.set_user_pass(self.username, self.password)
                self.cp = self.cp_provider.get_basic_auth_cp()
            owners = self.cp.getOwnerList(self.username)
            log.debug("Successfully retrieved org list from server.")
            if len(owners):
                print("+-------------------------------------------+")
                print("          {name} {label}".format(
                    name=self.username, label=_("Organizations")))
                print("+-------------------------------------------+")
                print("")
                for owner in owners:
                    print(
                        columnize(ORG_LIST, echo_columnize_callback,
                                  owner["displayName"], owner["key"]) + "\n")
            else:
                print(
                    _("{username} cannot register with any organizations.").
                    format(username=self.username))

        except connection.RestlibException as re:
            log.exception(re)
            log.error(
                "Error: Unable to retrieve org list from server: {re}".format(
                    re=re))

            mapped_message: str = ExceptionMapper().get_message(re)
            system_exit(os.EX_SOFTWARE, mapped_message)
        except Exception as e:
            handle_exception(
                _("Error: Unable to retrieve org list from server"), e)
예제 #28
0
    def _do_command(self):
        """
        Executes the command.
        """
        self._validate_options()
        return_code = 0
        if self.is_registered():
            ent_service = entitlement.EntitlementService(self.cp)
            try:
                if self.options.all:
                    total = ent_service.remove_all_entitlements()
                    # total will be None on older Candlepins that don't
                    # support returning the number of subscriptions unsubscribed from
                    if total is None:
                        print(_("All subscriptions have been removed at the server."))
                    else:
                        count = total["deletedRecords"]
                        print(
                            ungettext(
                                "%s subscription removed at the server.",
                                "%s subscriptions removed at the server.",
                                count,
                            )
                            % count
                        )
                else:
                    # Try to remove subscriptions defined by pool IDs first (remove --pool=...)
                    if self.options.pool_ids:
                        (
                            removed_pools,
                            unremoved_pools,
                            removed_serials,
                        ) = ent_service.remove_entilements_by_pool_ids(self.options.pool_ids)
                        if not removed_pools:
                            return_code = 1
                        self._print_unbind_ids_result(removed_pools, unremoved_pools, "pools")
                    else:
                        removed_serials = []
                    # Then try to remove subscriptions defined by serials (remove --serial=...)
                    unremoved_serials = []
                    if self.options.serials:
                        serials = unique_list_items(self.options.serials)
                        # Don't remove serials already removed by a pool
                        serials_to_remove = [serial for serial in serials if serial not in removed_serials]
                        _removed_serials, unremoved_serials = ent_service.remove_entitlements_by_serials(
                            serials_to_remove
                        )
                        removed_serials.extend(_removed_serials)
                        if not _removed_serials:
                            return_code = 1
                    # Print final result of removing pools
                    self._print_unbind_ids_result(removed_serials, unremoved_serials, "serial numbers")
            except connection.GoneException as ge:
                raise ge
            except connection.RestlibException as err:
                log.error(err)

                mapped_message: str = ExceptionMapper().get_message(err)
                system_exit(os.EX_SOFTWARE, mapped_message)
            except Exception as e:
                handle_exception(
                    _("Unable to perform remove due to the following exception: {e}").format(e=e), e
                )
        else:
            # We never got registered, just remove the cert
            try:
                if self.options.all:
                    total = 0
                    for ent in self.entitlement_dir.list():
                        ent.delete()
                        total = total + 1
                    print(_("{total} subscriptions removed from this system.").format(total=total))
                else:
                    if self.options.serials or self.options.pool_ids:
                        serials = self.options.serials or []
                        pool_ids = self.options.pool_ids or []
                        count = 0
                        for ent in self.entitlement_dir.list():
                            ent_pool_id = str(getattr(ent.pool, "id", None) or "")
                            if str(ent.serial) in serials or ent_pool_id in pool_ids:
                                ent.delete()
                                print(
                                    _(
                                        "Subscription with serial number {serial} removed from this system"
                                    ).format(serial=str(ent.serial))
                                )
                                count = count + 1
                        if count == 0:
                            return_code = 1
            except Exception as e:
                handle_exception(
                    _("Unable to perform remove due to the following exception: {e}").format(e=e), e
                )

        # it is okay to call this no matter what happens above,
        # it's just a notification to perform a check
        self._request_validity_check()
        return return_code
예제 #29
0
 def test_returns_none_when_no_mapped_exception_present(self):
     mapper = ExceptionMapper()
     self.assertEqual(None, mapper.get_message(RuntimeError()))
    def test_return_str_when_no_mapped_exception(self):
        expected_message = "Expected message"
        mapper = ExceptionMapper()

        err = RuntimeError(expected_message)
        self.assertEqual(expected_message, mapper.get_message(err))
예제 #31
0
    def _do_command(self):
        # get current consumer identity
        identity = inj.require(inj.IDENTITY)

        # check for Classic before doing anything else
        if ClassicCheck().is_registered_with_classic():
            if identity.is_valid():
                print(
                    _("server type: {type}").format(
                        type=get_branding().REGISTERED_TO_BOTH_SUMMARY))
            else:
                # no need to continue if user is only registered to Classic
                print(
                    _("server type: {type}").format(
                        type=get_branding().REGISTERED_TO_OTHER_SUMMARY))
                return

        try:
            self._validate_options()
            consumerid = self.identity.uuid
            consumer_name = self.identity.name
            if not self.options.regenerate:
                owner = get_current_owner(self.cp, self.identity)
                ownername = owner["displayName"]
                ownerid = owner["key"]

                print(
                    _("system identity: {consumerid}").format(
                        consumerid=consumerid))
                print(
                    _("name: {consumer_name}").format(
                        consumer_name=consumer_name))
                print(_("org name: {ownername}").format(ownername=ownername))
                print(_("org ID: {ownerid}").format(ownerid=ownerid))

                supported_resources = get_supported_resources(
                    self.cp, self.identity)
                if "environments" in supported_resources:
                    consumer = self.cp.getConsumer(consumerid)
                    evn_key = "environments" if self.cp.has_capability(
                        MULTI_ENV) else "environment"
                    environments = consumer[evn_key]
                    if environments:
                        if evn_key == "environment":
                            environment_names = environments["name"]
                        else:
                            environment_names = ",".join([
                                environment["name"]
                                for environment in environments
                            ])
                    else:
                        environment_names = _("None")
                    print(
                        ungettext(
                            "environment name: {environment_name}",
                            "environment names: {environment_name}",
                            len(environment_names.split(",")),
                        ).format(environment_name=environment_names))
            else:
                if self.options.force:
                    # get an UEP with basic auth or keycloak auth
                    if self.options.token:
                        self.cp = self.cp_provider.get_keycloak_auth_cp(
                            self.options.token)
                    else:
                        self.cp_provider.set_user_pass(self.username,
                                                       self.password)
                        self.cp = self.cp_provider.get_basic_auth_cp()
                consumer = self.cp.regenIdCertificate(consumerid)
                managerlib.persist_consumer_cert(consumer)

                # do this in persist_consumer_cert? or some other
                # high level, "I just registered" thing
                self.identity.reload()

                print(_("Identity certificate has been regenerated."))

                log.debug("Successfully generated a new identity from server.")
        except connection.GoneException as ge:
            # Gone exception is caught in CliCommand and a consistent message
            # is printed there for all commands
            raise ge
        except connection.RestlibException as re:
            log.exception(re)
            log.error(
                "Error: Unable to generate a new identity for the system: {re}"
                .format(re=re))

            mapped_message: str = ExceptionMapper().get_message(re)
            system_exit(os.EX_SOFTWARE, mapped_message)
        except Exception as e:
            handle_exception(
                _("Error: Unable to generate a new identity for the system"),
                e)
 def test_returns_none_when_no_mapped_exception_present(self):
     mapper = ExceptionMapper()
     self.assertEqual(None, mapper.get_message(RuntimeError()))
    def test_restlib_exception_uses_custom_message(self):
        expected_message = "Expected MESSAGE"
        mapper = ExceptionMapper()

        err = RestlibException(404, expected_message)
        self.assertEqual("HTTP error code 404: %s" % expected_message, mapper.get_message(err))
예제 #34
0
    def _do_command(self):
        """
        Executes the command.
        """

        self.log_client_version()

        # Always warn the user if registered to old RHN/Spacewalk
        if ClassicCheck().is_registered_with_classic():
            print(get_branding().REGISTERED_TO_OTHER_WARNING)

        self._validate_options()

        # gather installed products info
        self.installed_mgr = inj.require(inj.INSTALLED_PRODUCTS_MANAGER)

        previously_registered = False
        if self.is_registered() and self.options.force:
            previously_registered = True
            # First let's try to un-register previous consumer; if this fails
            # we'll let the error bubble up, so that we don't blindly re-register.
            # managerlib.unregister handles the special case that the consumer has already been removed.
            old_uuid = self.identity.uuid

            print(
                _("Unregistering from: {hostname}:{port}{prefix}").format(
                    hostname=conf["server"]["hostname"],
                    port=conf["server"]["port"],
                    prefix=conf["server"]["prefix"],
                )
            )
            try:
                unregister.UnregisterService(self.cp).unregister()
                self.entitlement_dir.__init__()
                self.product_dir.__init__()
                log.info("--force specified, unregistered old consumer: {old_uuid}".format(old_uuid=old_uuid))
                print(_("The system with UUID {old_uuid} has been unregistered").format(old_uuid=old_uuid))
            except ssl.SSLError as e:
                # since the user can override serverurl for register, a common use case is to try to switch servers
                # using register --force... However, this normally cannot successfully unregister since the servers
                # are different.
                handle_exception("Unregister failed: {e}".format(e=e), e)
            except Exception as e:
                handle_exception("Unregister failed", e)

        self.cp_provider.clean()
        if previously_registered:
            print(_("All local data removed"))

        # Proceed with new registration:
        try:
            if self.options.token:
                admin_cp = self.cp_provider.get_keycloak_auth_cp(self.options.token)
            elif not self.options.activation_keys:
                hostname = conf["server"]["hostname"]
                if ":" in hostname:
                    normalized_hostname = "[{hostname}]".format(hostname=hostname)
                else:
                    normalized_hostname = hostname
                print(
                    _("Registering to: {hostname}:{port}{prefix}").format(
                        hostname=normalized_hostname,
                        port=conf["server"]["port"],
                        prefix=conf["server"]["prefix"],
                    )
                )
                self.cp_provider.set_user_pass(self.username, self.password)
                admin_cp = self.cp_provider.get_basic_auth_cp()
            else:
                admin_cp = self.cp_provider.get_no_auth_cp()

            # This is blocking and not async, which aside from blocking here, also
            # means things like following name owner changes gets weird.
            service = register.RegisterService(admin_cp)

            if self.options.consumerid:
                log.debug("Registering as existing consumer: {id}".format(id=self.options.consumerid))
                consumer = service.register(None, consumerid=self.options.consumerid)
            else:
                if self.options.org:
                    owner_key = self.options.org
                else:
                    owner_key = service.determine_owner_key(
                        username=self.username, get_owner_cb=self._get_owner_cb, no_owner_cb=self._no_owner_cb
                    )
                environment_ids = self._process_environments(admin_cp, owner_key)
                consumer = service.register(
                    owner_key,
                    activation_keys=self.options.activation_keys,
                    environments=environment_ids,
                    force=self.options.force,
                    name=self.options.consumername,
                    type=self.options.consumertype,
                    service_level=self.options.service_level,
                )
        except (connection.RestlibException, exceptions.ServiceError) as re:
            log.exception(re)

            mapped_message: str = ExceptionMapper().get_message(re)
            system_exit(os.EX_SOFTWARE, mapped_message)
        except Exception as e:
            handle_exception(_("Error during registration: {e}").format(e=e), e)
        else:
            consumer_info = identity.ConsumerIdentity(consumer["idCert"]["key"], consumer["idCert"]["cert"])
            print(_("The system has been registered with ID: {id}").format(id=consumer_info.getConsumerId()))
            print(_("The registered system name is: {name}").format(name=consumer_info.getConsumerName()))
            if self.options.service_level:
                print(_("Service level set to: {level}").format(level=self.options.service_level))

        # We have new credentials, restart virt-who
        restart_virt_who()

        # get a new UEP as the consumer
        self.cp = self.cp_provider.get_consumer_auth_cp()

        # log the version of the server we registered to
        self.log_server_version()

        facts = inj.require(inj.FACTS)

        # FIXME: can these cases be replaced with invoking
        # FactsLib (or a FactsManager?)
        # Must update facts to clear out the old ones:
        if self.options.consumerid:
            log.debug("Updating facts")
            #
            # FIXME: Need a ConsumerFacts.sync or update or something
            # TODO: We register, with facts, then update facts again...?
            #       Are we trying to sync potential new or dynamic facts?
            facts.update_check(self.cp, consumer["uuid"], force=True)

        # Facts and installed products went out with the registration request,
        # manually write caches to disk:
        # facts service job now(soon)
        facts.write_cache()
        self.installed_mgr.update_check(self.cp, consumer["uuid"])

        if self.options.release:
            # TODO: grab the list of valid options, and check
            self.cp.updateConsumer(consumer["uuid"], release=self.options.release)

        if self.autoattach:
            self._do_auto_attach(consumer)

        if (
            self.options.consumerid
            or self.options.activation_keys
            or self.autoattach
            or self.cp.has_capability(CONTENT_ACCESS_CERT_CAPABILITY)
        ):
            log.debug("System registered, updating entitlements if needed")
            # update certs, repos, and caches.
            # FIXME: aside from the overhead, should this be cert_action_client.update?
            self.entcertlib.update()

        try:
            profile_mgr = inj.require(inj.PROFILE_MANAGER)
            # 767265: always force an upload of the packages when registering
            profile_mgr.update_check(self.cp, consumer["uuid"], True)
        except RemoteServerException as err:
            # When it is not possible to upload profile ATM, then print only error about this
            # to rhsm.log. The rhsmcertd will try to upload it next time.
            log.error("Unable to upload profile: {err}".format(err=str(err)))

        subscribed = 0
        if self.options.activation_keys or self.autoattach:
            # update with latest cert info
            self.sorter = inj.require(inj.CERT_SORTER)
            self.sorter.force_cert_check()
            subscribed = show_autosubscribe_output(self.cp, self.identity)

        self._request_validity_check()
        return subscribed
예제 #35
0
    def _do_command(self):
        self._validate_options()
        # Abort if not registered
        self.assert_should_be_registered()

        supported_resources = get_supported_resources()
        if "content_overrides" not in supported_resources:
            system_exit(
                os.EX_UNAVAILABLE,
                _("Error: The 'repo-override' command is not supported by the server."
                  ))

        # update entitlement certificates if necessary. If we do have new entitlements
        # CertLib.update() will call RepoActionInvoker.update().
        self.entcertlib.update()
        # make sure the EntitlementDirectory singleton is refreshed
        self._request_validity_check()

        overrides = Overrides()

        if not manage_repos_enabled():
            print(_("Repositories disabled by configuration."))

        if self.options.list:
            results = overrides.get_overrides(self.identity.uuid)
            if results:
                self._list(results, self.options.repos)
            else:
                print(
                    _("This system does not have any content overrides applied to it."
                      ))
            return

        if self.options.additions:
            repo_ids = [
                repo.id
                for repo in overrides.repo_lib.get_repos(apply_overrides=False)
            ]
            to_add = [
                Override(repo, name, value) for repo in self.options.repos
                for name, value in list(self.options.additions.items())
            ]
            try:
                results = overrides.add_overrides(self.identity.uuid, to_add)
            except connection.RestlibException as ex:
                if ex.code == 400:
                    # blocklisted overrides specified.
                    # Print message and return a less severe code.
                    mapped_message: str = ExceptionMapper().get_message(ex)
                    system_exit(1, mapped_message)
                else:
                    raise ex

            # Print out warning messages if the specified repo does not exist in the repo file.
            for repo in self.options.repos:
                if repo not in repo_ids:
                    print(
                        _("Repository '{repo}' does not currently exist, but the override has been added."
                          ).format(repo=repo))

        if self.options.removals:
            to_remove = [
                Override(repo, item) for repo in self.options.repos
                for item in self.options.removals
            ]
            results = overrides.remove_overrides(self.identity.uuid, to_remove)
        if self.options.remove_all:
            results = overrides.remove_all_overrides(self.identity.uuid,
                                                     self.options.repos)

        # Update the cache and refresh the repo file.
        overrides.update(results)
예제 #36
0
    def _do_command(self):
        """
        Executes the command.
        """
        self.assert_should_be_registered()
        self._validate_options()

        # --pool or --file turns off default auto attach
        if self.options.pool or self.options.file:
            self.auto_attach = False

        # Do not try to do auto-attach, when simple content access mode is used
        # BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1826300
        #
        if is_simple_content_access(uep=self.cp, identity=self.identity):
            if self.auto_attach is True:
                self._print_ignore_auto_attach_mesage()
            else:
                self._print_ignore_attach_message()
            return 0

        installed_products_num = 0
        return_code = 0
        report = None

        # TODO: change to if self.auto_attach: else: pool/file stuff
        try:
            cert_action_client = ActionClient(skips=[PackageProfileActionInvoker])
            cert_action_client.update()
            cert_update = True

            attach_service = attach.AttachService(self.cp)
            if self.options.pool:
                subscribed = False

                for pool in self.options.pool:
                    # odd html strings will cause issues, reject them here.
                    if pool.find("#") >= 0:
                        system_exit(os.EX_USAGE, _("Please enter a valid numeric pool ID."))

                    try:
                        ents = attach_service.attach_pool(pool, self.options.quantity)
                        # Usually just one, but may as well be safe:
                        for ent in ents:
                            pool_json = ent["pool"]
                            print(
                                _("Successfully attached a subscription for: {name}").format(
                                    name=pool_json["productName"]
                                )
                            )
                            log.debug(
                                "Attached a subscription for {name}".format(name=pool_json["productName"])
                            )
                            subscribed = True
                    except connection.RestlibException as re:
                        log.exception(re)

                        exception_mapper = ExceptionMapper()
                        mapped_message = exception_mapper.get_message(re)

                        if re.code == 403:
                            print(mapped_message)  # already subscribed.
                        elif re.code == 400 or re.code == 404:
                            print(mapped_message)  # no such pool.
                        else:
                            system_exit(os.EX_SOFTWARE, mapped_message)  # some other error.. don't try again
                if not subscribed:
                    return_code = 1
            # must be auto
            else:
                installed_products_num = len(products.InstalledProducts(self.cp).list())
                # if we are green, we don't need to go to the server
                self.sorter = inj.require(inj.CERT_SORTER)

                if self.sorter.is_valid():
                    if not installed_products_num:
                        print(_("No Installed products on system. " "No need to attach subscriptions."))
                    else:
                        print(
                            _(
                                "All installed products are covered by valid entitlements. "
                                "No need to update subscriptions at this time."
                            )
                        )
                    cert_update = False
                else:
                    # If service level specified, make an additional request to
                    # verify service levels are supported on the server:
                    if self.options.service_level:
                        consumer = self.cp.getConsumer(self.identity.uuid)
                        if "serviceLevel" not in consumer:
                            system_exit(
                                os.EX_UNAVAILABLE,
                                _(
                                    "Error: The --servicelevel option is not "
                                    "supported by the server. Did not "
                                    "complete your request."
                                ),
                            )

                    attach_service.attach_auto(self.options.service_level)
                    if self.options.service_level is not None:
                        #  RHBZ 1632797 we should only save the sla if the sla was actually
                        #  specified. The uep and consumer_uuid are None, because service_level was sent
                        # to candlepin server using attach_service.attach_auto()
                        save_sla_to_syspurpose_metadata(
                            uep=None, consumer_uuid=None, service_level=self.options.service_level
                        )
                        print(_("Service level set to: {}").format(self.options.service_level))

            if cert_update:
                report = self.entcertlib.update()

            profile_action_client = ProfileActionClient()
            profile_action_client.update()

            if report and report.exceptions():
                print(_("Entitlement Certificate(s) update failed due to the following reasons:"))
                for e in report.exceptions():
                    print("\t-", str(e))
            elif self.auto_attach:
                if not installed_products_num:
                    return_code = 1
                else:
                    self.sorter.force_cert_check()
                    # Make sure that we get fresh status of installed products
                    status_cache = inj.require(inj.ENTITLEMENT_STATUS_CACHE)
                    status_cache.load_status(
                        self.sorter.cp_provider.get_consumer_auth_cp(),
                        self.sorter.identity.uuid,
                        self.sorter.on_date,
                    )
                    self.sorter.load()
                    # run this after entcertlib update, so we have the new entitlements
                    return_code = show_autosubscribe_output(self.cp, self.identity)

        except Exception as e:
            handle_exception("Unable to attach: {e}".format(e=e), e)

        # it is okay to call this no matter what happens above,
        # it's just a notification to perform a check
        self._request_validity_check()

        return return_code