def clone(name, source, *varargs, **kwargs):
    '''
    Clone a VM (qvm-clone).
    '''
    # Return if VM already exists
    exists_status = Status(**_state_action('qvm.check', name, *['exists']))
    if exists_status.passed():
        message = "A VM with the name '{0}' already exists.".format(name)
        status = Status()._format(prefix='[SKIP] ', message=message)
        return vars(status._finalize(test_mode=__opts__['test']))
    return _state_action('qvm.clone', source, name, *varargs, **kwargs)
def kill(name, *varargs, **kwargs):
    '''
    Kill vmname (qvm-kill).
    '''
    # Return if VM already halted (stderr will contain message if VM absent)
    halted_status = Status(**_state_action('qvm.state', name, *['halted']))
    if halted_status.passed():
        message = halted_status.stderr or "'{0}' is already halted.".format(
            name)
        status = Status()._format(prefix='[SKIP] ', message=message)
        return vars(status._finalize(test_mode=__opts__['test']))
    return _state_action('qvm.kill', name, *varargs, **kwargs)
def absent(name, *varargs, **kwargs):
    '''
    Make sure the named VM is absent.

    VM will be deleted (removed) if present (qvm-absent).
    '''
    # Return if VM already absent
    missing_status = Status(**_state_action('qvm.check', name, *['missing']))
    if missing_status.passed():
        message = "The VM with the name '{0}' is already missing.".format(name)
        status = Status()._format(prefix='[SKIP] ', message=message)
        return vars(status._finalize(test_mode=__opts__['test']))
    return _state_action('qvm.remove', name, *varargs, **kwargs)
def present(name, *varargs, **kwargs):
    '''
    Make sure the named VM is present.

    VM will be created if missing (qvm-present).
    '''
    # Return if VM already exists
    exists_status = Status(**_state_action('qvm.check', name, *['exists']))
    if exists_status.passed():
        message = "A VM with the name '{0}' already exists.".format(name)
        status = Status()._format(prefix='[SKIP] ', message=message)
        return vars(status._finalize(test_mode=__opts__['test']))
    return _state_action('qvm.create', name, *varargs, **kwargs)
    def status(self):
        '''
        Returns finalized merged 'data' status.
        '''
        status = Status()
        status_mode = 'last' if 'last' in self.defaults.status_mode else 'all'
        debug_mode = True if 'debug' in self.defaults.status_mode else False

        # pylint: disable=W0212
        return status._finalize(data=self._data,
                                status_mode=status_mode,
                                cli_mode=self.defaults.cli_mode,
                                debug_mode=debug_mode,
                                test_mode=__opts__['test'])
def halted(name, *varargs, **kwargs):
    '''
    Return True is vmname is halted (qvm-halted).
    '''
    varargs = list(varargs)
    varargs.append('halted')
    # Return if VM already halted (stderr will contain message if VM absent)
    halted_status = Status(**_state_action('qvm.state', name, *varargs,
                                           **kwargs))
    if halted_status.passed() or halted_status.stderr:
        message = halted_status.stderr or "'{0}' is already halted.".format(
            name)
        status = Status()._format(prefix='[SKIP] ', message=message)
        return vars(status._finalize(test_mode=__opts__['test']))
    return _state_action('qvm.state', name, *varargs, **kwargs)
Ejemplo n.º 7
0
    def status(self):
        '''
        Returns finalized merged 'data' status.
        '''
        status = Status()
        status_mode = 'last' if 'last' in self.defaults.status_mode else 'all'
        debug_mode = True if 'debug' in self.defaults.status_mode else False

        # pylint: disable=W0212
        return status._finalize(
            data=self._data,
            status_mode=status_mode,
            cli_mode=self.defaults.cli_mode,
            debug_mode=debug_mode,
            test_mode=__opts__['test']
        )
Ejemplo n.º 8
0
def create(name, comment, result=None):
    '''
    Used to show an alert message when a condition is met not to include a
    state.

    :param name:
    :param comment:
    :param result:
    '''
    return dict(Status(name=name, result=result, comment=comment))
Ejemplo n.º 9
0
def _state_action(_action, *varargs, **kwargs):
    '''
    '''
    try:
        status = __salt__[_action](*varargs, **kwargs)

    except (SaltInvocationError, CommandExecutionError) as e:
        status = Status(retcode=1, result=False, comment=e.message + '\n')

    return vars(status)
Ejemplo n.º 10
0
    def save_status(
        self,
        status=None,
        retcode=None,
        result=None,
        data=None,
        prefix=None,
        message='',
        error_message=''
    ):
        '''
        Merges data from individual status into master data dictionary
        which will be returned and includes all changes and comments as well
        as the overall status status.

        :param status:
        :param retcode:
        :param result:
        :param data:
        :param prefix:
        :param message:
        :param error_message:
        '''
        # Create a default status if one does not exist
        if status is None:
            status = Status()

        if not status.name:
            status.name = self.__virtualname__

        # pylint: disable=W0212
        status._format(
            retcode=retcode,
            result=result,
            data=data,
            prefix=prefix,
            message=message,
            error_message=error_message
        )
        self._data.append(status)

        return status
    def save_status(self,
                    status=None,
                    retcode=None,
                    result=None,
                    data=None,
                    prefix=None,
                    message='',
                    error_message=''):
        '''
        Merges data from individual status into master data dictionary
        which will be returned and includes all changes and comments as well
        as the overall status status.

        :param status:
        :param retcode:
        :param result:
        :param data:
        :param prefix:
        :param message:
        :param error_message:
        '''
        # Create a default status if one does not exist
        if status is None:
            status = Status()

        if not status.name:
            status.name = self.__virtualname__

        # pylint: disable=W0212
        status._format(retcode=retcode,
                       result=result,
                       data=data,
                       prefix=prefix,
                       message=message,
                       error_message=error_message)
        self._data.append(status)

        return status
    def run(self,
            cmd,
            test_ignore=False,
            post_hook=None,
            data=None,
            **options):
        '''
        Executes cmd using salt.utils run_all function.

        Fake status are returned instead of executing the command if test
        mode is enabled.

        :param cmd:
        :param test_ignore:
        :param post_hook:
        :param data:
        '''
        if __opts__['test'] and not test_ignore:
            status = Status(retcode=0, prefix='[TEST] ')

        else:
            if isinstance(cmd, list):
                cmd = ' '.join(pipes.quote(c) for c in cmd)

            status = Status(**__salt__['cmd.run_all'](cmd,
                                                      runas=self.run_as_user,
                                                      output_loglevel='quiet',
                                                      **options))
            delattr(status, 'pid')

        self._run_post_hook(post_hook, cmd, status, data)

        cmd_options = str(options) if options else ''
        cmd_string = '{0} {1}'.format(cmd, cmd_options)

        return self.save_status(status, message=cmd_string)
Ejemplo n.º 13
0
def clone(name, source, *varargs, **kwargs):
    '''
    Clone a VM (qvm-clone).
    '''
    # Return if VM already exists
    exists_status = Status(**_state_action('qvm.check', name, *['exists']))
    if exists_status.passed():
        message = "A VM with the name '{0}' already exists.".format(name)
        status = Status()._format(prefix='[SKIP] ', message=message)
        return vars(status._finalize(test_mode=__opts__['test']))
    return _state_action('qvm.clone', source, name, *varargs, **kwargs)
Ejemplo n.º 14
0
def kill(name, *varargs, **kwargs):
    '''
    Kill vmname (qvm-kill).
    '''
    # Return if VM already halted (stderr will contain message if VM absent)
    halted_status = Status(**_state_action('qvm.state', name, *['halted']))
    if halted_status.passed():
        message = halted_status.stderr or "'{0}' is already halted.".format(
            name)
        status = Status()._format(prefix='[SKIP] ', message=message)
        return vars(status._finalize(test_mode=__opts__['test']))
    return _state_action('qvm.kill', name, *varargs, **kwargs)
Ejemplo n.º 15
0
def absent(name, *varargs, **kwargs):
    '''
    Make sure the named VM is absent.

    VM will be deleted (removed) if present (qvm-absent).
    '''
    # Return if VM already absent
    missing_status = Status(**_state_action('qvm.check', name, *['missing']))
    if missing_status.passed():
        message = "The VM with the name '{0}' is already missing.".format(name)
        status = Status()._format(prefix='[SKIP] ', message=message)
        return vars(status._finalize(test_mode=__opts__['test']))
    return _state_action('qvm.remove', name, *varargs, **kwargs)
Ejemplo n.º 16
0
def present(name, *varargs, **kwargs):
    '''
    Make sure the named VM is present.

    VM will be created if missing (qvm-present).
    '''
    # Return if VM already exists
    exists_status = Status(**_state_action('qvm.check', name, *['exists']))
    if exists_status.passed():
        message = "A VM with the name '{0}' already exists.".format(name)
        status = Status()._format(prefix='[SKIP] ', message=message)
        return vars(status._finalize(test_mode=__opts__['test']))
    return _state_action('qvm.create', name, *varargs, **kwargs)
Ejemplo n.º 17
0
def _state_action(_action, *varargs, **kwargs):
    '''
    State utility to standardize calling Qubes modules.

    Python State Example:

    .. code-block:: python

        from qubes_state_utils import state_action as _state_action

        def exists(name, *varargs, **kwargs):
            varargs = list(varargs)
            varargs.append('exists')
            return _state_action('qvm.check', name, *varargs, **kwargs)
    '''
    try:
        status = __salt__[_action](*varargs, **kwargs)
    except (SaltInvocationError, CommandExecutionError) as err:
        status = Status(retcode=1, result=False, stderr=err.message + '\n')
    return vars(status)
Ejemplo n.º 18
0
def halted(name, *varargs, **kwargs):
    '''
    Return True is vmname is halted (qvm-halted).
    '''
    varargs = list(varargs)
    varargs.append('halted')
    # Return if VM already halted (stderr will contain message if VM absent)
    halted_status = Status(
        **_state_action('qvm.state', name, *varargs, **kwargs))
    if halted_status.passed() or halted_status.stderr:
        message = halted_status.stderr or "'{0}' is already halted.".format(
            name)
        status = Status()._format(prefix='[SKIP] ', message=message)
        return vars(status._finalize(test_mode=__opts__['test']))
    return _state_action('qvm.state', name, *varargs, **kwargs)
def import_key(*varargs, **kwargs):
    '''
    Import a key from text or file.

    user
        Which user's keychain to access, defaults to user Salt is running as.
        Passing the user as 'salt' will set the GPG home directory to
        /etc/salt/gpgkeys.

    contents
        The text containing import key to import.

    contents-pillar
        The pillar id containing import key to import.

    source
        The filename containing the key to import.

    CLI Example:

    .. code-block:: bash

        qubesctl gnupg.import_key contents='-----BEGIN PGP PUBLIC KEY BLOCK-----
        ... -----END PGP PUBLIC KEY BLOCK-----'

        qubesctl gnupg.import_key source='/path/to/public-key-file'

        qubesctl gnupg.import_key contents-piller='gnupg:gpgkeys'
    '''
    base = _GPGBase('gpg.import_key', **kwargs)
    base.parser.add_argument('name', nargs='?', help=argparse.SUPPRESS)
    group = base.parser.add_mutually_exclusive_group()

    group.add_argument(
        'source',
        nargs='?',
        help='The filename containing the key to import'
    )

    group.add_argument(
        '--contents',
        nargs=1,
        metavar='TEXT',
        help='The text containing import key to import'
    )

    group.add_argument(
        '--contents-pillar',
        '--contents_pillar',
        type=_coerce_to_string,
        nargs=1,
        metavar='PILLAR-ID',
        help='The pillar id containing import key to import'
    )

    base.parser.add_argument(
        '--user',
        nargs=1,
        default='salt',
        help="Which user's keychain to access, defaults to user Salt is \
        running as.  Passing the user as 'salt' will set the GPG home \
        directory to /etc/salt/gpgkeys."
    )

    args = base.parse_args(*varargs, **kwargs)
    base.args.contents_pillar = _coerce_to_string(
        base.args.contents_pillar
    ) if base.args.contents_pillar else base.args.contents_pillar

    keywords = {'user': args.user, }
    status = Status()
    if args.source:
        keywords['filename'] = _get_path(args.source)
        if not keywords['filename']:
            status.recode = 1
            status.message = 'Invalid filename source {0}'.format(args.source)

    elif args.contents:
        keywords['text'] = args.contents

    elif args.contents_pillar:
        keywords['text'] = __pillar__.get(args.contents_pillar, None)
        if not keywords['text']:
            status.recode = 1
            status.message = 'Invalid pillar id source {0}'.format(
                args.contents_pillar
            )

    else:
        status.recode = 1
        status.message = 'Invalid options!'

    if status.failed():
        base.save_status(status)
    if __opts__['test']:
        base.save_status(message='Key will be imported')
    else:
        status = Status(**_import(**keywords))
        base.save_status(status)

    # Returns the status 'data' dictionary
    return base.status()
def verify(name, *varargs, **kwargs):
    '''
    Verify a message or file.

    source
        The filename.asc to verify.

    key-content
        The text to verify.

    data-source
        The filename data to verify.

    user
        Which user's keychain to access, defaults to user Salt is running as.
        Passing the user as 'salt' will set the GPG home directory to
        /etc/salt/gpgkeys.

    CLI Example:

    .. code-block:: bash

        qubesctl gnupg.verify source='/path/to/important.file.asc'

        qubesctl gnupg.verify <source|key-content> [key-data] [user=]

    '''
    base = _GPGBase('gpg.verify', **kwargs)
    base.parser.add_argument('name', help='The name id of state object')
    group = base.parser.add_mutually_exclusive_group()

    group.add_argument(
        'source',
        nargs='?',
        help='The filename containing the key to import'
    )

    group.add_argument(
        '--key-contents',
        '--key_contents',
        nargs=1,
        help='The text containing import key to import'
    )

    base.parser.add_argument(
        '--data-source',
        '--data_source',
        nargs='?',
        help='Source file data path to verify (source)'
    )

    base.parser.add_argument(
        '--user',
        nargs=1,
        default='salt',
        help="Which user's keychain to access, defaults to user Salt is \
        running as.  Passing the user as 'salt' will set the GPG home \
        directory to /etc/salt/gpgkeys."
    )

    args = base.parse_args(name, *varargs, **kwargs)
    gnupg = _gpg._create_gpg(args.user)  # pylint: disable=W0212
    status = Status()

    # Key source validation
    if args.source:
        key_source = _get_path(args.source)
        if not key_source:
            status.recode = 1
            status.message = 'GPG validation failed: invalid key-source {0}'.format(
                key_source
            )

    elif args.key_contents:
        key_source = args.key_contents

    else:
        key_source = _get_path(args.name)

    # Data source validation
    data_source = _get_path(args.data_source)
    if not data_source:
        data_source, ext = os.path.splitext(key_source)  # pylint: disable=W0612

    if not os.path.exists(data_source):
        status.retcode = 1
        message = 'GPG validation failed: invalid data-source {0}'.format(
            data_source
        )
        base.save_status(status, message=message)
        return base.status()

    # GPG verify
    status = Status()
    data = gnupg.verify_data(key_source, _get_data(data_source))

    if not data.valid:
        raise CommandExecutionError(data.stderr)

    status.stdout = data.stderr
    base.save_status(status)

    # Returns the status 'data' dictionary
    return base.status()