async def namespace_observer( *, clusterwide: bool, namespaces: Collection[references.NamespacePattern], insights: references.Insights, settings: configuration.OperatorSettings, ) -> None: exact_namespaces = references.select_specific_namespaces(namespaces) resource = await insights.backbone.wait_for(references.NAMESPACES) # Populate the namespaces atomically (instead of notifying on every item from the watch-stream). if not settings.scanning.disabled and not clusterwide: try: objs, _ = await fetching.list_objs( settings=settings, resource=resource, namespace=None, logger=logger, ) async with insights.revised: revise_namespaces(raw_bodies=objs, insights=insights, namespaces=namespaces) insights.revised.notify_all() except errors.APIForbiddenError: logger.warning( "Not enough permissions to list namespaces. " "Falling back to a list of namespaces which are assumed to exist: " f"{exact_namespaces!r}") async with insights.revised: insights.namespaces.update(exact_namespaces) insights.revised.notify_all() else: async with insights.revised: insights.namespaces.update( {None} if clusterwide else exact_namespaces) insights.revised.notify_all() # Notify those waiting for the initial listing (e.g. CLI commands). insights.ready_namespaces.set() if not settings.scanning.disabled and not clusterwide: try: await queueing.watcher(settings=settings, resource=resource, namespace=None, processor=functools.partial( process_discovered_namespace_event, namespaces=namespaces, insights=insights)) except errors.APIForbiddenError: logger.warning( "Not enough permissions to watch for namespaces: " "changes (deletion/creation) will not be noticed; " "the namespaces are only refreshed on operator restarts.") await asyncio.Event().wait() else: await asyncio.Event().wait()
def test_empty_pattern_list(): names = select_specific_namespaces([]) assert not names
def test_excluded_regexps(): names = select_specific_namespaces([re.compile(r'ns1')]) assert not names
def test_excluded_globs(): names = select_specific_namespaces(['n*s', 'n?s']) assert not names
def test_excluded_multipatterns(): names = select_specific_namespaces(['ns1,ns2']) assert not names
def test_included_exact_strings(): names = select_specific_namespaces(['ns2', 'ns1']) assert names == {'ns1', 'ns2'}
def test_included_empty_string(): names = select_specific_namespaces(['']) assert names == {''}