Пример #1
0
def render(jp_data, saltenv='base', sls='', **kws):
    '''
    Accepts Java Properties as a string or as a file object and runs it through the jproperties
    parser. Uses the jproperties package https://pypi.python.org/pypi/jproperties so please
    "pip install jproperties" to use this renderer.

    Returns a flat dictionary by default:
      {'some.java.thing': 'whatever'}
    If using a 'shebang' "#!jproperties" header on the first line, an argument can be optionally
    supplied as a key to contain a dictionary of the rendered properties (ie. "#!jproperties foo"):
      {'foo': {'some.java.thing': 'whatever'}}

    :rtype: A Python data structure
    '''
    if not isinstance(jp_data, string_types):
        jp_data = jp_data.read()

    container = False
    if jp_data.startswith('#!'):
        args = jp_data[:jp_data.find('\n')].split()
        if len(args) >= 2:
            container = args[1]
        jp_data = jp_data[(jp_data.find('\n') + 1):]
    if not jp_data.strip():
        return {}
    properties = jp()
    properties.load(jp_data)
    if container:
        return {container: dict([(k, properties[k]) for k in six.iterkeys(properties)])}
    else:
        return dict([(k, properties[k]) for k in six.iterkeys(properties)])
Пример #2
0
    def test_basic(self):
        '''
        Make sure that the process is alive 2s later
        '''
        def spin():
            salt.utils.appendproctitle('test_basic')
            while True:
                time.sleep(1)

        process_manager = salt.utils.process.ProcessManager()
        process_manager.add_process(spin)
        initial_pid = next(six.iterkeys(process_manager._process_map))
        time.sleep(2)
        process_manager.check_children()
        try:
            assert initial_pid == next(six.iterkeys(process_manager._process_map))
        finally:
            process_manager.stop_restarting()
            process_manager.kill_children()
            time.sleep(0.5)
            # Are there child processes still running?
            if process_manager._process_map.keys():
                process_manager.send_signal_to_processes(signal.SIGKILL)
                process_manager.stop_restarting()
                process_manager.kill_children()
Пример #3
0
def table_find(table_to_find):
    '''
    Finds the schema in which the
    given table is present

    CLI Example::

        salt '*' drizzle.table_find table_name
    '''

    # Initializing the required variables
    ret_val = {}
    count = 1
    drizzle_db = _connect()
    cursor = drizzle_db.cursor()

    # Finding the schema
    schema = schemas()
    for schema_iter in six.iterkeys(schema):
        table = tables(schema[schema_iter])
        for table_iter in six.iterkeys(table):
            if table[table_iter] == table_to_find:
                ret_val[count] = schema[schema_iter]
                count = count+1

    cursor.close()
    drizzle_db.close()
    return ret_val
Пример #4
0
def __call_cli(jboss_config, command, retries=1):
    command_segments = [
        jboss_config['cli_path'],
        '--connect',
        '--controller="{0}"'.format(jboss_config['controller'])
    ]
    if 'cli_user' in six.iterkeys(jboss_config):
        command_segments.append('--user="******"'.format(jboss_config['cli_user']))
    if 'cli_password' in six.iterkeys(jboss_config):
        command_segments.append('--password="******"'.format(jboss_config['cli_password']))
    command_segments.append('--command="{0}"'.format(__escape_command(command)))
    cli_script = ' '.join(command_segments)

    cli_command_result = __salt__['cmd.run_all'](cli_script)
    log.debug('cli_command_result=%s', str(cli_command_result))

    log.debug('========= STDOUT:\n%s', cli_command_result['stdout'])
    log.debug('========= STDERR:\n%s', cli_command_result['stderr'])
    log.debug('========= RETCODE: %d', cli_command_result['retcode'])

    if cli_command_result['retcode'] == 127:
        raise CommandExecutionError('Could not execute jboss-cli.sh script. Have you specified server_dir variable correctly?\nCurrent CLI path: {cli_path}. '.format(cli_path=jboss_config['cli_path']))

    if cli_command_result['retcode'] == 1 and 'Unable to authenticate against controller' in cli_command_result['stderr']:
        raise CommandExecutionError('Could not authenticate against controller, please check username and password for the management console. Err code: {retcode}, stdout: {stdout}, stderr: {stderr}'.format(**cli_command_result))

    # It may happen that eventhough server is up it may not respond to the call
    if cli_command_result['retcode'] == 1 and 'JBAS012144' in cli_command_result['stderr'] and retries > 0:  # Cannot connect to cli
        log.debug('Command failed, retrying... (%d tries left)', retries)
        time.sleep(3)
        return __call_cli(jboss_config, command, retries - 1)

    return cli_command_result
Пример #5
0
    def stages_iter(self):
        '''
        Return an iterator that yields the state call data as it is processed
        '''

        def yielder(gen_ret):
            if (not isinstance(gen_ret, list)
                    and not isinstance(gen_ret, dict)
                    and hasattr(gen_ret, 'next')):
                for sub_ret in gen_ret:
                    for yret in yielder(sub_ret):
                        yield yret
            else:
                yield gen_ret

        self.over_run = {}
        yield self.over
        for comp in self.over:
            name = next(six.iterkeys(comp))
            stage = comp[name]
            if name not in self.over_run:
                v_stage = self.verify_stage(stage)
                if isinstance(v_stage, list):
                    yield [comp]
                    yield v_stage
                else:
                    for sret in self.call_stage(name, stage):
                        for yret in yielder(sret):
                            sname = next(six.iterkeys(yret))
                            yield [self.get_stage(sname)]
                            final = {}
                            for minion in yret[sname]:
                                final[minion] = yret[sname][minion]['ret']
                            yield final
Пример #6
0
    def test_cmd_call(self):
        result = self.HIGHSTATE.state.call_template_str(
            textwrap.dedent(
                """\
            #!pydsl
            state('A').cmd.run('echo this is state A', cwd='/')

            some_var = 12345
            def do_something(a, b, *args, **kws):
                return dict(result=True, changes={'a': a, 'b': b, 'args': args, 'kws': kws, 'some_var': some_var})

            state('C').cmd.call(do_something, 1, 2, 3, x=1, y=2) \
                          .require(state('A').cmd)

            state('G').cmd.wait('echo this is state G', cwd='/') \
                          .watch(state('C').cmd)
        """
            )
        )
        ret = next(result[k] for k in six.iterkeys(result) if "do_something" in k)
        changes = ret["changes"]
        self.assertEqual(changes, dict(a=1, b=2, args=(3,), kws=dict(x=1, y=2), some_var=12345))

        ret = next(result[k] for k in six.iterkeys(result) if "-G_" in k)
        self.assertEqual(ret["changes"]["stdout"], "this is state G")
Пример #7
0
Файл: pkg.py Проект: bryson/salt
def list_upgrades(jid, style="group", outputter="nested", ext_source=None):
    """
    Show list of available pkg upgrades using a specified format style

    CLI Example:

    .. code-block:: bash

        salt-run pkg.list_upgrades jid=20141120114114417719 style=group
    """
    mminion = salt.minion.MasterMinion(__opts__)
    returner = _get_returner((__opts__["ext_job_cache"], ext_source, __opts__["master_job_cache"]))

    data = mminion.returners["{0}.get_jid".format(returner)](jid)
    pkgs = {}

    if style == "group":
        for minion in data:
            results = data[minion]["return"]
            for pkg, pkgver in six.iteritems(results):
                if pkg not in six.iterkeys(pkgs):
                    pkgs[pkg] = {pkgver: {"hosts": []}}

                if pkgver not in six.iterkeys(pkgs[pkg]):
                    pkgs[pkg].update({pkgver: {"hosts": []}})

                pkgs[pkg][pkgver]["hosts"].append(minion)

    if outputter:
        salt.output.display_output(pkgs, outputter, opts=__opts__)

    return pkgs
Пример #8
0
    def test_kill(self):
        def spin():
            salt.utils.appendproctitle('test_kill')
            while True:
                time.sleep(1)

        process_manager = salt.utils.process.ProcessManager()
        process_manager.add_process(spin)
        initial_pid = next(six.iterkeys(process_manager._process_map))
        # kill the child
        os.kill(initial_pid, signal.SIGKILL)
        # give the OS time to give the signal...
        time.sleep(0.1)
        process_manager.check_children()
        try:
            assert initial_pid != next(six.iterkeys(process_manager._process_map))
        finally:
            process_manager.stop_restarting()
            process_manager.kill_children()
            time.sleep(0.5)
            # Are there child processes still running?
            if process_manager._process_map.keys():
                process_manager.send_signal_to_processes(signal.SIGKILL)
                process_manager.stop_restarting()
                process_manager.kill_children()
Пример #9
0
 def SetIncludes(self, includes):
     if includes:
         for inc in includes:
             value = inc[next(six.iterkeys(inc))]
             include = next(six.iterkeys(inc))
             self.SetInclude(include, value)
             log.debug('was asked to set {0} to {1}'.format(include, value))
Пример #10
0
def user_role_add(user_id=None, user=None, tenant_id=None,
                  tenant=None, role_id=None, role=None, profile=None,
                  project_id=None, project_name=None, **connection_args):
    '''
    Add role for user in tenant (keystone user-role-add)

    CLI Examples:

    .. code-block:: bash

        salt '*' keystone.user_role_add \
user_id=298ce377245c4ec9b70e1c639c89e654 \
tenant_id=7167a092ece84bae8cead4bf9d15bb3b \
role_id=ce377245c4ec9b70e1c639c89e8cead4
        salt '*' keystone.user_role_add user=admin tenant=admin role=admin
    '''
    kstone = auth(profile, **connection_args)

    if project_id and not tenant_id:
        tenant_id = project_id
    elif project_name and not tenant:
        tenant = project_name

    if user:
        user_id = user_get(name=user, profile=profile,
                           **connection_args)[user].get('id')
    else:
        user = next(six.iterkeys(user_get(user_id, profile=profile,
                                          **connection_args)))['name']
    if not user_id:
        return {'Error': 'Unable to resolve user id'}

    if tenant:
        tenant_id = tenant_get(name=tenant, profile=profile,
                               **connection_args)[tenant].get('id')
    else:
        tenant = next(six.iterkeys(tenant_get(tenant_id, profile=profile,
                                              **connection_args)))['name']
    if not tenant_id:
        return {'Error': 'Unable to resolve tenant/project id'}

    if role:
        role_id = role_get(name=role, profile=profile,
                           **connection_args)[role]['id']
    else:
        role = next(six.iterkeys(role_get(role_id, profile=profile,
                                          **connection_args)))['name']
    if not role_id:
        return {'Error': 'Unable to resolve role id'}

    if _OS_IDENTITY_API_VERSION > 2:
        kstone.roles.grant(role_id, user=user_id, project=tenant_id)
    else:
        kstone.roles.add_user_role(user_id, role_id, tenant_id)
    ret_msg = '"{0}" role added for user "{1}" for "{2}" tenant/project'
    return ret_msg.format(role, user, tenant)
Пример #11
0
    def test_restarting(self):
        '''
        Make sure that the process is alive 2s later
        '''
        def die():
            time.sleep(1)

        process_manager = salt.utils.process.ProcessManager()
        process_manager.add_process(die)
        initial_pid = next(six.iterkeys(process_manager._process_map))
        time.sleep(2)
        process_manager.check_children()
        assert initial_pid != next(six.iterkeys(process_manager._process_map))
        process_manager.kill_children()
Пример #12
0
    def test_kill(self):
        def spin():
            while True:
                time.sleep(1)

        process_manager = salt.utils.process.ProcessManager()
        process_manager.add_process(spin)
        initial_pid = next(six.iterkeys(process_manager._process_map))
        # kill the child
        os.kill(initial_pid, signal.SIGTERM)
        # give the OS time to give the signal...
        time.sleep(0.1)
        process_manager.check_children()
        assert initial_pid != next(six.iterkeys(process_manager._process_map))
        process_manager.kill_children()
Пример #13
0
    def test_basic(self):
        '''
        Make sure that the process is alive 2s later
        '''
        def spin():
            while True:
                time.sleep(1)

        process_manager = salt.utils.process.ProcessManager()
        process_manager.add_process(spin)
        initial_pid = next(six.iterkeys(process_manager._process_map))
        time.sleep(2)
        process_manager.check_children()
        assert initial_pid == next(six.iterkeys(process_manager._process_map))
        process_manager.kill_children()
Пример #14
0
def _list_iter(host=None, path=None):
    '''
    Return a generator iterating over hosts

    path
        path to the container parent
        default: /var/lib/lxc (system default)

        .. versionadded:: Beryllium
    '''
    tgt = host or '*'
    client = salt.client.get_local_client(__opts__['conf_file'])
    for container_info in client.cmd_iter(
        tgt, 'lxc.list', kwarg={'path': path}
    ):
        if not container_info:
            continue
        if not isinstance(container_info, dict):
            continue
        chunk = {}
        id_ = next(six.iterkeys(container_info))
        if host and host != id_:
            continue
        if not isinstance(container_info[id_], dict):
            continue
        if 'ret' not in container_info[id_]:
            continue
        if not isinstance(container_info[id_]['ret'], dict):
            continue
        chunk[id_] = container_info[id_]['ret']
        yield chunk
Пример #15
0
def resume(name):
    '''
    Resume a paused vm
    '''
    ret = {}
    client = salt.client.get_local_client(__opts__['conf_file'])
    data = vm_info(name, quiet=True)
    if not data:
        __jid_event__.fire_event({'error': 'Failed to find VM {0} to pause'.format(name)}, 'progress')
        return 'not found'
    hyper = next(six.iterkeys(data))
    if data[hyper][name]['state'] != 'paused':
        __jid_event__.fire_event({'error': 'VM {0} is not paused'.format(name)}, 'progress')
        return 'bad state'
    try:
        cmd_ret = client.cmd_iter(
                hyper,
                'virt.resume',
                [name],
                timeout=600)
    except SaltClientError as client_error:
        return 'Virtual machine {0} could not be resumed: {1}'.format(name, client_error)
    for comp in cmd_ret:
        ret.update(comp)
    __jid_event__.fire_event({'message': 'Resumed VM {0}'.format(name)}, 'progress')
    return 'good'
Пример #16
0
def config(name, config, edit=True):
    '''
    Create VirtualHost configuration files

    name
        File for the virtual host
    config
        VirtualHost configurations

    .. note::

        This function is not meant to be used from the command line.
        Config is meant to be an ordered dict of all of the apache configs.

    CLI Example:

    .. code-block:: bash

        salt '*' apache.config /etc/httpd/conf.d/ports.conf config="[{'Listen': '22'}]"
    '''

    for entry in config:
        key = next(six.iterkeys(entry))
        configs = _parse_config(entry[key], key)
        if edit:
            with salt.utils.fopen(name, 'w') as configfile:
                configfile.write('# This file is managed by saltstack.\n')
                configfile.write(configs)
    return configs
Пример #17
0
def _expand_one_key_dictionary(_dict):
    '''
    Returns the only one key and it's value from a dictionary.
    '''
    key = next(six.iterkeys(_dict))
    value = _dict[key]
    return key, value
Пример #18
0
    def attrs(self):
        kwargs = self.kwargs

        # handle our requisites
        for attr in REQUISITES:
            if attr in kwargs:
                # our requisites should all be lists, but when you only have a
                # single item it's more convenient to provide it without
                # wrapping it in a list. transform them into a list
                if not isinstance(kwargs[attr], list):
                    kwargs[attr] = [kwargs[attr]]

                # rebuild the requisite list transforming any of the actual
                # StateRequisite objects into their representative dict
                kwargs[attr] = [
                    req() if isinstance(req, StateRequisite) else req
                    for req in kwargs[attr]
                ]

        # build our attrs from kwargs. we sort the kwargs by key so that we
        # have consistent ordering for tests
        return [
            {k: kwargs[k]}
            for k in sorted(six.iterkeys(kwargs))
        ]
Пример #19
0
 def spec_check(self, auth_list, fun, form):
     '''
     Check special API permissions
     '''
     if form != 'cloud':
         comps = fun.split('.')
         if len(comps) != 2:
             return False
         mod = comps[0]
         fun = comps[1]
     else:
         mod = fun
     for ind in auth_list:
         if isinstance(ind, six.string_types):
             if ind.startswith('@') and ind[1:] == mod:
                 return True
             if ind == '@{0}'.format(form):
                 return True
             if ind == '@{0}s'.format(form):
                 return True
         elif isinstance(ind, dict):
             if len(ind) != 1:
                 continue
             valid = next(six.iterkeys(ind))
             if valid.startswith('@') and valid[1:] == mod:
                 if isinstance(ind[valid], six.string_types):
                     if self.match_check(ind[valid], fun):
                         return True
                 elif isinstance(ind[valid], list):
                     for regex in ind[valid]:
                         if self.match_check(regex, fun):
                             return True
     return False
Пример #20
0
    def __gather_minions(self):
        '''
        Return a list of minions to use for the batch run
        '''
        args = [self.opts['tgt'],
                'test.ping',
                [],
                self.opts['timeout'],
                ]

        selected_target_option = self.opts.get('selected_target_option', None)
        if selected_target_option is not None:
            args.append(selected_target_option)
        else:
            args.append(self.opts.get('expr_form', 'glob'))

        ping_gen = self.local.cmd_iter(*args, **self.eauth)

        fret = set()
        try:
            for ret in ping_gen:
                m = next(six.iterkeys(ret))
                if m is not None:
                    fret.add(m)
            return (list(fret), ping_gen)
        except StopIteration:
            raise salt.exceptions.SaltClientError('No minions matched the target.')
Пример #21
0
    def destroy(self, linger=5000):
        if self.cpub is True and self.sub.closed is False:
            # Wait at most 2.5 secs to send any remaining messages in the
            # socket or the context.term() below will hang indefinitely.
            # See https://github.com/zeromq/pyzmq/issues/102
            self.sub.close()
        if self.cpush is True and self.push.closed is False:
            self.push.close()
        # If sockets are not unregistered from a poller, nothing which touches
        # that poller gets garbage collected. The Poller itself, its
        # registered sockets and the Context
        if isinstance(self.poller.sockets, dict):
            for socket in six.iterkeys(self.poller.sockets):
                if socket.closed is False:
                    socket.setsockopt(zmq.LINGER, linger)
                    socket.close()
                self.poller.unregister(socket)
        else:
            for socket in self.poller.sockets:
                if socket[0].closed is False:
                    socket[0].setsockopt(zmq.LINGER, linger)
                    socket[0].close()
                self.poller.unregister(socket[0])
        if self.context.closed is False:
            self.context.term()

        # Hardcore destruction
        if hasattr(self.context, 'destroy'):
            self.context.destroy(linger=1)

        # https://github.com/zeromq/pyzmq/issues/173#issuecomment-4037083
        # Assertion failed: get_load () == 0 (poller_base.cpp:32)
        time.sleep(0.025)
Пример #22
0
    def _sanatize_network_params(self, kwargs):
        """
        Sanatize novaclient network parameters
        """
        params = [
            "label",
            "bridge",
            "bridge_interface",
            "cidr",
            "cidr_v6",
            "dns1",
            "dns2",
            "fixed_cidr",
            "gateway",
            "gateway_v6",
            "multi_host",
            "priority",
            "project_id",
            "vlan_start",
            "vpn_start",
        ]

        for variable in six.iterkeys(kwargs):  # iterate over a copy, we might delete some
            if variable not in params:
                del kwargs[variable]
        return kwargs
Пример #23
0
def purge(name, delete_key=True):
    '''
    Destroy the named vm
    '''
    ret = {}
    client = salt.client.get_local_client(__opts__['conf_file'])
    data = vm_info(name, quiet=True)
    if not data:
        __jid_event__.fire_event({'error': 'Failed to find vm {0} to purge'.format(name)}, 'progress')
        return 'fail'
    hyper = next(six.iterkeys(data))
    try:
        cmd_ret = client.cmd_iter(
                hyper,
                'virt.purge',
                [name, True],
                timeout=600)
    except SaltClientError as client_error:
        return 'Virtual machine {0} could not be purged: {1}'.format(name, client_error)

    for comp in cmd_ret:
        ret.update(comp)

    if delete_key:
        skey = salt.key.Key(__opts__)
        skey.delete_key(name)
    __jid_event__.fire_event({'message': 'Purged VM {0}'.format(name)}, 'progress')
    return 'good'
Пример #24
0
def force_off(name):
    '''
    Force power down the named virtual machine
    '''
    ret = {}
    client = salt.client.get_local_client(__opts__['conf_file'])
    data = vm_info(name, quiet=True)
    if not data:
        print('Failed to find vm {0} to destroy'.format(name))
        return 'fail'
    hyper = next(six.iterkeys(data))
    if data[hyper][name]['state'] == 'shutdown':
        print('VM {0} is already shutdown'.format(name))
        return'bad state'
    try:
        cmd_ret = client.cmd_iter(
                hyper,
                'virt.destroy',
                [name],
                timeout=600)
    except SaltClientError as client_error:
        return 'Virtual machine {0} could not be forced off: {1}'.format(name, client_error)
    for comp in cmd_ret:
        ret.update(comp)
    __jid_event__.fire_event({'message': 'Powered off VM {0}'.format(name)}, 'progress')
    return 'good'
Пример #25
0
def list_keypairs(call=None):
    '''
    Return a dict of all available VM locations on the cloud provider with
    relevant data
    '''
    if call != 'function':
        log.error(
            'The list_keypairs function must be called with -f or --function.'
        )
        return False

    items = query(method='account/keys')
    ret = {}
    for key_pair in items['ssh_keys']:
        name = key_pair['name']
        if name in ret:
            raise SaltCloudSystemExit(
                'A duplicate key pair name, \'{0}\', was found in DigitalOcean\'s '
                'key pair list. Please change the key name stored by DigitalOcean. '
                'Be sure to adjust the value of \'ssh_key_file\' in your cloud '
                'profile or provider configuration, if necessary.'.format(
                    name
                )
            )
        ret[name] = {}
        for item in six.iterkeys(key_pair):
            ret[name][item] = str(key_pair[item])

    return ret
Пример #26
0
def list_renderers(*args):
    """
    List the renderers loaded on the minion

    .. versionadded:: 2015.5.0

    CLI Example:

    .. code-block:: bash

        salt '*' sys.list_renderers

    Render names can be specified as globs.

    .. code-block:: bash

        salt '*' sys.list_renderers 'yaml*'

    """
    ren_ = salt.loader.render(__opts__, [])
    ren = set()

    if not args:
        for func in six.iterkeys(ren_):
            ren.add(func)
        return sorted(ren)

    for module in args:
        for func in fnmatch.filter(ren_, module):
            ren.add(func)
    return sorted(ren)
Пример #27
0
def avail_images(call=None):
    '''
    Return a list of the images that are on the provider
    '''
    if call == 'action':
        raise SaltCloudSystemExit(
            'The avail_images function must be called with '
            '-f or --function, or with the --list-images option'
        )

    fetch = True
    page = 1
    ret = {}

    while fetch:
        items = query(method='images', command='?page=' + str(page) + '&per_page=200')

        for image in items['images']:
            ret[image['name']] = {}
            for item in six.iterkeys(image):
                ret[image['name']][item] = image[item]

        page += 1
        try:
            fetch = 'next' in items['links']['pages']
        except KeyError:
            fetch = False

    return ret
Пример #28
0
def pause(name):
    '''
    Pause the named VM
    '''
    ret = {}
    client = salt.client.get_local_client(__opts__['conf_file'])

    data = vm_info(name, quiet=True)
    if not data:
        __jid_event__.fire_event({'error': 'Failed to find VM {0} to pause'.format(name)}, 'progress')
        return 'fail'
    host = next(six.iterkeys(data))
    if data[host][name]['state'] == 'paused':
        __jid_event__.fire_event({'error': 'VM {0} is already paused'.format(name)}, 'progress')
        return 'bad state'
    try:
        cmd_ret = client.cmd_iter(
                host,
                'virt.pause',
                [name],
                timeout=600)
    except SaltClientError as client_error:
        return 'Virtual machine {0} could not be pasued: {1}'.format(name, client_error)
    for comp in cmd_ret:
        ret.update(comp)
    __jid_event__.fire_event({'message': 'Paused VM {0}'.format(name)}, 'progress')
    return 'good'
Пример #29
0
def start(name):
    '''
    Start a named virtual machine
    '''
    ret = {}
    client = salt.client.get_local_client(__opts__['conf_file'])
    data = vm_info(name, quiet=True)
    if not data:
        __jid_event__.fire_event({'message': 'Failed to find vm {0} to start'.format(name)}, 'progress')
        return 'fail'
    hyper = next(six.iterkeys(data))
    if data[hyper][name]['state'] == 'running':
        print('VM {0} is already running'.format(name))
        return 'bad state'
    try:
        cmd_ret = client.cmd_iter(
                hyper,
                'virt.start',
                [name],
                timeout=600)
    except SaltClientError as client_error:
        return 'Virtual machine {0} not started: {1}'. format(name, client_error)
    for comp in cmd_ret:
        ret.update(comp)
    __jid_event__.fire_event({'message': 'Started VM {0}'.format(name)}, 'progress')
    return 'good'
Пример #30
0
def _execute_pillar(pillar_name, run_type):
    '''
    Run one or more nagios plugins from pillar data and get the result of run_type
    The pillar have to be in this format:
    ------
    webserver:
        Ping_google:
            - check_icmp: 8.8.8.8
            - check_icmp: google.com
        Load:
            - check_load: -w 0.8 -c 1
        APT:
            - check_apt
    -------
    '''
    groups = __salt__['pillar.get'](pillar_name)

    data = {}
    for group in groups:
        data[group] = {}
        commands = groups[group]
        for command in commands:
            # Check if is a dict to get the arguments
            # in command if not set the arguments to empty string
            if isinstance(command, dict):
                plugin = next(six.iterkeys(command))
                args = command[plugin]
            else:
                plugin = command
                args = ''
            command_key = _format_dict_key(args, plugin)
            data[group][command_key] = run_type(plugin, args)
    return data
Пример #31
0
    def test_get(self):
        # test with no JID
        self.http_client.fetch(
            self.get_url('/jobs'),
            self.stop,
            method='GET',
            headers={saltnado.AUTH_TOKEN_HEADER: self.token['token']},
            follow_redirects=False,
        )
        response = self.wait(timeout=30)
        response_obj = json.loads(response.body)['return'][0]
        for jid, ret in six.iteritems(response_obj):
            self.assertIn('Function', ret)
            self.assertIn('Target', ret)
            self.assertIn('Target-type', ret)
            self.assertIn('User', ret)
            self.assertIn('StartTime', ret)
            self.assertIn('Arguments', ret)

        # test with a specific JID passed in
        jid = next(six.iterkeys(response_obj))
        self.http_client.fetch(
            self.get_url('/jobs/{0}'.format(jid)),
            self.stop,
            method='GET',
            headers={saltnado.AUTH_TOKEN_HEADER: self.token['token']},
            follow_redirects=False,
        )
        response = self.wait(timeout=30)
        response_obj = json.loads(response.body)['return'][0]
        self.assertIn('Function', response_obj)
        self.assertIn('Target', response_obj)
        self.assertIn('Target-type', response_obj)
        self.assertIn('User', response_obj)
        self.assertIn('StartTime', response_obj)
        self.assertIn('Arguments', response_obj)
        self.assertIn('Result', response_obj)
Пример #32
0
    def add_job(self, data, persist=True):
        '''
        Adds a new job to the scheduler. The format is the same as required in
        the configuration file. See the docs on how YAML is interpreted into
        python data-structures to make sure, you pass correct dictionaries.
        '''

        # we don't do any checking here besides making sure its a dict.
        # eval() already does for us and raises errors accordingly
        if not isinstance(data, dict):
            raise ValueError('Scheduled jobs have to be of type dict.')
        if not len(data) == 1:
            raise ValueError('You can only schedule one new job at a time.')

        # if enabled is not included in the job,
        # assume job is enabled.
        for job in data.keys():
            if 'enabled' not in data[job]:
                data[job]['enabled'] = True

        new_job = next(six.iterkeys(data))

        if new_job in self.opts['schedule']:
            log.info('Updating job settings for scheduled '
                     'job: {0}'.format(new_job))
        else:
            log.info('Added new job {0} to scheduler'.format(new_job))

        self.opts['schedule'].update(data)

        # Fire the complete event back along with updated list of schedule
        evt = salt.utils.event.get_event('minion', opts=self.opts, listen=False)
        evt.fire_event({'complete': True, 'schedule': self.opts['schedule']},
                       tag='/salt/minion/minion_schedule_add_complete')

        if persist:
            self.persist()
Пример #33
0
    def __gather_minions(self):
        '''
        Return a list of minions to use for the batch run
        '''
        args = [self.opts['tgt'],
                'test.ping',
                [],
                self.opts['timeout'],
                ]

        selected_target_option = self.opts.get('selected_target_option', None)
        if selected_target_option is not None:
            args.append(selected_target_option)
        else:
            args.append(self.opts.get('expr_form', 'glob'))

        self.pub_kwargs['yield_pub_data'] = True
        ping_gen = self.local.cmd_iter(*args, **self.pub_kwargs)

        # Broadcast to targets
        fret = set()
        nret = set()
        try:
            for ret in ping_gen:
                if ('minions' and 'jid') in ret:
                    for minion in ret['minions']:
                        nret.add(minion)
                    continue
                else:
                    m = next(six.iterkeys(ret))
                    if m is not None:
                        fret.add(m)
            return (list(fret), ping_gen, nret.difference(fret))
        except StopIteration:
            if not self.quiet:
                print_cli('No minions matched the target.')
        return list(fret), ping_gen
Пример #34
0
def list_returners(*args):
    '''
    .. versionadded:: 2014.7.0

    List the runners loaded on the minion

    CLI Example:

    .. code-block:: bash

        salt '*' sys.list_returners

    .. versionadded:: Lithium

    Returner names can be specified as globs.

        salt '*' sys.list_returners 's*'

    '''
    returners_ = salt.loader.returners(__opts__, [])
    returners = set()

    if not args:
        for func in six.iterkeys(returners_):
            comps = func.split('.')
            if len(comps) < 2:
                continue
            returners.add(comps[0])
        return sorted(returners)

    for module in args:
        for func in fnmatch.filter(returners_.keys(), module):  # pylint: disable=incompatible-py3-code
            comps = func.split('.')                             # There's no problem feeding fnmatch.filter()
            if len(comps) < 2:                                  # with a Py3's dict_keys() instance
                continue
            returners.add(comps[0])
    return sorted(returners)
Пример #35
0
def listen(opts):
    """
    Attach to the pub socket and grab messages
    """
    event = salt.utils.event.get_event(
        opts["node"],
        sock_dir=opts["sock_dir"],
        transport=opts["transport"],
        opts=opts,
        listen=True,
    )
    check_access_and_print_warning(opts["sock_dir"])
    print(event.puburi)
    jid_counter = 0
    found_minions = []
    while True:
        ret = event.get_event(full=True)
        if ret is None:
            continue
        if opts["func_count"]:
            data = ret.get("data", False)
            if data:
                if ("id" in six.iterkeys(data)
                        and data.get("id", False) not in found_minions):
                    if data["fun"] == opts["func_count"]:
                        jid_counter += 1
                        found_minions.append(data["id"])
                        print(
                            "Reply received from [{0}]. Total replies now: [{1}]."
                            .format(ret["data"]["id"], jid_counter))
                    continue
        else:
            print("Event fired at {0}".format(time.asctime()))
            print("*" * 25)
            print("Tag: {0}".format(ret["tag"]))
            print("Data:")
            pprint.pprint(ret["data"])
Пример #36
0
Файл: joyent.py Проект: epu/salt
def reformat_node(item=None, full=False):
    '''
    Reformat the returned data from joyent, determine public/private IPs and
    strip out fields if necessary to provide either full or brief content.

    :param item: node dictionary
    :param full: full or brief output
    :return: dict
    '''
    desired_keys = [
        'id', 'name', 'state', 'public_ips', 'private_ips', 'size', 'image',
        'location'
    ]
    item['private_ips'] = []
    item['public_ips'] = []
    if 'ips' in item:
        for ip in item['ips']:
            if is_public_ip(ip):
                item['public_ips'].append(ip)
            else:
                item['private_ips'].append(ip)

    # add any undefined desired keys
    for key in desired_keys:
        if key not in item:
            item[key] = None

    # remove all the extra key value pairs to provide a brief listing
    if not full:
        for key in six.iterkeys(item):  # iterate over a copy of the keys
            if key not in desired_keys:
                del item[key]

    if 'state' in item:
        item['state'] = joyent_node_state(item['state'])

    return item
Пример #37
0
def list_floating_ips(call=None):
    '''
    Return a list of the floating ips that are on the provider

    .. versionadded:: 2016.3.0

    CLI Examples:

    ... code-block:: bash

        salt-cloud -f list_floating_ips my-digitalocean-config
    '''
    if call == 'action':
        raise SaltCloudSystemExit(
            'The list_floating_ips function must be called with '
            '-f or --function, or with the --list-floating-ips option')

    fetch = True
    page = 1
    ret = {}

    while fetch:
        items = query(method='floating_ips',
                      command='?page=' + str(page) + '&per_page=200')

        for floating_ip in items['floating_ips']:
            ret[floating_ip['ip']] = {}
            for item in six.iterkeys(floating_ip):
                ret[floating_ip['ip']][item] = floating_ip[item]

        page += 1
        try:
            fetch = 'next' in items['links']['pages']
        except KeyError:
            fetch = False

    return ret
Пример #38
0
def query(hyper=None, quiet=False):
    '''
    Query the virtual machines. When called without options all hypervisors
    are detected and a full query is returned. A single hypervisor can be
    passed in to specify an individual hypervisor to query.
    '''
    if quiet:
        log.warn('\'quiet\' is deprecated. Please migrate to --quiet')
    ret = {}
    client = salt.client.get_local_client(__opts__['conf_file'])
    for info in client.cmd_iter('virtual:physical',
                                'virt.full_info',
                                expr_form='grain'):
        if not info:
            continue
        if not isinstance(info, dict):
            continue
        chunk = {}
        id_ = next(six.iterkeys(info))
        if hyper:
            if hyper != id_:
                continue
        if not isinstance(info[id_], dict):
            continue
        if 'ret' not in info[id_]:
            continue
        if not isinstance(info[id_]['ret'], dict):
            continue
        chunk[id_] = info[id_]['ret']
        ret.update(chunk)
        if not quiet:
            __jid_event__.fire_event({
                'data': chunk,
                'outputter': 'virt_query'
            }, 'progress')

    return ret
Пример #39
0
def absent(name, acl_type, acl_name='', perms='', recurse=False):
    '''
    Ensure a Linux ACL does not exist
    '''
    ret = {'name': name,
           'result': True,
           'changes': {},
           'comment': ''}

    _current_perms = __salt__['acl.getfacl'](name)

    if _current_perms[name].get(acl_type, None):
        try:
            user = [i for i in _current_perms[name][acl_type] if next(six.iterkeys(i)) == acl_name].pop()
        except IndexError:
            user = None

        if user:
            ret['comment'] = 'Removing permissions'

            if __opts__['test']:
                ret['result'] = None
                return ret

            if recurse:
                __salt__['acl.delfacl'](acl_type, acl_name, perms, name, recursive=True)
            else:
                __salt__['acl.delfacl'](acl_type, acl_name, perms, name)
        else:
            ret['comment'] = 'Permissions are in the desired state'

    else:
        ret['comment'] = 'ACL Type does not exist'
        ret['result'] = False

    return ret
Пример #40
0
def output(data, **kwargs):  # pylint: disable=unused-argument
    '''
    Display output for the salt-run virt.query function
    '''
    out = ''
    for id_ in data['data']:
        out += '{0}\n'.format(id_)
        for vm_ in data['data'][id_]['vm_info']:
            out += '  {0}\n'.format(vm_)
            vm_data = data[id_]['vm_info'][vm_]
            if 'cpu' in vm_data:
                out += '    CPU: {0}\n'.format(vm_data['cpu'])
            if 'mem' in vm_data:
                out += '    Memory: {0}\n'.format(vm_data['mem'])
            if 'state' in vm_data:
                out += '    State: {0}\n'.format(vm_data['state'])
            if 'graphics' in vm_data:
                if vm_data['graphics'].get('type', '') == 'vnc':
                    out += '    Graphics: vnc - {0}:{1}\n'.format(
                        id_, vm_data['graphics']['port'])
            if 'disks' in vm_data:
                for disk, d_data in six.iteritems(vm_data['disks']):
                    out += '    Disk - {0}:\n'.format(disk)
                    out += '      Size: {0}\n'.format(d_data['disk size'])
                    out += '      File: {0}\n'.format(d_data['file'])
                    out += '      File Format: {0}\n'.format(
                        d_data['file format'])
            if 'nics' in vm_data:
                for mac in vm_data['nics']:
                    out += '    Nic - {0}:\n'.format(mac)
                    out += '      Source: {0}\n'.format(
                        vm_data['nics'][mac]['source'][next(
                            six.iterkeys(vm_data['nics'][mac]['source']))])
                    out += '      Type: {0}\n'.format(
                        vm_data['nics'][mac]['type'])
    return out
Пример #41
0
def service_highstate(requires=True):
    """
    Return running and enabled services in a highstate structure. By default
    also returns package dependencies for those services, which means that
    package definitions must be created outside this function. To drop the
    package dependencies, set ``requires`` to False.

    CLI Example:

        salt myminion introspect.service_highstate
        salt myminion introspect.service_highstate requires=False
    """
    ret = {}
    running = running_service_owners()
    for service in running:
        ret[service] = {"service": ["running"]}

        if requires:
            ret[service]["service"].append({"require": {"pkg": running[service]}})

    enabled = enabled_service_owners()
    for service in enabled:
        if service in ret:
            ret[service]["service"].append({"enabled": True})
        else:
            ret[service] = {"service": [{"enabled": True}]}

        if requires:
            exists = False
            for item in ret[service]["service"]:
                if isinstance(item, dict) and next(six.iterkeys(item)) == "require":
                    exists = True
            if not exists:
                ret[service]["service"].append({"require": {"pkg": enabled[service]}})

    return ret
Пример #42
0
    def send_signal_to_processes(self, signal_):
        if (salt.utils.platform.is_windows()
                and signal_ in (signal.SIGTERM, signal.SIGINT)):
            # On Windows, the subprocesses automatically have their signal
            # handlers invoked. If you send one of these signals while the
            # signal handler is running, it will kill the process where it
            # is currently running and the signal handler will not finish.
            # This will also break the process tree: children of killed
            # children will become parentless and not findable when trying
            # to kill the process tree (they don't inherit their parent's
            # parent). Hence the 'MWorker' processes would be left over if
            # the 'ReqServer' process is killed this way since 'taskkill'
            # with the tree option will not be able to find them.
            return

        for pid in six.iterkeys(self._process_map.copy()):
            try:
                os.kill(pid, signal_)
            except OSError as exc:
                if exc.errno not in (errno.ESRCH, errno.EACCES):
                    # If it's not a "No such process" error, raise it
                    raise
                # Otherwise, it's a dead process, remove it from the process map
                del self._process_map[pid]
Пример #43
0
def start(name):
    """
    Start a named virtual machine
    """
    ret = {}
    client = salt.client.get_local_client(__opts__["conf_file"])
    data = vm_info(name, quiet=True)
    if not data:
        __jid_event__.fire_event(
            {"message": "Failed to find VM {0} to start".format(name)}, "progress"
        )
        return "fail"
    host = next(six.iterkeys(data))
    if data[host][name]["state"] == "running":
        print("VM {0} is already running".format(name))
        return "bad state"
    try:
        cmd_ret = client.cmd_iter(host, "virt.start", [name], timeout=600)
    except SaltClientError as client_error:
        return "Virtual machine {0} not started: {1}".format(name, client_error)
    for comp in cmd_ret:
        ret.update(comp)
    __jid_event__.fire_event({"message": "Started VM {0}".format(name)}, "progress")
    return "good"
Пример #44
0
    def __gather_minions(self):
        '''
        Return a list of minions to use for the batch run
        '''
        args = [self.opts['tgt'],
                'test.ping',
                [],
                self.opts['timeout'],
                ]

        selected_target_option = self.opts.get('selected_target_option', None)
        if selected_target_option is not None:
            args.append(selected_target_option)
        else:
            args.append(self.opts.get('expr_form', 'glob'))

        ping_gen = self.local.cmd_iter(*args, **self.eauth)

        fret = set()
        for ret in ping_gen:
            m = next(six.iterkeys(ret))
            if m is not None:
                fret.add(m)
        return (list(fret), ping_gen)
Пример #45
0
def pause(name):
    '''
    Pause the named vm
    '''
    ret = {}
    client = salt.client.get_local_client(__opts__['conf_file'])

    data = vm_info(name, quiet=True)
    if not data:
        __jid_event__.fire_event(
            {'error': 'Failed to find VM {0} to pause'.format(name)},
            'progress')
        return 'fail'
    hyper = next(six.iterkeys(data))
    if data[hyper][name]['state'] == 'paused':
        __jid_event__.fire_event(
            {'error': 'VM {0} is already paused'.format(name)}, 'progress')
        return 'bad state'
    cmd_ret = client.cmd_iter(hyper, 'virt.pause', [name], timeout=600)
    for comp in cmd_ret:
        ret.update(comp)
    __jid_event__.fire_event({'message': 'Paused VM {0}'.format(name)},
                             'progress')
    return 'good'
Пример #46
0
def output(data, **kwargs):  # pylint: disable=unused-argument
    """
    Display output for the salt-run virt.query function
    """
    out = ""
    for id_ in data["data"]:
        out += "{0}\n".format(id_)
        for vm_ in data["data"][id_]["vm_info"]:
            out += "  {0}\n".format(vm_)
            vm_data = data[id_]["vm_info"][vm_]
            if "cpu" in vm_data:
                out += "    CPU: {0}\n".format(vm_data["cpu"])
            if "mem" in vm_data:
                out += "    Memory: {0}\n".format(vm_data["mem"])
            if "state" in vm_data:
                out += "    State: {0}\n".format(vm_data["state"])
            if "graphics" in vm_data:
                if vm_data["graphics"].get("type", "") == "vnc":
                    out += "    Graphics: vnc - {0}:{1}\n".format(
                        id_, vm_data["graphics"]["port"])
            if "disks" in vm_data:
                for disk, d_data in six.iteritems(vm_data["disks"]):
                    out += "    Disk - {0}:\n".format(disk)
                    out += "      Size: {0}\n".format(d_data["disk size"])
                    out += "      File: {0}\n".format(d_data["file"])
                    out += "      File Format: {0}\n".format(
                        d_data["file format"])
            if "nics" in vm_data:
                for mac in vm_data["nics"]:
                    out += "    Nic - {0}:\n".format(mac)
                    out += "      Source: {0}\n".format(
                        vm_data["nics"][mac]["source"][next(
                            six.iterkeys(vm_data["nics"][mac]["source"]))])
                    out += "      Type: {0}\n".format(
                        vm_data["nics"][mac]["type"])
    return out
Пример #47
0
def force_off(name):
    '''
    Force power down the named virtual machine
    '''
    ret = {}
    client = salt.client.get_local_client(__opts__['conf_file'])
    data = vm_info(name, quiet=True)
    if not data:
        print('Failed to find VM {0} to destroy'.format(name))
        return 'fail'
    host = next(six.iterkeys(data))
    if data[host][name]['state'] == 'shutdown':
        print('VM {0} is already shutdown'.format(name))
        return 'bad state'
    try:
        cmd_ret = client.cmd_iter(host, 'virt.destroy', [name], timeout=600)
    except SaltClientError as client_error:
        return 'Virtual machine {0} could not be forced off: {1}'.format(
            name, client_error)
    for comp in cmd_ret:
        ret.update(comp)
    __jid_event__.fire_event({'message': 'Powered off VM {0}'.format(name)},
                             'progress')
    return 'good'
Пример #48
0
def force_off(name):
    """
    Force power down the named virtual machine
    """
    ret = {}
    client = salt.client.get_local_client(__opts__["conf_file"])
    data = vm_info(name, quiet=True)
    if not data:
        print("Failed to find VM {0} to destroy".format(name))
        return "fail"
    host = next(six.iterkeys(data))
    if data[host][name]["state"] == "shutdown":
        print("VM {0} is already shutdown".format(name))
        return "bad state"
    try:
        cmd_ret = client.cmd_iter(host, "virt.stop", [name], timeout=600)
    except SaltClientError as client_error:
        return "Virtual machine {0} could not be forced off: {1}".format(
            name, client_error)
    for comp in cmd_ret:
        ret.update(comp)
    __jid_event__.fire_event({"message": "Powered off VM {0}".format(name)},
                             "progress")
    return "good"
Пример #49
0
def ext_pillar(minion_id, pillar, pillar_name=None):
    """
    A salt external pillar which provides the list of nodegroups of which the minion is a member.

    :param minion_id: used for compound matching nodegroups
    :param pillar: provided by salt, but not used by nodegroups ext_pillar
    :param pillar_name: optional name to use for the pillar, defaults to 'nodegroups'
    :return: a dictionary which is included by the salt master in the pillars returned to the minion
    """

    pillar_name = pillar_name or "nodegroups"
    all_nodegroups = __opts__["nodegroups"]
    nodegroups_minion_is_in = []
    ckminions = None
    for nodegroup_name in six.iterkeys(all_nodegroups):
        ckminions = ckminions or CkMinions(__opts__)
        _res = ckminions.check_minions(all_nodegroups[nodegroup_name],
                                       "compound")
        match = _res["minions"]

        if minion_id in match:
            nodegroups_minion_is_in.append(nodegroup_name)

    return {pillar_name: nodegroups_minion_is_in}
Пример #50
0
def _action(action='get', search=None, one=True, force=False):
    '''
    Multi action helper for start, stop, get, ...
    '''
    vms = {}
    matched_vms = []
    client = salt.client.get_local_client(__opts__['conf_file'])

    ## lookup vms
    try:
        vmadm_args = {}
        vmadm_args['order'] = 'uuid,alias,hostname,state'
        if '=' in search:
            vmadm_args['search'] = search
        for cn in client.cmd_iter('G@virtual:physical and G@os:smartos',
                                  'vmadm.list',
                                  kwarg=vmadm_args,
                                  tgt_type='compound'):
            if not cn:
                continue
            node = next(six.iterkeys(cn))
            if not isinstance(cn[node], dict) or \
                    'ret' not in cn[node] or \
                    not isinstance(cn[node]['ret'], dict):
                continue
            for vm in cn[node]['ret']:
                vmcfg = cn[node]['ret'][vm]
                vmcfg['node'] = node
                vms[vm] = vmcfg
    except SaltClientError as client_error:
        pass

    ## check if we have vms
    if not vms:
        return {'Error': 'No vms found.'}

    ## simple search
    if '=' not in search:
        loop_pass = 0
        while loop_pass < 3:
            ## each pass will try a different field
            if loop_pass == 0:
                field = 'uuid'
            elif loop_pass == 1:
                field = 'hostname'
            else:
                field = 'alias'

            ## loop vms and try to match
            for vm in vms:
                if field == 'uuid' and vm == search:
                    matched_vms.append(vm)
                    break  # exit for on uuid match (max = 1)
                elif field in vms[vm] and vms[vm][field] == search:
                    matched_vms.append(vm)

            ## exit on match(es) or try again
            if matched_vms:
                break
            else:
                loop_pass += 1
    else:
        for vm in vms:
            matched_vms.append(vm)

    ## check if we have vms
    if not matched_vms:
        return {'Error': 'No vms matched.'}

    ## multiple allowed?
    if one and len(matched_vms) > 1:
        return {
            'Error':
            'Matched {0} vms, only one allowed!'.format(len(matched_vms)),
            'Matches': matched_vms
        }

    ## perform action
    ret = {}
    if action in ['start', 'stop', 'reboot', 'get']:
        for vm in matched_vms:
            vmadm_args = {'key': 'uuid', 'vm': vm}
            try:
                for vmadm_res in client.cmd_iter(vms[vm]['node'],
                                                 'vmadm.{0}'.format(action),
                                                 kwarg=vmadm_args):
                    if not vmadm_res:
                        continue
                    if vms[vm]['node'] in vmadm_res:
                        ret[vm] = vmadm_res[vms[vm]['node']]['ret']
            except SaltClientError as client_error:
                ret[vm] = False
    elif action in ['is_running']:
        ret = True
        for vm in matched_vms:
            if vms[vm]['state'] != 'running':
                ret = False
                break
    return ret
Пример #51
0
    def run(self, jid=None):
        '''
        Execute the overall routine, print results via outputters
        '''
        fstr = '{0}.prep_jid'.format(self.opts['master_job_cache'])
        jid = self.returners[fstr](
            passed_jid=jid or self.opts.get('jid', None))

        # Save the invocation information
        argv = self.opts['argv']

        if self.opts.get('raw_shell', False):
            fun = 'ssh._raw'
            args = argv
        else:
            fun = argv[0] if argv else ''
            args = argv[1:]

        job_load = {
            'jid': jid,
            'tgt_type': self.tgt_type,
            'tgt': self.opts['tgt'],
            'user': self.opts['user'],
            'fun': fun,
            'arg': args,
        }

        # save load to the master job cache
        try:
            if isinstance(jid, bytes):
                jid = jid.decode('utf-8')
            self.returners['{0}.save_load'.format(
                self.opts['master_job_cache'])](jid, job_load)
        except Exception as exc:
            log.exception(exc)
            log.error('Could not save load with returner {0}: {1}'.format(
                self.opts['master_job_cache'], exc))

        if self.opts.get('verbose'):
            msg = 'Executing job with jid {0}'.format(jid)
            print(msg)
            print('-' * len(msg) + '\n')
            print('')
        sret = {}
        outputter = self.opts.get('output', 'nested')
        final_exit = 0
        for ret in self.handle_ssh():
            host = next(six.iterkeys(ret))
            if isinstance(ret[host], dict):
                host_ret = ret[host].get('retcode', 0)
                if host_ret != 0:
                    final_exit = 1
            else:
                # Error on host
                final_exit = 1

            self.cache_job(jid, host, ret[host], fun)
            ret = self.key_deploy(host, ret)
            if not isinstance(ret[host], dict):
                p_data = {host: ret[host]}
            elif 'return' not in ret[host]:
                p_data = ret
            else:
                outputter = ret[host].get('out',
                                          self.opts.get('output', 'nested'))
                p_data = {host: ret[host].get('return', {})}
            if self.opts.get('static'):
                sret.update(p_data)
            else:
                salt.output.display_output(p_data, outputter, self.opts)
            if self.event:
                self.event.fire_event(
                    ret, salt.utils.event.tagify([jid, 'ret', host], 'job'))
        if self.opts.get('static'):
            salt.output.display_output(sret, outputter, self.opts)
        if final_exit:
            sys.exit(salt.defaults.exitcodes.EX_AGGREGATE)
Пример #52
0
def acl(username):
    '''

    :param username: Username to filter for
    :return: Dictionary that can be slotted into the ``__opts__`` structure for
        eauth that designates the user associated ACL

    Database records such as:

    ===========  ====================     =========
    username     minion_or_fn_matcher     minion_fn
    ===========  ====================     =========
    fred                                  test.ping
    fred         server1                  network.interfaces
    fred         server1                  raid.list
    fred         server2                  .*
    guru         .*
    smartadmin   server1                  .*
    ===========  ====================     =========

    Should result in an eauth config such as:

    .. code-block:: yaml

        fred:
          - test.ping
          - server1:
              - network.interfaces
              - raid.list
          - server2:
              - .*
        guru:
          - .*
        smartadmin:
          - server1:
            - .*

    '''
    __django_auth_setup()

    if username is None:
        db_records = DJANGO_AUTH_CLASS.objects.all()
    else:
        db_records = DJANGO_AUTH_CLASS.objects.filter(
            user_fk__username=username)
    auth_dict = {}

    for a in db_records:
        if a.user_fk.username not in auth_dict:
            auth_dict[a.user_fk.username] = []

        if not a.minion_or_fn_matcher and a.minion_fn:
            auth_dict[a.user_fk.username].append(a.minion_fn)
        elif a.minion_or_fn_matcher and not a.minion_fn:
            auth_dict[a.user_fk.username].append(a.minion_or_fn_matcher)
        else:
            found = False
            for d in auth_dict[a.user_fk.username]:
                if isinstance(d, dict):
                    if a.minion_or_fn_matcher in six.iterkeys(d):
                        auth_dict[a.user_fk.username][
                            a.minion_or_fn_matcher].append(a.minion_fn)
                        found = True
            if not found:
                auth_dict[a.user_fk.username].append(
                    {a.minion_or_fn_matcher: [a.minion_fn]})

    log.debug('django auth_dict is %s', auth_dict)
    return auth_dict
Пример #53
0
def list_vms(search=None, verbose=False):
    '''
    List all vms

    search : string
        filter vms, see the execution module
    verbose : boolean
        print additional information about the vm

    CLI Example:

    .. code-block:: bash

        salt-run vmadm.list
        salt-run vmadm.list search='type=KVM'
        salt-run vmadm.list verbose=True
    '''
    ret = OrderedDict() if verbose else []
    client = salt.client.get_local_client(__opts__['conf_file'])
    try:
        vmadm_args = {}
        vmadm_args[
            'order'] = 'uuid,alias,hostname,state,type,cpu_cap,vcpus,ram'
        if search:
            vmadm_args['search'] = search
        for cn in client.cmd_iter('G@virtual:physical and G@os:smartos',
                                  'vmadm.list',
                                  kwarg=vmadm_args,
                                  tgt_type='compound'):
            if not cn:
                continue
            node = next(six.iterkeys(cn))
            if not isinstance(cn[node], dict) or \
                    'ret' not in cn[node] or \
                    not isinstance(cn[node]['ret'], dict):
                continue
            for vm in cn[node]['ret']:
                vmcfg = cn[node]['ret'][vm]
                if verbose:
                    ret[vm] = OrderedDict()
                    ret[vm]['hostname'] = vmcfg['hostname']
                    ret[vm]['alias'] = vmcfg['alias']
                    ret[vm]['computenode'] = node
                    ret[vm]['state'] = vmcfg['state']
                    ret[vm]['resources'] = OrderedDict()
                    ret[vm]['resources']['memory'] = vmcfg['ram']
                    if vmcfg['type'] == 'KVM':
                        ret[vm]['resources']['cpu'] = "{0:.2f}".format(
                            int(vmcfg['vcpus']))
                    else:
                        if vmcfg['cpu_cap'] != '':
                            ret[vm]['resources']['cpu'] = "{0:.2f}".format(
                                int(vmcfg['cpu_cap']) / 100)
                else:
                    ret.append(vm)
    except SaltClientError as client_error:
        return "{0}".format(client_error)

    if not verbose:
        ret = sorted(ret)

    return ret
Пример #54
0
def init(
        name,
        cpu,
        mem,
        image=None,
        nic='default',
        hypervisor=VIRT_DEFAULT_HYPER,
        start=True,  # pylint: disable=redefined-outer-name
        disk='default',
        saltenv='base',
        **kwargs):
    '''
    Initialize a new vm

    CLI Example:

    .. code-block:: bash

        salt 'hypervisor' virt.init vm_name 4 512 salt://path/to/image.raw
        salt 'hypervisor' virt.init vm_name 4 512 nic=profile disk=profile
    '''
    hypervisor = __salt__['config.get']('libvirt:hypervisor', hypervisor)

    nicp = _nic_profile(nic, hypervisor, **kwargs)

    diskp = None
    seedable = False
    if image:  # with disk template image
        # if image was used, assume only one disk, i.e. the
        # 'default' disk profile
        # TODO: make it possible to use disk profiles and use the
        # template image as the system disk
        diskp = _disk_profile('default', hypervisor, **kwargs)

        # When using a disk profile extract the sole dict key of the first
        # array element as the filename for disk
        disk_name = next(six.iterkeys(diskp[0]))
        disk_type = diskp[0][disk_name]['format']
        disk_file_name = '{0}.{1}'.format(disk_name, disk_type)

        if hypervisor in ['esxi', 'vmware']:
            # TODO: we should be copying the image file onto the ESX host
            raise SaltInvocationError('virt.init does not support image '
                                      'template template in conjunction '
                                      'with esxi hypervisor')
        elif hypervisor in ['qemu', 'kvm']:
            img_dir = __salt__['config.option']('virt.images')
            img_dest = os.path.join(img_dir, name, disk_file_name)
            img_dir = os.path.dirname(img_dest)
            sfn = __salt__['cp.cache_file'](image, saltenv)
            if not os.path.isdir(img_dir):
                os.makedirs(img_dir)
            try:
                salt.utils.files.copyfile(sfn, img_dest)
                mask = os.umask(0)
                os.umask(mask)
                # Apply umask and remove exec bit
                mode = (0o0777 ^ mask) & 0o0666
                os.chmod(img_dest, mode)

            except (IOError, OSError):
                return False
            seedable = True
        else:
            log.error('unsupported hypervisor when handling disk image')

    else:
        # no disk template image specified, create disks based on disk profile
        diskp = _disk_profile(disk, hypervisor, **kwargs)
        if hypervisor in ['qemu', 'kvm']:
            # TODO: we should be creating disks in the local filesystem with
            # qemu-img
            raise SaltInvocationError('virt.init does not support disk '
                                      'profiles in conjunction with '
                                      'qemu/kvm at this time, use image '
                                      'template instead')
        else:
            # assume libvirt manages disks for us
            for disk in diskp:
                for disk_name, args in six.iteritems(disk):
                    xml = _gen_vol_xml(name, disk_name, args['size'],
                                       hypervisor)
                    define_vol_xml_str(xml)

    xml = _gen_xml(name, cpu, mem, diskp, nicp, hypervisor, **kwargs)
    define_xml_str(xml)

    if kwargs.get('seed') and seedable:
        install = kwargs.get('install', True)
        seed_cmd = kwargs.get('seed_cmd', 'seed.apply')

        __salt__[seed_cmd](img_dest,
                           id_=name,
                           config=kwargs.get('config'),
                           install=install)
    if start:
        create(name)

    return True
Пример #55
0
def object_present(
    name,
    source=None,
    hash_type=None,
    extra_args=None,
    extra_args_from_pillar='boto_s3_object_extra_args',
    region=None,
    key=None,
    keyid=None,
    profile=None,
):
    '''
    Ensure object exists in S3.

    name
        The name of the state definition.
        This will be used to determine the location of the object in S3,
        by splitting on the first slash and using the first part
        as the bucket name and the remainder as the S3 key.

    source
        The source file to upload to S3,
        currently this only supports files hosted on the minion's local
        file system (starting with /).

    hash_type
        Hash algorithm to use to check that the object contents are correct.
        Defaults to the value of the `hash_type` config option.

    extra_args
        A dictionary of extra arguments to use when uploading the file.
        Note that these are only enforced if new objects are uploaded,
        and not modified on existing objects.
        The supported args are those in the ALLOWED_UPLOAD_ARGS list at
        http://boto3.readthedocs.io/en/latest/reference/customizations/s3.html.
        However, Note that the 'ACL', 'GrantFullControl', 'GrantRead',
        'GrantReadACP',  and 'GrantWriteACL' keys are currently not supported.

    extra_args_from_pillar
        Name of pillar dict that contains extra arguments.
        Extra arguments defined for this specific state will be
        merged over those from the pillar.

    region
        Region to connect to.

    key
        Secret key to be used.

    keyid
        Access key to be used.

    profile
        A dict with region, key and keyid, or a pillar key (string) that
        contains a dict with region, key and keyid.
    '''
    ret = {
        'name': name,
        'comment': '',
        'changes': {},
    }

    if extra_args is None:
        extra_args = {}
    combined_extra_args = copy.deepcopy(__salt__['config.get'](
        extra_args_from_pillar, {}))
    __utils__['dictupdate.update'](combined_extra_args, extra_args)
    if combined_extra_args:
        supported_args = STORED_EXTRA_ARGS | UPLOAD_ONLY_EXTRA_ARGS
        combined_extra_args_keys = frozenset(six.iterkeys(combined_extra_args))
        extra_keys = combined_extra_args_keys - supported_args
        if extra_keys:
            msg = 'extra_args keys {0} are not supported'.format(extra_keys)
            return {'error': msg}

    # Get the hash of the local file
    if not hash_type:
        hash_type = __opts__['hash_type']
    try:
        digest = salt.utils.hashutils.get_hash(source, form=hash_type)
    except IOError as e:
        ret['result'] = False
        ret['comment'] = "Could not read local file {0}: {1}".format(
            source,
            e,
        )
        return ret
    except ValueError as e:
        # Invalid hash type exception from get_hash
        ret['result'] = False
        ret['comment'] = 'Could not hash local file {0}: {1}'.format(
            source,
            e,
        )
        return ret

    HASH_METADATA_KEY = 'salt_managed_content_hash'
    combined_extra_args.setdefault('Metadata', {})
    if HASH_METADATA_KEY in combined_extra_args['Metadata']:
        # Be lenient, silently allow hash metadata key if digest value matches
        if combined_extra_args['Metadata'][HASH_METADATA_KEY] != digest:
            ret['result'] = False
            ret['comment'] = (
                'Salt uses the {0} metadata key internally,'
                'do not pass it to the boto_s3.object_present state.'
            ).format(HASH_METADATA_KEY)
            return ret
    combined_extra_args['Metadata'][HASH_METADATA_KEY] = digest
    # Remove upload-only keys from full set of extra_args
    # to create desired dict for comparisons
    desired_metadata = dict((k, v)
                            for k, v in six.iteritems(combined_extra_args)
                            if k not in UPLOAD_ONLY_EXTRA_ARGS)

    # Some args (SSE-C, RequestPayer) must also be passed to get_metadata
    metadata_extra_args = dict((k, v)
                               for k, v in six.iteritems(combined_extra_args)
                               if k in GET_METADATA_EXTRA_ARGS)
    r = __salt__['boto_s3.get_object_metadata'](
        name,
        extra_args=metadata_extra_args,
        region=region,
        key=key,
        keyid=keyid,
        profile=profile,
    )
    if 'error' in r:
        ret['result'] = False
        ret['comment'] = 'Failed to check if S3 object exists: {0}.'.format(
            r['error'], )
        return ret

    if r['result']:
        # Check if content and metadata match
        # A hash of the content is injected into the metadata,
        # so we can combine both checks into one
        # Only check metadata keys specified by the user,
        # ignore other fields that have been set
        s3_metadata = dict((k, r['result'][k]) for k in STORED_EXTRA_ARGS
                           if k in desired_metadata and k in r['result'])
        if s3_metadata == desired_metadata:
            ret['result'] = True
            ret['comment'] = 'S3 object {0} is present.'.format(name)
            return ret
        action = 'update'
    else:
        s3_metadata = None
        action = 'create'

    def _yaml_safe_dump(attrs):
        '''
        Safely dump YAML using a readable flow style
        '''
        dumper_name = 'IndentedSafeOrderedDumper'
        dumper = __utils__['yaml.get_dumper'](dumper_name)
        return __utils__['yaml.dump'](attrs,
                                      default_flow_style=False,
                                      Dumper=dumper)

    changes_diff = ''.join(
        difflib.unified_diff(
            _yaml_safe_dump(s3_metadata).splitlines(True),
            _yaml_safe_dump(desired_metadata).splitlines(True),
        ))

    if __opts__['test']:
        ret['result'] = None
        ret['comment'] = 'S3 object {0} set to be {1}d.'.format(name, action)
        ret['comment'] += '\nChanges:\n{0}'.format(changes_diff)
        ret['pchanges'] = {'diff': changes_diff}
        return ret

    r = __salt__['boto_s3.upload_file'](
        source,
        name,
        extra_args=combined_extra_args,
        region=region,
        key=key,
        keyid=keyid,
        profile=profile,
    )

    if 'error' in r:
        ret['result'] = False
        ret['comment'] = 'Failed to {0} S3 object: {1}.'.format(
            action,
            r['error'],
        )
        return ret

    ret['result'] = True
    ret['comment'] = 'S3 object {0} {1}d.'.format(name, action)
    ret['comment'] += '\nChanges:\n{0}'.format(changes_diff)
    ret['changes'] = {'diff': changes_diff}
    return ret
Пример #56
0
    def _low(self, fun, low):
        '''
        Execute a function from low data
        Low data includes:
            required:
                - fun: the name of the function to run
            optional:
                - args: a list of args to pass to fun
                - kwargs: kwargs for fun
                - __user__: user who is running the command
                - __jid__: jid to run under
                - __tag__: tag to run under
        '''
        # fire the mminion loading (if not already done) here
        # this is not to clutter the output with the module loading
        # if we have a high debug level.
        self.mminion  # pylint: disable=W0104
        jid = low.get('__jid__', salt.utils.jid.gen_jid())
        tag = low.get('__tag__', tagify(jid, prefix=self.tag_prefix))

        data = {
            'fun': '{0}.{1}'.format(self.client, fun),
            'jid': jid,
            'user': low.get('__user__', 'UNKNOWN'),
        }

        event = salt.utils.event.get_event('master',
                                           self.opts['sock_dir'],
                                           self.opts['transport'],
                                           opts=self.opts,
                                           listen=False)

        namespaced_event = salt.utils.event.NamespacedEvent(
            event,
            tag,
            print_func=self.print_async_event if hasattr(
                self, 'print_async_event') else None)
        # TODO: document these, and test that they exist
        # TODO: Other things to inject??
        func_globals = {
            '__jid__': jid,
            '__user__': data['user'],
            '__tag__': tag,
            # weak ref to avoid the Exception in interpreter
            # teardown of event
            '__jid_event__': weakref.proxy(namespaced_event),
        }

        func_globals['__jid_event__'].fire_event(data, 'new')

        try:
            verify_fun(self.functions, fun)

            # Inject some useful globals to *all* the function's global
            # namespace only once per module-- not per func
            completed_funcs = []

            for mod_name in six.iterkeys(self.functions):
                if '.' not in mod_name:
                    continue
                mod, _ = mod_name.split('.', 1)
                if mod in completed_funcs:
                    continue
                completed_funcs.append(mod)
                for global_key, value in six.iteritems(func_globals):
                    self.functions[mod_name].__globals__[global_key] = value

            # There are some descrepencies of what a "low" structure is in the
            # publisher world it is a dict including stuff such as jid, fun,
            # arg (a list of args, with kwargs packed in). Historically this
            # particular one has had no "arg" and just has had all the kwargs
            # packed into the top level object. The plan is to move away from
            # that since the caller knows what is an arg vs a kwarg, but while
            # we make the transition we will load "kwargs" using format_call if
            # there are no kwargs in the low object passed in
            f_call = None
            if 'arg' not in low:
                f_call = salt.utils.format_call(
                    self.functions[fun],
                    low,
                    expected_extra_kws=CLIENT_INTERNAL_KEYWORDS)
                args = f_call.get('arg', ())
            else:
                args = low['arg']
            if 'kwarg' not in low:
                if f_call is None:
                    f_call = salt.utils.format_call(
                        self.functions[fun],
                        low,
                        expected_extra_kws=CLIENT_INTERNAL_KEYWORDS)
                kwargs = f_call.get('kwarg', {})

                # throw a warning for the badly formed low data if we found
                # kwargs using the old mechanism
                if kwargs:
                    salt.utils.warn_until(
                        'Carbon',
                        'kwargs must be passed inside the low under "kwargs"')
            else:
                kwargs = low['kwarg']

            # Initialize a context for executing the method.
            with tornado.stack_context.StackContext(
                    self.functions.context_dict.clone):
                data['return'] = self.functions[fun](*args, **kwargs)
                data['success'] = True
        except (Exception, SystemExit) as ex:
            if isinstance(ex, salt.exceptions.NotImplemented):
                data['return'] = str(ex)
            else:
                data['return'] = 'Exception occurred in {0} {1}: {2}'.format(
                    self.client,
                    fun,
                    traceback.format_exc(),
                )
            data['success'] = False

        namespaced_event.fire_event(data, 'ret')
        try:
            salt.utils.job.store_job(
                self.opts,
                {
                    'id': self.opts['id'],
                    'tgt': self.opts['id'],
                    'jid': data['jid'],
                    'return': data,
                },
                event=None,
                mminion=self.mminion,
            )
        except salt.exceptions.SaltCacheError:
            log.error(
                'Could not store job cache info. Job details for this run may be unavailable.'
            )
        # if we fired an event, make sure to delete the event object.
        # This will ensure that we call destroy, which will do the 0MQ linger
        log.info('Runner completed: {0}'.format(data['jid']))
        del event
        del namespaced_event
        return data['return']
Пример #57
0
def _call_function(name, returner=None, **kwargs):
    '''
    Calls a function from the specified module.

    :param name:
    :param kwargs:
    :return:
    '''
    argspec = salt.utils.args.get_function_argspec(__salt__[name])

    # func_kw is initialized to a dictionary of keyword arguments the function to be run accepts
    func_kw = dict(
        zip(
            argspec.args[-len(argspec.defaults or []):],  # pylint: disable=incompatible-py3-code
            argspec.defaults or []))

    # func_args is initialized to a list of positional arguments that the function to be run accepts
    func_args = argspec.args[:len(argspec.args or []) -
                             len(argspec.defaults or [])]
    arg_type, na_type, kw_type = [], {}, False
    for funcset in reversed(kwargs.get('func_args') or []):
        if not isinstance(funcset, dict):
            # We are just receiving a list of args to the function to be run, so just append
            # those to the arg list that we will pass to the func.
            arg_type.append(funcset)
        else:
            for kwarg_key in six.iterkeys(funcset):
                # We are going to pass in a keyword argument. The trick here is to make certain
                # that if we find that in the *args* list that we pass it there and not as a kwarg
                if kwarg_key in func_args:
                    arg_type.append(funcset[kwarg_key])
                    continue
                else:
                    # Otherwise, we're good and just go ahead and pass the keyword/value pair into
                    # the kwargs list to be run.
                    func_kw.update(funcset)
    arg_type.reverse()
    _exp_prm = len(argspec.args or []) - len(argspec.defaults or [])
    _passed_prm = len(arg_type)
    missing = []
    if na_type and _exp_prm > _passed_prm:
        for arg in argspec.args:
            if arg not in func_kw:
                missing.append(arg)
    if missing:
        raise SaltInvocationError('Missing arguments: {0}'.format(
            ', '.join(missing)))
    elif _exp_prm > _passed_prm:
        raise SaltInvocationError(
            'Function expects {0} parameters, got only {1}'.format(
                _exp_prm, _passed_prm))

    mret = __salt__[name](*arg_type, **func_kw)
    if returner is not None:
        returners = salt.loader.returners(__opts__, __salt__)
        if returner in returners:
            returners[returner]({
                'id': __opts__['id'],
                'ret': mret,
                'fun': name,
                'jid': salt.utils.jid.gen_jid(__opts__)
            })

    return mret
Пример #58
0
    def low(self, fun, low, print_event=True, full_return=False):
        '''
        Execute a function from low data
        Low data includes:
            required:
                - fun: the name of the function to run
            optional:
                - arg: a list of args to pass to fun
                - kwarg: kwargs for fun
                - __user__: user who is running the command
                - __jid__: jid to run under
                - __tag__: tag to run under
        '''
        # fire the mminion loading (if not already done) here
        # this is not to clutter the output with the module loading
        # if we have a high debug level.
        self.mminion  # pylint: disable=W0104
        jid = low.get('__jid__', salt.utils.jid.gen_jid(self.opts))
        tag = low.get('__tag__',
                      salt.utils.event.tagify(jid, prefix=self.tag_prefix))

        data = {
            'fun': '{0}.{1}'.format(self.client, fun),
            'jid': jid,
            'user': low.get('__user__', 'UNKNOWN'),
        }

        event = salt.utils.event.get_event('master',
                                           self.opts['sock_dir'],
                                           self.opts['transport'],
                                           opts=self.opts,
                                           listen=False)

        if print_event:
            print_func = self.print_async_event \
                if hasattr(self, 'print_async_event') \
                else None
        else:
            # Suppress printing of return event (this keeps us from printing
            # runner/wheel output during orchestration).
            print_func = None

        namespaced_event = salt.utils.event.NamespacedEvent(
            event, tag, print_func=print_func)

        # TODO: test that they exist
        # TODO: Other things to inject??
        func_globals = {
            '__jid__': jid,
            '__user__': data['user'],
            '__tag__': tag,
            # weak ref to avoid the Exception in interpreter
            # teardown of event
            '__jid_event__': weakref.proxy(namespaced_event),
        }

        try:
            self_functions = pycopy.copy(self.functions)
            salt.utils.lazy.verify_fun(self_functions, fun)

            # Inject some useful globals to *all* the function's global
            # namespace only once per module-- not per func
            completed_funcs = []

            for mod_name in six.iterkeys(self_functions):
                if '.' not in mod_name:
                    continue
                mod, _ = mod_name.split('.', 1)
                if mod in completed_funcs:
                    continue
                completed_funcs.append(mod)
                for global_key, value in six.iteritems(func_globals):
                    self.functions[mod_name].__globals__[global_key] = value

            # There are some discrepancies of what a "low" structure is in the
            # publisher world it is a dict including stuff such as jid, fun,
            # arg (a list of args, with kwargs packed in). Historically this
            # particular one has had no "arg" and just has had all the kwargs
            # packed into the top level object. The plan is to move away from
            # that since the caller knows what is an arg vs a kwarg, but while
            # we make the transition we will load "kwargs" using format_call if
            # there are no kwargs in the low object passed in.

            if 'arg' in low and 'kwarg' in low:
                args = low['arg']
                kwargs = low['kwarg']
            else:
                f_call = salt.utils.args.format_call(
                    self.functions[fun],
                    low,
                    expected_extra_kws=CLIENT_INTERNAL_KEYWORDS)
                args = f_call.get('args', ())
                kwargs = f_call.get('kwargs', {})

            # Update the event data with loaded args and kwargs
            data['fun_args'] = list(args) + ([kwargs] if kwargs else [])
            func_globals['__jid_event__'].fire_event(data, 'new')

            # Initialize a context for executing the method.
            with tornado.stack_context.StackContext(
                    self.functions.context_dict.clone):
                func = self.functions[fun]
                try:
                    data['return'] = func(*args, **kwargs)
                except TypeError as exc:
                    data['return'] = salt.utils.text.cli_info(
                        'Error: {exc}\nUsage:\n{doc}'.format(exc=exc,
                                                             doc=func.__doc__),
                        'Passed invalid arguments')
                except Exception as exc:
                    data['return'] = salt.utils.text.cli_info(
                        six.text_type(exc), 'General error occurred')
                try:
                    data['success'] = self.context.get('retcode', 0) == 0
                except AttributeError:
                    # Assume a True result if no context attribute
                    data['success'] = True
                if isinstance(data['return'],
                              dict) and 'data' in data['return']:
                    # some functions can return boolean values
                    data['success'] = salt.utils.state.check_result(
                        data['return']['data'])
        except (Exception, SystemExit) as ex:
            if isinstance(ex, salt.exceptions.NotImplemented):
                data['return'] = six.text_type(ex)
            else:
                data[
                    'return'] = 'Exception occurred in {client} {fun}: {tb}'.format(
                        client=self.client, fun=fun, tb=traceback.format_exc())
            data['success'] = False

        if self.store_job:
            try:
                salt.utils.job.store_job(
                    self.opts,
                    {
                        'id': self.opts['id'],
                        'tgt': self.opts['id'],
                        'jid': data['jid'],
                        'return': data,
                    },
                    event=None,
                    mminion=self.mminion,
                )
            except salt.exceptions.SaltCacheError:
                log.error('Could not store job cache info. '
                          'Job details for this run may be unavailable.')

        # Outputters _can_ mutate data so write to the job cache first!
        namespaced_event.fire_event(data, 'ret')

        # if we fired an event, make sure to delete the event object.
        # This will ensure that we call destroy, which will do the 0MQ linger
        log.info('Runner completed: %s', data['jid'])
        del event
        del namespaced_event
        return data if full_return else data['return']
Пример #59
0
def present(name, acl_type, acl_name='', perms='', recurse=False):
    '''
    Ensure a Linux ACL is present
    '''
    ret = {'name': name, 'result': True, 'changes': {}, 'comment': ''}

    _octal = {'r': 4, 'w': 2, 'x': 1, '-': 0}

    __current_perms = __salt__['acl.getfacl'](name)

    if acl_type.startswith(('d:', 'default:')):
        _acl_type = ':'.join(acl_type.split(':')[1:])
        _current_perms = __current_perms[name].get('defaults', {})
        _default = True
    else:
        _acl_type = acl_type
        _current_perms = __current_perms[name]
        _default = False

    # The getfacl execution module lists default with empty names as being
    # applied to the user/group that owns the file, e.g.,
    # default:group::rwx would be listed as default:group:root:rwx
    # In this case, if acl_name is empty, we really want to search for root

    # We search through the dictionary getfacl returns for the owner of the
    # file if acl_name is empty.
    if acl_name == '':
        _search_name = __current_perms[name].get('comment').get(_acl_type)
    else:
        _search_name = acl_name

    if _current_perms.get(_acl_type, None) or _default:
        try:
            user = [
                i for i in _current_perms[_acl_type]
                if next(six.iterkeys(i)) == _search_name
            ].pop()
        except (AttributeError, IndexError, StopIteration, KeyError):
            user = None

        if user:
            if user[_search_name]['octal'] == sum(
                [_octal.get(i, i) for i in perms]):
                ret['comment'] = 'Permissions are in the desired state'
            else:
                ret['comment'] = 'Permissions have been updated'

                if __opts__['test']:
                    ret['result'] = None
                    return ret

                if recurse:
                    __salt__['acl.modfacl'](acl_type,
                                            acl_name,
                                            perms,
                                            name,
                                            recursive=True)
                else:
                    __salt__['acl.modfacl'](acl_type, acl_name, perms, name)
        else:
            ret['comment'] = 'Permissions will be applied'

            if __opts__['test']:
                ret['result'] = None
                return ret

            if recurse:
                __salt__['acl.modfacl'](acl_type,
                                        acl_name,
                                        perms,
                                        name,
                                        recursive=True)
            else:
                __salt__['acl.modfacl'](acl_type, acl_name, perms, name)
    else:
        ret['comment'] = 'ACL Type does not exist'
        ret['result'] = False

    return ret
Пример #60
0
def create_user(username, password, permissions, users=None):
    '''
    Create user accounts

    CLI Example:

    .. code-block:: bash

        salt dell drac.create_user [USERNAME] [PASSWORD] [PRIVILEGES]
        salt dell drac.create_user diana secret login,test_alerts,clear_logs

    DRAC Privileges
      * login                   : Login to iDRAC
      * drac                    : Configure iDRAC
      * user_management         : Configure Users
      * clear_logs              : Clear Logs
      * server_control_commands : Execute Server Control Commands
      * console_redirection     : Access Console Redirection
      * virtual_media           : Access Virtual Media
      * test_alerts             : Test Alerts
      * debug_commands          : Execute Debug Commands
    '''
    _uids = set()

    if users is None:
        users = list_users()

    if username in users:
        log.warning('\'{0}\' already exists'.format(username))
        return False

    for idx in six.iterkeys(users):
        _uids.add(users[idx]['index'])

    uid = sorted(list(set(range(2, 12)) - _uids), reverse=True).pop()

    # Create user accountvfirst
    if not __execute_cmd('config -g cfgUserAdmin -o \
                 cfgUserAdminUserName -i {0} {1}'.format(uid, username)):
        delete_user(username, uid)
        return False

    # Configure users permissions
    if not set_permissions(username, permissions, uid):
        log.warning('unable to set user permissions')
        delete_user(username, uid)
        return False

    # Configure users password
    if not change_password(username, password, uid):
        log.warning('unable to set user password')
        delete_user(username, uid)
        return False

    # Enable users admin
    if not __execute_cmd('config -g cfgUserAdmin -o \
                          cfgUserAdminEnable -i {0} 1'.format(uid)):
        delete_user(username, uid)
        return False

    return True