Exemple #1
0
 async def get_data_sources_config(
         authorization: Optional[str] = Header(None)):
     """
     Provides OPAL clients with their base data config, meaning from where they should
     fetch a *complete* picture of the policy data they need. Clients will use this config
     to pull all data when they initially load and when they are reconnected to server after
     a period of disconnection (in which they cannot receive incremental updates).
     """
     token = get_token_from_header(authorization)
     if data_sources_config.config is not None:
         logger.info("Serving source configuration")
         return data_sources_config.config
     elif data_sources_config.external_source_url is not None:
         url = str(data_sources_config.external_source_url)
         short_token = token[:5] + "..." + token[-5:]
         logger.info(
             "Source configuration is available at '{url}', redirecting with token={token} (abbrv.)",
             url=url,
             token=short_token)
         redirect_url = set_url_query_param(url, 'token', token)
         return RedirectResponse(url=redirect_url)
     else:
         logger.error("pydantic model invalid", model=data_sources_config)
         raise HTTPException(
             status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
             detail="Did not find a data source configuration!")
Exemple #2
0
 async def launch_policy_store_dependent_tasks(self):
     try:
         for task in asyncio.as_completed([self.launch_policy_updater(), self.launch_data_updater()]):
             await task
     except websockets.exceptions.InvalidStatusCode as err:
         logger.error("Failed to launch background task -- {err}", err=err)
         logger.info("triggering shutdown with SIGTERM...")
         # this will send SIGTERM (Keyboard interrupt) to the worker, making uvicorn
         # send "lifespan.shutdown" event to Starlette via the ASGI lifespan interface.
         # Starlette will then trigger the @app.on_event("shutdown") callback, which
         # in our case (self.stop_client_background_tasks()) will gracefully shutdown
         # the background processes and only then will terminate the worker.
         os.kill(os.getpid(), signal.SIGTERM)
Exemple #3
0
    async def launch_policy_store_dependent_tasks(self):
        try:
            await self.maybe_init_healthcheck_policy()
        except Exception:
            logger.critical(
                "healthcheck policy enabled but could not be initialized!")
            self._trigger_shutdown()
            return

        try:
            for task in asyncio.as_completed(
                [self.launch_policy_updater(),
                 self.launch_data_updater()]):
                await task
        except websockets.exceptions.InvalidStatusCode as err:
            logger.error("Failed to launch background task -- {err}",
                         err=repr(err))
            self._trigger_shutdown()
Exemple #4
0
    async def maybe_init_healthcheck_policy(self):
        """
        This function only runs if OPA_HEALTH_CHECK_POLICY_ENABLED is true.

        Puts the healthcheck policy in opa cache and inits the transaction log used by the policy.
        If any action fails, opal client will shutdown.
        """
        if not opal_client_config.OPA_HEALTH_CHECK_POLICY_ENABLED:
            return  # skip

        healthcheck_policy_relpath = opal_client_config.OPA_HEALTH_CHECK_POLICY_PATH

        here = os.path.abspath(os.path.dirname(__file__))
        healthcheck_policy_path = os.path.join(here,
                                               healthcheck_policy_relpath)
        if not os.path.exists(healthcheck_policy_path):
            logger.error(
                "Critical: OPA health-check policy is enabled, but cannot find policy at {path}",
                path=healthcheck_policy_path)
            raise ValueError("OPA health check policy not found!")

        try:
            healthcheck_policy_code = open(healthcheck_policy_path, 'r').read()
        except IOError as err:
            logger.error("Critical: Cannot read healthcheck policy: {err}",
                         err=repr(err))
            raise

        try:
            await self.policy_store.init_healthcheck_policy(
                policy_id=healthcheck_policy_relpath,
                policy_code=healthcheck_policy_code)
        except aiohttp.ClientError as err:
            logger.error(
                "Failed to connect to OPA agent while init healthcheck policy -- {err}",
                err=repr(err))
            raise
Exemple #5
0
 async def _fail(self, exc: Exception):
     """
     called when the watcher fails, and stops all tasks gracefully
     """
     logger.error("watcher failed with exception: {err}", err=exc)
     await self.stop()