def test_list_installed_products_with_filter(self):
        self.mock_cp.getConsumer.return_value = CONTENT_JSON
        self.mock_cert_sorter.reasons = mock.Mock()
        self.mock_cert_sorter.reasons.get_product_reasons = mock.Mock(
            return_value=[])
        self.mock_cert_sorter.get_status = mock.Mock(return_value="subscribed")
        # Mock methods in calculator
        self.mock_calculator.calculate = mock.Mock()

        self.mock_calculator.calculate.return_value.begin = mock.Mock()
        self.mock_calculator.calculate.return_value.begin.return_value.astimezone = mock.Mock(
        )
        self.mock_calculator.calculate.return_value.begin.return_value.astimezone.return_value.strftime = mock.Mock(
            return_value='{d.day}.{d.month}.{d.year}'.format(d=START_DATE))
        self.mock_calculator.calculate.return_value.end = mock.Mock()
        self.mock_calculator.calculate.return_value.end.return_value.astimezone = mock.Mock(
        )
        self.mock_calculator.calculate.return_value.end.return_value.astimezone.return_value.strftime = mock.Mock(
            return_value='{d.day}.{d.month}.{d.year}'.format(d=END_DATE))

        expected_result = [
            (u'Red Hat Enterprise Linux Server - Extended Update Support',
             '70', u'7.2', u'x86_64', 'subscribed', [],
             '{d.day}.{d.month}.{d.year}'.format(d=START_DATE),
             '{d.day}.{d.month}.{d.year}'.format(d=END_DATE)),
        ]

        self.mock_cert_sorter.installed_products = {
            '69': self._create_rhel74_cert(),
            '70': self._create_rhel72_ues_cert()
        }

        result = products.InstalledProducts(self.mock_cp).list("*Extended*")

        self.assertEqual(expected_result, result)
Esempio n. 2
0
def show_autosubscribe_output(uep, identity):
    """
    Try to show auto-attach output
    :param uep: object with connection to candlepin
    :param identity: object with identity
    :return: return 1, when all installed products are subscribed, otherwise return 0
    """

    if is_simple_content_access(uep=uep, identity=identity):
        return 0

    installed_products = products.InstalledProducts(uep).list()

    if not installed_products:
        # Returning an error code here breaks registering when no products are installed, and the
        # AttachCommand already performs this check before calling.
        print(_("No products installed."))
        return 0

    log.debug("Attempted to auto-attach/heal the system.")
    print(_("Installed Product Current Status:"))
    subscribed = 1
    all_subscribed = True
    for product in installed_products:
        if product[4] == SUBSCRIBED:
            subscribed = 0
        status = STATUS_MAP[product[4]]
        if product[4] == NOT_SUBSCRIBED:
            all_subscribed = False
        print(columnize(PRODUCT_STATUS, echo_columnize_callback, product[0], status) + "\n")
    if not all_subscribed:
        print(_("Unable to find available subscriptions for all your installed products."))
    return subscribed
    def get_pools(self, pool_subsets=None, matches=None, pool_only=None, match_installed=None,
                  no_overlap=None, service_level=None, show_all=None, on_date=None, future=None,
                  after=None, **kwargs):
        # We accept a **kwargs argument so that the DBus object can pass whatever dictionary it receives
        # via keyword expansion.
        if kwargs:
            raise exceptions.ValidationError(_("Unknown arguments: %s") % kwargs.keys())

        if isinstance(pool_subsets, six.string_types):
            pool_subsets = [pool_subsets]

        # [] or None means look at all pools
        if not pool_subsets:
            pool_subsets = ['installed', 'consumed', 'available']

        options = {
            'pool_subsets': pool_subsets,
            'matches': matches,
            'pool_only': pool_only,
            'match_installed': match_installed,
            'no_overlap': no_overlap,
            'service_level': service_level,
            'show_all': show_all,
            'on_date': on_date,
            'future': future,
            'after': after,
        }
        self.validate_options(options)
        results = {}
        if 'installed' in pool_subsets:
            installed = products.InstalledProducts(self.cp).list(matches)
            results['installed'] = [x._asdict() for x in installed]
        if 'consumed' in pool_subsets:
            consumed = self.get_consumed_product_pools(service_level=service_level, matches=matches)
            if pool_only:
                results['consumed'] = [x._asdict()['pool_id'] for x in consumed]
            else:
                results['consumed'] = [x._asdict() for x in consumed]
        if 'available' in pool_subsets:
            available = self.get_available_pools(
                show_all=show_all,
                on_date=on_date,
                no_overlap=no_overlap,
                match_installed=match_installed,
                matches=matches,
                service_level=service_level,
                future=future,
                after=after,
            )
            if pool_only:
                results['available'] = [x['id'] for x in available]
            else:
                results['available'] = available

        return results
    def test_list_installed_products_without_filter(self):
        self.mock_cp.getConsumer.return_value = CONTENT_JSON
        self.mock_cert_sorter.reasons = mock.Mock()
        self.mock_cert_sorter.reasons.get_product_reasons = mock.Mock(
            return_value=[])
        self.mock_cert_sorter.get_status = mock.Mock(return_value="subscribed")
        # Mock methods in calculator
        self.mock_calculator.calculate = mock.Mock()

        self.mock_calculator.calculate.return_value.begin = mock.Mock()
        self.mock_calculator.calculate.return_value.begin.return_value.astimezone = mock.Mock(
        )
        self.mock_calculator.calculate.return_value.begin.return_value.astimezone.return_value.strftime = (
            mock.Mock(return_value="{d.day}.{d.month}.{d.year}".format(
                d=START_DATE)))
        self.mock_calculator.calculate.return_value.end = mock.Mock()
        self.mock_calculator.calculate.return_value.end.return_value.astimezone = mock.Mock(
        )
        self.mock_calculator.calculate.return_value.end.return_value.astimezone.return_value.strftime = (
            mock.Mock(return_value="{d.day}.{d.month}.{d.year}".format(
                d=END_DATE)))

        expected_result = [
            (
                "Red Hat Enterprise Linux Server",
                "69",
                "7.4",
                "x86_64",
                "subscribed",
                [],
                "{d.day}.{d.month}.{d.year}".format(d=START_DATE),
                "{d.day}.{d.month}.{d.year}".format(d=END_DATE),
            ),
            (
                "Red Hat Enterprise Linux Server - Extended Update Support",
                "70",
                "7.2",
                "x86_64",
                "subscribed",
                [],
                "{d.day}.{d.month}.{d.year}".format(d=START_DATE),
                "{d.day}.{d.month}.{d.year}".format(d=END_DATE),
            ),
        ]

        self.mock_cert_sorter.installed_products = {
            "69": self._create_rhel74_cert(),
            "70": self._create_rhel72_ues_cert(),
        }

        result = products.InstalledProducts(self.mock_cp).list()

        self.assertEqual(expected_result, result)
    def test_list_no_installed_products(self):
        self.mock_cp.getConsumer.return_value = NO_CONTENT_JSON
        self.mock_cert_sorter.installed_products = []

        result = products.InstalledProducts(self.mock_cp).list()
        self.assertEqual([], result)
Esempio n. 6
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
Esempio n. 7
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
Esempio n. 8
0
    def _do_command(self):
        """
        Executes the command.
        """
        self._validate_options()

        if self.options.installed and not self.options.pid_only:
            installed_products = products.InstalledProducts(self.cp).list(
                self.options.filter_string)

            if len(installed_products):
                print("+-------------------------------------------+")
                print(_("    Installed Product Status"))
                print("+-------------------------------------------+")

                for product in installed_products:
                    if is_simple_content_access(self.cp, self.identity):
                        print(
                            columnize(
                                INSTALLED_PRODUCT_STATUS_SCA,
                                none_wrap_columnize_callback,
                                product[0],  # Name
                                product[1],  # ID
                                product[2],  # Version
                                product[3],  # Arch
                            ) + "\n")
                    else:
                        status = STATUS_MAP[product[4]]
                        print(
                            columnize(
                                INSTALLED_PRODUCT_STATUS,
                                none_wrap_columnize_callback,
                                product[0],  # Name
                                product[1],  # ID
                                product[2],  # Version
                                product[3],  # Arch
                                status,  # Status
                                product[5],  # Status details
                                product[6],  # Start
                                product[7],  # End
                            ) + "\n")
            else:
                if self.options.filter_string:
                    print(
                        _('No installed products were found matching the expression "{filter}".'
                          ).format(filter=self.options.filter_string))
                else:
                    print(_("No installed products to list"))

        if self.options.available:
            self.assert_should_be_registered()
            on_date = None
            after_date = None
            if self.options.on_date:
                on_date = self._parse_date(self.options.on_date)
            elif self.options.after_date:
                after_date = self._parse_date(self.options.after_date)

            epools = entitlement.EntitlementService().get_available_pools(
                show_all=self.options.all,
                on_date=on_date,
                no_overlap=self.options.no_overlap,
                match_installed=self.options.match_installed,
                matches=self.options.filter_string,
                service_level=self.options.service_level,
                after_date=after_date,
            )

            if len(epools):
                if self.options.pid_only:
                    for data in epools:
                        print(data["id"])
                else:
                    print("+-------------------------------------------+")
                    print("    " + _("Available Subscriptions"))
                    print("+-------------------------------------------+")

                    for data in epools:
                        if PoolWrapper(data).is_virt_only():
                            entitlement_type = _("Virtual")
                        else:
                            entitlement_type = _("Physical")

                        if "management_enabled" in data and data[
                                "management_enabled"]:
                            data["management_enabled"] = _("Yes")
                        else:
                            data["management_enabled"] = _("No")

                        kwargs = {
                            "filter_string": self.options.filter_string,
                            "match_columns": AVAILABLE_SUBS_MATCH_COLUMNS,
                            "is_atty": sys.stdout.isatty(),
                        }
                        print(
                            columnize(
                                AVAILABLE_SUBS_LIST,
                                highlight_by_filter_string_columnize_cb,
                                data["productName"], data["providedProducts"],
                                data["productId"], data["contractNumber"]
                                or "", data["id"], data["management_enabled"],
                                data["quantity"], data["suggested"],
                                data["service_type"] or "",
                                self._split_mulit_value_field(
                                    data["roles"]), data["service_level"]
                                or "", data["usage"] or "",
                                self._split_mulit_value_field(data["addons"]),
                                data["pool_type"], data["startDate"],
                                data["endDate"], entitlement_type, **kwargs) +
                            "\n")
            elif not self.options.pid_only:
                if self.options.filter_string and self.options.service_level:
                    print(
                        _('No available subscription pools were found matching the expression "{filter}" and the service level "{level}".'
                          ).format(filter=self.options.filter_string,
                                   level=self.options.service_level))
                elif self.options.filter_string:
                    print(
                        _('No available subscription pools were found matching the expression "{filter}".'
                          ).format(filter=self.options.filter_string))
                elif self.options.service_level:
                    print(
                        _('No available subscription pools were found matching the service level "{level}".'
                          ).format(level=self.options.service_level))
                else:
                    print(_("No available subscription pools to list"))

        if self.options.consumed:
            self.print_consumed(
                service_level=self.options.service_level,
                filter_string=self.options.filter_string,
                pid_only=self.options.pid_only,
            )
    def get_pools(self,
                  pool_subsets=None,
                  matches=None,
                  pool_only=None,
                  match_installed=None,
                  no_overlap=None,
                  service_level=None,
                  show_all=None,
                  on_date=None,
                  future=None,
                  after_date=None,
                  page=0,
                  items_per_page=0,
                  **kwargs):
        # We accept a **kwargs argument so that the DBus object can pass whatever dictionary it receives
        # via keyword expansion.
        if kwargs:
            raise exceptions.ValidationError(
                _("Unknown arguments: %s") % kwargs.keys())

        if isinstance(pool_subsets, str):
            pool_subsets = [pool_subsets]

        # [] or None means look at all pools
        if not pool_subsets:
            pool_subsets = ["installed", "consumed", "available"]

        options = {
            "pool_subsets": pool_subsets,
            "matches": matches,
            "pool_only": pool_only,
            "match_installed": match_installed,
            "no_overlap": no_overlap,
            "service_level": service_level,
            "show_all": show_all,
            "on_date": on_date,
            "future": future,
            "after_date": after_date,
        }
        self.validate_options(options)
        results = {}
        if "installed" in pool_subsets:
            installed = products.InstalledProducts(self.cp).list(
                matches, iso_dates=True)
            results["installed"] = [x._asdict() for x in installed]
        if "consumed" in pool_subsets:
            consumed = self.get_consumed_product_pools(
                service_level=service_level, matches=matches, iso_dates=True)
            if pool_only:
                results["consumed"] = [
                    x._asdict()["pool_id"] for x in consumed
                ]
            else:
                results["consumed"] = [x._asdict() for x in consumed]
        if "available" in pool_subsets:
            available = self.get_available_pools(
                show_all=show_all,
                on_date=on_date,
                no_overlap=no_overlap,
                match_installed=match_installed,
                matches=matches,
                service_level=service_level,
                future=future,
                after_date=after_date,
                page=int(page),
                items_per_page=int(items_per_page),
                iso_dates=True,
            )
            if pool_only:
                results["available"] = [x["id"] for x in available]
            else:
                results["available"] = available

        return results