Exemplo n.º 1
0
    def validate_update_configuration_request(cls, configuration):
        errors = {}

        # <editor-fold desc="Validate Server options">
        if not Utility.is_valid_server_password(
                configuration['SERVER_PASSWORD']):
            errors['serverPassword'] = '******'

        if not Utility.is_valid_loopback_hostname(
                configuration['SERVER_HOSTNAME_LOOPBACK']):
            errors['serverHostnameLoopback'] = 'Must be a valid loopback IP address or hostname\n' \
                                               'Recommended value => {0}'.format(DEFAULT_HOSTNAME_LOOPBACK)

        if not Utility.is_valid_private_hostname(
                configuration['SERVER_HOSTNAME_PRIVATE']):
            if not Utility.is_valid_public_hostname(
                    configuration['SERVER_HOSTNAME_PRIVATE']):
                private_ip_address = Utility.determine_private_ip_address()

                errors[
                    'serverHostnamePrivate'] = 'Must be a valid private IP address, public IP address, or hostname'

                if private_ip_address:
                    errors[
                        'serverHostnamePrivate'] += '\nRecommended value => {0}'.format(
                            private_ip_address)

        if not Utility.is_valid_public_hostname(
                configuration['SERVER_HOSTNAME_PUBLIC']):
            public_ip_address = Utility.determine_public_ip_address()

            errors[
                'serverHostnamePublic'] = 'Must be a valid public IP address or hostname'

            if public_ip_address:
                errors[
                    'serverHostnamePublic'] += '\nRecommended value => {0}'.format(
                        public_ip_address)

        if not Utility.is_valid_port_number(configuration['SERVER_HTTP_PORT']):
            errors['serverPort'] = 'Must be a number between 0 and 65535'
        # </editor-fold>

        for provider_name in sorted(
                ProvidersController.get_providers_map_class()):
            ProvidersController.get_provider_map_class(
                provider_name).configuration_class(
                ).validate_update_configuration_request(configuration, errors)

        return errors
Exemplo n.º 2
0
    def read_configuration_file(cls, initial_read=True):
        with cls._lock.writer_lock:
            cls._backup_configuration()

            try:
                configuration_object = ConfigObj(cls._configuration_file_path,
                                                 file_error=True,
                                                 indent_type='',
                                                 interpolation=False,
                                                 raise_errors=True,
                                                 write_empty_values=True)

                configuration_object_md5 = hashlib.md5(
                    '{0}'.format(configuration_object).encode()).hexdigest()

                configuration = {}
                providers = []

                non_defaultable_error = False
                error_message_to_log = []
                message_to_log = []

                password = None
                hostname_loopback = DEFAULT_HOSTNAME_LOOPBACK
                hostname_private = None
                hostname_public = None
                http_port = None
                https_port = None

                # <editor-fold desc="Read Server section">
                try:
                    server_section = configuration_object['Server']

                    try:
                        password = server_section['password']
                    except KeyError:
                        non_defaultable_error = True

                        error_message_to_log.append(
                            'Could not find a password option in the [Server] section\n'
                        )

                    try:
                        server_hostnames_section = server_section['Hostnames']

                        # <editor-fold desc="Read loopback option">
                        try:
                            hostname_loopback = server_hostnames_section[
                                'loopback']

                            if not Utility.is_valid_loopback_hostname(
                                    hostname_loopback):
                                error_message_to_log.append(
                                    'The loopback option in the [Hostnames] section has an invalid loopback hostname\n'
                                    'Defaulting to {0}\n'.format(
                                        DEFAULT_HOSTNAME_LOOPBACK))
                        except KeyError:
                            hostname_loopback = DEFAULT_HOSTNAME_LOOPBACK

                            error_message_to_log.append(
                                'The loopback option in the [Hostnames] section is missing\n'
                                'Defaulting to {0}\n'.format(
                                    DEFAULT_HOSTNAME_LOOPBACK))
                        # </editor-fold>

                        # <editor-fold desc="Read private option">
                        do_determine_private_ip_address = False

                        try:
                            hostname_private = server_hostnames_section[
                                'private']

                            if not Utility.is_valid_private_hostname(
                                    hostname_private):
                                if Utility.is_valid_public_hostname(
                                        hostname_private):
                                    error_message_to_log.append(
                                        'The private option in the [Hostnames] section has a public IP address\n'
                                    )
                                else:
                                    do_determine_private_ip_address = True
                        except KeyError:
                            do_determine_private_ip_address = True
                        # </editor-fold>

                        # <editor-fold desc="Read public option">
                        do_determine_public_ip_address = False

                        try:
                            hostname_public = server_hostnames_section[
                                'public']
                            if not Utility.is_valid_public_hostname(
                                    hostname_public):
                                do_determine_public_ip_address = True
                        except KeyError:
                            do_determine_public_ip_address = True
                        # </editor-fold>
                    except KeyError:
                        error_message_to_log.append(
                            'Could not find a [Hostnames] section in the [Server] section\n'
                        )

                        hostname_loopback = DEFAULT_HOSTNAME_LOOPBACK

                        do_determine_private_ip_address = True
                        do_determine_public_ip_address = True

                    if do_determine_private_ip_address:
                        hostname_private = Utility.determine_private_ip_address(
                        )

                        if hostname_private:
                            error_message_to_log.append(
                                'The private option in the [Hostnames] section has an invalid private IP address\n'
                                'Reverting to {0}\n'.format(hostname_private))

                    if do_determine_public_ip_address:
                        hostname_public = Utility.determine_public_ip_address()

                        if hostname_public:
                            error_message_to_log.append(
                                'The public option in the [Hostnames] section has an invalid public IP address\n'
                                'Reverting to {0}\n'.format(hostname_public))

                    try:
                        server_ports_section = server_section['Ports']

                        # <editor-fold desc="Read http option">
                        try:
                            http_port = server_ports_section['http']
                            if not Utility.is_valid_port_number(http_port):
                                non_defaultable_error = True

                                error_message_to_log.append(
                                    'The http option in the [Ports] section must be a number between 0 and 65535\n'
                                )
                        except KeyError:
                            non_defaultable_error = True

                            error_message_to_log.append(
                                'Could not find an http option in the [Ports] section\n'
                                'The http option in the [Ports] section must be a number between 0 and 65535\n'
                            )
                        # </editor-fold>

                        # <editor-fold desc="Read https option">
                        try:
                            https_port = server_ports_section['https']
                            if not Utility.is_valid_port_number(https_port):
                                non_defaultable_error = True

                                error_message_to_log.append(
                                    'The https option in the [Ports] section must be a number between 0 and 65535\n'
                                )
                        except KeyError:
                            non_defaultable_error = True

                            error_message_to_log.append(
                                'Could not find an https option in the [Ports] section\n'
                                'The https option in the [Ports] section must be a number between 0 and 65535\n'
                            )
                        # </editor-fold>
                    except KeyError:
                        non_defaultable_error = True

                        error_message_to_log.append(
                            'Could not find a [Ports] section in the [Server] section\n'
                        )
                except KeyError:
                    non_defaultable_error = True

                    error_message_to_log.append(
                        'Could not find a [Server] section\n')
                # </editor-fold>

                if not non_defaultable_error:
                    configuration = {
                        'SERVER_PASSWORD': password,
                        'SERVER_HOSTNAME_LOOPBACK': hostname_loopback,
                        'SERVER_HOSTNAME_PRIVATE': hostname_private,
                        'SERVER_HOSTNAME_PUBLIC': hostname_public,
                        'SERVER_HTTP_PORT': http_port,
                        'SERVER_HTTPS_PORT': https_port
                    }

                    message_to_log = [
                        '{0}ead configuration file\n'
                        'Configuration file path          => {1}\n\n'
                        'SERVER_PASSWORD                  => {2}\n'
                        'SERVER_HOSTNAME_LOOPBACK         => {3}\n'
                        'SERVER_HOSTNAME_PRIVATE          => {4}\n'
                        'SERVER_HOSTNAME_PUBLIC           => {5}\n'
                        'SERVER_HTTP_PORT                 => {6}\n'
                        'SERVER_HTTPS_PORT                => {7}'.format(
                            'R' if initial_read else 'Rer',
                            cls._configuration_file_path, password,
                            hostname_loopback, hostname_private,
                            hostname_public, http_port, https_port)
                    ]

                for provider_name in sorted(
                        ProvidersController.get_providers_map_class()):
                    ProvidersController.get_provider_map_class(
                        provider_name).configuration_class(
                        ).read_configuration_file(configuration_object,
                                                  configuration, providers,
                                                  message_to_log,
                                                  error_message_to_log)

                if not non_defaultable_error:
                    logger.info('\n'.join(message_to_log))

                    cls._set_configuration(configuration)

                    if configuration_object_md5 != hashlib.md5('{0}'.format(
                            configuration_object).encode()).hexdigest():
                        cls._update_configuration_file(configuration_object)

                    if initial_read:
                        ProvidersController.initialize_providers(providers)

                if error_message_to_log:
                    error_message_to_log.insert(
                        0, '{0} configuration file values\n'
                        'Configuration file path => {1}\n'.format(
                            'Invalid'
                            if non_defaultable_error else 'Warnings regarding',
                            cls._configuration_file_path))

                    if initial_read and non_defaultable_error:
                        error_message_to_log.append('Exiting...')
                    elif non_defaultable_error:
                        error_message_to_log.append(
                            'Configuration file skipped')
                    else:
                        error_message_to_log.append(
                            'Configuration file processed')

                    logger.error('\n'.join(error_message_to_log))

                    if initial_read and non_defaultable_error:
                        sys.exit()
            except OSError:
                logger.error(
                    'Could not open the specified configuration file for reading\n'
                    'Configuration file path => {0}'
                    '{1}'.format(cls._configuration_file_path,
                                 '\n\nExiting...' if initial_read else ''))

                if initial_read:
                    sys.exit()
            except SyntaxError as e:
                logger.error('Invalid configuration file syntax\n'
                             'Configuration file path => {0}\n'
                             '{1}'
                             '{2}'.format(
                                 cls._configuration_file_path, '{0}'.format(e),
                                 '\n\nExiting...' if initial_read else ''))

                if initial_read:
                    sys.exit()