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
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()