Skip to content

Engine

eunomia.engine.opa

OpaPolicyEngine

Interface to the Open Policy Agent (OPA) engine.

This class manages the lifecycle of an OPA server instance and provides an interface for interacting with it. It handles the installation check, server startup, and shutdown operations.

Source code in src/eunomia/engine/opa.py
class OpaPolicyEngine:
    """
    Interface to the Open Policy Agent (OPA) engine.

    This class manages the lifecycle of an OPA server instance and provides
    an interface for interacting with it. It handles the installation check,
    server startup, and shutdown operations.
    """

    def __init__(self) -> None:
        self._server_address = f"{settings.OPA_SERVER_HOST}:{settings.OPA_SERVER_PORT}"
        self.policy_folder = settings.OPA_POLICY_FOLDER
        # Global variable to store the OPA process
        self._process: subprocess.Popen[bytes] | None = None
        self.url = f"http://{self._server_address}/v1/data/eunomia"

    def _check_installation(self) -> str:
        # Check if the OPA binary is available; if not, attempt to install it.
        # Returns the absolute path of the OPA binary.

        opa_path = shutil.which("opa")
        if opa_path:
            logging.info("OPA is installed at:", opa_path)
            return opa_path

        logging.info("OPA not found. Attempting to install OPA...")
        system = platform.system()
        try:
            if system == "Darwin":
                subprocess.run(["brew", "install", "opa"], check=True)
            elif system == "Linux":
                subprocess.run(["sudo", "apt-get", "update"], check=True)
                subprocess.run(["sudo", "apt-get", "install", "-y", "opa"], check=True)
            else:
                logging.info(f"Automatic installation not supported on {system}.")
                sys.exit(1)
        except subprocess.CalledProcessError:
            logging.info(
                "Failed to install OPA automatically. Please install it manually."
            )
            sys.exit(1)

        opa_path = shutil.which("opa")
        if not opa_path:
            logging.info(
                "OPA installation succeeded, but the binary is still not found in PATH."
            )
            sys.exit(1)

        logging.info("OPA is now installed at:", opa_path)
        return opa_path

    def start(self) -> None:
        """
        Start the OPA server.

        This method first checks the installation of OPA and tries to install it
        if it is not found. Then it launches the OPA server as a subprocess using
        the configured address and policy path. It waits briefly to ensure the
        server has started before returning.

        Raises
        ------
        SystemExit
            If OPA binary cannot be found or installed.
        """
        opa_binary = self._check_installation()
        opa_cmd = [
            opa_binary,
            "run",
            "--server",
            "--addr",
            self._server_address,
            self.policy_folder,
        ]

        # Start the OPA server as a subprocess, and wait to ensure it's running
        self._process = subprocess.Popen(opa_cmd, stdout=sys.stdout, stderr=sys.stderr)
        time.sleep(2)

    def stop(self) -> None:
        """
        Stop the OPA server.

        This method terminates the OPA server subprocess if it is running
        and waits for it to exit.
        """
        if self._process:
            self._process.terminate()
            self._process.wait()
start()

Start the OPA server.

This method first checks the installation of OPA and tries to install it if it is not found. Then it launches the OPA server as a subprocess using the configured address and policy path. It waits briefly to ensure the server has started before returning.

Raises:

Type Description
SystemExit

If OPA binary cannot be found or installed.

Source code in src/eunomia/engine/opa.py
def start(self) -> None:
    """
    Start the OPA server.

    This method first checks the installation of OPA and tries to install it
    if it is not found. Then it launches the OPA server as a subprocess using
    the configured address and policy path. It waits briefly to ensure the
    server has started before returning.

    Raises
    ------
    SystemExit
        If OPA binary cannot be found or installed.
    """
    opa_binary = self._check_installation()
    opa_cmd = [
        opa_binary,
        "run",
        "--server",
        "--addr",
        self._server_address,
        self.policy_folder,
    ]

    # Start the OPA server as a subprocess, and wait to ensure it's running
    self._process = subprocess.Popen(opa_cmd, stdout=sys.stdout, stderr=sys.stderr)
    time.sleep(2)
stop()

Stop the OPA server.

This method terminates the OPA server subprocess if it is running and waits for it to exit.

Source code in src/eunomia/engine/opa.py
def stop(self) -> None:
    """
    Stop the OPA server.

    This method terminates the OPA server subprocess if it is running
    and waits for it to exit.
    """
    if self._process:
        self._process.terminate()
        self._process.wait()