def _add_group(self, group):
        tree_iter = None
        if group.name and len(group.entitlements) > 1:
            unique = self.find_unique_name_count(group.entitlements)
            if unique - 1 > 0:
                name_string = ungettext(
                    "Stack of {group_name} and 1 other",
                    "Stack of {group_name} and {unique} others", unique - 1)
            else:
                name_string = _("Stack of {group_name}")
            name_string = name_string.format(group_name=group.name,
                                             unique=(unique - 1))
            tree_iter = self.store.add_map(
                tree_iter, self._create_stacking_header_entry(name_string))

        new_parent_image = None
        for i, cert in enumerate(group.entitlements):
            image = self._get_entry_image(cert)
            self.store.add_map(tree_iter, self._create_entry_map(cert, image))

            # Determine if we need to change the parent's image. We
            # will match the parent's image with the children if any of
            # the children have an image.
            if self.image_ranks_higher(new_parent_image, image):
                new_parent_image = image

        # Update the parent image if required.
        if new_parent_image and tree_iter:
            self.store.set_value(
                tree_iter, self.store['image'],
                ga_GdkPixbuf.Pixbuf.new_from_file_at_size(
                    new_parent_image, 13, 13))
Example #2
0
    def _are_provided_values_valid(self, values):
        """
        Try to validate the provided values. Check if all the values are included in valid fields.
        If any of the values is not provided in the valid fields and we can connect candlepin
        server, then print some warning.
        :param values: provided values on CLI
        :return: list of invalid values
        """

        # First check if the the value is in the valid_fields.  Comparison is case insensitive.
        invalid_values = []
        valid_fields = self._get_valid_fields()
        if self.attr in valid_fields:
            for value in values:
                if all([
                        x.casefold() != value.casefold()
                        for x in valid_fields[self.attr]
                ]):
                    invalid_values.append(value)
        invalid_values_len = len(invalid_values)

        # When there are values not in the valid fields, then try to print some warning,
        # when the system is registered or username & password was provided as CLI option.
        # When the system is not registered and no username & password was provided, then
        # these values will be set silently.
        if invalid_values_len > 0:
            if self.is_registered() or \
                    (self.options.username and self.options.password) or \
                    self.options.token:
                if self.attr in valid_fields:
                    if len(valid_fields[self.attr]) > 0:
                        # TRANSLATORS: this is used to quote a string
                        quoted_values = [
                            _("\"{value}\"").format(value=value)
                            for value in invalid_values
                        ]
                        printable_values = friendly_join(quoted_values)
                        print(
                            ungettext(
                                'Warning: Provided value {vals} is not included in the list of valid values',
                                'Warning: Provided values {vals} are not included in the list of valid values',
                                invalid_values_len).format(
                                    vals=printable_values))
                        self._print_valid_values(valid_fields)
                    else:
                        print(
                            _('Warning: This org does not have any subscriptions with an available "{attr}" is empty.'
                              ).format(attr=self.attr))
                else:
                    print(
                        _('Warning: This org does not have any subscriptions with an available "{attr}"'
                          ).format(attr=self.attr))

        return invalid_values
    def delete(self, rogue):
        for cert in rogue:
            try:
                cert.delete()
                self.report.rogue.append(cert)
            except OSError as er:
                log.exception(er)
                log.warn("Failed to delete cert")

        # If we just deleted certs, we need to refresh the now stale
        # entitlement directory before we go to delete expired certs.
        rogue_count = len(self.report.rogue)
        if rogue_count > 0:
            print(ungettext("%s local certificate has been deleted.",
                            "%s local certificates have been deleted.",
                            rogue_count) % rogue_count)
            self.ent_dir.refresh()
Example #4
0
    def delete(self, rogue):
        for cert in rogue:
            try:
                cert.delete()
                self.report.rogue.append(cert)
            except OSError as er:
                log.exception(er)
                log.warn("Failed to delete cert")

        # If we just deleted certs, we need to refresh the now stale
        # entitlement directory before we go to delete expired certs.
        rogue_count = len(self.report.rogue)
        if rogue_count > 0:
            print(
                ungettext("%s local certificate has been deleted.",
                          "%s local certificates have been deleted.",
                          rogue_count) % rogue_count)
            self.ent_dir.refresh()
 def __str__(self):
     """
     Text representation of exception
     :return: string of exception
     """
     conflicts = []
     for key, value in self.conflict_fields.items():
         conflicts.append('{conflict_attr} of "{existing_value}"'.format(
             conflict_attr=key,
             existing_value=value,
         ))
     conflict_msg = ", ".join(conflicts)
     return ungettext(
         "Warning: The following field was recently set "
         "for this system by the entitlement server "
         "administrator: {conflict_msg}",
         "Warning: The following fields were recently set "
         "for this system by the entitlement server "
         "administrator: {conflict_msg}",
         len(conflicts),
     ).format(conflict_msg=conflict_msg)
Example #6
0
def check_set_environment_names(all_env_list, name_string):
    """
    Checks the environment name(s) input for duplicates and
    inclusion in the full list
    """
    names = [name.strip() for name in name_string.split(",")]
    if len(names) > len(set(names)):
        system_exit(
            os.EX_DATAERR,
            _("Error: The same environment may not be listed more than once. ")
        )

    all_names_ids = dict((environment["name"], environment["id"])
                         for environment in all_env_list)
    missing_names = [
        name for name in names if name not in all_names_ids.keys()
    ]
    if len(missing_names) > 0:
        msg = ungettext(
            "No such environment: {names}", "No such environments: {names}",
            len(missing_names)).format(names=", ".join(missing_names))
        system_exit(os.EX_DATAERR, msg)

    return ",".join([all_names_ids[name] for name in names])
Example #7
0
    def update(self):
        entries = []
        range_calculator = inj.require(
            inj.PRODUCT_DATE_RANGE_CALCULATOR,
            self.backend.cp_provider.get_consumer_auth_cp())

        installed_products = products.InstalledProducts(
            self.backend.cp_provider.get_consumer_auth_cp()).list()

        for product in installed_products:
            entry = {}
            entry['product'] = product[0]
            entry['product_id'] = product_id = product[1]
            entry['version'] = product[2]
            entry['arch'] = product[
                3]  # TODO: need to test, when more more architectures is supported
            status = product[4]

            # NOTE: following code cannot be used, because start_date and expiration_date
            # are stored in textual form in product and GUI requires datetime format.
            # entry['start_date'] = product[6]
            # entry['expiration_date'] = product[7]

            # Common properties
            entry['align'] = 0.5

            # TODO:  Pull this date logic out into a separate lib!
            #        This is also used in mysubstab...
            if status != NOT_SUBSCRIBED:

                compliant_range = range_calculator.calculate(product_id)
                start = ''
                end = ''
                if compliant_range:
                    start = compliant_range.begin()
                    end = compliant_range.end()
                entry['start_date'] = start
                entry['expiration_date'] = end

                contract_ids, sub_names = self._calc_subs_providing(
                    product_id, compliant_range)
                contract = friendly_join(contract_ids)
                num_of_contracts = len(contract_ids)

                entry['subscription'] = list(sub_names)

                if status == FUTURE_SUBSCRIBED:
                    entry['image'] = self._render_icon('red')
                    entry['status'] = _('Future Subscription')
                    entry['validity_note'] = _("Future Subscribed")
                elif status == EXPIRED:
                    entry['image'] = self._render_icon('red')
                    entry['status'] = _('Expired')
                    sub_numbers = set([])
                    for ent_cert in self.entitlement_dir.list_for_product(
                            product_id):
                        order = ent_cert.order
                        # FIXME:  getSubscription() seems to always be None...?
                        if order.subscription:
                            sub_numbers.add(order.subscription)
                    subs_str = ', '.join(sub_numbers)

                    entry['validity_note'] = \
                         _('Subscription %s is expired') % subs_str
                elif status == PARTIALLY_SUBSCRIBED:
                    entry['image'] = self._render_icon('yellow')
                    entry['status'] = _('Partially Subscribed')
                    entry['validity_note'] = _("Partially Subscribed")
                elif status == UNKNOWN:
                    entry['image'] = self._render_icon('unknown')
                    entry['status'] = _('Unknown')
                    if not self.backend.cs.is_registered():
                        entry['validity_note'] = _("System is not registered.")
                    else:
                        # System must be registered but unable to reach server:
                        entry['validity_note'] = _(
                            "Entitlement server is unreachable.")
                else:
                    entry['image'] = self._render_icon('green')
                    entry['status'] = _('Subscribed')
                    entry['validity_note'] = \
                        ungettext("Covered by contract %s through %s",
                                  'Covered by contracts %s through %s',
                                  num_of_contracts) % \
                        (contract,
                         managerlib.format_date(entry['expiration_date']))
            else:
                entry['image'] = self._render_icon('red')
                entry['status'] = _('Not Subscribed')
                entry['validity_note'] = _("Not Subscribed")
            entries.append(entry)
        self._entries = entries
Example #8
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
    def update(self):
        entries = []
        range_calculator = inj.require(
            inj.PRODUCT_DATE_RANGE_CALCULATOR,
            self.backend.cp_provider.get_consumer_auth_cp()
        )

        installed_products = products.InstalledProducts(self.backend.cp_provider.get_consumer_auth_cp()).list()

        for product in installed_products:
            entry = {}
            entry['product'] = product[0]
            entry['product_id'] = product_id = product[1]
            entry['version'] = product[2]
            entry['arch'] = product[3]  # TODO: need to test, when more more architectures is supported
            status = product[4]

            # NOTE: following code cannot be used, because start_date and expiration_date
            # are stored in textual form in product and GUI requires datetime format.
            # entry['start_date'] = product[6]
            # entry['expiration_date'] = product[7]

            # Common properties
            entry['align'] = 0.5

            # TODO:  Pull this date logic out into a separate lib!
            #        This is also used in mysubstab...
            if status != NOT_SUBSCRIBED:

                compliant_range = range_calculator.calculate(product_id)
                start = ''
                end = ''
                if compliant_range:
                    start = compliant_range.begin()
                    end = compliant_range.end()
                entry['start_date'] = start
                entry['expiration_date'] = end

                contract_ids, sub_names = self._calc_subs_providing(
                        product_id, compliant_range)
                contract = friendly_join(contract_ids)
                num_of_contracts = len(contract_ids)

                entry['subscription'] = list(sub_names)

                if status == FUTURE_SUBSCRIBED:
                    entry['image'] = self._render_icon('red')
                    entry['status'] = _('Future Subscription')
                    entry['validity_note'] = _("Future Subscribed")
                elif status == EXPIRED:
                    entry['image'] = self._render_icon('red')
                    entry['status'] = _('Expired')
                    sub_numbers = set([])
                    for ent_cert in self.entitlement_dir.list_for_product(product_id):
                        order = ent_cert.order
                        # FIXME:  getSubscription() seems to always be None...?
                        if order.subscription:
                            sub_numbers.add(order.subscription)
                    subs_str = ', '.join(sub_numbers)

                    entry['validity_note'] = \
                         _('Subscription %s is expired') % subs_str
                elif status == PARTIALLY_SUBSCRIBED:
                    entry['image'] = self._render_icon('yellow')
                    entry['status'] = _('Partially Subscribed')
                    entry['validity_note'] = _("Partially Subscribed")
                elif status == UNKNOWN:
                    entry['image'] = self._render_icon('unknown')
                    entry['status'] = _('Unknown')
                    if not self.backend.cs.is_registered():
                        entry['validity_note'] = _("System is not registered.")
                    else:
                        # System must be registered but unable to reach server:
                        entry['validity_note'] = _("Entitlement server is unreachable.")
                else:
                    entry['image'] = self._render_icon('green')
                    entry['status'] = _('Subscribed')
                    entry['validity_note'] = \
                        ungettext("Covered by contract %s through %s",
                                  'Covered by contracts %s through %s',
                                  num_of_contracts) % \
                        (contract,
                         managerlib.format_date(entry['expiration_date']))
            else:
                entry['image'] = self._render_icon('red')
                entry['status'] = _('Not Subscribed')
                entry['validity_note'] = _("Not Subscribed")
            entries.append(entry)
        self._entries = entries
Example #10
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)