ok

Mini Shell

Direktori : /var/opt/nydus/ops/primordial/wsgi/
Upload File :
Current File : //var/opt/nydus/ops/primordial/wsgi/cherrytools.py

# -*- coding: utf-8 -*-
from typing import Callable, Optional
import ssl

import cherrypy

from primordial.config import Config


def start_cherry(config: Config, api: Callable, path: str) -> None:
    """Start CherryPy running an API.

    :param config: The configuration to use for CherryPy
    :param api: The API callable to be started
    :param path: The path under which the API should respond to requests
    """
    cherrypy.tree.graft(api, path)
    run_cherrypy(config)


def start_cherry_https(config: Config, api: Callable, path: str) -> None:
    """Start CherryPy running an API on HTTPS only.

    This is a backport of how ServiceGroup & DNS
    verticals start.

    :param config: The configuration to use for CherryPy
    :param api: The API callable to be started
    :param path: The path under which the API should respond to requests
    """

    cherrypy.tree.graft(api, path)

    cert_file = config.get("server_cert")
    pkey_file = config.get("server_key")
    ca_certs_file = config.get("server_ca")

    run_cherrypy(
        config,
        cert_path=cert_file,
        key_path=pkey_file,
        ca_certs_path=ca_certs_file)


def run_cherrypy(
        config: Config,
        cert_path: Optional[str] = None,
        key_path: Optional[str] = None,
        ca_certs_path: Optional[str] = None) -> None:
    """Run CherryPy. Called by `start_cherry`.

    :param config: The configuration to use for running CherryPy
    """
    restart_trigger = config.get('restart_trigger')
    cherrypy.engine.autoreload.files.add(restart_trigger)

    # Only reload when the restart trigger changes (not other files)
    # TODO non-local only
    cherrypy.engine.autoreload.match = restart_trigger

    server_host = config.get('server.host')
    https_port = config.get_int('server.https.port')
    if https_port and cert_path is not None:
        cherrypy.config.update({
            'server.socket_host': server_host,
            'server.socket_port': https_port,
            'server.ssl_module': 'builtin',
            'server.ssl_certificate': cert_path,
            'server.ssl_private_key': key_path,
            'server.ssl_context': ssl_context(cert_path, key_path, ca_certs_path)})
    else:
        server_port = config.get_int('server.port')
        cherrypy.config.update({'server.socket_host': server_host,
                                'server.socket_port': server_port})

    cherrypy.engine.start()
    cherrypy.engine.block()


def ssl_context(certificate, private_key, ca_certs):
    """Create a server SSL context requiring client certificate authentication.
    :param certificate: Path to server certificate.
    :param private_key: Path to server private key.
    :param ca_certs: Path to certificate authority chain against which client
                     certificates are validated.
    """
    context = ssl.create_default_context(
        purpose=ssl.Purpose.CLIENT_AUTH,
        cafile=ca_certs
    )
    context.load_cert_chain(certificate, private_key)
    context.verify_mode = ssl.CERT_REQUIRED
    return context

Zerion Mini Shell 1.0