def check_pattoo_client(): """Ensure client configuration exists. Args: None Returns: True: if the client has been configured correctly """ # Print Status print('Checking client configuration parameters.') # Checks client config config_file = configuration.agent_config_filename('pattoo') config = files.read_yaml_file(config_file) # Check main keys keys = ['pattoo'] for key in keys: if key not in config: log_message = ('''\ Section "{}" not found in {} configuration file. Please fix.\ '''.format(key, config_file)) log.log2die_safe(20090, log_message) # Check secondary keys for 'pattoo' secondaries = [ 'log_level', 'log_directory', 'cache_directory', 'daemon_directory' ] secondary_key_check(config, 'pattoo', secondaries) # Print Status return True
def check_config(config_file, config_dict): """Ensure agent configuration exists. Args: config: The name of the configuration file config_dict: A dictionary containing the primary configuration keys and a list of the secondary keys Returns: None """ # Initialize key variables config_directory = os.environ['PATTOO_CONFIGDIR'] # Print Status print('??: Checking configuration parameters.') # Retrieve config dict config = files.read_yaml_file(config_file) # Check main keys for primary in config_dict: if primary not in config: log_message = ('''\ Section "{}" not found in configuration file {} in directory {}. Please fix.\ '''.format(primary, config_file, config_directory)) log.log2die_safe(1055, log_message) # Print Status print('OK: Configuration parameter check passed.')
def log_directory(self): """Get log_directory. Args: None Returns: result: result """ # Get result sub_key = 'log_directory' result = None key = 'pattoo' # Get new result _result = search(key, sub_key, self._base_yaml_configuration) # Expand linux ~ notation for home directories if provided. result = os.path.expanduser(_result) # Check if value exists. We cannot use log2die_safe as it does not # require a log directory location to work properly if os.path.isdir(result) is False: log_message = ('log_directory: "{}" ' 'in configuration doesn\'t exist!'.format(result)) log.log2die_safe(1003, log_message) # Return return result
def activate_venv(activation_path): """Activate the virtual environment in the current interpreter. Args: activation_path: The path to the activate_this.py file Returns: None """ # Open activte_this.py for reading try: f_handle = open(activation_path) except PermissionError: log.log2die_safe( 1061, '''\ Insufficient permissions on file: {}. Ensure the directory has the necessary \ read-write permissions'''.format(activation_path)) except FileNotFoundError: log.log2die_safe( 1074, '''\ activate_this.py for the venv has not been created at {} with virtualenv. \ Ensure that its created using the module "virtualenv" '''.format(activation_path)) else: with f_handle: code = compile(f_handle.read(), activation_path, 'exec') exec(code, dict(__file__=activation_path))
def _get_runtime_directory(config_directory): """Get the RuntimeDirectory. Args: config_dir: Configuration directory Returns: tuple: (Path, Relative Path to /var/run) """ result = None filepath = os.path.join(config_directory, 'pattoo.yaml') if os.path.isfile(filepath) is False: shared.log('{} does not exist'.format(filepath)) # Read yaml file try: file_handle = open(filepath, 'r') except PermissionError: log.log2die_safe(1080, '''\ Insufficient permissions for reading the file: {}.''') else: with file_handle: yaml_from_file = file_handle.read() config = yaml.safe_load(yaml_from_file) pattoo = config.get('pattoo') if bool(pattoo) is True: result = pattoo.get('system_daemon_directory') if result is None: shared.log('''\ "system_daemon_directory" parameter not found in the {} configuration file\ '''.format(filepath)) _result = result.replace('/var/run/', '') _result = _result.replace('/run/', '') return (result, _result)
def docker_check(): """Check if docker is installed/running. Args: None Returns: None """ status = shared.run_script('service docker status', verbose=False, die=False)[0] if status == 0: return True elif status == 3: message = '''\ The docker daemon is not running. Ensure that the docker daemon is running before installing.''' elif status == 4: message = '''\ Docker has not been installed to the system. Ensure that docker is installed before creating the pattoo docker container.''' else: message = '''\ Unknown error code. Ensure that docker is running and has the adequate permissions''' log.log2die_safe(80007, message)
def remove_file(file_path): """Safely removes files that aren't symlinks. Args: file_path: The path to the file being removed Returns: None """ if os.path.islink(file_path) is False: # Delete files that aren't symlinks print('{} Is not a symlink. Removing'.format(file_path)) try: os.remove(file_path) except PermissionError: log.log2die_safe(1089, '''\ Insufficient permissions for removing {}'''.format(file_path)) except OSError as e: # errno.ENOENT = no such file or directory if e.errno != errno.ENOENT: raise # re-raise exception if a different error occured else: log.log2die_safe(1092, '''\ Cannot remove {}. It does not exist'''.format(file_path))
def read_config(filepath, default_config): """Read configuration file and replace default values. Args: filepath: Name of configuration file default_config: Default configuration dict Returns: config: Dict of configuration """ # Read config if os.path.isfile(filepath) is True: try: f_handle = open(filepath, 'r') except PermissionError: log.log2die_safe( 1078, '''\ Insufficient permissions for reading the file:{}'''.format(filepath)) else: with f_handle: yaml_string = f_handle.read() config = yaml.safe_load(yaml_string) else: config = default_config return config
def _check_symlinks(etc_dir, daemon): """Ensure the files in the etc dir are symlinks. Args: etc_dir: The directory that the symlinks are located in symlink_dir: The directory that the symlinks point to daemon: The daemon being checked Returns: None """ # Initialize key variables symlink_path = os.path.join(etc_dir, '{}.service'.format(daemon)) # Say what we are doing print('Checking if the {}.service file is a symlink '.format(daemon)) link = os.path.islink(symlink_path) if link is False: # Attempt to remove file remove_file(symlink_path) if getpass.getuser() != 'root': log.log2die_safe(1086, 'Current user is not root') print('Creating symlink for {}'.format(daemon)) # Create symlink if it doesn't exist shared.run_script('systemctl enable {}'.format(daemon)) print('OK: Symlink is present for {}'.format(daemon))
def check(): """Ensure PIP3 packages are installed correctly. Args: None Returns: None """ # Initialize key variables config_directory = os.environ['PATTOO_CONFIGDIR'] # Print Status print('??: Checking configuration parameters.') # Check config (pattoo.yaml) config_file = configuration.agent_config_filename('pattoo') config = files.read_yaml_file(config_file) # Check main keys keys = ['pattoo', 'pattoo_web_api', 'pattoo_agent_api'] for key in keys: if key not in config: log_message = ('''\ Section "{}" not found in configuration file in directory {}. Please fix.\ '''.format(key, config_directory)) log.log2die_safe(80007, log_message) # Check secondary keys secondaries = [ 'log_level', 'log_directory', 'cache_directory', 'daemon_directory' ] secondary_key_check(config, 'pattoo', secondaries) secondaries = ['ip_address', 'ip_bind_port'] secondary_key_check(config, 'pattoo_agent_api', secondaries) secondaries = ['ip_address', 'ip_bind_port'] secondary_key_check(config, 'pattoo_web_api', secondaries) # Check config (pattoo_webd.yaml) config_file = configuration.agent_config_filename('pattoo_webd') config = files.read_yaml_file(config_file) # Check main keys keys = ['pattoo_webd'] for key in keys: if key not in config: log_message = ('''\ Section "{}" not found in configuration file in directory {}. Please fix.\ '''.format(key, config_directory)) log.log2die_safe(80020, log_message) # Check secondary keys secondaries = ['ip_listen_address', 'ip_bind_port'] secondary_key_check(config, 'pattoo_webd', secondaries) # Print Status print('OK: Configuration parameter check passed.')
def pattoo_config(file_name, config_directory, config_dict): """Create configuration file. Args: file_name: Name of the configuration file without its file extension config_directory: Full path to the configuration directory config_dict: A dictionary containing the configuration values. Returns: The path to the configuration file """ # Initialize key variables config_file = os.path.join(config_directory, '{}.yaml'.format(file_name)) # Say what we are doing print('\nConfiguring {} file.\n'.format(config_file)) # Get configuration config = read_config(config_file, config_dict) # Check validity of directories, if any if bool(config) is False: # Set default config = config_dict # Iterate over config dict for _, value in sorted(config.items()): if isinstance(value, dict) is True: for secondary_key in value.keys(): if 'directory' in secondary_key: if os.sep not in value.get(secondary_key): log.log2die_safe( 1019, '{} is an invalid directory'.format(value)) # Attempt to create directory full_directory = os.path.expanduser( value.get(secondary_key)) if os.path.isdir(full_directory) is False: print('Creating: {}'.format(full_directory)) files.mkdir(full_directory) # Recursively set file ownership to pattoo user and group if getpass.getuser() == 'root': shared.chown(full_directory) # Write file try: f_handle = open(config_file, 'w') except PermissionError: log.log2die( 1076, '''\ Insufficient permissions for creating the file:{}'''.format(config_file)) else: with f_handle: yaml.dump(config, f_handle, default_flow_style=False) return config_file
def expose_ports(config_path, docker_path): """Expose ports in the Dockerfile. This will write to the docker file based on the configuration values in the configuration directory. Args: config_path: The path to the configuration file with the ports to be exposed docker_path: The path to the Dockerfile Returns: None """ # Initialize key variables ports = get_ports(config_path) expose_index = None # Read Dockerfile and expose the respective ports below the line starting # with Expose ports try: f_handle = open(docker_path, 'r+') except FileNotFoundError: log.log2die_safe(20319, 'The Dockerfile does not exist') except PermissionError: log.log2die_safe( 20591, 'Insufficient permissions for reading the Dockerfile') else: with f_handle: content = f_handle.readlines() # Retrieve the index of the line with 'Expose ports' for line in content: if line.startswith('# Expose ports'): expose_index = content.index(line) break if expose_index is not None: # Insert new port entries based on the configuration file for port in ports: expose_line = 'EXPOSE {}\n'.format(port) # Skip duplicate lines if expose_line in content: pass else: content.insert(expose_index + 1, expose_line) # Set pointer to beginning of file f_handle.seek(0, 0) # Rewrite file contents f_handle.write(''.join(content))
def image_check(image_name): """Check if a docker image already exists for the image specified. Args: The name of the image being checked Returns: None """ status = shared.run_script('docker image inspect {}'.format(image_name), die=False)[0] if status == 0: message = 'The docker image "{}" already exists'.format(image_name) log.log2die_safe(80009, message)
def check_pattoo_server(): """Ensure server configuration exists. Args: None Returns: None """ # Print Status print('??: Checking server configuration parameters.') ########################################################################### # Check server config ########################################################################### config_file = configuration.agent_config_filename('pattoo_server') config = files.read_yaml_file(config_file) # Check main keys keys = [ 'pattoo_db', 'pattoo_api_agentd', 'pattoo_apid', 'pattoo_ingesterd' ] for key in keys: if key not in config: log_message = ('''\ Section "{}" not found in {} configuration file. Please fix.\ '''.format(key, config_file)) log.log2die_safe(20141, log_message) # Check secondary keys for 'pattoo_db' secondaries = [ 'db_pool_size', 'db_max_overflow', 'db_hostname', 'db_username', 'db_password', 'db_name' ] secondary_key_check(config, 'pattoo_db', secondaries) # Check secondary keys for 'pattoo_api_agentd' secondaries = ['ip_listen_address', 'ip_bind_port'] secondary_key_check(config, 'pattoo_api_agentd', secondaries) # Check secondary keys for 'pattoo_apid' secondaries = ['ip_listen_address', 'ip_bind_port'] secondary_key_check(config, 'pattoo_apid', secondaries) # Print Status print('OK: Server configuration parameter check passed.')
def read_yaml_files(config_directory): """Read the contents of all yaml files in a directory. Args: config_directory: Directory with configuration files Returns: config_dict: Single dict of combined yaml read from all files """ # Initialize key variables yaml_found = False yaml_from_file = '' all_yaml_read = '' if os.path.isdir(config_directory) is False: log_message = ('Configuration directory "{}" ' 'doesn\'t exist!'.format(config_directory)) log.log2die_safe(1026, log_message) # Cycle through list of files in directory for filename in os.listdir(config_directory): # Examine all the '.yaml' files in directory if filename.endswith('.yaml'): # YAML files found yaml_found = True # Read file and add to string filepath = '{}{}{}'.format(config_directory, os.sep, filename) yaml_from_file = read_yaml_file(filepath, as_string=True, die=True) # Append yaml from file to all yaml previously read all_yaml_read = '{}\n{}'.format(all_yaml_read, yaml_from_file) # Verify YAML files found in directory. We cannot use logging as it # requires a logfile location from the configuration directory to work # properly if yaml_found is False: log_message = ( 'No configuration files found in directory "{}" with ".yaml" ' 'extension.'.format(config_directory)) log.log2die_safe(1015, log_message) # Return config_dict = yaml.safe_load(all_yaml_read) return config_dict
def install_missing_pip3(package, verbose=False): """Automatically Install missing pip3 packages. Args: package: The pip3 package to be installed Returns: None """ # Intitialize key variables command = 'python3 -m pip install {0} -U --force-reinstall'.format(package) try: shared.run_script(command, verbose=verbose) except SystemExit: message = 'Invalid pip package/package version "{}"'.format(package) log.log2die_safe(1088, message)
def secondary_key_check(config, primary, secondaries): """Check secondary keys. Args: config: Configuration dict primary: Primary key secondaries: List of secondary keys Returns: None """ # Check keys for key in secondaries: if key not in config[primary]: log_message = ('''\ Configuration file's "{}" section does not have a "{}" sub-section. \ Please fix.'''.format(primary, key)) log.log2die_safe(65009, log_message)
def expose_ports(config_path, docker_path): """Expose ports in the Dockerfile. This will write to the docker file based on the configuration values in the configuration directory. Args: config_path: The path to the configuration file with the ports to be exposed docker_path: The path to the Dockerfile Returns: None """ # Initialize key variables ports = get_ports(config_path) expose_index = None # Read Dockerfile and expose the respective ports below the line starting # with Expose ports try: f_handle = open(docker_path, 'r+') except FileNotFoundError: log.log2die_safe(80090, 'The Dockerfile does not exist') except PermissionError: log.log2die_safe( 80092, 'Insufficient permissions for reading the Dockerfile') else: with f_handle: content = f_handle.readlines() expose_index = get_expose_index(content) if expose_index is not None: # Insert new port entries based on the configuration file insert_expose(expose_index, ports, content) # Set pointer to beginning of file f_handle.seek(0, 0) # Rewrite file contents f_handle.write(''.join(content))
def read_config(filepath, default_config): """Read configuration file and replace default values. Args: filepath: Name of configuration file default_config: Default configuration dict Returns: config: Dict of configuration """ # Read config if os.path.isfile(filepath) is True: try: f_handle = open(filepath, 'r') except PermissionError: log.log2die_safe( 1078, '''\ Insufficient permissions for reading the file:{}'''.format(filepath)) else: with f_handle: yaml_string = f_handle.read() config = yaml.safe_load(yaml_string) # Find and replace dictionary values # for default_key, default_value in default_config.items(): # if isinstance(default_value, dict) # for key in config: # if key == default_key: # config[key] = default_config.get(default_key) # # Add new entries to config dict if they aren't in the file # if default_key not in config: # config[default_key] = default_config.get(default_key) else: config = default_config return config
def read_json_file(filepath, die=True): """Read the contents of a YAML file. Args: filepath: Path to file to be read die: Die if there is an error Returns: result: Dict of JSON read """ # Read file if filepath.endswith('.json'): try: with open(filepath, 'r') as file_handle: result = json.load(file_handle) except: log_message = ('''\ Error reading file {}. Check permissions, existence and file syntax.\ '''.format(filepath)) if bool(die) is True: log.log2die_safe(1012, log_message) else: log.log2debug(1013, log_message) return {} else: # Die if not a JSON file log_message = '{} is not a JSON file.'.format(filepath) if bool(die) is True: log.log2die_safe(1010, log_message) else: log.log2debug(1011, log_message) return {} # Return return result
def _environment(config_directory): """Make sure environmental variables are OK. Args: config_directory: Directory with the configuration Returns: None """ # Create a message for the screen screen_message = (''' The PATTOO_CONFIGDIR is set to the wrong directory. Run this command to do \ so: $ export PATTOO_CONFIGDIR={} Then run this command again. '''.format(config_directory)) # Make sure the PATTOO_CONFIGDIR environment variable is set if 'PATTOO_CONFIGDIR' not in os.environ: log.log2die_safe(65023, screen_message) # Make sure the PATTOO_CONFIGDIR environment variable is set correctly if os.environ['PATTOO_CONFIGDIR'] != config_directory: log.log2die_safe(65024, screen_message) # Update message screen_message = ('''{} PATTOO_CONFIGDIR is incorrectly set to {} '''.format(screen_message, os.environ['PATTOO_CONFIGDIR'])) # Make sure the PATTOO_CONFIGDIR environment variable is set to unittest if 'unittest' not in os.environ['PATTOO_CONFIGDIR']: log_message = ( 'The PATTOO_CONFIGDIR is not set to a unittest directory') log.log2die_safe(65025, log_message)
def search(key, sub_key, config_dict, die=True): """Get config parameter from YAML. Args: key: Primary key sub_key: Secondary key config_dict: Dictionary to explore die: Die if true and the result encountered is None Returns: result: result """ # Get result result = None # Verify config_dict is indeed a dict. # Die safely as log_directory is not defined if isinstance(config_dict, dict) is False: log.log2die_safe(1021, 'Invalid configuration file. YAML not found') # Get new result if config_dict.get(key) is not None: # Make sure we don't have a None value if config_dict[key] is None: log_message = ( '{}: value in configuration is blank. Please fix'.format(key)) log.log2die_safe(1004, log_message) # Get value we need result = config_dict[key].get(sub_key) # Error if not configured if result is None and die is True: log_message = ('{}:{} not defined in configuration dict {}'.format( key, sub_key, config_dict)) log.log2die_safe(1016, log_message) # Return return result
def test_log2die_safe(self): """Testing function log2die_safe.""" # Test with self.assertRaises(SystemExit): log.log2die_safe(self.code, self.message)
def install(requirements_dir, installation_directory, verbose=False): """Ensure PIP3 packages are installed correctly. Args: requirements_dir: The directory with the pip_requirements file. installation_directory: Directory where packages must be installed. verbose: Print status messages if True Returns: True if pip3 packages are installed successfully """ # Initialize key variables lines = [] # Read pip_requirements file filepath = '{}{}pip_requirements.txt'.format(requirements_dir, os.sep) # Say what we are doing print('Checking pip3 packages') if os.path.isfile(filepath) is False: shared.log('Cannot find PIP3 requirements file {}'.format(filepath)) # Opens pip_requirements file for reading try: _fp = open(filepath, 'r') except PermissionError: log.log2die_safe(1079, '''\ Insufficient permissions for reading the file: {}. \ Ensure the file has read-write permissions and try again'''.format(filepath)) else: line = _fp.readline() while line: # Strip line _line = line.strip() # Read line if True in [_line.startswith('#'), bool(_line) is False]: pass else: lines.append(_line) line = _fp.readline() # Process each line of the file for line in lines: # Determine the package package = line.split('=', 1)[0] package = package.split('>', 1)[0] # If verbose is true, the package being checked is shown if verbose: print('Installing package {}'.format(package)) command = 'python3 -m pip show {}'.format(package) (returncode, _, _) = shared.run_script( command, verbose=verbose, die=False) # Install any missing pip3 package if bool(returncode) is True: install_missing_pip3(package, verbose=verbose) # Set ownership of any newly installed python packages to pattoo user if getpass.getuser() == 'root': if os.path.isdir(installation_directory) is True: shared.run_script('chown -R pattoo:pattoo {}'.format( installation_directory), verbose=verbose) print('pip3 packages successfully installed')
def _insert_pair_xlate_group(): """Insert starting default entries into the PairXlate table. Args: None Returns: None """ # Initialize key variables default_name = 'Pattoo Default' idx_pair_xlate_groups = {} language_dict = {} pair_xlate_data = [ ('OPC UA Agents', [('en', 'pattoo_agent_opcuad_opcua_server', 'OPC UA Server', '')]), ('IfMIB Agents', [('en', 'pattoo_agent_snmpd_.1.3.6.1.2.1.31.1.1.1.9', 'Interface Broadcast Packets (HC inbound)', 'Packets / Second'), ('en', 'pattoo_agent_snmpd_.1.3.6.1.2.1.31.1.1.1.8', 'Interface Multicast Packets (HC inbound)', 'Packets / Second'), ('en', 'pattoo_agent_snmpd_.1.3.6.1.2.1.31.1.1.1.6', 'Interface Traffic (HC inbound)', 'Bits / Second'), ('en', 'pattoo_agent_snmpd_.1.3.6.1.2.1.31.1.1.1.7', 'Interface Unicast Packets (inbound)', 'Packets / Second'), ('en', 'pattoo_agent_snmpd_.1.3.6.1.2.1.31.1.1.1.13', 'Interface Broadcast Packets (HC outbound)', 'Packets / Second'), ('en', 'pattoo_agent_snmpd_.1.3.6.1.2.1.31.1.1.1.12', 'Interface Multicast Packets (HC outbound)', 'Packets / Second'), ('en', 'pattoo_agent_snmpd_.1.3.6.1.2.1.31.1.1.1.10', 'Interface Traffic (HC outbound)', 'Bits / Second'), ('en', 'pattoo_agent_snmpd_.1.3.6.1.2.1.31.1.1.1.11', 'Interface Unicast Packets (HC outbound)', 'Packets / Second'), ('en', 'pattoo_agent_snmpd_.1.3.6.1.2.1.31.1.1.1.3', 'Interface Broadcast Packets (inbound)', 'Packets / Second'), ('en', 'pattoo_agent_snmpd_.1.3.6.1.2.1.2.2.1.13', 'Interface Discard Errors (inbound)', 'Errors / Second'), ('en', 'pattoo_agent_snmpd_.1.3.6.1.2.1.2.2.1.14', 'Interface Errors (inbound)', 'Errors / Second'), ('en', 'pattoo_agent_snmpd_.1.3.6.1.2.1.31.1.1.1.2', 'Interface Multicast Packets (inbound)', 'Packets / Second'), ('en', 'pattoo_agent_snmpd_.1.3.6.1.2.1.2.2.1.10', 'Interface Traffic (inbound)', 'Bits / Second'), ('en', 'pattoo_agent_snmpd_.1.3.6.1.2.1.2.2.1.11', 'Interface Traffic (inbound)', 'Bits / Second'), ('en', 'pattoo_agent_snmpd_.1.3.6.1.2.1.31.1.1.1.5', 'Interface Broadcast Packets (outbound)', 'Packets / Second'), ('en', 'pattoo_agent_snmpd_.1.3.6.1.2.1.2.2.1.19', 'Interface Discard Errors (outbound)', 'Errors / Second'), ('en', 'pattoo_agent_snmpd_.1.3.6.1.2.1.2.2.1.20', 'Interface Errors (outbound)', 'Errors / Second'), ('en', 'pattoo_agent_snmpd_.1.3.6.1.2.1.31.1.1.1.4', 'Interface Multicast Packets (outbound)', 'Packets / Second'), ('en', 'pattoo_agent_snmpd_.1.3.6.1.2.1.2.2.1.16', 'Interface Traffic (outbound)', 'Bits / Second'), ('en', 'pattoo_agent_snmpd_.1.3.6.1.2.1.2.2.1.17', 'Interface Unicast Packets (outbound)', 'Packets / Second'), ('en', 'pattoo_agent_snmp_ifmibd_ifalias', 'Interface Alias', ''), ('en', 'pattoo_agent_snmp_ifmibd_ifdescr', 'Interface Description', ''), ('en', 'pattoo_agent_snmp_ifmibd_ifhcinbroadcastpkts', 'Interface Broadcast Packets (HC inbound)', 'Packets / Second'), ('en', 'pattoo_agent_snmp_ifmibd_ifhcinmulticastpkts', 'Interface Multicast Packets (HC inbound)', 'Packets / Second'), ('en', 'pattoo_agent_snmp_ifmibd_ifhcinoctets', 'Interface Traffic (HC inbound)', 'Bits / Second'), ('en', 'pattoo_agent_snmp_ifmibd_ifhcinucastpkts', 'Interface Unicast Packets (HC inbound)', 'Packets / Second'), ('en', 'pattoo_agent_snmp_ifmibd_ifhcoutbroadcastpkts', 'Interface Broadcast Packets (HC outbound)', 'Packets / Second'), ('en', 'pattoo_agent_snmp_ifmibd_ifhcoutmulticastpkts', 'Interface Multicast Packets (HC outbound)', 'Packets / Second'), ('en', 'pattoo_agent_snmp_ifmibd_ifhcoutoctets', 'Interface Traffic (HC outbound)', 'Bits / Second'), ('en', 'pattoo_agent_snmp_ifmibd_ifhcoutucastpkts', 'Interface Unicast Packets (HC outbound)', 'Packets / Second'), ('en', 'pattoo_agent_snmp_ifmibd_ifinbroadcastpkts', 'Interface Broadcast Packets (inbound)', 'Packets / Second'), ('en', 'pattoo_agent_snmp_ifmibd_ifinmulticastpkts', 'Interface Multicast Packets (inbound)', 'Packets / Second'), ('en', 'pattoo_agent_snmp_ifmibd_ifinoctets', 'Interface Traffic (inbound)', 'Bits / Second'), ('en', 'pattoo_agent_snmp_ifmibd_ifname', 'Interface Name', ''), ('en', 'pattoo_agent_snmp_ifmibd_ifoutbroadcastpkts', 'Interface Broadcast Packets (outbound)', 'Packets / Second'), ('en', 'pattoo_agent_snmp_ifmibd_ifoutmulticastpkts', 'Interface Multicast Packets (outbound)', 'Packets / Second'), ('en', 'pattoo_agent_snmp_ifmibd_ifoutoctets', 'Interface Traffic (outbound)', 'Bits / Second'), ('en', 'pattoo_agent_snmp_ifmibd_oid', 'SNMP OID', ''), ('en', 'pattoo_agent_snmpd_ifalias', 'Interface Alias', ''), ('en', 'pattoo_agent_snmpd_ifdescr', 'Interface Description', ''), ('en', 'pattoo_agent_snmpd_ifname', 'Interface Name', ''), ('en', 'pattoo_agent_snmpd_oid', 'SNMP OID', '')]), ('Linux Agents', [('en', 'pattoo_agent_linux_autonomousd_processor', 'Processor Type', ''), ('en', 'pattoo_agent_linux_autonomousd_release', 'OS Release', ''), ('en', 'pattoo_agent_linux_autonomousd_type', 'OS Type', ''), ('en', 'pattoo_agent_linux_autonomousd_version', 'OS Version', ''), ('en', 'pattoo_agent_linux_autonomousd_cpus', 'OS CPU Count', ''), ('en', 'pattoo_agent_linux_autonomousd_hostname', 'Hostname', ''), ('en', 'pattoo_agent_linux_autonomousd_disk_partition_device', 'Disk Partition', ''), ('en', 'pattoo_agent_linux_autonomousd_disk_partition_fstype', 'Filesystem Type', ''), ('en', 'pattoo_agent_linux_autonomousd_disk_partition_mountpoint', 'Mount Point', ''), ('en', 'pattoo_agent_linux_autonomousd_disk_partition_opts', 'Partition Options', ''), ('en', 'pattoo_agent_linux_autonomousd_cpu_times_percent_user', 'User (Percent CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_autonomousd_cpu_times_percent_nice', 'Nice (Percent CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_autonomousd_cpu_times_percent_system', 'System (Percent CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_autonomousd_cpu_times_percent_idle', 'Idle (Percent CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_autonomousd_cpu_times_percent_iowait', 'IO Wait (Percent CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_autonomousd_cpu_times_percent_irq', 'IRQ (Percent CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_autonomousd_cpu_times_percent_softirq', 'Soft IRQ (Percent CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_autonomousd_cpu_times_percent_steal', 'Steal (Percent CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_autonomousd_cpu_times_percent_guest', 'Guest (Percent CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_autonomousd_cpu_times_percent_guest_nice', 'Guest / Nice (Percent CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_autonomousd_cpu_times_user', 'User (CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_autonomousd_cpu_times_nice', 'Nice (CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_autonomousd_cpu_times_system', 'System (CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_autonomousd_cpu_times_idle', 'Idle (CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_autonomousd_cpu_times_iowait', 'IO Wait (CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_autonomousd_cpu_times_irq', 'IRQ (CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_autonomousd_cpu_times_softirq', 'Soft IRQ (CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_autonomousd_cpu_times_steal', 'Steal (CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_autonomousd_cpu_times_guest', 'Guest (CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_autonomousd_cpu_times_guest_nice', 'Guest / Nice (CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_autonomousd_cpu_stats_ctx_switches', 'CPU (Context Switches)', 'Events / Second'), ('en', 'pattoo_agent_linux_autonomousd_cpu_stats_interrupts', 'CPU (Context Switches)', 'Events / Second'), ('en', 'pattoo_agent_linux_autonomousd_cpu_stats_soft_interrupts', 'CPU (Soft Interrupts)', 'Events / Second'), ('en', 'pattoo_agent_linux_autonomousd_cpu_stats_syscalls', 'CPU (System Calls)', 'Events / Second'), ('en', 'pattoo_agent_linux_autonomousd_memory_total', 'Memory (Total)', 'Bytes'), ('en', 'pattoo_agent_linux_autonomousd_memory_available', 'Memory (Available)', 'Bytes'), ('en', 'pattoo_agent_linux_autonomousd_memory_percent', 'Memory (Percent)', 'Percentage Utilization'), ('en', 'pattoo_agent_linux_autonomousd_memory_used', 'Memory (Used)', 'Bytes'), ('en', 'pattoo_agent_linux_autonomousd_memory_free', 'Memory (Free)', 'Bytes'), ('en', 'pattoo_agent_linux_autonomousd_memory_active', 'Memory (Active)', 'Bytes'), ('en', 'pattoo_agent_linux_autonomousd_memory_inactive', 'Memory (Inactive)', 'Bytes'), ('en', 'pattoo_agent_linux_autonomousd_memory_buffers', 'Memory (Buffers)', 'Bytes'), ('en', 'pattoo_agent_linux_autonomousd_memory_cached', 'Memory (Cached)', 'Bytes'), ('en', 'pattoo_agent_linux_autonomousd_memory_shared', 'Memory (Shared)', 'Bytes'), ('en', 'pattoo_agent_linux_autonomousd_memory_slab', 'Memory (Slab)', 'Bytes'), ('en', 'pattoo_agent_linux_autonomousd_swap_memory_total', 'Swap Memory (Total)', 'Bytes'), ('en', 'pattoo_agent_linux_autonomousd_swap_memory_used', 'Swap Memory (Used)', 'Bytes'), ('en', 'pattoo_agent_linux_autonomousd_swap_memory_free', 'Swap Memory (Free)', 'Bytes'), ('en', 'pattoo_agent_linux_autonomousd_swap_memory_percent', 'Swap Memory (Percent)', 'Percent'), ('en', 'pattoo_agent_linux_autonomousd_swap_memory_sin', 'Swap Memory (In)', 'Bytes / Second'), ('en', 'pattoo_agent_linux_autonomousd_swap_memory_sout', 'Swap Memory (Out)', 'Bytes / Second'), ('en', 'pattoo_agent_linux_autonomousd_disk_partition_disk_usage_total', 'Disk size', 'Bytes'), ('en', 'pattoo_agent_linux_autonomousd_disk_partition_disk_usage_used', 'Disk Utilization', 'Percent'), ('en', 'pattoo_agent_linux_autonomousd_disk_partition_disk_usage_free', 'Disk Free', 'Bytes'), ('en', 'pattoo_agent_linux_autonomousd_disk_partition_disk_usage_percent', 'Disk Percentage Utilization', ''), ('en', 'pattoo_agent_linux_autonomousd_disk_io_read_count', 'Disk I/O (Read Count)', 'Reads / Second'), ('en', 'pattoo_agent_linux_autonomousd_disk_partition', 'Disk Partition', ''), ('en', 'pattoo_agent_linux_autonomousd_disk_io_write_count', 'Disk I/O (Write Count)', 'Writes / Second'), ('en', 'pattoo_agent_linux_autonomousd_disk_io_read_bytes', 'Disk I/O (Bytes Read)', 'Bytes / Second'), ('en', 'pattoo_agent_linux_autonomousd_disk_io_write_bytes', 'Disk I/O (Bytes Written)', 'Bytes / Second'), ('en', 'pattoo_agent_linux_autonomousd_disk_io_read_time', 'Disk I/O (Read Time)', ''), ('en', 'pattoo_agent_linux_autonomousd_disk_io_write_time', 'Disk I/O (Write Time)', ''), ('en', 'pattoo_agent_linux_autonomousd_disk_io_read_merged_count', 'Disk I/O (Read Merged Count)', 'Reads / Second'), ('en', 'pattoo_agent_linux_autonomousd_disk_io_write_merged_count', 'Disk I/O (Write Merged Count)', 'Writes / Second'), ('en', 'pattoo_agent_linux_autonomousd_disk_io_busy_time', 'Disk I/O (Busy Time)', ''), ('en', 'pattoo_agent_linux_autonomousd_network_io_bytes_sent', 'Network I/O (Bandwidth Inbound)', 'Bits / Second'), ('en', 'pattoo_agent_linux_autonomousd_network_io_interface', 'Network Interface', ''), ('en', 'pattoo_agent_linux_autonomousd_network_io_bytes_recv', 'Network I/O (Bandwidth Outbound)', 'Bits / Second'), ('en', 'pattoo_agent_linux_autonomousd_network_io_packets_sent', 'Network I/O (Packets Sent)', 'Packets / Second'), ('en', 'pattoo_agent_linux_autonomousd_network_io_packets_recv', 'Network I/O (Packets Received)', 'Packets / Second'), ('en', 'pattoo_agent_linux_autonomousd_network_io_errin', 'Network I/O (Errors Inbound)', 'Errors / Second'), ('en', 'pattoo_agent_linux_autonomousd_network_io_errout', 'Network I/O (Errors Outbound)', 'Errors / Second'), ('en', 'pattoo_agent_linux_autonomousd_network_io_dropin', 'Network I/O (Drops Inbound)', 'Drops / Second'), ('en', 'pattoo_agent_linux_autonomousd_network_io_dropout', 'Network I/O (Drops Outbound)', 'Drops / Second'), ('en', 'pattoo_agent_linux_autonomousd_cpu_frequency', 'CPU Frequency', 'Frequency'), ('en', 'pattoo_agent_linux_spoked_processor', 'Processor Type', ''), ('en', 'pattoo_agent_linux_spoked_release', 'OS Release', ''), ('en', 'pattoo_agent_linux_spoked_type', 'OS Type', ''), ('en', 'pattoo_agent_linux_spoked_version', 'OS Version', ''), ('en', 'pattoo_agent_linux_spoked_cpus', 'OS CPU Count', ''), ('en', 'pattoo_agent_linux_spoked_hostname', 'Hostname', ''), ('en', 'pattoo_agent_linux_spoked_disk_partition_device', 'Disk Partition', ''), ('en', 'pattoo_agent_linux_spoked_disk_partition_fstype', 'Filesystem Type', ''), ('en', 'pattoo_agent_linux_spoked_disk_partition_mountpoint', 'Mount Point', ''), ('en', 'pattoo_agent_linux_spoked_disk_partition_opts', 'Partition Options', ''), ('en', 'pattoo_agent_linux_spoked_cpu_times_percent_user', 'User (Percent CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_spoked_cpu_times_percent_nice', 'Nice (Percent CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_spoked_cpu_times_percent_system', 'System (Percent CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_spoked_cpu_times_percent_idle', 'Idle (Percent CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_spoked_cpu_times_percent_iowait', 'IO Wait (Percent CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_spoked_cpu_times_percent_irq', 'IRQ (Percent CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_spoked_cpu_times_percent_softirq', 'Soft IRQ (Percent CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_spoked_cpu_times_percent_steal', 'Steal (Percent CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_spoked_cpu_times_percent_guest', 'Guest (Percent CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_spoked_cpu_times_percent_guest_nice', 'Guest / Nice (Percent CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_spoked_cpu_times_user', 'User (CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_spoked_cpu_times_nice', 'Nice (CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_spoked_cpu_times_system', 'System (CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_spoked_cpu_times_idle', 'Idle (CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_spoked_cpu_times_iowait', 'IO Wait (CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_spoked_cpu_times_irq', 'IRQ (CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_spoked_cpu_times_softirq', 'Soft IRQ (CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_spoked_cpu_times_steal', 'Steal (CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_spoked_cpu_times_guest', 'Guest (CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_spoked_cpu_times_guest_nice', 'Guest / Nice (CPU Usage)', 'Percent'), ('en', 'pattoo_agent_linux_spoked_cpu_stats_ctx_switches', 'CPU (Context Switches)', 'Events / Second'), ('en', 'pattoo_agent_linux_spoked_cpu_stats_interrupts', 'CPU (Context Switches)', 'Events / Second'), ('en', 'pattoo_agent_linux_spoked_cpu_stats_soft_interrupts', 'CPU (Soft Interrupts)', 'Events / Second'), ('en', 'pattoo_agent_linux_spoked_cpu_stats_syscalls', 'CPU (System Calls)', 'Events / Second'), ('en', 'pattoo_agent_linux_spoked_memory_total', 'Memory (Total)', 'Bytes'), ('en', 'pattoo_agent_linux_spoked_memory_available', 'Memory (Available)', 'Bytes'), ('en', 'pattoo_agent_linux_spoked_memory_percent', 'Memory (Percent)', ''), ('en', 'pattoo_agent_linux_spoked_memory_used', 'Memory (Used)', 'Bytes'), ('en', 'pattoo_agent_linux_spoked_memory_free', 'Memory (Free)', 'Bytes'), ('en', 'pattoo_agent_linux_spoked_memory_active', 'Memory (Active)', 'Bytes'), ('en', 'pattoo_agent_linux_spoked_memory_inactive', 'Memory (Inactive)', 'Bytes'), ('en', 'pattoo_agent_linux_spoked_memory_buffers', 'Memory (Buffers)', 'Bytes'), ('en', 'pattoo_agent_linux_spoked_memory_cached', 'Memory (Cached)', 'Bytes'), ('en', 'pattoo_agent_linux_spoked_memory_shared', 'Memory (Shared)', 'Bytes'), ('en', 'pattoo_agent_linux_spoked_memory_slab', 'Memory (Slab)', 'Bytes'), ('en', 'pattoo_agent_linux_spoked_swap_memory_total', 'Swap Memory (Total)', 'Bytes'), ('en', 'pattoo_agent_linux_spoked_swap_memory_used', 'Swap Memory (Used)', 'Bytes'), ('en', 'pattoo_agent_linux_spoked_swap_memory_free', 'Swap Memory (Free)', 'Bytes'), ('en', 'pattoo_agent_linux_spoked_swap_memory_percent', 'Swap Memory (Percent)', ''), ('en', 'pattoo_agent_linux_spoked_swap_memory_sin', 'Swap Memory (In)', 'Bytes / Second'), ('en', 'pattoo_agent_linux_spoked_swap_memory_sout', 'Swap Memory (Out)', 'Bytes / Second'), ('en', 'pattoo_agent_linux_spoked_disk_partition_disk_usage_total', 'Disk size', 'Bytes'), ('en', 'pattoo_agent_linux_spoked_disk_partition_disk_usage_used', 'Disk Utilization', 'Percent'), ('en', 'pattoo_agent_linux_spoked_disk_partition_disk_usage_free', 'Disk Free', 'Bytes'), ('en', 'pattoo_agent_linux_spoked_disk_partition_disk_usage_percent', 'Disk Percentage Utilization', ''), ('en', 'pattoo_agent_linux_spoked_disk_io_read_count', 'Disk I/O (Read Count)', 'Reads / Second'), ('en', 'pattoo_agent_linux_spoked_disk_partition', 'Disk Partition', ''), ('en', 'pattoo_agent_linux_spoked_disk_io_write_count', 'Disk I/O (Write Count)', 'Writes / Second'), ('en', 'pattoo_agent_linux_spoked_disk_io_read_bytes', 'Disk I/O (Bytes Read)', 'Bytes / Second'), ('en', 'pattoo_agent_linux_spoked_disk_io_write_bytes', 'Disk I/O (Bytes Written)', 'Bytes / Second'), ('en', 'pattoo_agent_linux_spoked_disk_io_read_time', 'Disk I/O (Read Time)', ''), ('en', 'pattoo_agent_linux_spoked_disk_io_write_time', 'Disk I/O (Write Time)', ''), ('en', 'pattoo_agent_linux_spoked_disk_io_read_merged_count', 'Disk I/O (Read Merged Count)', 'Reads / Second'), ('en', 'pattoo_agent_linux_spoked_disk_io_write_merged_count', 'Disk I/O (Write Merged Count)', 'Writes / Second'), ('en', 'pattoo_agent_linux_spoked_disk_io_busy_time', 'Disk I/O (Busy Time)', ''), ('en', 'pattoo_agent_linux_spoked_network_io_bytes_sent', 'Network I/O (Bandwidth Inbound)', 'Bits / Second'), ('en', 'pattoo_agent_linux_spoked_network_io_interface', 'Network Interface', ''), ('en', 'pattoo_agent_linux_spoked_network_io_bytes_recv', 'Network I/O (Bandwidth Outbound)', 'Bits / Second'), ('en', 'pattoo_agent_linux_spoked_network_io_packets_sent', 'Network I/O (Packets Sent)', 'Packets / Second'), ('en', 'pattoo_agent_linux_spoked_network_io_packets_recv', 'Network I/O (Packets Received)', 'Packets / Second'), ('en', 'pattoo_agent_linux_spoked_network_io_errin', 'Network I/O (Errors Inbound)', 'Errors / Second'), ('en', 'pattoo_agent_linux_spoked_network_io_errout', 'Network I/O (Errors Outbound)', 'Errors / Second'), ('en', 'pattoo_agent_linux_spoked_network_io_dropin', 'Network I/O (Drops Inbound)', 'Drops / Second'), ('en', 'pattoo_agent_linux_spoked_network_io_dropout', 'Network I/O (Drops Outbound)', 'Drops / Second'), ('en', 'pattoo_agent_linux_spoked_cpu_frequency', 'CPU Frequency', '')]) ] # Insert into PairXlateGroup if pair_xlate_group.idx_exists(1) is False: # Create the default PairXlateGroup pair_xlate_group.insert_row(default_name) # Create PairXlateGroup for some pattoo agents for name, rows in pair_xlate_data: # Get PairXlateGroup index value after creating an entry pair_xlate_group.insert_row(name) idx_pair_xlate_group = pair_xlate_group.exists(name) idx_pair_xlate_groups[name] = idx_pair_xlate_group # Insert values into the PairXlate table for PairXlateGroup for row in rows: if len(row) != 4: log_message = ( 'Translation line "{}" is invalid.'.format(row)) log.log2die_safe(20140, log_message) (code, _key, _value, _units) = row idx_language = language_dict.get(language) if bool(idx_language) is False: idx_language = language.exists(code) language_dict[code] = idx_language pair_xlate.insert_row(_key, _value, _units, idx_language, idx_pair_xlate_group)
def read_json_files(_directory, die=True, age=0, count=None): """Read the contents of all JSON files in a directory. Args: _directory: Directory with JSON files die: Die if there is an error age: Minimum age of files in seconds count: Return first X number of sorted filenames is not None Returns: result: sorted list of tuples containing JSON read from each file and filepath. Sorting is important as it causes the files with the older timestamp names to be processed first. This allows the last_timestamp column to be incrementally processed versus some unexpected order. [(filepath, JSON), (filepath, JSON) ...] """ # Initialize key variables json_found = False result = [] processed = 0 # Set age try: age = float(age) except: age = 0 # Verify directory if os.path.isdir(_directory) is False: log_message = 'Directory "{}" doesn\'t exist!'.format(_directory) log.log2die(1009, log_message) # Cycle through list of files in directory for filename in sorted(os.listdir(_directory)): # Examine all the '.json' files in directory if filename.endswith('.json'): # Read file and add to tuple list filepath = '{}{}{}'.format(_directory, os.sep, filename) fileage = time.time() - os.stat(filepath).st_mtime if fileage > age: _data = read_json_file(filepath, die=die) if bool(_data) is True: # JSON files found json_found = True result.append((filepath, _data)) else: # Ignore, don't update 'processed' value log_message = ('''\ Error reading file {}. Ignoring.'''.format(filepath)) log.log2debug(1053, log_message) continue # Stop if necessary processed += 1 if bool(count) is True: if processed == count: break # Verify JSON files found in directory. We cannot use logging as it # requires a logfile location from the configuration directory to work # properly if (json_found is False) and (bool(die) is True): log_message = ( 'No valid JSON files found in directory "{}" with ".json" ' 'extension.'.format(_directory)) log.log2die_safe(1060, log_message) # Return result.sort() return result
def read_yaml_file(filepath, as_string=False, die=True): """Read the contents of a YAML file. Args: filepath: Path to file to be read as_string: Return a string if True die: Die if there is an error Returns: result: Dict of yaml read """ # Initialize key variables if as_string is False: result = {} else: result = '' # Read file if filepath.endswith('.yaml'): try: with open(filepath, 'r') as file_handle: yaml_from_file = file_handle.read() except: log_message = ('Error reading file {}. Check permissions, ' 'existence and file syntax.' ''.format(filepath)) if bool(die) is True: log.log2die_safe(1006, log_message) else: log.log2debug(1014, log_message) return {} # Get result if as_string is False: try: result = yaml.safe_load(yaml_from_file) except: log_message = ('Error reading file {}. Check permissions, ' 'existence and file syntax.' ''.format(filepath)) if bool(die) is True: log.log2die_safe(1001, log_message) else: log.log2debug(1002, log_message) return {} else: result = yaml_from_file else: # Die if not a YAML file log_message = '{} is not a YAML file.'.format(filepath) if bool(die) is True: log.log2die_safe(1065, log_message) else: log.log2debug(1005, log_message) if bool(as_string) is False: return {} else: return '' # Return return result
def update_environment_strings( filepaths, config_dir, install_dir, username, group): """Update the environment variables in the filepaths files. Args: filepaths: List of filepaths config_dir: Directory where configurations will be stored username: Username to run daemon group: Group of user to run daemon Returns: None """ # Initialize key variables env_config_path = '^Environment="PATTOO_CONFIGDIR=(.*?)"$' env_user = '******' env_group = '^Group=(.*?)$' env_run = '^RuntimeDirectory=(.*?)$' # Do the needful for filepath in filepaths: # Read files and replace matches lines = [] try: _fp = open(filepath, 'r') except PermissionError: log.log2die_safe(1081, '''\ Insufficient permissions for reading the file: {}.'''.format(filepath)) except FileNotFoundError: log.log2die_safe(1082, '''\ The file: {}, does not exist. Ensure that the file is created.''') else: with _fp: line = _fp.readline() while line: # Strip line _line = line.strip() # Fix the binary directory _line = _line.replace('INSTALLATION_DIRECTORY', install_dir) # Test PATTOO_CONFIGDIR if bool(re.search(env_config_path, line)) is True: _line = 'Environment="PATTOO_CONFIGDIR={}"'.format( config_dir) # Add RuntimeDirectory and create if bool(re.search(env_run, line)) is True: (run_path, relative_run_path) = _get_runtime_directory(config_dir) _line = 'RuntimeDirectory={}'.format(relative_run_path) if getpass.getuser == 'root': os.makedirs(run_path, 0o750, exist_ok=True) shutil.chown(run_path, user=username, group=group) # Add user if bool(re.search(env_user, line)) is True: _line = 'User={}'.format(username) # Add group if bool(re.search(env_group, line)) is True: _line = 'Group={}'.format(group) lines.append(_line) line = _fp.readline() # Write new output try: _fp = open(filepath, 'w') except PermissionError: log.log2die_safe(1085, '''\ Insufficient permissions for writing/creating the file: {}'''.format(filepath)) else: with _fp: _fp.writelines('{}\n'.format(line) for line in lines)