コード例 #1
0
ファイル: fdg.py プロジェクト: umutbb/hubble
def _check_block(block, block_id):
    """
    Check if a block is valid
    """
    if not block:
        raise CommandExecutionError(
            'Could not execute block \'{0}\', as it is not found.'.format(
                block_id))
    if 'module' not in block:
        raise CommandExecutionError(
            'Could not execute block \'{0}\': no \'module\' found.'.format(
                block_id))
    acceptable_block_args = {
        'return',
        'module',
        'xpipe_on_true',
        'xpipe_on_false',
        'xpipe',
        'pipe',
        'pipe_on_true',
        'pipe_on_false',
        'args',
        'kwargs',
    }
    for key in block:
        if key not in acceptable_block_args:
            raise CommandExecutionError(
                'Could not execute block \'{0}\': '
                '\'{1}\' is not a valid block key'.format(block_id, key))
    return True
コード例 #2
0
ファイル: win_file.py プロジェクト: umutbb/hubble
def readlink(path):
    """
    Return the path that a symlink points to

    This is only supported on Windows Vista or later.

    Inline with Unix behavior, this function will raise an error if the path is
    not a symlink, however, the error raised will be a SaltInvocationError, not
    an OSError.

    Args:
        path (str): The path to the symlink

    Returns:
        str: The path that the symlink points to

    CLI Example:

    .. code-block:: bash

        salt '*' file.readlink /path/to/link
    """
    if sys.getwindowsversion().major < 6:
        raise HubbleInvocationError(
            "Symlinks are only supported on Windows Vista or later."
        )

    try:
        return hubblestack.utils.path.readlink(path)
    except OSError as exc:
        if exc.errno == errno.EINVAL:
            raise CommandExecutionError("{0} is not a symbolic link".format(path))
        raise CommandExecutionError(exc.__str__())
    except Exception as exc:  # pylint: disable=broad-except
        raise CommandExecutionError(exc)
コード例 #3
0
ファイル: linux_sysctl.py プロジェクト: umutbb/hubble
def assign(name, value):
    """
    Assign a single sysctl parameter for this minion
    CLI Example:
    .. code-block:: bash
        salt '*' sysctl.assign net.ipv4.ip_forward 1
    """
    value = str(value)
    tran_tab = name.translate("".maketrans("./", "/."))

    sysctl_file = "/proc/sys/{0}".format(tran_tab)
    if not os.path.exists(sysctl_file):
        raise CommandExecutionError("sysctl {0} does not exist".format(name))

    ret = {}
    cmd = 'sysctl -w {0}="{1}"'.format(name, value)
    data = __mods__["cmd.run_all"](cmd, python_shell=False)
    out = data["stdout"]
    err = data["stderr"]

    # Example:
    #    # sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216"
    #    net.ipv4.tcp_rmem = 4096 87380 16777216
    regex = re.compile(r"^{0}\s+=\s+{1}$".format(re.escape(name),
                                                 re.escape(value)))

    if not regex.match(out) or "Invalid argument" in str(err):
        if data["retcode"] != 0 and err:
            error = err
        else:
            error = out
        raise CommandExecutionError("sysctl -w failed: {0}".format(error))
    new_name, new_value = out.split(" = ", 1)
    ret[new_name] = new_value
    return ret
コード例 #4
0
ファイル: win_file.py プロジェクト: umutbb/hubble
def _resolve_symlink(path, max_depth=64):
    """
    Resolves the given symlink path to its real path, up to a maximum of the
    `max_depth` parameter which defaults to 64.

    If the path is not a symlink path, it is simply returned.
    """
    if sys.getwindowsversion().major < 6:
        raise HubbleInvocationError(
            "Symlinks are only supported on Windows Vista or later."
        )

    # make sure we don't get stuck in a symlink loop!
    paths_seen = set((path,))
    cur_depth = 0
    while is_link(path):
        path = readlink(path)
        if path in paths_seen:
            raise CommandExecutionError("The given path is involved in a symlink loop.")
        paths_seen.add(path)
        cur_depth += 1
        if cur_depth > max_depth:
            raise CommandExecutionError("Too many levels of symbolic links.")

    return path
コード例 #5
0
    def _load_yaml(self, filepath, filename):
        """
        Load and validate yaml file
        File must be a valid yaml file, and content loaded must form a python-dictionary

        Arguments:
            filepath {str} -- Actual filepath of profile file
            filename {str} -- Filename for logging purpose

        Returns:
            [dict] -- Dictionary representation for yaml
        """
        log.debug('Validating yaml file: %s', filename)
        # validating physical file existance
        if not filepath or not os.path.isfile(filepath):
            raise CommandExecutionError(
                'Could not find file: {0}'.format(filepath))

        yaml_data = None
        try:
            with open(filepath, 'r') as file_handle:
                yaml_data = yaml.safe_load(file_handle)
        except Exception as exc:
            raise CommandExecutionError(
                'Could not load yaml file: {0}, Exception: {1}'.format(
                    filepath, exc))

        if not yaml_data or not isinstance(yaml_data, dict):
            raise CommandExecutionError(
                'yaml data could not be loaded as dictionary: {0}'.format(
                    filepath))

        return yaml_data
コード例 #6
0
ファイル: win_file.py プロジェクト: umutbb/hubble
def remove(path, force=False):
    """
    Remove the named file or directory

    Args:
        path (str): The path to the file or directory to remove.
        force (bool): Remove even if marked Read-Only. Default is False

    Returns:
        bool: True if successful, False if unsuccessful

    CLI Example:

    .. code-block:: bash

        salt '*' file.remove C:\\Temp
    """
    # This must be a recursive function in windows to properly deal with
    # Symlinks. The shutil.rmtree function will remove the contents of
    # the Symlink source in windows.

    path = os.path.expanduser(path)

    if not os.path.isabs(path):
        raise HubbleInvocationError("File path must be absolute: {0}".format(path))

    # Does the file/folder exists
    if not os.path.exists(path) and not is_link(path):
        raise CommandExecutionError("Path not found: {0}".format(path))

    # Remove ReadOnly Attribute
    if force:
        # Get current file attributes
        file_attributes = win32api.GetFileAttributes(path)
        win32api.SetFileAttributes(path, win32con.FILE_ATTRIBUTE_NORMAL)

    try:
        if os.path.isfile(path):
            # A file and a symlinked file are removed the same way
            os.remove(path)
        elif is_link(path):
            # If it's a symlink directory, use the rmdir command
            os.rmdir(path)
        else:
            for name in os.listdir(path):
                item = "{0}\\{1}".format(path, name)
                # If its a normal directory, recurse to remove it's contents
                remove(item, force)

            # rmdir will work now because the directory is empty
            os.rmdir(path)
    except (OSError, IOError) as exc:
        if force:
            # Reset attributes to the original if delete fails.
            win32api.SetFileAttributes(path, file_attributes)
        raise CommandExecutionError("Could not remove '{0}': {1}".format(path, exc))

    return True
コード例 #7
0
    def _validate_module_params(self,
                                module_name,
                                profile_id,
                                module_args,
                                chaining_args=None):
        """
        A helper method to invoke module's validate_params method
        """
        if not module_args:
            raise CommandExecutionError(
                'Could not execute block \'{0}\', as it is not found.'.format(
                    profile_id))

        # Comparators must exist in Audit
        if self._caller == Caller.AUDIT:
            if 'args' not in module_args:
                raise HubbleCheckValidationError(
                    'No mention of args in audit-id: {0}'.format(profile_id))
            if 'comparator' not in module_args:
                raise HubbleCheckValidationError(
                    'No mention of comparator in audit-id: {0}'.format(
                        profile_id))
        elif self._caller == Caller.FDG:
            if 'module' not in module_args:
                raise CommandExecutionError(
                    'Could not execute block \'{0}\': no \'module\' found.'.
                    format(profile_id))
            acceptable_block_args = {
                'return',
                'module',
                'args',
                'comparator',
                'xpipe_on_true',
                'xpipe_on_false',
                'xpipe',
                'pipe',
                'pipe_on_true',
                'pipe_on_false',
            }
            for key in module_args:
                if key not in acceptable_block_args:
                    # Just doing error logging for unsupported tags
                    log.warning('Please check block \'{0}\': '
                                '\'{1}\' is an unsupported block key'.format(
                                    profile_id, key))
            if 'args' not in module_args and 'comparator' not in module_args:
                raise CommandExecutionError(
                    'Could not execute block \'{0}\': '
                    'either \'args\' or \'comparator\' is not present in block.'
                    .format(profile_id, key))

        validate_param_method = '{0}.validate_params'.format(module_name)
        __hmods__[validate_param_method](profile_id, module_args, {
            'chaining_args': chaining_args,
            'caller': self._caller
        })
コード例 #8
0
ファイル: grep.py プロジェクト: umutbb/hubble
def _grep(pattern, path=None, string=None, args=None):
    """
    Grep for a string in the specified file or string

    .. note::
        This function's return value is slated for refinement in future
        versions of Salt

    pattern
        Pattern to match. For example: ``test``, or ``a[0-5]``

    path
        Path to the file to be searched

        .. note::
            Globbing is supported (i.e. ``/var/log/foo/*.log``, but if globbing
            is being used then the path should be quoted to keep the shell from
            attempting to expand the glob expression.

    string
        String to search

    args
        Optionally pass a list of flags to pass to the grep command. For example:
        ``-v`` or ``-i`` or ``-B2``
.. note::
            The options should come after a double-dash (as shown in the
            examples below) to keep Salt's own argument parser from
            interpreting them.

    CLI Example:

    .. code-block:: bash

        salt '*' file.grep /etc/passwd nobody
        salt '*' file.grep /etc/sysconfig/network-scripts/ifcfg-eth0 ipaddr '[-i, -B2]'
        salt '*' file.grep /etc/sysconfig/network-scripts/ifcfg-eth0 ipaddr '[-i, -B2]'
        salt '*' file.grep "/etc/sysconfig/network-scripts/*" ipaddr '[-i, -B2]'
    """
    if path:
        path = os.path.expanduser(path)

    options = []
    if args and not isinstance(args, (list, tuple)):
        args = [args]
    for arg in args:
        options += arg.split()
    cmd = ['grep'] + options + [pattern]
    if path:
        cmd += [path]

    try:
        ret = __mods__['cmd.run_stdout'](cmd,
                                         python_shell=False,
                                         ignore_retcode=True,
                                         stdin=string)
    except (IOError, OSError) as exc:
        raise CommandExecutionError(exc.strerror)

    return ret
コード例 #9
0
ファイル: misc.py プロジェクト: umutbb/hubble
def world_writable_file(reason=''):
    """
    Ensure no world writable files exist
    """
    raise CommandExecutionError('Module disabled due to performance concerns')
    result = _execute_shell_command('df --local -P | awk {\'if (NR!=1) print $6\'} | xargs -I \'{}\' find \'{}\' -xdev -type f -perm -0002', python_shell=True)
    return True if result == '' else result
コード例 #10
0
ファイル: misc.py プロジェクト: umutbb/hubble
def unowned_files_or_dir(reason=''):
    """
    Ensure no unowned files or directories exist
    """
    raise CommandExecutionError('Module disabled due to performance concerns')
    result = _execute_shell_command('df --local -P | awk {\'if (NR!=1) print $6\'} | xargs -I \'{}\' find \'{}\' -xdev -nouser', python_shell=True)
    return True if result == '' else result
コード例 #11
0
def _get_top_data(topfile):
    """
    Helper method to retrieve and parse the nova topfile
    """
    orig_topfile = topfile
    topfile = os.path.join(_hubble_dir()[1], topfile)

    log.debug('reading nova topfile=%s (%s)', topfile, orig_topfile)

    try:
        with open(topfile) as handle:
            topdata = yaml.safe_load(handle)

    except Exception as exc:
        log.error('error loading nova topfile: %s', exc)
        return list()

    if not isinstance(topdata, dict) or 'nova' not in topdata or \
            (not isinstance(topdata['nova'], dict)):
        raise CommandExecutionError('Nova topfile not formatted correctly')

    topdata = topdata['nova']

    ret = []

    for match, data in topdata.items():
        if __mods__['match.compound'](match):
            ret.extend(data)

    return ret
コード例 #12
0
def set_mode(path, mode):
    """
    Set the mode of a file

    path
        file or directory of which to set the mode

    mode
        mode to set the path to

    CLI Example:

    .. code-block:: bash

        salt '*' file.set_mode /etc/passwd 0644
    """
    path = os.path.expanduser(path)

    mode = str(mode).lstrip("0Oo")
    if not mode:
        mode = "0"
    if not os.path.exists(path):
        raise CommandExecutionError("{0}: File not found".format(path))
    try:
        os.chmod(path, int(mode, 8))
    except Exception:  # pylint: disable=broad-except
        return "Invalid Mode " + mode
    return get_mode(path)
コード例 #13
0
def remove(path):
    """
    Remove the named file. If a directory is supplied, it will be recursively
    deleted.

    CLI Example:

    .. code-block:: bash

        salt '*' file.remove /tmp/foo

    .. versionchanged:: Neon
        The method now works on all types of file system entries, not just
        files, directories and symlinks.
    """
    path = os.path.expanduser(path)

    if not os.path.isabs(path):
        raise HubbleInvocationError("File path must be absolute: {0}".format(path))

    try:
        if os.path.islink(path) or (os.path.exists(path) and not os.path.isdir(path)):
            os.remove(path)
            return True
        elif os.path.isdir(path):
            shutil.rmtree(path)
            return True
    except (OSError, IOError) as exc:
        raise CommandExecutionError("Could not remove '{0}': {1}".format(path, exc))
    return False
コード例 #14
0
def refresh_db():
    '''
    Updates the package list

    - ``True``: Database updated successfully
    - ``False``: Problem updating database
    '''
    ret = {}
    cmd = ['apk', 'update']
    call = __mods__['cmd.run_all'](cmd,
                                   output_loglevel='trace',
                                   python_shell=False)
    if call['retcode'] == 0:
        errors = []
        ret = True
    else:
        errors = [call['stdout']]
        ret = False

    if errors:
        raise CommandExecutionError(
            'Problem encountered installing package(s)',
            info={'errors': errors, 'changes': ret}
        )

    return ret
コード例 #15
0
def persist(name, value, config="/etc/sysctl.conf", apply_change=False):
    """
    Assign and persist a simple sysctl parameter for this minion
    name
        The name of the sysctl value to edit.
    value
        The sysctl value to apply.
    config
        The location of the sysctl configuration file.
    apply_change
        Default is False; Default behavior only creates or edits
        the sysctl.conf file. If apply is set to True, the changes are
        applied to the system.
    CLI Example:
    .. code-block:: bash
        salt '*' sysctl.persist net.inet.icmp.icmplim 50
        salt '*' sysctl.persist coretemp_load NO config=/etc/sysctl.conf
    """
    nlines = []
    edited = False
    value = str(value)

    # If the sysctl.conf is not present, add it
    if not os.path.isfile(config):
        try:
            with hubblestack.utils.files.fopen(config, "w+") as _fh:
                _fh.write("#\n# Kernel sysctl configuration\n#\n")
        except (IOError, OSError):
            msg = "Could not write to file: {0}"
            raise CommandExecutionError(msg.format(config))

    with hubblestack.utils.files.fopen(config, "r") as ifile:
        for line in ifile:
            line = hubblestack.utils.stringutils.to_unicode(line)
            if not line.startswith("{0}=".format(name)):
                nlines.append(line)
                continue
            else:
                key, rest = line.split("=", 1)
                if rest.startswith('"'):
                    _, rest_v, rest = rest.split('"', 2)
                elif rest.startswith("'"):
                    _, rest_v, rest = rest.split("'", 2)
                else:
                    rest_v = rest.split()[0]
                    rest = rest[len(rest_v):]
                if rest_v == value:
                    return "Already set"
                nlines.append("{0}={1}\n".format(name, value))
                edited = True
    if not edited:
        nlines.append("{0}={1}\n".format(name, value))
    nlines = [hubblestack.utils.stringutils.to_str(_l) for _l in nlines]
    with hubblestack.utils.files.fopen(config, "w+") as ofile:
        ofile.writelines(nlines)
    # If apply_change=True, apply edits to system
    if apply_change is True:
        assign(name, value)
        return "Updated and applied"
    return "Updated"
コード例 #16
0
ファイル: misc.py プロジェクト: umutbb/hubble
def _grep(path,
          pattern,
          *args):
    """
    Grep for a string in the specified file

    .. note::
        This function's return value is slated for refinement in future
        versions of Salt

    path
        Path to the file to be searched

        .. note::
            Globbing is supported (i.e. ``/var/log/foo/*.log``, but if globbing
            is being used then the path should be quoted to keep the shell from
            attempting to expand the glob expression.

    pattern
        Pattern to match. For example: ``test``, or ``a[0-5]``

    opts
        Additional command-line flags to pass to the grep command. For example:
        ``-v``, or ``-i -B2``

        .. note::
            The options should come after a double-dash (as shown in the
            examples below) to keep Salt's own argument parser from
            interpreting them.

    CLI Example:

    .. code-block:: bash

        salt '*' file.grep /etc/passwd nobody
        salt '*' file.grep /etc/sysconfig/network-scripts/ifcfg-eth0 ipaddr -- -i
        salt '*' file.grep /etc/sysconfig/network-scripts/ifcfg-eth0 ipaddr -- -i -B2
        salt '*' file.grep "/etc/sysconfig/network-scripts/*" ipaddr -- -i -l
    """
    path = os.path.expanduser(path)

    if args:
        options = ' '.join(args)
    else:
        options = ''
    cmd = (
        r'''grep  {options} {pattern} {path}'''
        .format(
            options=options,
            pattern=pattern,
            path=path,
        )
    )

    try:
        ret = __mods__['cmd.run_all'](cmd, python_shell=False, ignore_retcode=True)
    except (IOError, OSError) as exc:
        raise CommandExecutionError(exc.strerror)

    return ret
コード例 #17
0
ファイル: win_reg.py プロジェクト: umutbb/hubble
 def __getattr__(self, k):
     try:
         return self.hkeys[k]
     except KeyError:
         msg = 'No hkey named \'{0}. Try one of {1}\''
         hkeys = ', '.join(self.hkeys)
         raise CommandExecutionError(msg.format(k, hkeys))
コード例 #18
0
ファイル: misc.py プロジェクト: umutbb/hubble
def sticky_bit_on_world_writable_dirs(reason=''):
    """
    Ensure sticky bit is set on all world-writable directories
    """
    raise CommandExecutionError('Module disabled due to performance concerns')
    result = _execute_shell_command('df --local -P | awk {\'if (NR!=1) print $6\'} | xargs -I \'{}\' find \'{}\' -xdev -type d \\( -perm -0002 -a ! -perm -1000 \\) 2>/dev/null', python_shell=True)
    return True if result == '' else "There are failures"
コード例 #19
0
ファイル: win_file.py プロジェクト: umutbb/hubble
def is_link(path):
    """
    Check if the path is a symlink

    This is only supported on Windows Vista or later.

    Inline with Unix behavior, this function will raise an error if the path
    is not a symlink, however, the error raised will be a SaltInvocationError,
    not an OSError.

    Args:
        path (str): The path to a file or directory

    Returns:
        bool: True if path is a symlink, otherwise False

    CLI Example:

    .. code-block:: bash

       salt '*' file.is_link /path/to/link
    """
    if sys.getwindowsversion().major < 6:
        raise HubbleInvocationError(
            "Symlinks are only supported on Windows Vista or later."
        )

    try:
        return hubblestack.utils.path.islink(path)
    except Exception as exc:  # pylint: disable=broad-except
        raise CommandExecutionError(exc)
コード例 #20
0
ファイル: audit.py プロジェクト: umutbb/hubble
def _get_top_data(topfile):
    """
    Helper method to retrieve and parse the Audit topfile
    """
    topfile = 'salt://' + BASE_DIR_AUDIT_PROFILES + os.sep + topfile
    log.debug('caching top file...')
    topfile_cache_path = __mods__['cp.cache_file'](topfile)
    if not topfile_cache_path:
        log.error('Could not find top file %s', topfile)
        return None
    topfile = __mods__['cp.cache_file'](topfile)
    if not topfile:
        raise CommandExecutionError('Topfile not found.')
    try:
        with open(topfile_cache_path) as handle:
            topdata = yaml.safe_load(handle)
    except Exception as exc:
        log.exception('Could not load topfile: {0}'.format(exc))
        return None
    if not isinstance(topdata, dict) or 'audit' not in topdata or \
            (not isinstance(topdata['audit'], dict)):
        log.error('Audit topfile not formatted correctly')
        return None
    topdata = topdata['audit']
    ret = []
    for match, data in topdata.items():
        if data is None:
            log.error('No profiles found for one or more filters in topfile %s', topfile)
            return None
        if __mods__['match.compound'](match):
            ret.extend(data)
    return ret
コード例 #21
0
def _check_available(name):
    '''
    Returns boolean telling whether or not the named service is available
    '''
    _status = _systemctl_status(name)
    sd_version = hubblestack.utils.systemd.version(__context__)
    if sd_version is not None and sd_version >= 231:
        # systemd 231 changed the output of "systemctl status" for unknown
        # services, and also made it return an exit status of 4. If we are on
        # a new enough version, check the retcode, otherwise fall back to
        # parsing the "systemctl status" output.
        # See: https://github.com/systemd/systemd/pull/3385
        # Also: https://github.com/systemd/systemd/commit/3dced37
        return 0 <= _status['retcode'] < 4

    out = _status['stdout'].lower()
    if 'could not be found' in out:
        # Catch cases where the systemd version is < 231 but the return code
        # and output changes have been backported (e.g. RHEL 7.3).
        return False

    for line in hubblestack.utils.itertools.split(out, '\n'):
        match = re.match(r'\s+loaded:\s+(\S+)', line)
        if match:
            ret = match.group(1) != 'not-found'
            break
    else:
        raise CommandExecutionError(
            'Failed to get information on unit \'%s\'' % name)
    return ret
コード例 #22
0
ファイル: pkgin.py プロジェクト: umutbb/hubble
def refresh_db(force=False):
    '''
    Use pkg update to get latest pkg_summary

    force
        Pass -f so that the cache is always refreshed.

        .. versionadded:: 2018.3.0
    '''
    # Remove rtag file to keep multiple refreshes from happening in pkg states
    hubblestack.utils.pkg.clear_rtag(__opts__)
    pkgin = _check_pkgin()

    if pkgin:
        cmd = [pkgin, 'up']
        if force:
            cmd.insert(1, '-f')
        call = __mods__['cmd.run_all'](cmd, output_loglevel='trace')

        if call['retcode'] != 0:
            comment = ''
            if 'stderr' in call:
                comment += call['stderr']

            raise CommandExecutionError(comment)

    return True
コード例 #23
0
def get_current_user(with_domain=True):
    """
    Gets the user executing the process

    Args:

        with_domain (bool):
            ``True`` will prepend the user name with the machine name or domain
            separated by a backslash

    Returns:
        str: The user name
    """
    try:
        user_name = win32api.GetUserNameEx(win32api.NameSamCompatible)
        if user_name[-1] == "$":
            # Make the system account easier to identify.
            # Fetch sid so as to handle other language than english
            test_user = win32api.GetUserName()
            if test_user == "SYSTEM":
                user_name = "SYSTEM"
            elif get_sid_from_name(test_user) == "S-1-5-18":
                user_name = "SYSTEM"
        elif not with_domain:
            user_name = win32api.GetUserName()
    except pywintypes.error as exc:
        raise CommandExecutionError(
            "Failed to get current user: {0}".format(exc))

    if not user_name:
        return False

    return user_name
コード例 #24
0
def stats(path, hash_type=None, follow_symlinks=True):
    """
    Return a dict containing the stats for a given file

    CLI Example:

    .. code-block:: bash

        salt '*' file.stats /etc/passwd
    """
    path = os.path.expanduser(path)

    ret = {}
    if not os.path.exists(path):
        try:
            # Broken symlinks will return False for os.path.exists(), but still
            # have a uid and gid
            pstat = os.lstat(path)
        except OSError:
            # Not a broken symlink, just a nonexistent path
            # NOTE: The file.directory state checks the content of the error
            # message in this exception. Any changes made to the message for this
            # exception will reflect the file.directory state as well, and will
            # likely require changes there.
            raise CommandExecutionError("Path not found: {0}".format(path))
    else:
        if follow_symlinks:
            pstat = os.stat(path)
        else:
            pstat = os.lstat(path)
    ret["inode"] = pstat.st_ino
    ret["uid"] = pstat.st_uid
    ret["gid"] = pstat.st_gid
    ret["group"] = gid_to_group(pstat.st_gid)
    ret["user"] = uid_to_user(pstat.st_uid)
    ret["atime"] = pstat.st_atime
    ret["mtime"] = pstat.st_mtime
    ret["ctime"] = pstat.st_ctime
    ret["size"] = pstat.st_size
    ret["mode"] = hubblestack.utils.files.normalize_mode(oct(stat.S_IMODE(pstat.st_mode)))
    if hash_type:
        ret["sum"] = get_hash(path, hash_type)
    ret["type"] = "file"
    if stat.S_ISDIR(pstat.st_mode):
        ret["type"] = "dir"
    if stat.S_ISCHR(pstat.st_mode):
        ret["type"] = "char"
    if stat.S_ISBLK(pstat.st_mode):
        ret["type"] = "block"
    if stat.S_ISREG(pstat.st_mode):
        ret["type"] = "file"
    if stat.S_ISLNK(pstat.st_mode):
        ret["type"] = "link"
    if stat.S_ISFIFO(pstat.st_mode):
        ret["type"] = "pipe"
    if stat.S_ISSOCK(pstat.st_mode):
        ret["type"] = "socket"
    ret["target"] = os.path.realpath(path)
    return ret
コード例 #25
0
ファイル: user.py プロジェクト: umutbb/hubble
def get_user():
    """
    Get the current user
    """
    if HAS_PWD:
        ret = pwd.getpwuid(os.geteuid()).pw_name
    elif HAS_WIN_FUNCTIONS and hubblestack.utils.win_functions.HAS_WIN32:
        ret = hubblestack.utils.win_functions.get_current_user()
    else:
        raise CommandExecutionError(
            "Required external library (pwd or win32api) not installed")
    return hubblestack.utils.stringutils.to_unicode(ret)
コード例 #26
0
ファイル: netbsd_sysctl.py プロジェクト: umutbb/hubble
def persist(name, value, config="/etc/sysctl.conf"):
    """
    Assign and persist a simple sysctl parameter for this minion
    CLI Example:
    .. code-block:: bash
        salt '*' sysctl.persist net.inet.icmp.icmplim 50
    """
    nlines = []
    edited = False
    value = str(value)

    # create /etc/sysctl.conf if not present
    if not os.path.isfile(config):
        try:
            with hubblestack.utils.files.fopen(config, "w+"):
                pass
        except (IOError, OSError):
            msg = "Could not create {0}"
            raise CommandExecutionError(msg.format(config))

    with hubblestack.utils.files.fopen(config, "r") as ifile:
        for line in ifile:
            line = hubblestack.utils.stringutils.to_unicode(line)
            m = re.match(r"{0}(\??=)".format(name), line)
            if not m:
                nlines.append(line)
                continue
            else:
                key, rest = line.split("=", 1)
                if rest.startswith('"'):
                    _, rest_v, rest = rest.split('"', 2)
                elif rest.startswith("'"):
                    _, rest_v, rest = rest.split("'", 2)
                else:
                    rest_v = rest.split()[0]
                    rest = rest[len(rest_v) :]
                if rest_v == value:
                    return "Already set"
                new_line = "{0}{1}{2}{3}".format(name, m.group(1), value, rest)
                nlines.append(new_line)
                edited = True

    if not edited:
        newline = "{0}={1}".format(name, value)
        nlines.append("{0}\n".format(newline))

    with hubblestack.utils.files.fopen(config, "wb") as ofile:
        ofile.writelines(hubblestack.utils.data.encode(nlines))

    assign(name, value)

    return "Updated"
コード例 #27
0
ファイル: fdg.py プロジェクト: umutbb/hubble
def _get_top_data(topfile, fdg_version):
    """
    Helper method to retrieve and parse the FDG topfile
    """
    if not topfile.startswith('salt://'):
        topfile = 'salt://' + BASE_DIR_FDG_PROFILES.get(
            fdg_version) + os.sep + topfile
    cached_topfile = __mods__['cp.cache_file'](topfile)

    if not cached_topfile:
        log.debug('FDG topfile %s not found from fileserver. Aborting.',
                  topfile)
        return []

    try:
        with open(cached_topfile) as handle:
            topdata = yaml.safe_load(handle)
    except Exception as exc:
        raise CommandExecutionError('Could not load topfile: {0}'.format(exc))

    if not isinstance(topdata, dict) or 'fdg' not in topdata:
        raise CommandExecutionError('fdg topfile not formatted correctly: '
                                    'missing ``fdg`` key or not formed as a '
                                    'dict: {0}'.format(topdata))

    topdata = topdata['fdg']

    ret = []

    for match, data in topdata.items():
        if data is None:
            log.error(
                'No profiles found for one or more filters in topfile %s',
                topfile)
            return None
        if __mods__['match.compound'](match):
            ret.extend(data)

    return ret
コード例 #28
0
def set_selinux_context(
        path,
        user=None,
        role=None,
        type=None,  # pylint: disable=W0622
        range=None,  # pylint: disable=W0622
        persist=False,
):
    """
    .. versionchanged:: 3001

        Added persist option

    Set a specific SELinux label on a given path

    CLI Example:

    .. code-block:: bash

        salt '*' file.set_selinux_context path <user> <role> <type> <range>
        salt '*' file.set_selinux_context /etc/yum.repos.d/epel.repo system_u object_r system_conf_t s0
    """
    if not any((user, role, type, range)):
        return False

    if persist:
        fcontext_result = __mods__["selinux.fcontext_add_policy"](
            path, sel_type=type, sel_user=user, sel_level=range
        )
        if fcontext_result.get("retcode", None) != 0:
            # Problem setting fcontext policy
            raise CommandExecutionError(
                "Problem setting fcontext: {0}".format(fcontext_result)
            )

    cmd = ["chcon"]
    if user:
        cmd.extend(["-u", user])
    if role:
        cmd.extend(["-r", role])
    if type:
        cmd.extend(["-t", type])
    if range:
        cmd.extend(["-l", range])
    cmd.append(path)

    ret = not __mods__["cmd.retcode"](cmd, python_shell=False)
    if ret:
        return get_selinux_context(path)
    else:
        return ret
コード例 #29
0
ファイル: pulsar.py プロジェクト: umutbb/hubble
def get_top_data(topfile):
    """
    Cache the topfile and process the list of configs this host should use.
    """
    # Get topdata from filesystem if we don't have them already
    global TOP
    global TOP_STALENESS
    if TOP and TOP_STALENESS < 60:
        TOP_STALENESS += 1
        topdata = TOP
    else:
        log.debug(
            'Missing/stale cached topdata found for pulsar, retrieving fresh from fileserver.'
        )
        topfile = __mods__['cp.cache_file'](topfile)
        try:
            with open(topfile) as handle:
                topdata = yaml.safe_load(handle)
        except Exception as e:
            raise CommandExecutionError(
                'Could not load topfile: {0}'.format(e))

        if not isinstance(topdata, dict) or 'pulsar' not in topdata or \
                not(isinstance(topdata['pulsar'], dict)):
            raise CommandExecutionError(
                'Pulsar topfile not formatted correctly')

        topdata = topdata['pulsar']
        TOP = topdata
        TOP_STALENESS = 0

    ret = []

    for match, data in topdata.items():
        if __mods__['match.compound'](match):
            ret.extend(data)

    return ret
コード例 #30
0
ファイル: misc.py プロジェクト: umutbb/hubble
def check_ungrouped_files(reason=''):
    """
    Ensure no ungrouped files or directories exist
    """
    raise CommandExecutionError('Module disabled due to performance concerns')
    ungrouped_files = _execute_shell_command("df --local -P | awk 'NR!=1 {print $6}' | xargs -I '{}' find '{}' -xdev -nogroup 2>/dev/null", python_shell=True).strip()
    ungrouped_files = ungrouped_files.split('\n') if ungrouped_files != "" else []
    # The command above only searches local filesystems, there may still be compromised items on network
    # mounted partitions.
    # Following command will check each partition for unowned files
    ungrouped_partition_files = _execute_shell_command("mount | awk '{print $3}' | xargs -I '{}' find '{}' -xdev -nogroup 2>/dev/null", python_shell=True).strip()
    ungrouped_partition_files = ungrouped_partition_files.split('\n') if ungrouped_partition_files != "" else []
    ungrouped_files = ungrouped_files + ungrouped_partition_files
    return True if ungrouped_files == [] else str(list(set(ungrouped_files)))