Пример #1
0
    def test_correctness(self, tmpdir):
        config_file = os.path.join(str(tmpdir), "config.yaml")
        logging_config_file = os.path.join(str(tmpdir), "logging.json")

        beer_garden.config.generate(
            ["-c", config_file, "-l", logging_config_file])

        spec = YapconfSpec(beer_garden.config._SPECIFICATION)
        spec.add_source(label="config_file",
                        source_type="yaml",
                        filename=config_file)
        config = spec.load_config("config_file")

        # Defaults from spec
        assert config.log.fallback_file is None
        assert config.log.fallback_level == "INFO"

        # Value passed in
        assert config.log.config_file == logging_config_file

        # Ensure that bootstrap items were not written to file
        assert config.configuration.file is None

        with open(config_file) as f:
            yaml_config = yaml.safe_load(f)
        assert "configuration" not in yaml_config
Пример #2
0
def _safe_migrate(spec: YapconfSpec, filename: str) -> None:
    """Copy existing file to backup before migrating configuration

    Args:
        spec: Yapconf specification
        filename: Config filename

    Returns:
        None
    """
    tmp_filename = filename + ".tmp"
    try:
        spec.migrate_config_file(
            filename,
            current_file_type="yaml",
            output_file_name=tmp_filename,
            output_file_type="yaml",
            include_bootstrap=False,
        )
    except Exception:
        import logging

        # Logging isn't configured yet so this will use the last-chance logger, STDERR
        logging.getLogger(__name__).warning(
            "Could not successfully migrate application configuration. "
            "Will attempt to load the previous configuration.",
            exc_info=True,
        )
        return

    if _is_new_config(filename, tmp_filename):
        _backup_previous_config(filename, tmp_filename)
    else:
        os.remove(tmp_filename)
Пример #3
0
def main():
    signal.signal(signal.SIGINT, signal_handler)
    signal.signal(signal.SIGTERM, signal_handler)

    spec = YapconfSpec(SPECIFICATION, env_prefix="BG_")
    parser = ArgumentParser()
    spec.add_arguments(parser)
    args = parser.parse_args(sys.argv[1:])

    bartender.setup_bartender(spec=spec, cli_args=vars(args))

    # Ensure we have a brew-view connection
    progressive_backoff(
        partial(bartender.bv_client.can_connect, timeout=5),
        bartender.application,
        "Unable to connect to brew-view, is it started?",
    )

    # Ensure we have a mongo connection
    progressive_backoff(
        partial(setup_database, bartender.config),
        bartender.application,
        "Unable to connect to mongo, is it started?",
    )

    # Ensure we have message queue connections
    progressive_backoff(
        bartender.application.clients["pika"].is_alive,
        bartender.application,
        "Unable to connect to rabbitmq, is it started?",
    )
    progressive_backoff(
        bartender.application.clients["pyrabbit"].is_alive,
        bartender.application,
        "Unable to connect to rabbitmq admin interface. "
        "Is the management plugin enabled?",
    )

    # Since we wait for RabbitMQ and brew-view we could already be shutting down
    # In that case we don't want to start
    if not bartender.application.stopped():
        # Make sure that the bartender user has admin permissions
        bartender.ensure_admin()

        bartender.logger.info("Hi, what can I get you to drink?")
        bartender.application.start()

        bartender.logger.info("Let me know if you need anything else!")

        # You may be wondering why we don't just call bartender.application.join() or .wait().
        # Well, you're in luck because I'm going to tell you why. Either of these methods
        # cause the main python thread to lock out our signal handler, which means we cannot
        # shut down gracefully in some circumstances. So instead we simply use pause() to wait
        # for a signal to be sent to us. If you choose to change this please test thoroughly
        # when deployed via system packages (apt/yum) as well as python packages and docker.
        # Thanks!
        signal.pause()

    bartender.logger.info("Don't forget to drive safe!")
Пример #4
0
def spec_with_dicts():
    """YapconfSpec for testing YapconfDictItem variations"""
    return YapconfSpec({
        'database': {
            'type': 'dict',
            'required': True,
            'items': {
                'name': {'type': 'str', 'required': True, },
                'host': {'type': 'str', 'required': True, },
                'port': {'type': 'int', 'required': True, },
            }
        },
        'foo': {
            'type': 'dict',
            'required': True,
            'items': {
                'bar': {
                    'type': 'dict',
                    'required': True,
                    'items': {
                        'baz': {
                            'type': 'str', 'required': True,
                        },
                    },
                },
                'bat': {
                    'type': 'bool',
                }
            },
        },
    })
Пример #5
0
def _parse_args(args: Sequence[str]) -> Tuple[YapconfSpec, dict]:
    """Construct a spec and parse command line arguments

    Args:
        args: Command line arguments

    Returns:
        Config object with only the named items
    """
    spec = YapconfSpec(_SPECIFICATION, env_prefix="BG_")

    parser = ArgumentParser()
    spec.add_arguments(parser)
    cli_vars = vars(parser.parse_args(args))

    return spec, cli_vars
Пример #6
0
def _setup_config_sources(spec: YapconfSpec, cli_vars: Iterable[str]) -> List[str]:
    """Sets the sources for configuration loading

    Args:
        spec: Yapconf specification
        cli_vars: Command line arguments

    Returns:
        List of configuration sources
    """
    spec.add_source("cli_args", "dict", data=cli_vars)
    spec.add_source("ENVIRONMENT", "environment")

    config_sources = ["cli_args", "ENVIRONMENT"]

    # Load bootstrap items to see if there's a config file
    temp_config = spec.load_config(*config_sources, bootstrap=True)
    config_filename = temp_config.configuration.file

    if config_filename:
        _safe_migrate(spec, config_filename)
        spec.add_source(config_filename, "yaml", filename=config_filename)
        config_sources.insert(1, config_filename)

    return config_sources
Пример #7
0
def spec():
    return YapconfSpec({
        "log": {
            "type": "dict",
            "items": {
                "config_file": {
                    "type": "str",
                    "description": "Path to a logging config file.",
                    "required": False,
                    "cli_short_name": "l",
                    "previous_names": ["log_config"],
                    "alt_env_names": ["LOG_CONFIG"],
                },
                "file": {
                    "type": "str",
                    "description":
                    "File you would like the application to log to",
                    "required": False,
                    "previous_names": ["log_file"],
                },
                "level": {
                    "type":
                    "str",
                    "description":
                    "Log level for the application",
                    "default":
                    "INFO",
                    "choices": [
                        "DEBUG",
                        "INFO",
                        "WARN",
                        "WARNING",
                        "ERROR",
                        "CRITICAL",
                    ],
                    "previous_names": ["log_level"],
                },
            },
        },
        "configuration": {
            "type": "dict",
            "bootstrap": True,
            "items": {
                "file": {
                    "required": False,
                    "bootstrap": True,
                    "cli_short_name": "c",
                },
                "type": {
                    "required": False,
                    "bootstrap": True,
                    "cli_short_name": "t",
                },
            },
        },
    })
Пример #8
0
def main():
    signal.signal(signal.SIGINT, signal_handler)
    signal.signal(signal.SIGTERM, signal_handler)

    spec = YapconfSpec(SPECIFICATION, env_prefix="BG_")
    parser = ArgumentParser()
    spec.add_arguments(parser)
    args = parser.parse_args(sys.argv[1:])

    # Logging isn't set up until after this...
    brew_view.setup(spec, vars(args))

    # Schedule things to happen after the ioloop comes up
    brew_view.io_loop.add_callback(brew_view.startup)

    brew_view.logger.info("Starting IO loop")
    brew_view.io_loop.start()

    brew_view.logger.info("Application is shut down. Goodbye!")
Пример #9
0
    def _load_config(args, kwargs):
        """Load a config based on the CONNECTION section of the Brewtils Specification

        This will load a configuration with the following source precedence:

        1. kwargs
        2. kwargs with "old" names ("host", "port", "url_prefix")
        3. host and port passed as positional arguments
        4. the global configuration (brewtils.plugin.CONFIG)

        Args:
            args (deprecated): host and port
            kwargs: Standard connection arguments to be used

        Returns:
            The resolved configuration object
        """
        spec = YapconfSpec(_CONNECTION_SPEC)

        renamed = {}
        for key in ["host", "port", "url_prefix"]:
            if kwargs.get(key):
                renamed["bg_" + key] = kwargs.get(key)

        positional = {}
        if len(args) > 0:
            _deprecate(
                "Heads up - passing bg_host as a positional argument is deprecated "
                "and will be removed in version 4.0",
                stacklevel=kwargs.get("stacklevel", 3),
            )
            positional["bg_host"] = args[0]
        if len(args) > 1:
            _deprecate(
                "Heads up - passing bg_port as a positional argument is deprecated "
                "and will be removed in version 4.0",
                stacklevel=kwargs.get("stacklevel", 3),
            )
            positional["bg_port"] = args[1]

        return spec.load_config(
            *[kwargs, renamed, positional, brewtils.plugin.CONFIG])
Пример #10
0
def fallback_spec():
    return YapconfSpec({
        'defaults': {
            'type': 'dict',
            'items': {
                'str': {'type': 'str', 'default': 'default_str'},
                'int': {'type': 'int', 'default': 123},
                'long': {'type': 'long', 'default': 123},
                'float': {'type': 'float', 'default': 123.123},
                'bool': {'type': 'bool', 'default': True},
                'complex': {'type': 'complex', 'default': 1j},
                'list': {
                    'type': 'list',
                    'default': [1, 2, 3],
                    'items': {
                        'list_item': {'type': 'int', 'default': 1}
                    },
                },
                'dict': {
                    'type': 'dict',
                    'default': {'foo': 'dict_default'},
                    'items': {
                        'foo': {'type': 'str', 'default': 'item_default'}
                    },
                },
            },
        },
        'str': {'type': 'str', 'fallback': 'defaults.str'},
        'int': {'type': 'int', 'fallback': 'defaults.int'},
        'long': {'type': 'long', 'fallback': 'defaults.long'},
        'float': {'type': 'float', 'fallback': 'defaults.float'},
        'bool': {'type': 'bool', 'fallback': 'defaults.bool'},
        'complex': {'type': 'complex', 'fallback': 'defaults.complex'},
        'list': {
            'type': 'list',
            'fallback': 'defaults.list',
            'items': {
                'list_item': {
                    'type': 'int',
                    'fallback': 'defaults.list.list_item'
                },
            },
        },
        'dict': {
            'type': 'dict',
            'fallback': 'defaults.dict',
            'items': {
                'foo': {
                    'type': 'str',
                    'fallback': 'defaults.dict.foo'
                },
            },
        },
    })
Пример #11
0
    def setUpClass(cls):
        db_patcher = patch('bg_utils.setup_database')
        db_patcher.start()
        server_patch = patch('brew_view.HTTPServer')
        server_patch.start()

        spec = YapconfSpec(SPECIFICATION)
        brew_view.setup(spec, {})
        connect('beer_garden', host='mongomock://localhost')

        cls.app = brew_view.tornado_app
Пример #12
0
    def test_create_garden_with_empty_connection_params(self, bg_garden):
        """create_garden should explicitly load default HTTP configs from brewtils when empty"""

        config_map = {
            "bg_host": "host",
            "bg_port": "port",
            "ssl_enabled": "ssl",
            "bg_url_prefix": "url_prefix",
            "ca_cert": "ca_cert",
            "ca_verify": "ca_verify",
            "client_cert": "client_cert",
        }

        spec = YapconfSpec(_CONNECTION_SPEC)
        # bg_host is required by brewtils garden spec
        defaults = spec.load_config({"bg_host": ""})

        garden = create_garden(bg_garden)
        for key in config_map:
            assert garden.connection_params["http"][
                config_map[key]] == defaults[key]
Пример #13
0
def simple_spec():
    """Simple YapconfSpec for all YapconfItem variations"""
    return YapconfSpec(
        {
            'my_string': {'type': 'str', 'required': True, },
            'my_int': {'type': 'int', 'required': True, },
            'my_long': {'type': 'long', 'required': True, },
            'my_float': {'type': 'float', 'required': True, },
            'my_bool': {'type': 'bool', 'required': True, },
            'my_complex': {'type': 'complex', 'required': True, },
        }
    )
Пример #14
0
    def setUp(self):
        self.config = YapconfSpec(SPECIFICATION).load_config()
        bartender.config = self.config

        self.app = BartenderApp()
        self.thrift_server = Mock()
        self.queue_manager = Mock()
        self.local_monitor = Mock()
        self.status_monitor = Mock()
        self.plugin_manager = Mock()
        self.plugin_loader = Mock()
        self.clients = MagicMock()
        self.mongo_pruner = Mock()
Пример #15
0
    def setUpClass(cls):
        db_patcher = patch("brew_view.setup_database")
        db_patcher.start()
        server_patch = patch("brew_view.HTTPServer")
        server_patch.start()

        spec = YapconfSpec(SPECIFICATION)
        brew_view.setup(spec, {})

        # Setup anonymous user for testing.
        brew_view.anonymous_principal = brew_view.load_anonymous()

        connect("beer_garden", host="mongomock://localhost")

        cls.app = brew_view.tornado_app
Пример #16
0
def create_garden(garden: Garden) -> Garden:
    """Create a new Garden

    Args:
        garden: The Garden to create

    Returns:
        The created Garden

    """
    # Explicitly load default config options into garden params
    spec = YapconfSpec(_CONNECTION_SPEC)
    # bg_host is required to load brewtils garden spec
    defaults = spec.load_config({"bg_host": ""})

    config_map = {
        "bg_host": "host",
        "bg_port": "port",
        "ssl_enabled": "ssl",
        "bg_url_prefix": "url_prefix",
        "ca_cert": "ca_cert",
        "ca_verify": "ca_verify",
        "client_cert": "client_cert",
    }

    if garden.connection_params is None:
        garden.connection_params = {}
    garden.connection_params.setdefault("http", {})

    for key in config_map:
        garden.connection_params["http"].setdefault(config_map[key],
                                                    defaults[key])

    garden.status_info["heartbeat"] = datetime.utcnow()

    return db.create(garden)
Пример #17
0
def spec_with_lists():
    """YapconfSpec for testing YapconfListItem variations"""
    return YapconfSpec(
        {
            'simple_list': {
                'type': 'list',
                'required': True,
                'items': {
                    'list_item': {
                        'type': 'str', 'required': True
                    }
                }
            },
            'top_list': {
                'type': 'list',
                'required': True,
                'items': {
                    'nested_list': {
                        'type': 'list',
                        'required': True,
                        'items': {
                            'nested_list_items': {
                                'type': 'int',
                                'required': True
                            }
                        }
                    }
                }
            },
            'list_of_dictionaries': {
                'type': 'list',
                'required': True,
                'items': {
                    'list_item': {
                        'type': 'dict',
                        'required': True,
                        'items': {
                            'foo': {'type': 'str', 'required': True, },
                            'bar': {'type': 'str', 'required': False, }
                        }
                    }
                }
            }
        }
    )
Пример #18
0
def get_argument_parser():
    """Get an ArgumentParser pre-populated with Brewtils arguments

    This is helpful if you're expecting additional command line arguments to
    a plugin startup script.

    This enables doing something like::

        def main():
            parser = get_argument_parser()
            parser.add_argument('positional_arg')

            parsed_args = parser.parse_args(sys.argv[1:])

            # Now you can use the extra argument
            client = MyClient(parsed_args.positional_arg)

            # But you'll need to be careful when using the 'normal' Brewtils
            # configuration loading methods:

            # Option 1: Tell Brewtils about your customized parser
            connection = get_connection_info(cli_args=sys.argv[1:],
                                             argument_parser=parser)

            # Option 2: Use the parsed CLI as a dictionary
            connection = get_connection_info(**vars(parsed_args))

            # Now specify connection kwargs like normal
            plugin = RemotePlugin(client, name=...
                                  **connection)

    IMPORTANT: Note that in both cases the returned ``connection`` object **will
    not** contain your new value. Both options just prevent normal CLI parsing
    from failing on the unknown argument.

    Returns:
        :ArgumentParser: Argument parser with Brewtils arguments loaded
    """
    parser = ArgumentParser()

    YapconfSpec(SPECIFICATION).add_arguments(parser)

    return parser
Пример #19
0
def example_spec():
    return YapconfSpec(
        {
            'foo': {},
            'emoji': {},
            u'💩': {},
            'db': {
                'type': 'dict',
                'items': {
                    'name': {},
                    'port': {'type': 'int'}
                }
            },
            'items': {
                'type': 'list',
                'items': {
                    'item': {'type': 'int'},
                },
            },
        }
    )
Пример #20
0
def generate_config():
    spec = YapconfSpec(SPECIFICATION, env_prefix='BG_')
    bg_utils.generate_config_file(spec, sys.argv[1:])
Пример #21
0
 def test_no_config_file(self):
     beer_garden.config.load([], force=True)
     spec = YapconfSpec(beer_garden.config._SPECIFICATION)
     assert beer_garden.config._CONFIG.to_dict() == spec.defaults
Пример #22
0
def load_config(cli_args=None, argument_parser=None, **kwargs):
    """Load configuration using Yapconf

    Configuration will be loaded from these sources, with earlier sources having
    higher priority:

        1. ``**kwargs`` passed to this method
        2. ``cli_args`` passed to this method
        3. Environment variables using the ``BG_`` prefix
        4. Default values in the brewtils specification

    Args:
        cli_args (list, optional): List of command line arguments for
            configuration loading
        argument_parser (ArgumentParser, optional): Argument parser to use when
            parsing cli_args. Supplying this allows adding additional arguments
            prior to loading the configuration. This can be useful if your
            startup script takes additional arguments. See get_argument_parser
            for additional information.
        **kwargs: Additional configuration overrides

    Returns:
        :obj:`box.Box`: The resolved configuration object
    """
    spec = YapconfSpec(SPECIFICATION, env_prefix="BG_")

    sources = []

    if kwargs:
        # Do a little kwarg massaging for backwards compatibility
        if "bg_host" not in kwargs and "host" in kwargs:
            warnings.warn(
                "brewtils.load_config called with 'host' keyword "
                "argument. This name will be removed in version 3.0, "
                "please use 'bg_host' instead.",
                DeprecationWarning,
                stacklevel=2,
            )
            kwargs["bg_host"] = kwargs.pop("host")
        if "bg_port" not in kwargs and "port" in kwargs:
            warnings.warn(
                "brewtils.load_config called with 'port' keyword "
                "argument. This name will be removed in version 3.0, "
                "please use 'bg_port' instead.",
                DeprecationWarning,
                stacklevel=2,
            )
            kwargs["bg_port"] = kwargs.pop("port")

        sources.append(("kwargs", kwargs))

    if cli_args:
        if not argument_parser:
            argument_parser = ArgumentParser()
            spec.add_arguments(argument_parser)

        parsed_args = argument_parser.parse_args(cli_args)
        sources.append(("cli_args", vars(parsed_args)))

    sources.append("ENVIRONMENT")

    try:
        config = spec.load_config(*sources)
    except YapconfItemNotFound as ex:
        if ex.item.name == "bg_host":
            raise ValidationError(
                "Unable to create a plugin without a "
                "beer-garden host. Please specify one on the "
                "command line (--bg-host), in the "
                "environment (BG_HOST), or in kwargs "
                "(bg_host)"
            )
        raise

    # Make sure the url_prefix is normal
    config.url_prefix = normalize_url_prefix(config.url_prefix)

    return config
Пример #23
0
def load_config(cli_args=True,
                environment=True,
                argument_parser=None,
                bootstrap=False,
                **kwargs):
    """Load configuration using Yapconf

    Configuration will be loaded from these sources, with earlier sources having
    higher priority:

        1. ``**kwargs`` passed to this method
        2. Command line arguments (if ``cli_args`` argument is not False)
        3. Environment variables using the ``BG_`` prefix (if ``environment`` argument
            is not False)
        4. Default values in the brewtils specification

    Args:
        cli_args (Union[bool, list], optional): Specifies whether command line should be
            used as a configuration source
            - True: Argparse will use the standard sys.argv[1:]
            - False: Command line arguments will be ignored when loading configuration
            - List of strings: Will be parsed as CLI args (instead of using sys.argv)
        environment (bool): Specifies whether environment variables (with the ``BG_``
            prefix) should be used when loading configuration
        argument_parser (ArgumentParser, optional, deprecated): Argument parser to use
            when parsing cli_args. Supplying this allows adding additional arguments
            prior to loading the configuration. This can be useful if your
            startup script takes additional arguments. See get_argument_parser
            for additional information.
        **kwargs: Additional configuration overrides

    Returns:
        box.Box: The resolved configuration object
    """
    spec = YapconfSpec(SPECIFICATION, env_prefix="BG_")

    sources = []

    if kwargs:
        # First deprecate / translate items with multiple names
        mangled_kwargs = _translate_kwargs(**kwargs)

        # Metadata is a little weird because yapconf doesn't support raw dicts, so we
        # need to make it a json string in that case
        metadata = kwargs.get("metadata")
        if isinstance(metadata, dict):
            mangled_kwargs["metadata"] = json.dumps(metadata)

        sources.append(("kwargs", mangled_kwargs))

    if cli_args:
        if cli_args is True:
            sources.append("CLI")
        else:
            if not argument_parser:
                argument_parser = ArgumentParser()
                spec.add_arguments(argument_parser)

            parsed_args, unknown = argument_parser.parse_known_args(cli_args)
            sources.append(("cli_args", vars(parsed_args)))

    if environment:
        sources.append("ENVIRONMENT")

    try:
        config = spec.load_config(*sources, bootstrap=bootstrap)
    except YapconfItemNotFound as ex:
        if ex.item.name == "bg_host":
            raise ValidationError(
                "Unable to create a plugin without a Beer-garden host. Please specify "
                "one on the command line (--bg-host), in the environment (BG_HOST), or "
                "in kwargs (bg_host).")
        raise

    # Make sure the url_prefix is normal
    if "bg_url_prefix" in config:
        config.bg_url_prefix = normalize_url_prefix(config.bg_url_prefix)

    return config
Пример #24
0
def real_world_spec():
    """YapconfSpec based on a 'real-world' example"""
    current_dir = os.path.abspath(os.path.dirname(__file__))
    filename = os.path.join(current_dir, 'files', 'real_world', 'spec.yaml')
    return YapconfSpec(filename, file_type='yaml', env_prefix='MY_APP_')
Пример #25
0
def generate_logging_config():
    spec = YapconfSpec(SPECIFICATION, env_prefix="BG_")
    bg_utils.generate_logging_config_file(spec, get_default_logging_config,
                                          sys.argv[1:])
Пример #26
0
def migrate_config():
    spec = YapconfSpec(SPECIFICATION, env_prefix="BG_")
    bg_utils.update_config_file(spec, sys.argv[1:])
Пример #27
0
class HttpInitTest(unittest.TestCase):
    def setUp(self):
        self.spec = YapconfSpec(SPECIFICATION)
        bg.config = None
        bg.io_loop = None
        bg.logger = None
        bg.thrift_context = None

    def tearDown(self):
        bg.config = None
        bg.io_loop = None
        bg.logger = None
        bg.thrift_context = None

    @patch("bg_utils.setup_application_logging", Mock())
    @patch("brew_view.setup_database", Mock())
    @patch("brew_view.load_plugin_logging_config", Mock())
    @patch("brew_view.HTTPServer.listen", Mock())
    def test_setup_no_file(self):
        bg.setup(self.spec, {})
        self.assertIsInstance(bg.config, Box)
        self.assertIsInstance(bg.logger, logging.Logger)
        self.assertIsNotNone(bg.thrift_context)
        self.assertIsInstance(bg.io_loop, IOLoop)

    def test_setup_tornado_app(self):
        bg.config = self.spec.load_config({"web": {"url_prefix": "/"}})
        app = bg._setup_tornado_app()
        self.assertIsInstance(app, Application)

    def test_setup_tornado_app_debug_true(self):
        bg.config = self.spec.load_config({
            "debug_mode": True,
            "web": {
                "url_prefix": "/"
            }
        })
        app = bg._setup_tornado_app()
        self.assertTrue(app.settings.get("autoreload"))

    def test_setup_ssl_context_ssl_not_enabled(self):
        bg.config = self.spec.load_config({"web": {"ssl": {"enabled": False}}})
        server_ssl, client_ssl = bg._setup_ssl_context()
        self.assertIsNone(server_ssl)
        self.assertIsNone(client_ssl)

    @patch("brew_view.ssl")
    def test_setup_ssl_context_ssl_enabled(self, ssl_mock):
        bg.config = self.spec.load_config({
            "web": {
                "ssl": {
                    "enabled": True,
                    "public_key": "/path/to/public.key",
                    "private_key": "/path/to/private.key",
                    "ca_cert": "/path/to/ca/file",
                    "ca_path": "/path/to/ca/path",
                }
            }
        })
        server_context = Mock()
        client_context = Mock()
        ssl_mock.create_default_context.side_effect = [
            server_context, client_context
        ]

        bg._setup_ssl_context()
        server_context.load_cert_chain.assert_called_with(
            certfile="/path/to/public.key", keyfile="/path/to/private.key")
        client_context.load_cert_chain.assert_called_with(
            certfile="/path/to/public.key", keyfile="/path/to/private.key")
        server_context.load_verify_locations.assert_called_with(
            cafile="/path/to/ca/file", capath="/path/to/ca/path")
        client_context.load_verify_locations.assert_called_with(
            cafile="/path/to/ca/file", capath="/path/to/ca/path")

    @patch("brew_view.PluginLoggingLoader")
    def test_load_plugin_logging_config(self, PluginLoggingLoaderMock):
        app_config = Mock()
        app_config.plugin_logging.config_file = "plugin_log_config"
        app_config.plugin_logging.level = "INFO"

        bg.app_logging_config = "app_logging_config"
        loader_mock = Mock()
        PluginLoggingLoaderMock.return_value = loader_mock
        bg.load_plugin_logging_config(app_config)
        loader_mock.load.assert_called_with(
            filename="plugin_log_config",
            level="INFO",
            default_config="app_logging_config",
        )
Пример #28
0
class BeerGardenTest(unittest.TestCase):
    def setUp(self):
        self.spec = YapconfSpec(SPECIFICATION)
        bg.config = None
        bg.io_loop = None
        bg.logger = None
        bg.thrift_context = None

    def tearDown(self):
        bg.config = None
        bg.io_loop = None
        bg.logger = None
        bg.thrift_context = None

    @patch('bg_utils.setup_application_logging', Mock())
    @patch('bg_utils.setup_database', Mock())
    @patch('brew_view.load_plugin_logging_config', Mock())
    @patch('brew_view.HTTPServer.listen', Mock())
    def test_setup_no_file(self):
        bg.setup(self.spec, {})
        self.assertIsInstance(bg.config, Box)
        self.assertIsInstance(bg.logger, logging.Logger)
        self.assertIsNotNone(bg.thrift_context)
        self.assertIsInstance(bg.io_loop, IOLoop)

    def test_setup_tornado_app(self):
        bg.config = self.spec.load_config({'web': {'url_prefix': '/'}})
        app = bg._setup_tornado_app()
        self.assertIsInstance(app, Application)

    def test_setup_tornado_app_debug_true(self):
        bg.config = self.spec.load_config({
            'debug_mode': True,
            'web': {
                'url_prefix': '/'
            }
        })
        app = bg._setup_tornado_app()
        self.assertTrue(app.settings.get('autoreload'))

    def test_setup_ssl_context_ssl_not_enabled(self):
        bg.config = self.spec.load_config({'web': {'ssl': {'enabled': False}}})
        server_ssl, client_ssl = bg._setup_ssl_context()
        self.assertIsNone(server_ssl)
        self.assertIsNone(client_ssl)

    @patch('brew_view.ssl')
    def test_setup_ssl_context_ssl_enabled(self, ssl_mock):
        bg.config = self.spec.load_config({
            'web': {
                'ssl': {
                    'enabled': True,
                    'public_key': '/path/to/public.key',
                    'private_key': '/path/to/private.key',
                    'ca_cert': '/path/to/ca/file',
                    'ca_path': '/path/to/ca/path',
                }
            }
        })
        server_context = Mock()
        client_context = Mock()
        ssl_mock.create_default_context.side_effect = [
            server_context, client_context
        ]

        bg._setup_ssl_context()
        server_context.load_cert_chain.assert_called_with(
            certfile='/path/to/public.key', keyfile='/path/to/private.key')
        client_context.load_cert_chain.assert_called_with(
            certfile='/path/to/public.key', keyfile='/path/to/private.key')
        server_context.load_verify_locations.assert_called_with(
            cafile='/path/to/ca/file', capath='/path/to/ca/path')
        client_context.load_verify_locations.assert_called_with(
            cafile='/path/to/ca/file', capath='/path/to/ca/path')

    @patch('brew_view.PluginLoggingLoader')
    def test_load_plugin_logging_config(self, PluginLoggingLoaderMock):
        app_config = Mock()
        app_config.plugin_logging.config_file = "plugin_log_config"
        app_config.plugin_logging.level = "INFO"

        bg.app_logging_config = "app_logging_config"
        loader_mock = Mock()
        PluginLoggingLoaderMock.return_value = loader_mock
        bg.load_plugin_logging_config(app_config)
        loader_mock.load.assert_called_with(
            filename="plugin_log_config",
            level="INFO",
            default_config="app_logging_config")
Пример #29
0
 def setUp(self):
     self.spec = YapconfSpec(SPECIFICATION)
     bg.config = None
     bg.io_loop = None
     bg.logger = None
     bg.thrift_context = None
Пример #30
0
def basic_spec(simple_item_spec):
    """Most basic spec you can have"""
    return YapconfSpec(simple_item_spec)