def getInstalledProductStatus(product_directory, entitlement_directory, facts=None): """ Returns the Installed products and their subscription states """ # allow us to stub this out for testing if facts is None: facts = Facts().get_facts() product_status = [] sorter = CertSorter(product_directory, entitlement_directory, facts) for installed_product in sorter.installed_products: product_cert = sorter.installed_products[installed_product] for product in product_cert.products: begin = "" end = "" calculator = ValidProductDateRangeCalculator(sorter) prod_status_range = calculator.calculate(product.id) if prod_status_range: # Format the date in user's local time as the date # range is returned in GMT. begin = formatDate(prod_status_range.begin()) end = formatDate(prod_status_range.end()) data = (product.name, installed_product, product.version, ",".join(product.architectures), sorter.get_status(product.id), begin, end) product_status.append(data) return product_status
def get_releases(self): # cdn base url # let us pass in a facts object for testing if not self.facts: self.facts = Facts(ent_dir=self.entitlement_dir, prod_dir=self.product_dir) # find entitlements for rhel product? (or vice versa) sorter = CertSorter(self.product_dir, self.entitlement_dir, self.facts.get_facts()) # find the rhel product rhel_product = None for product_hash in sorter.installed_products: product_cert = sorter.installed_products[product_hash] products = product_cert.products for product in products: product_tags = product.provided_tags if self._is_rhel(product_tags): rhel_product = product if rhel_product is None: return [] entitlements = sorter.get_entitlements_for_product(rhel_product.id) listings = [] for entitlement in entitlements: contents = entitlement.content for content in contents: # ignore content that is not enabled # see bz #820639 if not content.enabled: continue if self._is_correct_rhel(rhel_product.provided_tags, content.required_tags): content_url = content.url listing_parts = content_url.split('$releasever', 1) listing_base = listing_parts[0] listing_path = "%s/listing" % listing_base listings.append(listing_path) # FIXME: not sure how to get the "base" content if we have multiple # entitlements for a product # for a entitlement, gran the corresponding entitlement cert # use it for this connection # hmm. We are really only supposed to have one product # with one content with one listing file. We shall see. releases = [] listings = sorted(set(listings)) for listing_path in listings: data = self.content_connection.get_versions(listing_path) ver_listing = listing.ListingFile(data=data) releases = releases + ver_listing.get_releases() releases_set = sorted(set(releases)) return releases_set
def test_unregistered_system_status(self, mock_update): self.status_mgr.load_status = Mock(return_value=None) self.status_mgr.server_status = None sorter = CertSorter() sorter.is_registered = Mock(return_value=False) expected = subscription_manager.cert_sorter.STATUS_MAP['unknown'] self.assertEqual(expected, sorter.get_system_status())
def test_unregistered_system_status(self, mock_update): self.status_mgr.load_status = Mock( return_value=None) sorter = CertSorter() sorter.is_registered = Mock(return_value=False) expected = subscription_manager.cert_sorter.STATUS_MAP['unknown'] self.assertEqual(expected, sorter.get_system_status())
def setUp(self, mock_update): SubManFixture.setUp(self) # Setup mock product and entitlement certs: self.prod_dir = StubProductDirectory( pids=[INST_PID_1, INST_PID_2, INST_PID_3, INST_PID_4]) self.ent_dir = StubEntitlementDirectory([ StubEntitlementCertificate(PROD_2, ent_id=ENT_ID_2), StubEntitlementCertificate(PROD_1, ent_id=ENT_ID_1), StubEntitlementCertificate(product=PROD_4, stacking_id=STACK_1, ent_id=ENT_ID_4), # entitled, but not installed StubEntitlementCertificate(StubProduct("not_installed_product", name="Some Product"), ent_id="SomeSubId"), ]) self.mock_uep = StubUEP() self.status_mgr = EntitlementStatusCache() self.status_mgr.load_status = Mock(return_value=SAMPLE_COMPLIANCE_JSON) self.status_mgr.write_cache = Mock() inj.provide(inj.ENTITLEMENT_STATUS_CACHE, self.status_mgr) inj.provide(inj.PROD_DIR, self.prod_dir) inj.provide(inj.ENT_DIR, self.ent_dir) self.sorter = CertSorter() self.sorter.is_registered = Mock(return_value=True)
def test_no_usable_status(self, mock_update): self.status_mgr.load_status = Mock( return_value=None) self.status_mgr.server_status = None sorter = CertSorter() sorter.is_registered = Mock(return_value=True) self.assertEqual(UNKNOWN, sorter.get_status(INST_PID_1))
def test_unregistered_system_status(self, mock_update): self.status_mgr.load_status = Mock(return_value=None) self.status_mgr.server_status = None sorter = CertSorter() sorter.is_registered = Mock(return_value=False) status_map = subscription_manager.cert_sorter.ComplianceManager.get_status_map( ) expected = status_map[subscription_manager.cert_sorter.UNKNOWN] self.assertEqual(expected, sorter.get_system_status())
def test_expired_in_future(self): self.sorter = CertSorter(self.prod_dir, self.ent_dir, {}, on_date=datetime(2050, 1, 1, tzinfo=GMT())) self.assertEqual(5, len(self.sorter.expired_entitlement_certs)) self.assertTrue(INST_PID_2 in self.sorter.expired_products) self.assertTrue(INST_PID_3 in self.sorter.expired_products) self.assertFalse(INST_PID_4 in self.sorter.expired_products) # it's not installed self.assertTrue(INST_PID_1 in self.sorter.unentitled_products) self.assertEqual(0, len(self.sorter.valid_entitlement_certs)) self.assertFalse(self.sorter.is_valid())
def test_ent_cert_no_product(self): self.ent_dir = StubCertificateDirectory( [StubEntitlementCertificate(None, provided_products=[], quantity=2)]) stub_facts = StubFacts(fact_dict={"cpu.cpu_socket(s)": 42}) self.sorter = CertSorter(self.prod_dir, self.ent_dir, stub_facts.get_facts()) self.assertEqual(0, len(self.sorter.partially_valid_products))
def test_expired(self): self.sorter = CertSorter(self.prod_dir, self.ent_dir, {}) self.assertEqual(1, len(self.sorter.expired_entitlement_certs)) self.assertTrue(cert_list_has_product( self.sorter.expired_entitlement_certs, INST_PID_3)) self.assertEqual(1, len(self.sorter.expired_products.keys())) self.assertTrue(INST_PID_3 in self.sorter.expired_products) self.assertFalse(self.sorter.is_valid()) self.assertEquals(EXPIRED, self.sorter.get_status(INST_PID_3))
def test_entitled_products(self): provided = [StubProduct(INST_PID_1), StubProduct(INST_PID_2), StubProduct(INST_PID_3)] self.ent_dir = StubCertificateDirectory([ StubEntitlementCertificate(StubProduct(INST_PID_5), provided_products=provided)]) self.sorter = CertSorter(self.prod_dir, self.ent_dir, {}) self.assertEquals(3, len(self.sorter.valid_products.keys())) self.assertTrue(INST_PID_1 not in self.sorter.partially_valid_products) self.assertTrue(INST_PID_1 in self.sorter.valid_products) self.assertTrue(INST_PID_2 in self.sorter.valid_products) self.assertTrue(INST_PID_3 in self.sorter.valid_products) self.assertTrue(self.sorter.is_valid())
def test_expired_but_provided_in_another_entitlement(self): self.ent_dir = StubCertificateDirectory([ StubEntitlementCertificate(StubProduct(INST_PID_5), provided_products=[StubProduct(INST_PID_3)]), StubEntitlementCertificate(StubProduct(INST_PID_5), start_date=datetime.now() - timedelta(days=365), end_date=datetime.now() - timedelta(days=2), provided_products=[StubProduct(INST_PID_3)]), StubEntitlementCertificate(StubProduct(INST_PID_4)) ]) self.sorter = CertSorter(self.prod_dir, self.ent_dir, {}) self.assertEquals(1, len(self.sorter.valid_products.keys())) self.assertTrue(INST_PID_3 in self.sorter.valid_products) self.assertEquals(0, len(self.sorter.expired_products.keys()))
def test_no_compliant_until(self, mock_update): # don't want to munge the module scope version of this because # setup will load it for later tests no_compliance_until = copy.deepcopy(SAMPLE_COMPLIANCE_JSON) no_compliance_until["compliantUntil"] = None # build and inject a status cache with new values status_mgr = EntitlementStatusCache() status_mgr.load_status = Mock(return_value=no_compliance_until) status_mgr.write_cache = Mock() inj.provide(inj.ENTITLEMENT_STATUS_CACHE, status_mgr) self.sorter = CertSorter() self.sorter.is_registered = Mock(return_value=True) self.assertTrue(self.sorter.compliant_until is None)
def load(self): consumer_json = self.backend.uep.getConsumer( self.consumer.getConsumerId()) if 'serviceLevel' not in consumer_json: raise ServiceLevelNotSupportedException() self.owner_key = consumer_json['owner']['key'] # This is often "", set to None in that case: self.current_sla = consumer_json['serviceLevel'] or None # Using the current date time, we may need to expand this to work # with arbitrary dates for future entitling someday: self.sorter = CertSorter(self.backend.product_dir, self.backend.entitlement_dir, self.facts.get_facts()) if len(self.sorter.installed_products) == 0: raise NoProductsException() if len(self.sorter.unentitled_products) == 0: raise AllProductsCoveredException() self._find_suitable_service_levels()
def check_status(force_signal): if force_signal is not None: debug("forcing status signal from cli arg") return force_signal if ClassicCheck().is_registered_with_classic(): debug("System is already registered to another entitlement system") return RHN_CLASSIC if not ConsumerIdentity.existsAndValid(): debug("The system is not currently registered.") return RHSM_REGISTRATION_REQUIRED facts = Facts() sorter = CertSorter(certdirectory.ProductDirectory(), certdirectory.EntitlementDirectory(), facts.get_facts()) if len(sorter.unentitled_products.keys()) > 0 or len( sorter.expired_products.keys()) > 0: debug("System has one or more certificates that are not valid") debug(sorter.unentitled_products.keys()) debug(sorter.expired_products.keys()) return RHSM_EXPIRED elif len(sorter.partially_valid_products) > 0: debug("System has one or more partially entitled products") return RHSM_PARTIALLY_VALID elif in_warning_period(sorter): debug("System has one or more entitlements in their warning period") return RHSM_WARNING else: debug("System entitlements appear valid") return RHSM_VALID
def test_missing_installed_product(self, mock_update): # Add a new installed product server doesn't know about: prod_dir = StubProductDirectory( pids=[INST_PID_1, INST_PID_2, INST_PID_3, "product4"]) inj.provide(inj.PROD_DIR, prod_dir) sorter = CertSorter() self.assertTrue("product4" in sorter.unentitled_products)
def setUp(self, mock_update): SubManFixture.setUp(self) # Setup mock product and entitlement certs: self.prod_dir = StubProductDirectory( pids=[INST_PID_1, INST_PID_2, INST_PID_3, INST_PID_4]) self.ent_dir = StubEntitlementDirectory([ StubEntitlementCertificate(PROD_2, ent_id=ENT_ID_2), StubEntitlementCertificate(PROD_1, ent_id=ENT_ID_1), StubEntitlementCertificate(product=PROD_4, stacking_id=STACK_1, ent_id=ENT_ID_4), # entitled, but not installed StubEntitlementCertificate(StubProduct('not_installed_product', name="Some Product"), ent_id="SomeSubId"), ]) self.mock_uep = StubUEP() self.status_mgr = EntitlementStatusCache() self.status_mgr.load_status = Mock( return_value=SAMPLE_COMPLIANCE_JSON) self.status_mgr.write_cache = Mock() inj.provide(inj.ENTITLEMENT_STATUS_CACHE, self.status_mgr) inj.provide(inj.PROD_DIR, self.prod_dir) inj.provide(inj.ENT_DIR, self.ent_dir) self.sorter = CertSorter() self.sorter.is_registered = Mock(return_value=True)
def test_partial_stack_for_uninstalled_products(self): # No products installed: prod_dir = StubCertificateDirectory([]) stub_facts = StubFacts(fact_dict={"cpu.cpu_socket(s)": 42}) ents = [] ents.append( stub_ent_cert(INST_PID_5, ['prod1'], stack_id=STACK_1, quantity=2)) ent_dir = StubCertificateDirectory(ents) sorter = CertSorter(prod_dir, ent_dir, stub_facts.get_facts()) # No installed products, so nothing should show up as partially valid: self.assertEquals(0, len(sorter.partially_valid_products)) self.assertEquals(1, len(sorter.partial_stacks)) self.assertTrue(STACK_1 in sorter.partial_stacks) self.assertFalse(sorter.is_valid())
def test_future_entitled(self): provided = [StubProduct(INST_PID_2), StubProduct(INST_PID_3)] self.ent_dir = StubCertificateDirectory([ StubEntitlementCertificate(StubProduct(INST_PID_5), provided_products=provided, start_date=datetime.now() + timedelta(days=30), end_date=datetime.now() + timedelta(days=120)), ]) self.sorter = CertSorter(self.prod_dir, self.ent_dir, {}) self.assertEquals(0, len(self.sorter.valid_products)) self.assertEquals(2, len(self.sorter.future_products)) self.assertEquals(3, len(self.sorter.unentitled_products)) self.assertTrue(INST_PID_2 in self.sorter.future_products) self.assertTrue(INST_PID_3 in self.sorter.future_products) self.assertEquals(FUTURE_SUBSCRIBED, self.sorter.get_status(INST_PID_2)) self.assertEquals(FUTURE_SUBSCRIBED, self.sorter.get_status(INST_PID_3))
def test_partial_stack_for_uninstalled_products(self): # No products installed: prod_dir = StubCertificateDirectory([]) stub_facts = StubFacts(fact_dict={"cpu.cpu_socket(s)": 42}) ents = [] ents.append(stub_ent_cert(INST_PID_5, ['prod1'], stack_id=STACK_1, quantity=2)) ent_dir = StubCertificateDirectory(ents) sorter = CertSorter(prod_dir, ent_dir, stub_facts.get_facts()) # No installed products, so nothing should show up as partially valid: self.assertEquals(0, len(sorter.partially_valid_products)) self.assertEquals(1, len(sorter.partial_stacks)) self.assertTrue(STACK_1 in sorter.partial_stacks) self.assertFalse(sorter.is_valid())
def _set_validity_status(self): """ Updates the entitlement validity status portion of the UI. """ if ClassicCheck().is_registered_with_classic(): self._set_status_icons(VALID) self.subscription_status_label.set_text( get_branding().RHSMD_REGISTERED_TO_OTHER) return is_registered = self.consumer.is_valid() self.set_registered(is_registered) # Look for products which have invalid entitlements sorter = CertSorter(self.product_dir, self.entitlement_dir, self.facts.get_facts()) warn_count = len(sorter.expired_products) + \ len(sorter.unentitled_products) partial_count = len(sorter.partially_valid_products) if warn_count > 0: self._set_status_icons(INVALID) # Change wording slightly for just one product if warn_count > 1: self.subscription_status_label.set_markup( _("%s installed products do not have valid subscriptions.") % warn_count) else: self.subscription_status_label.set_markup( _("1 installed product does not have a valid subscription." )) elif partial_count > 0: self._set_status_icons(PARTIAL) self.subscription_status_label.set_markup( _("This system does not match subscription limits.")) else: first_invalid = find_first_invalid_date(self.entitlement_dir, self.product_dir, self.facts.get_facts()) self._set_status_icons(VALID) if first_invalid: self.subscription_status_label.set_markup( _("System is properly subscribed through %s.") % \ managerlib.formatDate(first_invalid)) else: # No product certs installed, no first invalid date, and # the subscription assistant can't do anything, so we'll disable # the button to launch it: self.subscription_status_label.set_text( _("No installed products detected.")) if not is_registered: self.subscription_status_label.set_text( _("Keep your system up to date by registering."))
def test_installed_mismatch_unentitled(self, mock_update): # Use a different product directory with something not present # in the response from the server as an unentitled product: prod_dir = StubProductDirectory(pids=[INST_PID_1, INST_PID_2]) inj.provide(inj.PROD_DIR, prod_dir) sorter = CertSorter() self.assertFalse(INST_PID_3 in sorter.installed_products) # Should get filtered out of unentitled products even though # server reported it here: self.assertFalse(INST_PID_3 in sorter.unentitled_products)
def test_multi_product_entitlement_expired(self): # Setup one ent cert that provides several things installed # installed: provided = [StubProduct(INST_PID_2), StubProduct(INST_PID_3)] self.ent_dir = StubCertificateDirectory([ StubEntitlementCertificate(StubProduct(INST_PID_5), provided_products=provided)]) self.sorter = CertSorter(self.prod_dir, self.ent_dir, {}, on_date=datetime(2050, 1, 1, tzinfo=GMT())) self.assertEquals(1, len(self.sorter.expired_entitlement_certs)) self.assertEquals(2, len(self.sorter.expired_products.keys())) self.assertTrue(INST_PID_2 in self.sorter.expired_products) self.assertTrue(INST_PID_3 in self.sorter.expired_products) # Expired should not show up as unentitled also: self.assertEquals(1, len(self.sorter.unentitled_products.keys())) self.assertTrue(INST_PID_1 in self.sorter.unentitled_products) self.assertFalse(self.sorter.is_valid())
def getInstalledProductStatus(product_directory=None, entitlement_directory=None, facts=None): """ Returns the Installed products and their subscription states """ # allow us to stub these out for testing if product_directory is None: product_directory = certdirectory.ProductDirectory() if entitlement_directory is None: entitlement_directory = certdirectory.EntitlementDirectory() if facts is None: facts = Facts().get_facts() product_status = [] sorter = CertSorter(product_directory, entitlement_directory, facts) for installed_product in sorter.installed_products: product_cert = sorter.installed_products[installed_product] for product in product_cert.getProducts(): begin = "" end = "" calculator = ValidProductDateRangeCalculator(sorter) prod_status_range = calculator.calculate(product.getHash()) if prod_status_range: # Format the date in user's local time as the date # range is returned in GMT. begin = formatDate(prod_status_range.begin()) end = formatDate(prod_status_range.end()) data = (product.getName(), installed_product, product.getVersion(), product.getArch(), sorter.get_status(product.getHash()), begin, end) product_status.append(data) return product_status
def test_simple_full_stack_0_sockets(self): prod_dir = StubCertificateDirectory([stub_prod_cert(INST_PID_1)]) # System has 1 sockets: stub_facts = StubFacts(fact_dict={"cpu.cpu_socket(s)": 1}) # 0 sockets is basically "unlimited" sockets # see bz#805415 ent_dir = StubCertificateDirectory([ stub_ent_cert(INST_PID_5, [INST_PID_1], stack_id=STACK_1, sockets=0)]) sorter = CertSorter(prod_dir, ent_dir, stub_facts.get_facts()) self.assertTrue(INST_PID_1 in sorter.valid_products) self.assertFalse(INST_PID_1 in sorter.partially_valid_products) self.assertFalse(INST_PID_1 in sorter.unentitled_products)
def test_simple_partial_stack(self): prod_dir = StubCertificateDirectory([stub_prod_cert(INST_PID_1)]) # System has 8 sockets: stub_facts = StubFacts(fact_dict={"cpu.cpu_socket(s)": 8}) # Only 2 sockets covered: ent_dir = StubCertificateDirectory([ stub_ent_cert(INST_PID_5, [INST_PID_1], stack_id=STACK_1, sockets=2)]) sorter = CertSorter(prod_dir, ent_dir, stub_facts.get_facts()) self.assertFalse(INST_PID_1 in sorter.unentitled_products) self.assertFalse(INST_PID_1 in sorter.valid_products) self.assertTrue(INST_PID_1 in sorter.partially_valid_products) self.assertEquals(1, len(sorter.partially_valid_products)) self.assertEquals(1, len(sorter.partially_valid_products[INST_PID_1]))
def test_non_stacked_lacking_sockets(self): prod_dir = StubCertificateDirectory([stub_prod_cert(INST_PID_1)]) # System has 8 sockets: stub_facts = StubFacts(fact_dict={"cpu.cpu_socket(s)": 8}) # Only 2 sockets covered by a non-stacked entitlement: ent_dir = StubCertificateDirectory( [stub_ent_cert(INST_PID_5, [INST_PID_1], sockets=2, quantity=5)]) sorter = CertSorter(prod_dir, ent_dir, stub_facts.get_facts()) self.assertFalse(INST_PID_1 in sorter.unentitled_products) self.assertFalse(INST_PID_1 in sorter.valid_products) self.assertTrue(INST_PID_1 in sorter.partially_valid_products) self.assertEquals(1, len(sorter.partially_valid_products)) self.assertEquals(1, len(sorter.partially_valid_products[INST_PID_1]))
def test_simple_full_stack_singlecert_with_quantity(self): prod_dir = StubCertificateDirectory([stub_prod_cert(INST_PID_1)]) # System has 8 sockets: stub_facts = StubFacts(fact_dict={"cpu.cpu_socket(s)": 8}) # 1 ent cert providing 4 sockets with quantity 2 means we're valid: ent_dir = StubCertificateDirectory([ stub_ent_cert(INST_PID_5, [INST_PID_1], stack_id=STACK_1, sockets=4, quantity=2)]) sorter = CertSorter(prod_dir, ent_dir, stub_facts.get_facts()) self.assertFalse(INST_PID_1 in sorter.unentitled_products) self.assertTrue(INST_PID_1 in sorter.valid_products) self.assertFalse(INST_PID_1 in sorter.partially_valid_products) self.assertEquals(0, len(sorter.partially_valid_products))
def test_no_compliant_until(self, mock_update): # don't want to munge the module scope version of this because # setup will load it for later tests no_compliance_until = copy.deepcopy(SAMPLE_COMPLIANCE_JSON) no_compliance_until['compliantUntil'] = None # build and inject a status cache with new values status_mgr = EntitlementStatusCache() status_mgr.load_status = Mock(return_value=no_compliance_until) status_mgr.write_cache = Mock() inj.provide(inj.ENTITLEMENT_STATUS_CACHE, status_mgr) self.sorter = CertSorter() self.sorter.is_registered = Mock(return_value=True) self.assertTrue(self.sorter.compliant_until is None)
def _find_suitable_service_levels(self, consumer, facts): consumer_json = self.backend.uep.getConsumer(consumer.getConsumerId()) if 'serviceLevel' not in consumer_json: raise ServiceLevelNotSupportedException() owner_key = consumer_json['owner']['key'] # This is often "", set to None in that case: current_sla = consumer_json['serviceLevel'] or None # Using the current date time, we may need to expand this to work # with arbitrary dates for future entitling someday: sorter = CertSorter(self.backend.product_dir, self.backend.entitlement_dir, facts.get_facts()) if len(sorter.installed_products) == 0: raise NoProductsException() if len(sorter.unentitled_products) == 0: raise AllProductsCoveredException() if current_sla: available_slas = [current_sla] log.debug("Using system's current service level: %s" % current_sla) else: available_slas = self.backend.uep.getServiceLevelList(owner_key) log.debug("Available service levels: %s" % available_slas) # Will map service level (string) to the results of the dry-run # autobind results for each SLA that covers all installed products: suitable_slas = {} certmgr = CertManager(uep=self.backend.uep) certmgr.update() for sla in available_slas: dry_run_json = self.backend.uep.dryRunBind(consumer.uuid, sla) dry_run = DryRunResult(sla, dry_run_json, sorter) # If we have a current SLA for this system, we do not need # all products to be covered by the SLA to proceed through # this wizard: if current_sla or dry_run.covers_required_products(): suitable_slas[sla] = dry_run return (current_sla, sorter.unentitled_products.values(), suitable_slas)
def test_partial_stack_different_first_product(self): prod_dir = StubCertificateDirectory([stub_prod_cert(INST_PID_1)]) stub_facts = StubFacts(fact_dict={"cpu.cpu_socket(s)": 4}) ents = [] ents.append(stub_ent_cert(INST_PID_5, [INST_PID_1], stack_id=STACK_1, sockets=1)) ents.append(stub_ent_cert(INST_PID_6, [INST_PID_1], stack_id=STACK_1, sockets=1)) ent_dir = StubCertificateDirectory(ents) sorter = CertSorter(prod_dir, ent_dir, stub_facts.get_facts()) # Installed product should show up as partially valid: self.assertEquals(1, len(sorter.partially_valid_products)) self.assertTrue(INST_PID_1 in sorter.partially_valid_products) self.assertFalse(INST_PID_1 in sorter.valid_products) self.assertTrue(STACK_1 in sorter.partial_stacks)
def test_valid_stack_different_first_products(self): prod_dir = StubCertificateDirectory([stub_prod_cert(INST_PID_1)]) stub_facts = StubFacts(fact_dict={"cpu.cpu_socket(s)": 4}) # Two entitlements, same stack, different first products, each # providing 2 sockets: (should be valid) ents = [] ents.append(stub_ent_cert(INST_PID_5, [INST_PID_1], stack_id=STACK_1, sockets=2)) ents.append(stub_ent_cert(INST_PID_6, [INST_PID_1], stack_id=STACK_1, sockets=2)) ent_dir = StubCertificateDirectory(ents) sorter = CertSorter(prod_dir, ent_dir, stub_facts.get_facts()) # Installed product should show up as valid: self.assertEquals(1, len(sorter.valid_products)) self.assertTrue(INST_PID_1 in sorter.valid_products) self.assertEquals(0, len(sorter.partially_valid_products)) self.assertEquals(0, len(sorter.partial_stacks))
def _set_validity_status(self): """ Updates the entitlement validity status portion of the UI. """ if ClassicCheck().is_registered_with_classic(): self._set_status_icons(VALID) self.subscription_status_label.set_text( _("This system is registered to RHN Classic")) return is_registered = ConsumerIdentity.existsAndValid() self.set_registered(is_registered) # Look for products which have invalid entitlements sorter = CertSorter(self.product_dir, self.entitlement_dir, self.facts.get_facts()) warn_count = len(sorter.expired_products) + \ len(sorter.unentitled_products) partial_count = len(sorter.partially_valid_products) if warn_count > 0: self._set_status_icons(INVALID) # Change wording slightly for just one product if warn_count > 1: self.subscription_status_label.set_markup( _("You have <b>%s</b> products with <i>invalid</i> entitlement certificates." ) % warn_count) else: self.subscription_status_label.set_markup( _("You have <b>1</b> product with an <i>invalid</i> entitlement certificate." )) elif partial_count > 0: self._set_status_icons(PARTIAL) # Change wording slightly for just one product if partial_count > 1: self.subscription_status_label.set_markup( _("You have <b>%s</b> products in need of <i>additional</i> entitlement certificates." ) % partial_count) else: self.subscription_status_label.set_markup( _("You have <b>1</b> product in need of <i>additional</i> entitlement certificates." )) else: first_invalid = find_first_invalid_date(self.entitlement_dir, self.product_dir, self.facts.get_facts()) self._set_status_icons(VALID) if first_invalid: self.subscription_status_label.set_markup( _("Product entitlement certificates <i>valid</i> until %s") % \ managerlib.formatDate(first_invalid)) else: # No product certs installed, no first invalid date, and # the subscription assistant can't do anything, so we'll disable # the button to launch it: self.subscription_status_label.set_text( _("No product certificates installed.")) if not is_registered: self.subscription_status_label.set_text( _("You must register this system before subscribing."))
def test_unregistered_status(self, mock_update): sorter = CertSorter() sorter.is_registered = Mock(return_value=False) self.assertEqual(UNKNOWN, sorter.get_status(INST_PID_1))
class CertSorterTests(SubManFixture): @patch('subscription_manager.cache.InstalledProductsManager.update_check') def setUp(self, mock_update): SubManFixture.setUp(self) # Setup mock product and entitlement certs: self.prod_dir = StubProductDirectory( pids=[INST_PID_1, INST_PID_2, INST_PID_3, INST_PID_4]) self.ent_dir = StubEntitlementDirectory([ StubEntitlementCertificate(PROD_2, ent_id=ENT_ID_2), StubEntitlementCertificate(PROD_1, ent_id=ENT_ID_1), StubEntitlementCertificate(product=PROD_4, stacking_id=STACK_1, ent_id=ENT_ID_4), # entitled, but not installed StubEntitlementCertificate(StubProduct('not_installed_product', name="Some Product"), ent_id="SomeSubId"), ]) self.mock_uep = StubUEP() self.status_mgr = EntitlementStatusCache() self.status_mgr.load_status = Mock( return_value=SAMPLE_COMPLIANCE_JSON) self.status_mgr.write_cache = Mock() inj.provide(inj.ENTITLEMENT_STATUS_CACHE, self.status_mgr) inj.provide(inj.PROD_DIR, self.prod_dir) inj.provide(inj.ENT_DIR, self.ent_dir) self.sorter = CertSorter() self.sorter.is_registered = Mock(return_value=True) @patch('subscription_manager.cache.InstalledProductsManager.update_check') def test_unregistered_status(self, mock_update): sorter = CertSorter() sorter.is_registered = Mock(return_value=False) self.assertEqual(UNKNOWN, sorter.get_status(INST_PID_1)) # Server doesn't support compliance API, or server is unreachable and # we cannot use the cache for some reason. @patch('subscription_manager.cache.InstalledProductsManager.update_check') def test_no_usable_status(self, mock_update): self.status_mgr.load_status = Mock( return_value=None) sorter = CertSorter() sorter.is_registered = Mock(return_value=True) self.assertEqual(UNKNOWN, sorter.get_status(INST_PID_1)) # Consumer has been deleted, overall status should be unknown @patch('subscription_manager.cache.InstalledProductsManager.update_check') def test_deleted_consumer_status(self, mock_update): self.status_mgr.load_status = Mock( return_value=None) sorter = CertSorter() sorter.is_registered = Mock(return_value=True) expected = subscription_manager.cert_sorter.STATUS_MAP['unknown'] self.assertEqual(expected, sorter.get_system_status()) @patch('subscription_manager.cache.InstalledProductsManager.update_check') def test_unregistered_system_status(self, mock_update): self.status_mgr.load_status = Mock( return_value=None) sorter = CertSorter() sorter.is_registered = Mock(return_value=False) expected = subscription_manager.cert_sorter.STATUS_MAP['unknown'] self.assertEqual(expected, sorter.get_system_status()) def test_unentitled_products(self): self.assertEqual(1, len(self.sorter.unentitled_products)) self.assertTrue(INST_PID_3 in self.sorter.unentitled_products) def test_valid_products(self): self.assertEqual(1, len(self.sorter.valid_products)) self.assertTrue(INST_PID_1 in self.sorter.valid_products) def test_partially_valid_products(self): self.assertEqual(2, len(self.sorter.partially_valid_products)) self.assertTrue(INST_PID_2 in self.sorter.partially_valid_products) self.assertTrue(INST_PID_4 in self.sorter.partially_valid_products) def test_installed_products(self): self.assertEqual(4, len(self.sorter.installed_products)) self.assertTrue(INST_PID_1 in self.sorter.installed_products) self.assertTrue(INST_PID_2 in self.sorter.installed_products) self.assertTrue(INST_PID_3 in self.sorter.installed_products) self.assertTrue(INST_PID_3 in self.sorter.installed_products) def test_partial_stack(self): self.assertEqual(1, len(self.sorter.partial_stacks)) self.assertTrue(PARTIAL_STACK_ID in self.sorter.partial_stacks) def test_reasons(self): self.assertEqual(5, len(self.sorter.reasons.reasons)) expected_keys = ['NOTCOVERED', 'CORES', 'SOCKETS', 'RAM', 'ARCH'] result_keys = [reason['key'] for reason in self.sorter.reasons.reasons] self.assertEqual(sorted(expected_keys), sorted(result_keys)) @patch('subscription_manager.cache.InstalledProductsManager.update_check') def test_installed_mismatch_unentitled(self, mock_update): # Use a different product directory with something not present # in the response from the server as an unentitled product: prod_dir = StubProductDirectory( pids=[INST_PID_1, INST_PID_2]) inj.provide(inj.PROD_DIR, prod_dir) sorter = CertSorter() self.assertFalse(INST_PID_3 in sorter.installed_products) # Should get filtered out of unentitled products even though # server reported it here: self.assertFalse(INST_PID_3 in sorter.unentitled_products) @patch('subscription_manager.cache.InstalledProductsManager.update_check') def test_missing_installed_product(self, mock_update): # Add a new installed product server doesn't know about: prod_dir = StubProductDirectory(pids=[INST_PID_1, INST_PID_2, INST_PID_3, "product4"]) inj.provide(inj.PROD_DIR, prod_dir) sorter = CertSorter() self.assertTrue('product4' in sorter.unentitled_products) @patch('subscription_manager.cache.InstalledProductsManager.update_check') def test_no_compliant_until(self, mock_update): # don't want to munge the module scope version of this because # setup will load it for later tests no_compliance_until = copy.deepcopy(SAMPLE_COMPLIANCE_JSON) no_compliance_until['compliantUntil'] = None # build and inject a status cache with new values status_mgr = EntitlementStatusCache() status_mgr.load_status = Mock(return_value=no_compliance_until) status_mgr.write_cache = Mock() inj.provide(inj.ENTITLEMENT_STATUS_CACHE, status_mgr) self.sorter = CertSorter() self.sorter.is_registered = Mock(return_value=True) self.assertTrue(self.sorter.compliant_until is None) def test_compliant_until(self): compliant_until = self.sorter.compliant_until self.assertEqual(2013, compliant_until.year) self.assertEqual(4, compliant_until.month) self.assertEqual(26, compliant_until.day) self.assertEqual(13, compliant_until.hour) self.assertEqual(43, compliant_until.minute) self.assertEqual(12, compliant_until.second) def test_scan_for_expired_or_future_products(self): prod_dir = StubProductDirectory(pids=["a", "b", "c", "d", "e"]) ent_dir = StubEntitlementDirectory([ StubEntitlementCertificate(StubProduct("a")), StubEntitlementCertificate(StubProduct("b")), StubEntitlementCertificate(StubProduct("c")), StubEntitlementCertificate(StubProduct("d"), start_date=datetime.now() - timedelta(days=365), end_date=datetime.now() - timedelta(days=2)), StubEntitlementCertificate(StubProduct("e"), start_date=datetime.now() + timedelta(days=365), end_date=datetime.now() + timedelta(days=730)), ]) inj.provide(inj.PROD_DIR, prod_dir) inj.provide(inj.ENT_DIR, ent_dir) sorter = StubCertSorter() sorter.valid_products = {"a": StubProduct("a")} sorter.partially_valid_products = {"b": StubProduct("b")} sorter._scan_entitlement_certs() self.assertEqual(["d"], list(sorter.expired_products.keys())) self.assertEqual(["e"], list(sorter.future_products.keys())) self.assertEqual(3, len(sorter.valid_entitlement_certs)) def test_get_system_status(self): self.assertEqual('Invalid', self.sorter.get_system_status()) self.sorter.system_status = 'valid' self.assertEqual('Current', self.sorter.get_system_status()) self.sorter.system_status = 'partial' self.assertEqual('Insufficient', self.sorter.get_system_status())
def test_no_compliant_until(self, mock_update): SAMPLE_COMPLIANCE_JSON['compliantUntil'] = None self.sorter = CertSorter() self.sorter.is_registered = Mock(return_value=True) self.assertTrue(self.sorter.compliant_until is None) self.assertTrue(self.sorter.first_invalid_date is None)
def test_no_usable_status(self, mock_update): self.status_mgr.load_status = Mock( return_value=None) sorter = CertSorter() sorter.is_registered = Mock(return_value=True) self.assertEqual(UNKNOWN, sorter.get_status(INST_PID_1))
class CertSorterTests(unittest.TestCase): def setUp(self): # Setup mock product and entitlement certs: self.prod_dir = StubCertificateDirectory([ # Will be unentitled: StubProductCertificate(StubProduct(INST_PID_1)), # Will be entitled: StubProductCertificate(StubProduct(INST_PID_2)), # Will be entitled but expired: StubProductCertificate(StubProduct(INST_PID_3)), ]) self.ent_dir = StubEntitlementDirectory([ StubEntitlementCertificate(StubProduct(INST_PID_2)), StubEntitlementCertificate(StubProduct(INST_PID_3), start_date=datetime.now() - timedelta(days=365), end_date=datetime.now() - timedelta(days=2)), StubEntitlementCertificate(StubProduct(INST_PID_4), start_date=datetime.now() - timedelta(days=365), end_date=datetime.now() + timedelta(days=365)), StubEntitlementCertificate(StubProduct(INST_PID_5)), # entitled, but not installed StubEntitlementCertificate(StubProduct('not_installed_product')), ]) def test_unentitled_product_certs(self): self.sorter = CertSorter(self.prod_dir, self.ent_dir, {}) self.assertEqual(1, len(self.sorter.unentitled_products.keys())) self.assertTrue(INST_PID_1 in self.sorter.unentitled_products) self.assertFalse(self.sorter.is_valid()) self.assertEqual(NOT_SUBSCRIBED, self.sorter.get_status(INST_PID_1)) def test_ent_cert_no_installed_product(self): self.sorter = CertSorter(self.prod_dir, self.ent_dir, {}) # TODO: looks like this test was never completed def test_ent_cert_no_product(self): self.ent_dir = StubCertificateDirectory( [StubEntitlementCertificate(None, provided_products=[], quantity=2)]) stub_facts = StubFacts(fact_dict={"cpu.cpu_socket(s)": 42}) self.sorter = CertSorter(self.prod_dir, self.ent_dir, stub_facts.get_facts()) self.assertEqual(0, len(self.sorter.partially_valid_products)) def test_expired(self): self.sorter = CertSorter(self.prod_dir, self.ent_dir, {}) self.assertEqual(1, len(self.sorter.expired_entitlement_certs)) self.assertTrue(cert_list_has_product( self.sorter.expired_entitlement_certs, INST_PID_3)) self.assertEqual(1, len(self.sorter.expired_products.keys())) self.assertTrue(INST_PID_3 in self.sorter.expired_products) self.assertFalse(self.sorter.is_valid()) self.assertEquals(EXPIRED, self.sorter.get_status(INST_PID_3)) def test_expired_in_future(self): self.sorter = CertSorter(self.prod_dir, self.ent_dir, {}, on_date=datetime(2050, 1, 1, tzinfo=GMT())) self.assertEqual(5, len(self.sorter.expired_entitlement_certs)) self.assertTrue(INST_PID_2 in self.sorter.expired_products) self.assertTrue(INST_PID_3 in self.sorter.expired_products) self.assertFalse(INST_PID_4 in self.sorter.expired_products) # it's not installed self.assertTrue(INST_PID_1 in self.sorter.unentitled_products) self.assertEqual(0, len(self.sorter.valid_entitlement_certs)) self.assertFalse(self.sorter.is_valid()) def test_entitled_products(self): provided = [StubProduct(INST_PID_1), StubProduct(INST_PID_2), StubProduct(INST_PID_3)] self.ent_dir = StubCertificateDirectory([ StubEntitlementCertificate(StubProduct(INST_PID_5), provided_products=provided)]) self.sorter = CertSorter(self.prod_dir, self.ent_dir, {}) self.assertEquals(3, len(self.sorter.valid_products.keys())) self.assertTrue(INST_PID_1 not in self.sorter.partially_valid_products) self.assertTrue(INST_PID_1 in self.sorter.valid_products) self.assertTrue(INST_PID_2 in self.sorter.valid_products) self.assertTrue(INST_PID_3 in self.sorter.valid_products) self.assertTrue(self.sorter.is_valid()) def test_expired_but_provided_in_another_entitlement(self): self.ent_dir = StubCertificateDirectory([ StubEntitlementCertificate(StubProduct(INST_PID_5), provided_products=[StubProduct(INST_PID_3)]), StubEntitlementCertificate(StubProduct(INST_PID_5), start_date=datetime.now() - timedelta(days=365), end_date=datetime.now() - timedelta(days=2), provided_products=[StubProduct(INST_PID_3)]), StubEntitlementCertificate(StubProduct(INST_PID_4)) ]) self.sorter = CertSorter(self.prod_dir, self.ent_dir, {}) self.assertEquals(1, len(self.sorter.valid_products.keys())) self.assertTrue(INST_PID_3 in self.sorter.valid_products) self.assertEquals(0, len(self.sorter.expired_products.keys())) def test_multi_product_entitlement_expired(self): # Setup one ent cert that provides several things installed # installed: provided = [StubProduct(INST_PID_2), StubProduct(INST_PID_3)] self.ent_dir = StubCertificateDirectory([ StubEntitlementCertificate(StubProduct(INST_PID_5), provided_products=provided)]) self.sorter = CertSorter(self.prod_dir, self.ent_dir, {}, on_date=datetime(2050, 1, 1, tzinfo=GMT())) self.assertEquals(1, len(self.sorter.expired_entitlement_certs)) self.assertEquals(2, len(self.sorter.expired_products.keys())) self.assertTrue(INST_PID_2 in self.sorter.expired_products) self.assertTrue(INST_PID_3 in self.sorter.expired_products) # Expired should not show up as unentitled also: self.assertEquals(1, len(self.sorter.unentitled_products.keys())) self.assertTrue(INST_PID_1 in self.sorter.unentitled_products) self.assertFalse(self.sorter.is_valid()) def test_future_entitled(self): provided = [StubProduct(INST_PID_2), StubProduct(INST_PID_3)] self.ent_dir = StubCertificateDirectory([ StubEntitlementCertificate(StubProduct(INST_PID_5), provided_products=provided, start_date=datetime.now() + timedelta(days=30), end_date=datetime.now() + timedelta(days=120)), ]) self.sorter = CertSorter(self.prod_dir, self.ent_dir, {}) self.assertEquals(0, len(self.sorter.valid_products)) self.assertEquals(2, len(self.sorter.future_products)) self.assertEquals(3, len(self.sorter.unentitled_products)) self.assertTrue(INST_PID_2 in self.sorter.future_products) self.assertTrue(INST_PID_3 in self.sorter.future_products) self.assertEquals(FUTURE_SUBSCRIBED, self.sorter.get_status(INST_PID_2)) self.assertEquals(FUTURE_SUBSCRIBED, self.sorter.get_status(INST_PID_3)) def test_future_and_currently_entitled(self): provided = [StubProduct(INST_PID_2), StubProduct(INST_PID_3)] self.ent_dir = StubCertificateDirectory([ StubEntitlementCertificate(StubProduct(INST_PID_5), provided_products=provided, start_date=datetime.now() + timedelta(days=30), end_date=datetime.now() + timedelta(days=120)), StubEntitlementCertificate(StubProduct(INST_PID_5), provided_products=provided), ]) self.sorter = CertSorter(self.prod_dir, self.ent_dir, {}) self.assertEquals(2, len(self.sorter.valid_products)) self.assertEquals(2, len(self.sorter.future_products)) self.assertEquals(1, len(self.sorter.unentitled_products)) self.assertTrue(INST_PID_2 in self.sorter.future_products) self.assertTrue(INST_PID_3 in self.sorter.future_products) self.assertTrue(INST_PID_2 in self.sorter.valid_products) self.assertTrue(INST_PID_3 in self.sorter.valid_products) self.assertEquals(SUBSCRIBED, self.sorter.get_status(INST_PID_2)) self.assertEquals(SUBSCRIBED, self.sorter.get_status(INST_PID_3)) def test_non_stacked_lacking_sockets(self): prod_dir = StubCertificateDirectory([stub_prod_cert(INST_PID_1)]) # System has 8 sockets: stub_facts = StubFacts(fact_dict={"cpu.cpu_socket(s)": 8}) # Only 2 sockets covered by a non-stacked entitlement: ent_dir = StubCertificateDirectory([ stub_ent_cert(INST_PID_5, [INST_PID_1], sockets=2, quantity=5)]) sorter = CertSorter(prod_dir, ent_dir, stub_facts.get_facts()) self.assertFalse(INST_PID_1 in sorter.unentitled_products) self.assertFalse(INST_PID_1 in sorter.valid_products) self.assertTrue(INST_PID_1 in sorter.partially_valid_products) self.assertEquals(1, len(sorter.partially_valid_products)) self.assertEquals(1, len(sorter.partially_valid_products[INST_PID_1])) def test_non_stacked_0_sockets(self): prod_dir = StubCertificateDirectory([stub_prod_cert(INST_PID_1)]) # System has 8 sockets: stub_facts = StubFacts(fact_dict={"cpu.cpu_socket(s)": 8}) # 0 sockets is basically "unlimited" sockets # see bz#805415 ent_dir = StubCertificateDirectory([ stub_ent_cert(INST_PID_5, [INST_PID_1], sockets=0, quantity=5)]) sorter = CertSorter(prod_dir, ent_dir, stub_facts.get_facts()) self.assertFalse(INST_PID_1 in sorter.partially_valid_products) self.assertTrue(INST_PID_1 in sorter.valid_products) self.assertFalse(INST_PID_1 in sorter.unentitled_products)
def test_unentitled_product_certs(self): self.sorter = CertSorter(self.prod_dir, self.ent_dir, {}) self.assertEqual(1, len(self.sorter.unentitled_products.keys())) self.assertTrue(INST_PID_1 in self.sorter.unentitled_products) self.assertFalse(self.sorter.is_valid()) self.assertEqual(NOT_SUBSCRIBED, self.sorter.get_status(INST_PID_1))
def test_ent_cert_no_installed_product(self): self.sorter = CertSorter(self.prod_dir, self.ent_dir, {})