Example #1
0
    def _ssl_file(cls, filename):
        """Test that given SSL/TLS certificate or key file exist."""

        if filename is not None and not os.path.isfile(filename):
            Logger.print_status(
                'NOK: cannot run secured server because ssl/tls certificate file cannot be read: {}'
                .format(filename))
            sys.exit(1)

        return filename
Example #2
0
    def on_exit(server):
        """Gunicorn server exit hook.

        This is used to tell user that the server has been stopped.

        Args:
            server (obj): Gunicorn Arbiter() class object.
        """

        Logger.print_status('snippy server stopped at: {}'.format(server.app.options['snippy_host']))
Example #3
0
    def post_worker_init(worker):
        """Gunicorn worker initialized hook.

        This is called by the Gunicorn framework after a worker has been
        initialized. This is used to tell user that the server is running.
        Gunicorn server listen IP address is printed from workber because
        of a use where a random free ephemeral port is selected by OS.

        Args:
            worker (obj): Gunicorn Worker() class object.
        """

        listeners = ','.join([str(l) for l in worker.sockets])
        Logger.print_status('snippy server running at: {}'.format(listeners))
Example #4
0
    def server_schema_base_uri(cls):
        """Get server API schema base URI.

        Returns:
            str: Path where the API schema is stored in URI format.
        """

        filepath = pkg_resources.resource_filename(
            'snippy', 'data/server/openapi/schema/')
        if not os.path.isdir(filepath):
            Logger.print_status(
                'NOK: cannot run because server api schema base uri is not accessible: {}'
                .format(filepath))
            sys.exit(1)

        return 'file:' + filepath
Example #5
0
    def _test_resource(path, filename):
        """Test if Snippy resource exists.

        Args:
            path (str): Relative path under the snippy project.
            filename (str): Resource filename.

        Returns:
            str: File if the resource exists.
        """

        filename = os.path.join(
            pkg_resources.resource_filename('snippy', path), filename)
        if not os.path.isfile(filename):
            Logger.print_status(
                'NOK: cannot run because snippy resource file is not accessible: {}'
                .format(filename))
            sys.exit(1)

        return filename
Example #6
0
    def _storage_file(cls):
        """Construct store file with absolute path.

        The in-memory database is supported only in Python 3. The Sqlite, which
        is used as a in-memory database, supports this feature only in Python 3.

        Returns:
            str: Path or URI to the storage.
        """

        if cls.source.run_healthcheck:
            return Const.EMPTY

        if Config.storage_type == Const.DB_IN_MEMORY and not Const.PYTHON2:
            return 'file::memory:?cache=shared'

        if Config.storage_path:
            storage_path = Config.storage_path
        else:
            storage_path = pkg_resources.resource_filename(
                'snippy', 'data/storage')

        if os.path.exists(storage_path) and os.access(storage_path, os.W_OK):
            storage_file = os.path.join(storage_path, 'snippy.db')
        elif cls.source.server_readonly and os.path.exists(
                storage_path) and os.access(storage_path, os.R_OK):
            cls._logger.debug('running server in readonly mode')
            storage_file = os.path.join(storage_path, 'snippy.db')
        else:
            # This is a special case which prevents additional error log after
            # tool is already about to exit with help text from the CLI parser.
            if not cls.source.failure:
                Logger.print_status(
                    'NOK: cannot run because content storage path is not writable: {}'
                    .format(storage_path))
            sys.exit(1)

        return storage_file
Example #7
0
    def test_logger_007(capsys, caplog):
        """Test print_status with JSON logger

        Test case verifies print_status special treatment with JSON logs.
        """

        Logger.remove()

        # Even when logs are disbled, the print_status must output the
        # log in JSON format.
        caplog.clear()
        Logger.configure({
            'debug': False,
            'log_json': True,
            'log_msg_max': Logger.DEFAULT_LOG_MSG_MAX,
            'quiet': False,
            'very_verbose': False
        })
        Logger.print_status('snippy server running at: 127.0.0.1:8080')
        out, err = capsys.readouterr()
        assert not err
        assert json.loads(
            out.splitlines()
            [0])['message'] == 'snippy server running at: 127.0.0.1:8080'
        assert caplog.records[
            0].msg == 'snippy server running at: 127.0.0.1:8080'
        assert Field.is_iso8601(json.loads(out.splitlines()[0])['asctime'])

        # Because the debug and very_verbose options are not set, the JSON
        # log must not be printed because quiet is enabled.
        caplog.clear()
        Logger.configure({
            'debug': False,
            'log_json': True,
            'log_msg_max': Logger.DEFAULT_LOG_MSG_MAX,
            'quiet': True,
            'very_verbose': False
        })
        Logger.print_status('snippy server running at: 127.0.0.1:8080')
        out, err = capsys.readouterr()
        assert not err
        assert not out

        # Because the debug option have precedence over the quiet option,
        # the JSON log must be printed.
        caplog.clear()
        Logger.configure({
            'debug': True,
            'log_json': True,
            'log_msg_max': Logger.DEFAULT_LOG_MSG_MAX,
            'quiet': False,
            'very_verbose': False
        })
        Logger.print_status('snippy server running at: 127.0.0.1:8080')
        out, err = capsys.readouterr()
        assert not err
        assert json.loads(
            out.splitlines()
            [0])['message'] == 'snippy server running at: 127.0.0.1:8080'
        assert caplog.records[
            0].msg == 'snippy server running at: 127.0.0.1:8080'
        assert Field.is_iso8601(json.loads(out.splitlines()[0])['asctime'])

        # Because the very_verbose option have precedence over the quiet
        # option, the JSON log must be printed.
        caplog.clear()
        Logger.configure({
            'debug': False,
            'log_json': True,
            'log_msg_max': Logger.DEFAULT_LOG_MSG_MAX,
            'quiet': False,
            'very_verbose': True
        })
        Logger.print_status('snippy server running at: 127.0.0.1:8080')
        out, err = capsys.readouterr()
        assert not err
        assert json.loads(
            out.splitlines()
            [0])['message'] == 'snippy server running at: 127.0.0.1:8080'
        assert caplog.records[
            0].msg == 'snippy server running at: 127.0.0.1:8080'
        assert Field.is_iso8601(json.loads(out.splitlines()[0])['asctime'])
Example #8
0
    def test_logger_006(capsys, caplog):
        """Test logger basic usage.

        Test case verifies that quiet option works with different logger
        configuration combinations. This also verifies that the logger
        settings can be changed programmatically.
        """

        Logger.remove()

        # Cause is printed normally to stdout as is when log printing
        # is not activated by debug or very verbose options.
        caplog.clear()
        Logger.configure({
            'debug': False,
            'log_json': False,
            'log_msg_max': Logger.DEFAULT_LOG_MSG_MAX,
            'quiet': False,
            'very_verbose': False
        })
        Logger.print_status('NOK: exit cause')
        out, err = capsys.readouterr()
        assert not err
        assert out == 'NOK: exit cause\n'
        assert not caplog.records[:]

        # The quiet option prevents printing the cause as is to stdout.
        caplog.clear()
        Logger.configure({
            'debug': False,
            'log_json': False,
            'log_msg_max': Logger.DEFAULT_LOG_MSG_MAX,
            'quiet': True,
            'very_verbose': False
        })
        Logger.print_status('NOK: exit cause')
        out, err = capsys.readouterr()
        assert not err
        assert not out
        assert not caplog.records[:]

        # Because the very verbose log printing is enabled, the cause is
        # printed only in the log string with all lower case letters.
        caplog.clear()
        Logger.configure({
            'debug': False,
            'log_json': False,
            'log_msg_max': Logger.DEFAULT_LOG_MSG_MAX,
            'quiet': False,
            'very_verbose': True
        })
        Logger.print_status('NOK: exit cause')
        out, err = capsys.readouterr()
        assert not err
        assert 'nok: exit cause' in out
        assert caplog.records[0].msg == 'nok: exit cause'

        # Because the debug log printing is enabled, the cause is printed
        # only in the log string exactly the same as provided.
        caplog.clear()
        Logger.configure({
            'debug': True,
            'log_json': False,
            'log_msg_max': Logger.DEFAULT_LOG_MSG_MAX,
            'quiet': True,
            'very_verbose': False
        })
        Logger.print_status('NOK: exit cause')
        out, err = capsys.readouterr()
        assert not err
        assert 'NOK: exit cause' in out
        assert caplog.records[0].msg == 'NOK: exit cause'
Example #9
0
    def print_failure(cls):
        """Print only failure message."""

        if not cls.is_ok():
            Logger.print_status(cls.get_message())
Example #10
0
    def print_message(cls):
        """Print cause message."""

        Logger.print_status(cls.get_message())