Example #1
0
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
Example #2
0
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.')
Example #3
0
    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
Example #4
0
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)
Example #6
0
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))
Example #8
0
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))
Example #10
0
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.')
Example #11
0
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
Example #12
0
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))
Example #13
0
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)
Example #14
0
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.')
Example #15
0
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)
Example #18
0
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))
Example #19
0
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
Example #20
0
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
Example #21
0
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)
Example #22
0
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
Example #23
0
 def test_log2die_safe(self):
     """Testing function log2die_safe."""
     # Test
     with self.assertRaises(SystemExit):
         log.log2die_safe(self.code, self.message)
Example #24
0
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')
Example #25
0
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)
Example #26
0
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
Example #27
0
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)