def process(name, config, directory, config_translator=None): """ Configures Nginx based on the input configuration. Supports Document Root and Gzip settings. :param name: Name of this section of the configuration :param config: The configuration dictionary for this section :param directory: The directory in which the input files are mounted :param config_translator: Optional callable method for preprocessing config items :return: """ for required_key in ['configuration_file_name']: if required_key not in config: raise Exception( 'Required key %s not present in %s section of internal configuration' % (name, required_key)) logger.info('Configuring %s' % name) try: custom_values, file_format = custom_files.read_custom_file( os.path.join(directory, config['configuration_file_name'])) except Exception as file_reading_exception: logger.error( str(file_reading_exception)) # don't log the full stack trace logger.info('Not configuring %s (not a critical failure)' % name) return # abort but don't fail assert custom_values is not None and isinstance(custom_values, dict) if config_translator: for key, value in custom_values.iteritems(): custom_values[key] = config_translator.process(key, value) nginx_directory = os.path.join('etc', 'nginx') sites_enabled_directory = os.path.join(nginx_directory, 'sites-enabled') # # Document Root # document_root_key = 'DOCUMENT_ROOT' document_root_default = 'html' if document_root_key.lower() in custom_values: document_root = custom_values[document_root_key.lower()] if os.environ.get(document_root_key, document_root_default) not in [ document_root, document_root_default ]: raise Exception( 'Legacy %s variable is present with a conflicting value' % document_root_key) document_root_path = os.path.join('var', 'www', document_root) if not os.path.exists(document_root_path): os.makedirs(document_root_path) # # Update the on disk well known location so that other scripts # which need to know the document root can look it up. # with open(os.path.join('etc', document_root_key), 'w') as file_handle: file_handle.write("%s\n" % document_root) # # Update the nginx configuration # variable_regex = re.compile('\${?%s}?' % document_root_key) root_command_regex = re.compile('root /var/www/.*;') new_root_command = 'root /var/www/%s;' % document_root for file_path in os.listdir(sites_enabled_directory): full_file_path = os.path.join(sites_enabled_directory, file_path) if os.path.isfile(full_file_path): write_needed = False with open(full_file_path, 'r') as file_handle: lines = file_handle.readlines() for index, line in enumerate(lines): lines[index] = variable_regex.sub( document_root, lines[index]) lines[index] = root_command_regex.sub( new_root_command, lines[index]) write_needed = write_needed or lines[index] != line if write_needed: with open(full_file_path, 'w') as file_handle: file_handle.writelines(lines) logger.info('%13s = %s' % (document_root_key, document_root)) # # Gzip # gzip_key = 'gzip' if gzip_key in custom_values: gzip = False if custom_values['gzip'].strip().upper() != 'OFF': gzip = True gzip_level = custom_values[gzip_key] # # Update the nginx configuration # gzip_command_regex = re.compile('gzip \w*;') new_gzip_command = 'gzip %s;' % 'on' if gzip else 'off' if gzip: gzip_level_command_regex = re.compile('gzip_comp_level \d*;') new_gzip_level_command = 'gzip_comp_level %s;' % gzip_level full_file_path = os.path.join(nginx_directory, 'conf.d', 'gzip.conf') if os.path.isfile(full_file_path): write_needed = False with open(full_file_path, 'r') as file_handle: # Read lines = file_handle.readlines() # Modify for index, line in enumerate(lines): lines[index] = gzip_command_regex.sub( new_gzip_command, lines[index]) if gzip: lines[index] = gzip_level_command_regex.sub( new_gzip_level_command, lines[index]) write_needed = write_needed or lines[index] != line # Write if write_needed: with open(full_file_path, 'w') as file_handle: file_handle.writelines(lines) logger.info('%13s = %s' % (gzip_key.upper(), gzip_level))
def process(name, config, directory, config_translator=None): """ Configures Nginx based on the input configuration. Supports Document Root and Gzip settings. :param name: Name of this section of the configuration :param config: The configuration dictionary for this section :param directory: The directory in which the input files are mounted :param config_translator: Optional callable method for preprocessing config items :return: """ for required_key in [ 'configuration_file_name' ]: if required_key not in config: raise Exception( 'Required key %s not present in %s section of internal configuration' % (name, required_key) ) logger.info('Configuring %s' % name) try: custom_values, file_format = custom_files.read_custom_file( os.path.join(directory, config['configuration_file_name']) ) except Exception as file_reading_exception: logger.error(str(file_reading_exception)) # don't log the full stack trace logger.info('Not configuring %s (not a critical failure)' % name) return # abort but don't fail assert custom_values is not None and isinstance(custom_values, dict) if config_translator: for key, value in custom_values.iteritems(): custom_values[key] = config_translator.process(key, value) nginx_directory = os.path.join('etc', 'nginx') sites_enabled_directory = os.path.join(nginx_directory, 'sites-enabled') # # Document Root # document_root_key = 'DOCUMENT_ROOT' document_root_default = 'html' if document_root_key.lower() in custom_values: document_root = custom_values[document_root_key.lower()] if os.environ.get(document_root_key, document_root_default) not in [document_root, document_root_default]: raise Exception('Legacy %s variable is present with a conflicting value' % document_root_key) document_root_path = os.path.join('var', 'www', document_root) if not os.path.exists(document_root_path): os.makedirs(document_root_path) # # Update the on disk well known location so that other scripts # which need to know the document root can look it up. # with open(os.path.join('etc', document_root_key), 'w') as file_handle: file_handle.write("%s\n" % document_root) # # Update the nginx configuration # variable_regex = re.compile('\${?%s}?' % document_root_key) root_command_regex = re.compile('root /var/www/.*;') new_root_command = 'root /var/www/%s;' % document_root for file_path in os.listdir(sites_enabled_directory): full_file_path = os.path.join(sites_enabled_directory, file_path) if os.path.isfile(full_file_path): write_needed = False with open(full_file_path, 'r') as file_handle: lines = file_handle.readlines() for index, line in enumerate(lines): lines[index] = variable_regex.sub(document_root, lines[index]) lines[index] = root_command_regex.sub(new_root_command, lines[index]) write_needed = write_needed or lines[index] != line if write_needed: with open(full_file_path, 'w') as file_handle: file_handle.writelines(lines) logger.info('%13s = %s' % (document_root_key, document_root)) # # Gzip # gzip_key = 'gzip' if gzip_key in custom_values: gzip = False if custom_values[gzip_key].strip().upper() != 'OFF': gzip = True gzip_level = custom_values[gzip_key] else: gzip_level = '0' # # Update the nginx configuration # gzip_command_regex = re.compile('gzip \w*;') new_gzip_command = 'gzip on;' if gzip else 'gzip off;' if gzip: gzip_level_command_regex = re.compile('gzip_comp_level \d*;') new_gzip_level_command = 'gzip_comp_level %s;' % gzip_level full_file_path = os.path.join(nginx_directory, 'conf.d', 'gzip.conf') if os.path.isfile(full_file_path): write_needed = False with open(full_file_path, 'r') as file_handle: # Read lines = file_handle.readlines() # Modify for index, line in enumerate(lines): lines[index] = gzip_command_regex.sub(new_gzip_command, lines[index]) if gzip: lines[index] = gzip_level_command_regex.sub(new_gzip_level_command, lines[index]) write_needed = write_needed or lines[index] != line # Write if write_needed: with open(full_file_path, 'w') as file_handle: file_handle.writelines(lines) logger.info('%13s = %s' % (gzip_key.upper(), gzip_level))
def process(name, config, directory): """ Requires the input file (configuration_file_name) in directory to be multidimensional representation of overrides for the target file (ini_file_path). Input may be any format. Output will always be an ini file. :param name: Name of this section of the configuration :param config: The configuration dictionary for this section :param directory: The directory in which the input files are mounted :return: """ for required_key in [ 'ini_file_path', 'configuration_file_name' ]: if required_key not in config: raise Exception( 'Required key %s not present in %s section of internal configuration' % (name, required_key) ) logger.info('Configuring %s' % name) error_occurred_while_reading_an_input_file = False try: current_values, file_format = custom_files.read_custom_file( config['ini_file_path'] ) except Exception as file_reading_exception: logger.error(str(file_reading_exception)) # don't log the full stack trace error_occurred_while_reading_an_input_file = True try: custom_values, file_format = custom_files.read_custom_file( os.path.join(directory, config['configuration_file_name']) ) except Exception as file_reading_exception: logger.error(str(file_reading_exception)) # don't log the full stack trace error_occurred_while_reading_an_input_file = True if error_occurred_while_reading_an_input_file: logger.info('Not configuring %s (not a critical failure)' % name) return # abort but don't fail assert custom_values is not None and isinstance(current_values, dict) assert custom_values is not None and isinstance(custom_values, dict) resulting_file = ConfigParser.ConfigParser() for section_name in set(current_values.keys() + custom_values.keys()): resulting_file.add_section(section_name) for section_name in current_values.keys(): if not isinstance(current_values[section_name], dict): logger.error('%s is not a valid section in current values' % section_name) continue for key, value in current_values[section_name].items(): resulting_file.set(section_name, key, value) display_values = {} for section_name in custom_values.keys(): if not isinstance(custom_values[section_name], dict): logger.error('%s is not a valid section in custom values' % section_name) continue for key, value in custom_values[section_name].items(): display_values['%s/%s' % (section_name, key)] = value resulting_file.set(section_name, key, value) length = len(max(display_values.keys(), key=len)) for key in sorted(display_values.keys()): logger.info('%s = %s' % (key.rjust(length, ' '), display_values[key])) logger.info('Writing %s' % config['ini_file_path']) with open(config['ini_file_path'], 'wb') as file_handle: resulting_file.write(file_handle)
def process(name, config, directory, config_translator): """ Requires the input file (configuration_file_name) in directory to be multidimensional representation of overrides for the target file (ini_file_path). Input may be any format. Output will always be an ini file. :param name: Name of this section of the configuration :param config: The configuration dictionary for this section :param directory: The directory in which the input files are mounted :return: """ for required_key in ['ini_file_path', 'configuration_file_name']: if required_key not in config: raise Exception( 'Required key %s not present in %s section of internal configuration' % (required_key, name)) logger.info('Configuring %s' % name) error_occurred_while_reading_an_input_file = False try: current_values, file_format = custom_files.read_custom_file( config['ini_file_path']) except Exception as file_reading_exception: logger.error( str(file_reading_exception)) # don't log the full stack trace error_occurred_while_reading_an_input_file = True try: custom_values, file_format = custom_files.read_custom_file( os.path.join(directory, config['configuration_file_name'])) except Exception as file_reading_exception: logger.error( str(file_reading_exception)) # don't log the full stack trace error_occurred_while_reading_an_input_file = True if error_occurred_while_reading_an_input_file: logger.info('Not configuring %s (not a critical failure)' % name) return # abort but don't fail assert custom_values is not None and isinstance(current_values, dict) assert custom_values is not None and isinstance(custom_values, dict) resulting_file = ConfigParser.ConfigParser(allow_no_value=True) for section_name in set(current_values.keys() + custom_values.keys()): resulting_file.add_section(section_name) for section_name in current_values.keys(): if not isinstance(current_values[section_name], dict): logger.error('%s is not a valid section in current values' % section_name) continue for key, value in current_values[section_name].items(): resulting_file.set(section_name, key, value) display_values = {} for section_name in custom_values.keys(): if not isinstance(custom_values[section_name], dict): logger.error('%s is not a valid section in custom values' % section_name) continue for key, value in custom_values[section_name].items(): if config_translator: value = config_translator.process(key, value) display_values['%s/%s' % (section_name, key)] = value resulting_file.set(section_name, key, value) length = len(max(display_values.keys(), key=len)) for key in sorted(display_values.keys()): logger.info('%s = %s' % (key.rjust(length, ' '), display_values[key])) logger.info('Writing %s' % config['ini_file_path']) with open(config['ini_file_path'], 'wb') as file_handle: resulting_file.write(file_handle)
def process(name, config, directory, config_translator=None): """ Configures Apache 2 based on the input configuration. Supports Document Root and Gzip settings. :param name: Name of this section of the configuration :param config: The configuration dictionary for this section :param directory: The directory in which the input files are mounted :param config_translator: Optional callable method for preprocessing config items :return: """ for required_key in [ 'configuration_file_name' ]: if required_key not in config: raise Exception( 'Required key %s not present in %s section of internal configuration' % (name, required_key) ) logger.info('Configuring %s' % name) try: custom_values, file_format = custom_files.read_custom_file( os.path.join(directory, config['configuration_file_name']) ) except Exception as file_reading_exception: logger.error(str(file_reading_exception)) # don't log the full stack trace logger.info('Not configuring %s (not a critical failure)' % name) return # abort but don't fail assert custom_values is not None and isinstance(custom_values, dict) if config_translator: for key, value in custom_values.iteritems(): custom_values[key] = config_translator.process(key, value) apache2_directory = os.path.join('etc', 'apache2') sites_enabled_directory = os.path.join(apache2_directory, 'sites-enabled') conf_enabled_directory = os.path.join(apache2_directory, 'conf-enabled') mods_enabled_directory = os.path.join(apache2_directory, 'mods-enabled') document_root_key = 'DOCUMENT_ROOT' document_root_default = 'html' if document_root_key.lower() in custom_values: document_root = custom_values[document_root_key.lower()] document_root_path = os.path.join('var', 'www', document_root) if not os.path.exists(document_root_path): os.makedirs(document_root_path) regex = re.compile('\${?%s}?' % document_root_key) if os.environ.get(document_root_key, document_root_default) not in [document_root, document_root_default]: raise Exception('Legacy %s variable is present with a conflicting value' % document_root_key) # # Update the on disk well known location so that other scripts # which need to know the document root can look it up. # with open(os.path.join('etc', document_root_key), 'w') as file_handle: file_handle.write("%s\n" % document_root) # # Update the apache configuration # for target_directory in [sites_enabled_directory, conf_enabled_directory, mods_enabled_directory]: for file_path in os.listdir(target_directory): full_file_path = os.path.join(target_directory, file_path) if os.path.isfile(full_file_path): write_needed = False with open(full_file_path, 'r') as file_handle: lines = file_handle.readlines() for index, line in enumerate(lines): lines[index] = regex.sub(document_root, lines[index]) write_needed = write_needed or lines[index] != line if write_needed: with open(full_file_path, 'w') as file_handle: file_handle.writelines(lines) logger.info('%14s = %s' % (document_root_key, document_root)) gzip_key = 'gzip' if gzip_key in custom_values: gzip = True if custom_values['gzip'].strip().upper() != 'OFF': gzip_level = custom_values[gzip_key] else: gzip_level = None gzip = False # # Update the apache configuration # for file_path in os.listdir(mods_enabled_directory): if file_path not in ['deflate.conf', 'deflate.load']: continue full_file_path = os.path.join(mods_enabled_directory, file_path) if not gzip: # Remove the configuration to disable gzip os.unlink(full_file_path) if gzip and file_path.endswith('.conf'): # Add the level directive to the bottom of the configuration with open(full_file_path, 'a') as file_handle: file_handle.write( "DeflateCompressionLevel %s\n" % gzip_level ) if gzip_level: logger.info('%14s = %s' % (gzip_key.upper(), gzip_level)) if 'fancy_indexing' in custom_values: mod_alias_file = "/etc/apache2/mods-available/alias.conf" mod_alias_content = "" with open(mod_alias_file) as fd: mod_alias_content = fd.readlines() fancy_indexing = custom_values['fancy_indexing'] new_mod_alias_content = [] found = False for mod_alias_content_line in mod_alias_content: if mod_alias_content_line.find("Alias /icons/ \"/usr/share/apache2/icons/\"") > -1: found = True if fancy_indexing: new_mod_alias_content.append("\tAlias /icons/ \"/usr/share/apache2/icons/\"\n") else: new_mod_alias_content.append("\t# Alias /icons/ \"/usr/share/apache2/icons/\"\n") else: new_mod_alias_content.append(mod_alias_content_line) mod_alias_content = new_mod_alias_content new_mod_alias_content = [] if not found and fancy_indexing: for mod_alias_content_line in mod_alias_content: if mod_alias_content_line.find("<Directory") > -1: new_mod_alias_content.append("\tAlias /icons/ \"/usr/share/apache2/icons/\"\n\n") new_mod_alias_content.append(mod_alias_content_line) mod_alias_content = new_mod_alias_content with open(mod_alias_file, 'w') as fd: for mod_alias_content_line in mod_alias_content: fd.write(mod_alias_content_line) logger.info('%14s = %s' % ("FANCY INDEXING", str(fancy_indexing)))