Ejemplo n.º 1
0
def _delete_keys(stale_keys, minions):
    """
    Delete the keys
    """
    wheel = salt.wheel.WheelClient(__opts__)
    for k in stale_keys:
        log.info("Removing stale key for %s", k)
        wheel.cmd("key.delete", [salt.utils.stringutils.to_unicode(k)])
        del minions[k]
    return minions
Ejemplo n.º 2
0
def start(interval=3600, expire=604800):
    ck = salt.utils.minions.CkMinions(__opts__)
    presence_file = '{0}/presence.p'.format(__opts__['cachedir'])
    wheel = salt.wheel.WheelClient(__opts__)

    while True:
        log.debug('Checking for present minions')
        minions = {}
        if os.path.exists(presence_file):
            try:
                with salt.utils.fopen(presence_file, 'r') as f:
                    minions = msgpack.load(f)
            except IOError as e:
                log.error('Could not open presence file {0}: {1}'.format(
                    presence_file, e))
                time.sleep(interval)
                continue

        minion_keys = _get_keys()
        now = time.time()
        present = ck.connected_ids()

        # For our existing keys, check which are present
        for m in minion_keys:
            # If we have a key that's not in the presence file, it may be a new minion
            # It could also mean this is the first time this engine is running and no
            # presence file was found
            if m not in minions:
                minions[m] = now
            elif m in present:
                minions[m] = now

        log.debug('Finished checking for present minions')
        # Delete old keys
        stale_keys = []
        for m, seen in six.iteritems(minions):
            if now - expire > seen:
                stale_keys.append(m)

        if len(stale_keys):
            for k in stale_keys:
                log.info('Removing stale key for {0}'.format(k))
            wheel.cmd('key.delete', stale_keys)
            del minions[k]

        try:
            with salt.utils.fopen(presence_file, 'w') as f:
                msgpack.dump(minions, f)
        except IOError as e:
            log.error('Could not write to presence file {0}: {1}'.format(
                presence_file, e))
        time.sleep(interval)
Ejemplo n.º 3
0
def start(interval=3600, expire=604800):
    ck = salt.utils.minions.CkMinions(__opts__)
    presence_file = "{0}/minions/presence.p".format(__opts__["cachedir"])
    wheel = salt.wheel.WheelClient(__opts__)

    while True:
        log.debug("Checking for present minions")
        minions = {}
        if os.path.exists(presence_file):
            try:
                with salt.utils.fopen(presence_file, "r") as f:
                    minions = msgpack.load(f)
            except IOError as e:
                log.error("Could not open presence file {0}: {1}".format(presence_file, e))
                time.sleep(interval)
                continue

        minion_keys = _get_keys()
        now = time.time()
        present = ck.connected_ids()

        # For our existing keys, check which are present
        for m in minion_keys:
            # If we have a key that's not in the presence file, it may be a new minion
            # It could also mean this is the first time this engine is running and no
            # presence file was found
            if m not in minions:
                minions[m] = now
            elif m in present:
                minions[m] = now

        log.debug("Finished checking for present minions")
        # Delete old keys
        stale_keys = []
        for m, seen in minions.iteritems():
            if now - expire > seen:
                stale_keys.append(m)

        if len(stale_keys):
            for k in stale_keys:
                log.info("Removing stale key for {0}".format(k))
            wheel.cmd("key.delete", stale_keys)
            del minions[k]

        try:
            with salt.utils.fopen(presence_file, "w") as f:
                msgpack.dump(minions, f)
        except IOError as e:
            log.error("Could not write to presence file {0}: {1}".format(presence_file, e))
        time.sleep(interval)
Ejemplo n.º 4
0
def salt_keys_denied():
    ret_denied = wheel.cmd('key.list', ['denied'])
#    if len(ret_denied['minions_denied']) == 0:
#        return None
#    else:
#    return ret_denied['minions_denied']
    print ret_denied['minions_denied']


#def showkeys():
#    shows = local.cmd('*', 'cmd.run', ['whoami'])
##    local.cmd('*', 'cmd.run', ['whoami'])
#    print shows
 
#salt_keys_denied()
#keys_all()
#keys_denied()
#keys_acc()
#keys_unacc()
#keys_rej()
#wheel.cmd('key.list_all')

#import os
#import os.path
#
#PATH='/var/run/salt-master.pid'
#
#if os.path.isfile(PATH) and os.access(PATH, os.R_OK):
    print "File exists and is readable"
Ejemplo n.º 5
0
def display_minions():
    jj = _load_environment()
    context = {}
    context['conductors'] = list(conductors.keys())
    key_states = wheel.cmd('key.list_all')
    context['key_states'] = key_states
    connected_minions = runner.cmd('manage.up')
    context['connected_minions'] = connected_minions
    page_template = jj.get_template('minions.j2')
    return page_template.render(context)
Ejemplo n.º 6
0
    def wheel(self, fun, **kwargs):
        '''
        Run :ref:`wheel modules <all-salt.wheel>`

        Wraps :py:meth:`salt.wheel.WheelClient.master_call`.

        :return: Returns the result from the wheel module
        '''
        if kwargs.has_key('client'):
            kwargs.pop('client')
        kwargs['print_event'] = False
        wheel = salt.wheel.Wheel(self.opts)
        return wheel.cmd(fun, **kwargs)
Ejemplo n.º 7
0
def delete_salt_minion(minion_name):
    opts = salt.config.master_config('/etc/salt/master.d/susemanager.conf')
    wheel = salt.wheel.WheelClient(opts)
    minion_pre_list = wheel.cmd('key.list', ['pre'])

    if len(minion_pre_list['minions_pre']) > 0:
        for p in minion_pre_list['minions_pre']:
            if minion_name in p:
                p_dict = {
                    'minions_pre': [
                        p,
                    ],
                }
                print("Deleting minion from pending key accept: %s" % p_dict)
                wheel.cmd_async({'fun': 'key.delete_dict', 'match': p_dict})

    minion_denied_list = wheel.cmd('key.list', ['denied'])
    if len(minion_denied_list['minions_denied']) > 0:
        for p in minion_denied_list['minions_denied']:
            if minion_name in p:
                p_dict = {
                    'minions_denied': [
                        p,
                    ],
                }
                print("Deleting minion from denied key: %s" % p_dict)
                wheel.cmd_async({'fun': 'key.delete_dict', 'match': p_dict})

    minion_rejected_list = wheel.cmd('key.list', ['rejected'])
    if len(minion_rejected_list['minions_rejected']) > 0:
        for p in minion_rejected_list['minions_rejected']:
            if minion_name in p:
                p_dict = {
                    'minions_rejected': [
                        p,
                    ],
                }
                print("Deleting minion from rejected key: %s" % p_dict)
                wheel.cmd_async({'fun': 'key.delete_dict', 'match': p_dict})
Ejemplo n.º 8
0
def get_minions(type='minions', use_cache=True):
    """
    Build a cache using minions array.

    By default the type is minions and we use the cache
    """
    global minions
    if use_cache and type in minions:
        return minions[type]

    wheel = salt.wheel.WheelClient(opts)
    keys = wheel.cmd('key.list_all')
    if type not in keys:
        raise SaltError('no key {0} in key.list_all'.format(type))
    minions[type] = keys[type]
    return minions[type]
Ejemplo n.º 9
0
def clean_outfile():
    try:
        with open('/tmp/total_down.json') as outfile:
            _total_down = json.load(outfile)
    except:
        log.error("Keys Maintenance Runner - can't open outfile")

    for minion in list(_total_down):
        ret = wheel.cmd('key.name_match', [minion])
        if ret == {}:
            log.warning(
                "Keys Maintenance Runner - minion key %s does not exist, removing from json",
                minion)
            _total_down.pop(minion, None)

    return _total_down
Ejemplo n.º 10
0
def salt_call(minion_id,
              function=None,
              with_grains=True,
              with_pillar=True,
              preload_grains=True,
              preload_pillar=True,
              default_grains=None,
              default_pillar=None,
              cache_grains=False,
              cache_pillar=False,
              use_cached_grains=True,
              use_cached_pillar=True,
              use_existing_proxy=False,
              jid=None,
              args=(),
              **kwargs):
    '''
    Invoke a Salt Execution Function that requires or invokes an NAPALM
    functionality (directly or indirectly).

    minion_id:
        The ID of the Minion to compile Pillar data for.

    function
        The name of the Salt function to invoke.

    preload_grains: ``True``
        Whether to preload the Grains before establishing the connection with
        the remote network device.

    default_grains:
        Dictionary of the default Grains to make available within the functions
        loaded.

    with_grains: ``True``
        Whether to load the Grains modules and collect Grains data and make it
        available inside the Execution Functions.
        The Grains will be loaded after opening the connection with the remote
        network device.

    preload_pillar: ``True``
        Whether to preload Pillar data before opening the connection with the
        remote network device.

    default_pillar:
        Dictionary of the default Pillar data to make it available within the
        functions loaded.

    with_pillar: ``True``
        Whether to load the Pillar modules and compile Pillar data and make it
        available inside the Execution Functions.

    use_cached_pillar: ``True``
        Use cached Pillars whenever possible. If unable to gather cached data,
        it falls back to compiling the Pillar.

    use_cached_grains: ``True``
        Use cached Grains whenever possible. If unable to gather cached data,
        it falls back to collecting Grains.

    cache_pillar: ``False``
        Cache the compiled Pillar data before returning.

        .. warning::
            This option may be dangerous when targeting a device that already
            has a Proxy Minion associated, however recommended otherwise.

    cache_grains: ``False``
        Cache the collected Grains before returning.

        .. warning::
            This option may be dangerous when targeting a device that already
            has a Proxy Minion associated, however recommended otherwise.

    use_existing_proxy: ``False``
        Use the existing Proxy Minions when they are available (say on an
        already running Master).

    jid: ``None``
        The JID to pass on, when executing.

    arg
        The list of arguments to send to the Salt function.

    kwargs
        Key-value arguments to send to the Salt function.

    CLI Example:

    .. code-block:: bash

        salt-run proxy.salt_call bgp.neighbors junos 1.2.3.4 test test123
        salt-run proxy.salt_call net.load_config junos 1.2.3.4 test test123 text='set system ntp peer 1.2.3.4'
    '''
    if use_existing_proxy:
        # When using the existing Proxies, simply send the command to the
        # Minion through the ``salt.execute`` Runner.
        # But first, check if the Minion ID is accepted, otherwise, continue
        # and execute the function withing this Runner.
        wheel = salt.wheel.WheelClient(__opts__)
        accepted_minions = wheel.cmd('key.list', ['accepted'],
                                     print_event=False).get('minions', [])
        if minion_id in accepted_minions:
            log.debug(
                '%s seems to be a valid Minion, trying to spread out the command',
                minion_id,
            )
            log.info(
                'If %s is not responding, you might want to run without --use-existing-proxy',
                minion_id,
            )
            ret = __salt__['salt.execute'](minion_id,
                                           function,
                                           arg=args,
                                           kwarg=kwargs,
                                           jid=jid)
            return ret.get(minion_id)
        else:
            log.debug(
                '%s doesn\'t seem to be a valid existing Minion, executing locally',
                minion_id,
            )
    opts = copy.deepcopy(__opts__)
    opts['id'] = minion_id
    opts['pillarenv'] = __opts__.get('pillarenv', 'base')
    opts['__cli'] = __opts__.get('__cli', 'salt-call')
    if 'saltenv' not in opts:
        opts['saltenv'] = 'base'
    if not default_grains:
        default_grains = {}
    if use_cached_grains or use_cached_pillar:
        minion_cache = __salt__['cache.fetch']('minions/{}'.format(minion_id),
                                               'data')
    opts['grains'] = default_grains
    if not default_pillar:
        default_pillar = {}
    opts['pillar'] = default_pillar
    opts['proxy_load_pillar'] = with_pillar
    opts['proxy_load_grains'] = with_grains
    opts['proxy_preload_pillar'] = preload_pillar
    opts['proxy_preload_grains'] = preload_grains
    opts['proxy_cache_grains'] = cache_grains
    opts['proxy_cache_pillar'] = cache_pillar
    opts['proxy_use_cached_grains'] = use_cached_grains
    if use_cached_grains:
        opts['proxy_cached_grains'] = minion_cache.get('grains')
    opts['proxy_use_cached_pillar'] = use_cached_pillar
    if use_cached_pillar:
        opts['proxy_cached_pillar'] = minion_cache.get('pillar')
    sa_proxy = StandaloneProxy(opts)
    kwargs = clean_kwargs(**kwargs)
    ret = None
    try:
        ret = sa_proxy.functions[function](*args, **kwargs)
    except Exception as err:
        log.error(err, exc_info=True)
    finally:
        shut_fun = '{}.shutdown'.format(sa_proxy.opts['proxy']['proxytype'])
        sa_proxy.proxy[shut_fun](opts)
    if cache_grains:
        __salt__['cache.store']('minions/{}/data'.format(minion_id), 'grains',
                                sa_proxy.opts['grains'])
    if cache_pillar:
        __salt__['cache.store']('minions/{}/data'.format(minion_id), 'pillar',
                                sa_proxy.opts['pillar'])
    return ret
Ejemplo n.º 11
0
def salt_call(
    minion_id,
    function=None,
    unreachable_devices=None,
    failed_devices=None,
    with_grains=True,
    with_pillar=True,
    preload_grains=True,
    preload_pillar=True,
    default_grains=None,
    default_pillar=None,
    cache_grains=False,
    cache_pillar=False,
    use_cached_grains=True,
    use_cached_pillar=True,
    use_existing_proxy=False,
    no_connect=False,
    jid=None,
    roster_opts=None,
    test_ping=False,
    tgt=None,
    tgt_type=None,
    preload_targeting=False,
    invasive_targeting=False,
    failhard=False,
    timeout=60,
    returner='',
    returner_config='',
    returner_kwargs={},
    args=(),
    **kwargs
):
    '''
    Invoke a Salt Execution Function that requires or invokes an NAPALM
    functionality (directly or indirectly).

    minion_id:
        The ID of the Minion to compile Pillar data for.

    function
        The name of the Salt function to invoke.

    preload_grains: ``True``
        Whether to preload the Grains before establishing the connection with
        the remote network device.

    default_grains:
        Dictionary of the default Grains to make available within the functions
        loaded.

    with_grains: ``True``
        Whether to load the Grains modules and collect Grains data and make it
        available inside the Execution Functions.
        The Grains will be loaded after opening the connection with the remote
        network device.

    preload_pillar: ``True``
        Whether to preload Pillar data before opening the connection with the
        remote network device.

    default_pillar:
        Dictionary of the default Pillar data to make it available within the
        functions loaded.

    with_pillar: ``True``
        Whether to load the Pillar modules and compile Pillar data and make it
        available inside the Execution Functions.

    use_cached_pillar: ``True``
        Use cached Pillars whenever possible. If unable to gather cached data,
        it falls back to compiling the Pillar.

    use_cached_grains: ``True``
        Use cached Grains whenever possible. If unable to gather cached data,
        it falls back to collecting Grains.

    cache_pillar: ``False``
        Cache the compiled Pillar data before returning.

        .. warning::
            This option may be dangerous when targeting a device that already
            has a Proxy Minion associated, however recommended otherwise.

    cache_grains: ``False``
        Cache the collected Grains before returning.

        .. warning::
            This option may be dangerous when targeting a device that already
            has a Proxy Minion associated, however recommended otherwise.

    use_existing_proxy: ``False``
        Use the existing Proxy Minions when they are available (say on an
        already running Master).

    no_connect: ``False``
        Don't attempt to initiate the connection with the remote device.
        Default: ``False`` (it will initiate the connection).

    jid: ``None``
        The JID to pass on, when executing.

    test_ping: ``False``
        When using the existing Proxy Minion with the ``use_existing_proxy``
        option, can use this argument to verify also if the Minion is
        responsive.

    arg
        The list of arguments to send to the Salt function.

    kwargs
        Key-value arguments to send to the Salt function.

    CLI Example:

    .. code-block:: bash

        salt-run proxy.salt_call bgp.neighbors junos 1.2.3.4 test test123
        salt-run proxy.salt_call net.load_config junos 1.2.3.4 test test123 text='set system ntp peer 1.2.3.4'
    '''
    if use_existing_proxy:
        # When using the existing Proxies, simply send the command to the
        # Minion through the ``salt.execute`` Runner.
        # But first, check if the Minion ID is accepted, otherwise, continue
        # and execute the function withing this Runner.
        wheel = salt.wheel.WheelClient(__opts__)
        accepted_minions = wheel.cmd('key.list', ['accepted'], print_event=False).get(
            'minions', []
        )
        if minion_id in accepted_minions:
            log.debug(
                '%s seems to be a valid Minion, trying to spread out the command',
                minion_id,
            )
            log.info(
                'If %s is not responding, you might want to run without --use-existing-proxy, or with --test-ping',
                minion_id,
            )
            test_ping_succeeded = True
            if test_ping:
                log.debug('Checking if the Minion %s is responsive', minion_id)
                ret = __salt__['salt.execute'](minion_id, 'test.ping', jid=jid)
                test_ping_succeeded = ret.get(minion_id, False)
            if test_ping_succeeded:
                ret = __salt__['salt.execute'](
                    minion_id, function, arg=args, kwarg=kwargs, jid=jid
                )
                return ret.get(minion_id)
            else:
                log.info(
                    'Looks like the Minion %s is not responsive, executing locally',
                    minion_id,
                )
        else:
            log.debug(
                '%s doesn\'t seem to be a valid existing Minion, executing locally',
                minion_id,
            )
    opts = copy.deepcopy(__opts__)
    opts['id'] = minion_id
    opts['pillarenv'] = __opts__.get('pillarenv', 'base')
    opts['__cli'] = __opts__.get('__cli', 'salt-call')
    opts['__tgt'] = tgt
    opts['__tgt_type'] = tgt_type
    if 'saltenv' not in opts:
        opts['saltenv'] = 'base'
    if not default_grains:
        default_grains = {}
    if use_cached_grains or use_cached_pillar:
        minion_cache = __salt__['cache.fetch']('minions/{}'.format(minion_id), 'data')
    opts['grains'] = default_grains
    if not default_pillar:
        default_pillar = {}
    opts['pillar'] = default_pillar
    opts['proxy_load_pillar'] = with_pillar
    opts['proxy_load_grains'] = with_grains
    opts['proxy_preload_pillar'] = preload_pillar
    opts['proxy_preload_grains'] = preload_grains
    opts['proxy_cache_grains'] = cache_grains
    opts['proxy_cache_pillar'] = cache_pillar
    opts['preload_targeting'] = preload_targeting
    opts['invasive_targeting'] = invasive_targeting
    opts['proxy_use_cached_grains'] = use_cached_grains
    opts['proxy_no_connect'] = no_connect
    opts['proxy_test_ping'] = test_ping
    if use_cached_grains:
        opts['proxy_cached_grains'] = minion_cache.get('grains')
    opts['proxy_use_cached_pillar'] = use_cached_pillar
    if use_cached_pillar:
        opts['proxy_cached_pillar'] = minion_cache.get('pillar')
    opts['roster_opts'] = roster_opts
    opts['returner'] = returner
    minion_defaults = salt.config.DEFAULT_MINION_OPTS.copy()
    minion_defaults.update(salt.config.DEFAULT_PROXY_MINION_OPTS)
    for opt, val in six.iteritems(minion_defaults):
        if opt not in opts:
            opts[opt] = val
    sa_proxy = StandaloneProxy(opts, unreachable_devices)
    if not sa_proxy.ready:
        log.debug(
            'The SProxy Minion for %s is not able to start up, aborting', opts['id']
        )
        return
    kwargs = clean_kwargs(**kwargs)
    ret = None
    try:
        ret = sa_proxy.functions[function](*args, **kwargs)
    except Exception as err:
        log.error('Exception while running %s on %s', function, opts['id'])
        log.error(err, exc_info=True)
        if failed_devices is not None:
            failed_devices.append(opts['id'])
        if failhard:
            raise
    else:
        if returner:
            returner_fun = '{}.returner'.format(returner)
            if returner_fun in sa_proxy.returners:
                log.error('Sending the response from %s to the %s Returner', opts['id'], returner)
                ret_data = {
                    'id': opts['id'],
                    'jid': jid,
                    'fun': function,
                    'fun_args': args,
                    'return': ret,
                    'ret_config': returner_config,
                    'ret_kwargs': returner_kwargs,
                }
                try:
                    sa_proxy.returners[returner_fun](ret_data)
                except Exception as err:
                    log.error('Exception while sending the response from %s to the %s returner', opts['id'], returner)
                    log.error(err, exc_info=True)
            else:
                log.warning('Returner %s is not available. Check that the dependencies are properly installed')
    finally:
        if sa_proxy.connected:
            shut_fun = '{}.shutdown'.format(sa_proxy.opts['proxy']['proxytype'])
            sa_proxy.proxy[shut_fun](opts)
    if cache_grains:
        log.debug('Caching Grains for %s', minion_id)
        log.debug(sa_proxy.opts['grains'])
        cache_store = __salt__['cache.store'](
            'minions/{}/data'.format(minion_id), 'grains', sa_proxy.opts['grains']
        )
    if cache_pillar:
        log.debug('Caching Pillar for %s', minion_id)
        cached_store = __salt__['cache.store'](
            'minions/{}/data'.format(minion_id), 'pillar', sa_proxy.opts['pillar']
        )
    return ret
Ejemplo n.º 12
0
def delete_minion():
    minion = request.form.get('minion')
    wheel.cmd('key.delete', [minion])
    return "Salt Key for minion {} deleted".format(minion)
Ejemplo n.º 13
0
def keys_rej():
    ret = wheel.cmd('key.list', ['rejected'])
#    wheel.cmd('key.list_all')
    return ret['minions_rejected']
Ejemplo n.º 14
0
def salt_keys_unaccepted():
    ret_unacc = wheel.cmd('key.list', ['unaccepted'])
    #    return ret_unacc['minions_pre']
    return ret_unacc
Ejemplo n.º 15
0
def accept_minion():
    minion = request.form.get('minion')
    wheel.cmd('key.accept', [minion])
    return "Accepted Salt Key for minion {}".format(minion)
Ejemplo n.º 16
0
def key_create(id_, host, force=False):
    '''
    Generates minion keypair, accepts it on master and injects it to minion via SSH.

    :param id_: expected minion ID of target node
    :param host: IP address or resolvable hostname/FQDN of target node

    CLI Examples:

    .. code-block:: bash

        salt-call saltkey.key_create <MINION_ID> <MINION_IP_ADDRESS> force=False
    '''
    ret = {
        'retcode': 0,
        'msg': 'Salt Key for minion %s is already accepted' % id_,
    }

    opts = salt.config.master_config('/etc/salt/master')
    wheel = salt.wheel.WheelClient(opts)
    keys = wheel.cmd('key.gen_accept', arg=[id_], kwarg={'force': force})
    pub_key = keys.get('pub', None)
    priv_key = keys.get('priv', None)

    if pub_key and priv_key:
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        # Establish SSH connection to minion
        try:
            ssh.connect(host)
        except paramiko.ssh_exception.AuthenticationException:
            msg = (
                'Could not establish SSH connection to minion "%s" on address %s, please ensure '
                'that current user\'s SSH key is present in minions authorized_keys.'
            ) % (id_, host)
            LOG.error(msg)
            ret['retcode'] = 1
            ret['msg'] = msg
            wheel.cmd_async({'fun': 'key.delete', 'match': id_})
            return ret
        except Exception as e:
            msg = ('Unknown error occured while establishing SSH connection '
                   'to minion "%s" on address %s: %s') % (id_, host, repr(e))
            LOG.error(msg)
            ret['retcode'] = 1
            ret['msg'] = msg
            wheel.cmd_async({'fun': 'key.delete', 'match': id_})
            return ret
        # Setup the keys on minion side the ugly way, nice one didn't work
        key_path = '/etc/salt/pki/minion'
        command = (
            'echo "%(pub_key)s" > %(pub_path)s && chmod 644 %(pub_path)s && '
            'echo "%(priv_key)s" > %(priv_path)s && chmod 400 %(priv_path)s && '
            'salt-call --local service.restart salt-minion') % {
                'pub_path': os.path.join(key_path, 'minion.pub'),
                'pub_key': pub_key,
                'priv_path': os.path.join(key_path, 'minion.pem'),
                'priv_key': priv_key
            }

        ssh_chan = ssh.get_transport().open_session()
        ssh_chan.exec_command(command)
        # Wait for command return
        while True:
            if ssh_chan.exit_status_ready():
                exit_status = ssh_chan.recv_exit_status()
                stderr = ssh_chan.recv_stderr(1000)
                stdout = ssh_chan.recv(1000)
                break
        ssh.close()
        # Evaluate SSH command exit status
        if exit_status != 0:
            msg = 'Keypair injection to Salt minion failed on target with following error: %s' % stderr
            LOG.error(msg)
            ret['retcode'] = exit_status
            ret['msg'] = msg
            return ret

        ret['msg'] = 'Salt Key successfully created'

    return ret
Ejemplo n.º 17
0
def _delete_key(minion_id):
    # wheel = salt.wheel.Wheel(master_opts)
    # wheel.call_func('key.delete', match=minion)
    wheel = salt.wheel.WheelClient(master_opts)
    wheel.cmd('key.delete', [minion_id])
Ejemplo n.º 18
0
def saltstack_view():
    error = None
    if request.method == 'GET':
        salt_svc_check = salt_service_check()
        salt_keys_acc = salt_keys_accepted()
        salt_keys_unacc = salt_keys_unaccepted()
        salt_keys_den = salt_keys_denied()
        salt_keys_rej = salt_keys_rejected()
        return render_template('saltstack.html',
                               pxe_nodes=Saltstack_pxe_nodes.query.all(),
                               salt_svc_check=salt_svc_check,
                               salt_keys_acc=salt_keys_acc,
                               salt_keys_unacc=salt_keys_unacc,
                               salt_keys_den=salt_keys_den,
                               salt_keys_rej=salt_keys_rej)
    elif request.method == 'POST':
        if 'salt_keys_denied_delete' in request.form:
            if not request.form['salt_keys_denied_delete'] or request.form[
                    'key_ip'] == '':
                flash('Please fill all the fields before sending a request!',
                      'danger')
                return redirect(request.url)
            else:
                key_ip = request.form['key_ip']
                wheel.cmd_async({'fun': 'key.delete', 'match': key_ip})
                pxe_node = Saltstack_pxe_nodes.query.filter_by(
                    pxeipaddr=key_ip).first()
                if str(key_ip) == str(pxe_node):
                    db.session.delete(pxe_node)
                    db.session.commit()
                flash('Requested key ' + key_ip + ' has been removed!',
                      'success')
                return redirect(request.url)
        elif 'salt_keys_rejected_delete' in request.form:
            if not request.form['salt_keys_rejected_delete'] or request.form[
                    'key_ip'] == '':
                flash('Please fill all the fields before sending a request!',
                      'danger')
                return redirect(request.url)
            else:
                key_ip = request.form['key_ip']
                wheel.cmd_async({'fun': 'key.delete', 'match': key_ip})
                pxe_node = Saltstack_pxe_nodes.query.filter_by(
                    pxeipaddr=key_ip).first()
                if str(key_ip) == str(pxe_node):
                    db.session.delete(pxe_node)
                    db.session.commit()
                flash('Requested key ' + key_ip + ' has been removed!',
                      'success')
                return redirect(request.url)
        elif 'salt_keys_unaccepted_accept' in request.form:
            if not request.form['salt_keys_unaccepted_accept'] or request.form[
                    'key_ip'] == '':
                flash('Please fill all the fields before sending a request!',
                      'danger')
                return redirect(request.url)
            else:
                key_ip = request.form['key_ip']
                wheel.cmd('key.accept', [key_ip])
                flash('Requested key ' + key_ip + ' has been accepted!',
                      'success')
                return redirect(request.url)
        elif 'salt_keys_unaccepted_delete' in request.form:
            if not request.form['salt_keys_unaccepted_delete'] or request.form[
                    'key_ip'] == '':
                flash('Please fill all the fields before sending a request!',
                      'danger')
                return redirect(request.url)
            else:
                key_ip = request.form['key_ip']
                wheel.cmd_async({'fun': 'key.delete', 'match': key_ip})
                pxe_node = Saltstack_pxe_nodes.query.filter_by(
                    pxeipaddr=key_ip).first()
                if str(key_ip) == str(pxe_node):
                    db.session.delete(pxe_node)
                    db.session.commit()
                flash('Requested key ' + key_ip + ' has been removed!',
                      'success')
                return redirect(request.url)
        elif 'salt_keys_accepted_delete' in request.form:
            if not request.form['salt_keys_accepted_delete'] or request.form[
                    'key_ip'] == '':
                flash('Please fill all the fields before sending a request!',
                      'danger')
                return redirect(request.url)
            else:
                key_ip = request.form['key_ip']
                wheel.cmd_async({'fun': 'key.delete', 'match': key_ip})
                pxe_node = Saltstack_pxe_nodes.query.filter_by(
                    pxeipaddr=key_ip).first()
                if str(key_ip) == str(pxe_node):
                    db.session.delete(pxe_node)
                    db.session.commit()
                flash('Requested key ' + key_ip + ' has been removed!',
                      'success')
                return redirect(request.url)
        elif 'salt_keys_audit_save' in request.form:
            if not request.form['salt_keys_audit_save'] or request.form[
                    'key_ip'] == '':
                flash('Please fill all the fields before sending a request!',
                      'danger')
                return redirect(request.url)
            else:
                key_ip = request.form['key_ip']
                pxe_node_check = Saltstack_pxe_nodes.query.filter_by(
                    pxeipaddr=key_ip).first()
                if str(key_ip) == str(pxe_node_check):
                    flash(
                        'Candidate ' + key_ip + ' has already been audited !',
                        'danger')
                    return redirect(request.url)
                else:
                    pxe_int_name = local.cmd(key_ip, 'network.ifacestartswith',
                                             [key_ip])
                    pxe_mac_addr = local.cmd(key_ip, 'network.hwaddr',
                                             [pxe_int_name[key_ip][0]])
                    pxe_node = Saltstack_pxe_nodes(key_ip,
                                                   pxe_int_name[key_ip][0],
                                                   pxe_mac_addr[key_ip])
                    db.session.add(pxe_node)
                    db.session.commit()
                    #		print pxe_int_name[key_ip][0], pxe_mac_addr[key_ip]
                    flash(
                        'Requested key ' + key_ip +
                        ' has been audited! INT: ' + pxe_int_name[key_ip][0] +
                        ' MAC: ' + pxe_mac_addr[key_ip] + ' ', 'success')
                    return redirect(request.url)
        else:
            flash('Malformed form submitted !', 'danger')
            return redirect(request.url)
Ejemplo n.º 19
0
def salt_keys_rejected():
    ret_rej = wheel.cmd('key.list', ['rejected'])
    return ret_rej
Ejemplo n.º 20
0
def salt_keys_denied():
    ret_denied = wheel.cmd('key.list', ['denied'])
    return ret_denied
Ejemplo n.º 21
0
def execute(tgt,
            function=None,
            tgt_type='glob',
            roster=None,
            preview_target=False,
            target_details=False,
            timeout=60,
            with_grains=True,
            with_pillar=True,
            preload_grains=True,
            preload_pillar=True,
            default_grains=None,
            default_pillar=None,
            args=(),
            batch_size=10,
            sync=False,
            events=True,
            cache_grains=False,
            cache_pillar=False,
            use_cached_grains=True,
            use_cached_pillar=True,
            use_existing_proxy=False,
            **kwargs):
    '''
    Invoke a Salt function on the list of devices matched by the Roster
    subsystem.

    tgt
        The target expression, e.g., ``*`` for all devices, or ``host1,host2``
        for a list, etc. The ``tgt_list`` argument must be used accordingly,
        depending on the type of this expression.

    function
        The name of the Salt function to invoke.

    tgt_type: ``glob``
        The type of the ``tgt`` expression. Choose between: ``glob`` (default),
        ``list``, ``pcre``, ``rage``, or ``nodegroup``.

    roster: ``None``
        The name of the Roster to generate the targets. Alternatively, you can
        specify the name of the Roster by configuring the ``proxy_roster``
        option into the Master config.

    preview_target: ``False``
        Return the list of Roster targets matched by the ``tgt`` and
        ``tgt_type`` arguments.

    preload_grains: ``True``
        Whether to preload the Grains before establishing the connection with
        the remote network device.

    default_grains:
        Dictionary of the default Grains to make available within the functions
        loaded.

    with_grains: ``True``
        Whether to load the Grains modules and collect Grains data and make it
        available inside the Execution Functions.
        The Grains will be loaded after opening the connection with the remote
        network device.

    default_pillar:
        Dictionary of the default Pillar data to make it available within the
        functions loaded.

    with_pillar: ``True``
        Whether to load the Pillar modules and compile Pillar data and make it
        available inside the Execution Functions.

    arg
        The list of arguments to send to the Salt function.

    kwargs
        Key-value arguments to send to the Salt function.

    batch_size: ``10``
        The size of each batch to execute.

    sync: ``False``
        Whether to return the results synchronously (or return them as soon
        as the device replies).

    events: ``True``
        Whether should push events on the Salt bus, similar to when executing
        equivalent through the ``salt`` command.

    use_cached_pillar: ``True``
        Use cached Pillars whenever possible. If unable to gather cached data,
        it falls back to compiling the Pillar.

    use_cached_grains: ``True``
        Use cached Grains whenever possible. If unable to gather cached data,
        it falls back to collecting Grains.

    cache_pillar: ``False``
        Cache the compiled Pillar data before returning.

        .. warning::
            This option may be dangerous when targeting a device that already
            has a Proxy Minion associated, however recommended otherwise.

    cache_grains: ``False``
        Cache the collected Grains before returning.

        .. warning::
            This option may be dangerous when targeting a device that already
            has a Proxy Minion associated, however recommended otherwise.

    use_existing_proxy: ``False``
        Use the existing Proxy Minions when they are available (say on an
        already running Master).

    CLI Example:

    .. code-block:: bash

        salt-run proxy.execute_roster edge* test.ping
        salt-run proxy.execute_roster junos-edges test.ping tgt_type=nodegroup
    '''
    targets = []
    roster = roster or __opts__.get('proxy_roster', __opts__.get('roster'))
    if not roster or roster == 'None':
        log.info(
            'No Roster specified. Please use the ``roster`` argument, or set the ``proxy_roster`` option in the '
            'Master configuration.')
        targets = []
        if use_existing_proxy:
            # When targeting exiting Proxies, we're going to look and match the
            # accepted keys
            log.debug(
                'Requested to match the target based on the existing Minions')
            wheel = salt.wheel.WheelClient(__opts__)
            if tgt_type == 'list':
                # accepted_minions = wheel.cmd(
                #     'key.list', ['accepted'], print_event=False
                # ).get('minions', [])
                # log.debug('This Master has the following Minions accepted:')
                # log.debug(accepted_minions)
                # targets = [accepted for accepted in accepted_minions if accepted in tgt]
                # TODO: temporarily deactivated the above, as I thought it might
                # make more sense to try to execute best efforts on any of the
                # Minions listed, and later it will be checked if it's possible
                # to execute on an existing Minion or withing this Runner.
                # TBD if that's the right decision, re-evaluate while it's still
                # in beta release.
                targets = tgt[:]
            elif tgt_type == 'glob':
                targets = wheel.cmd('key.name_match', [tgt],
                                    print_event=False).get('minions', [])
        else:
            # Try a fuzzy match based on the exact target the user requested
            # only when not attempting to match an existing Proxy. If you do
            # want however, it won't be of much use, as the command is going to
            # be spread out to non-existing minions, so better turn off that
            # feature.
            log.debug('Trying a fuzzy match on the target')
            if tgt_type == 'list':
                targets = tgt[:]
            elif tgt_type == 'glob' and tgt != '*':
                targets = [tgt]
    else:
        log.debug('Computing the target using the %s Roster', roster)
        roster_modules = salt.loader.roster(__opts__, runner=__salt__)
        if '.targets' not in roster:
            roster = '{mod}.targets'.format(mod=roster)
        rtargets = roster_modules[roster](tgt, tgt_type=tgt_type)
        targets = list(rtargets.keys())
    log.debug('The target expression "%s" (%s) matched the following:',
              str(tgt), tgt_type)
    log.debug(targets)
    if not targets:
        return 'No devices matched your target. Please review your tgt / tgt_type arguments, or the Roster data source'
    if preview_target:
        return targets
    elif not function:
        return 'Please specify a Salt function to execute.'
    jid = kwargs.get('__pub_jid')
    if not jid:
        if salt.version.__version_info__ >= (2018, 3, 0):
            jid = salt.utils.jid.gen_jid(__opts__)
        else:
            jid = salt.utils.jid.gen_jid()
    if events:
        __salt__['event.send'](jid, {'minions': targets})
    return execute_devices(targets,
                           function,
                           tgt=tgt,
                           tgt_type=tgt_type,
                           with_grains=with_grains,
                           preload_grains=preload_grains,
                           with_pillar=with_pillar,
                           preload_pillar=preload_pillar,
                           default_grains=default_grains,
                           default_pillar=default_pillar,
                           args=args,
                           batch_size=batch_size,
                           sync=sync,
                           events=events,
                           cache_grains=cache_grains,
                           cache_pillar=cache_pillar,
                           use_cached_grains=use_cached_grains,
                           use_cached_pillar=use_cached_pillar,
                           use_existing_proxy=use_existing_proxy,
                           **kwargs)
Ejemplo n.º 22
0
def keys_acc():
    ret = wheel.cmd('key.list', ['accepted'])
#    wheel.cmd('key.list_all')
    return ret['minions']
Ejemplo n.º 23
0
def _delete_key(minion_id):
    # wheel = salt.wheel.Wheel(master_opts)
    # wheel.call_func('key.delete', match=minion)
    wheel = salt.wheel.WheelClient(master_opts)
    wheel.cmd('key.delete', [minion_id])
Ejemplo n.º 24
0
def keys_denied():
    ret = wheel.cmd('key.list', ['denied'])
#    wheel.cmd('key.list_all')
    return ret['minions_denied']
Ejemplo n.º 25
0
def keys_all():
    ret = wheel.cmd('key.list_all')
#    wheel.cmd('key.list_all')
    return ret
Ejemplo n.º 26
0
def salt_keys_accepted():
    ret_acc = wheel.cmd('key.list', ['accepted'])
    #    return ret_acc['minions']
    return ret_acc
Ejemplo n.º 27
0
def keys_unacc():
    ret = wheel.cmd('key.list', ['unaccepted'])
#    wheel.cmd('key.list_all')
    return ret['minions_pre']
Ejemplo n.º 28
0
def testing():
    ret = {}
    dupa = wheel.cmd('key.list', ['all'])
    return ret