Git Product home page Git Product logo

mirceaulinic / salt-sproxy Goto Github PK

View Code? Open in Web Editor NEW
115.0 8.0 19.0 1007 KB

Salt plugin to automate the management and configuration of (network) devices at scale, without running (Proxy) Minions.

Home Page: https://salt-sproxy.readthedocs.io/en/latest/

License: Apache License 2.0

Dockerfile 0.24% Python 97.09% Makefile 0.27% Shell 2.40%
network network-automation saltstack configuration-management orchestration python docker event-driven automation rest-api

salt-sproxy's Introduction

Salt Super-Proxy Tweet

PyPI downloads Docker pulls PyPI status PyPI versions Test plugin Documentation status Code style License GitHub make-a-pull-request

Salt plugin to automate the management and configuration of network devices at scale, without running (Proxy) Minions.

Using salt-sproxy, you can continue to benefit from the scalability, flexibility and extensibility of Salt, while you don't have to manage thousands of (Proxy) Minion services. However, you are able to use both salt-sproxy and your (Proxy) Minions at the same time.

Why salt-sproxy

salt-sproxy can be used as a standalone tool to manage your devices without having any further requirements, as well as an extension to your existing Salt environment (if you already have). In other words, if you have a Salt installation where you manage some network devices and servers, installing salt-sproxy on your Master will allow you to run any Salt command as always, e.g., executing salt \* test.ping and salt-sproxy \* test.ping will have the exact same effect, and result. On top of that, using salt-sproxy allows you to manage other devices for which you don't run (Proxy) Minions for.

Of course, if you don't already have Salt, no problem, you can start managing your devices straight away, check out the quick start steps.

In brief, here are some benefits you can get by using salt-sproxy:

  • Say goodbye to the burden of managing hundreds of system services for the Proxy Minion processes.
  • Reuse your existing extension modules, templates, Pillars, States, etc., you may have already developed in your Salt environment, transparently.
  • You can run it locally, on your own computer.
  • You can use salt-sproxy to uniformly manage network devices, servers (either using regular Minions, or SSH), applications (e.g., Docker containers, VMWare ESXi clusters and vCenters, Marathon or Chronos clusters, etc.), and virtually anything that has a programmable interface.
  • Python programming made a breeze - might go well with the ISalt package.
  • Integrates easily with your existing Salt environment (if you have), by installing the package on your Salt Master.
  • Can continue to leverage the event-driven automation and orchestration methodologies.
  • Can continue using any of the usual targeting mechanisms.
  • REST API, see also the Salt REST API documentation.
  • By sending events to a Salt Master, you are able to implement whatever auditing you need (e.g., what command was executed by who and when, etc.).
  • Benefit from inheriting all the native Salt features and integrations contributed by thousands of users, and tested in hundreds of different environments, over almost a decade of development.

Is salt-sproxy a wrapper around salt-ssh?

No, nothing to do with salt-ssh. The core of salt-sproxy is a Runner loaded dynamically on runtime, that spins up a pool of child processes, each running a temporary light version of the Proxy Minion underneath; as soon as the execution is complete for a device, its associated Proxy Minion is shut down, and another one takes its place into the child processes bucket.

A source of confusion may also be the usage of the Roster interface, which, historically has only been used by salt-ssh, although the Roster is not tightly coupled with salt-ssh: it just happened to be the only use case so far. Essentially, the Roster simply provides a list of devices together with their credentials (e.g., similar to the inventory as dubbed in other automation frameworks) - and now has another use case in salt-sproxy.

Prerequisites

The package is distributed via PyPI, under the name salt-sproxy. If you would like to install it on your computer, you might want to run it under a virtual environment.

Besides the CLI, the usage remains the same as when you're running a Salt environment with Proxy or regular Minions. See the following documents on how to get started and fully unleash the power of Salt:

Install

Install this package where you would like to manage your devices from. In case you need a specific Salt version, make sure you install it beforehand, otherwise this package will bring the latest Salt version available instead.

Execute:

pip install salt-sproxy

To install a specific Salt version, execute, e.g.,

pip install salt==2018.3.4
pip install salt-sproxy

See https://salt-sproxy.readthedocs.io/en/latest/install.html for more installation details.

Documentation

The complete documentation is available at https://salt-sproxy.readthedocs.io/en/latest/.

On Unix distributions you can also check the documentation locally, by executing man salt-sproxy.

Quick Start

See this recording for a live quick start:

In the above, minion1 is a dummy Proxy Minion, that can be used for getting started and make the first steps without connecting to an actual device, but get used to the salt-sproxy methodology.

The Master configuration file is /home/mircea/master, which is why the command is executed using the -c option specifying the path to the directory with the configuration file. In this Master configuration file, the pillar_roots option points to /srv/salt/pillar which is where salt-sproxy is going to load the Pillar data from. Accordingly, the Pillar Top file is under that path, /srv/salt/pillar/top.sls:

base:
  minion1:
    - dummy

This Pillar Top file says that the Minion minion1 will have the Pillar data from the dummy.sls from the same directory, thus /srv/salt/pillar/dummy.sls:

proxy:
  proxytype: dummy

In this case, it was sufficient to only set the proxytype field to dummy.

salt-sproxy can be used in conjunction with any of the available Salt Proxy modules, or others that you might have in your own environment. See https://docs.saltstack.com/en/latest/topics/proxyminion/index.html to understand how to write a new Proxy module if you require.

For example, let's take a look at how we can manage a network device through the NAPALM Proxy:

In the same Python virtual environment as previously, make sure you have NAPALM installed, by executing pip install napalm (see https://napalm.readthedocs.io/en/latest/installation/index.html for further installation requirements, depending on the platform you're running on). The connection credentials for the juniper-router are stored in the /srv/salt/pillar/junos.sls Pillar, and we can go ahead and start executing arbitrary Salt commands, e.g., net.arp to retrieve the ARP table, or net.load_config to apply a configuration change on the router.

The Pillar Top file in this example was (under the same path as previously, as the Master config was the same):

base:
  juniper-router:
    - junos

Usage

First off, make sure you have the Salt Pillar Top file is correctly defined and the proxy key is available into the Pillar. For more in-depth explanation and examples, check this tutorial from the official SaltStack docs.

Once you have that, you can start using salt-sproxy even without any Proxy Minions or Salt Master running. To check, can start by executing:

$ salt-sproxy -L a,b,c --preview-target
- a
- b
- c

The syntax is very similar to the widely used CLI command salt, however the way it works is completely different under the hood:

salt-sproxy <target> <function> [<arguments>]

Usage Example:

$ salt-sproxy cr1.thn.lon test.ping
cr1.thn.lon:
    True

You can continue reading further details at https://salt-sproxy.readthedocs.io/en/latest/, for now, check out the following section to see how to get started with salt-sproxy straight away.

See also https://salt-sproxy.readthedocs.io/en/latest/examples/index.html for more usage examples.

Event-Driven Automation and Orchestration

It is still possible to use the salt-sproxy functionality in the event-driven context, even without running Proxy or regular Minions. To see how to achieve this, see this section of the documentation: https://salt-sproxy.readthedocs.io/en/latest/events.html.

Using the Salt REST API

Salt has natively available an HTTP API. You can read more at https://docs.saltstack.com/en/latest/ref/netapi/all/salt.netapi.rest_cherrypy.html#a-rest-api-for-salt if you haven't used it before. The usage is very simple; for salt-sproxy specifically you can follow the notes from https://salt-sproxy.readthedocs.io/en/latest/salt_sapi.html how to set it up and use. Usage example - apply a small configuration change on a Juniper device, by executing an HTTP request via the Salt API:

$ curl -sS localhost:8080/run -H 'Accept: application/x-yaml' \
  -d eauth='pam' \
  -d username='mircea' \
  -d password='pass' \
  -d client='sproxy' \
  -d tgt='juniper-router' \
  -d fun='net.load_config' \
  -d text='set system ntp server 10.10.10.1'
return:
- juniper-router:
    already_configured: false
    comment: ''
    diff: '[edit system]
      +   ntp {
      +       server 10.10.10.1;
      +   }'
    loaded_config: ''
    result: true

See the documentation for explanation, and this example for a quick start.

What's included

When installing salt-sproxy, besides the core files (i.e., cli.py, parsers.py, scripts.py, and version.py), you will find the following directories and files, which provide additional features and backwards compatibility with older Salt versions:

  |-- cli.py
  |-- parsers.py
  |-- _roster/
  |   |-- ansible.py
  |   |-- file.py
  |   |-- netbox.py
  |   `-- pillar.py
  |-- _runners/
  |   `-- proxy.py
  |-- scripts.py
  `-- version.py

The extension modules under the _roster and _runner directories are documented at https://salt-sproxy.readthedocs.io/en/latest/roster/index.html and https://salt-sproxy.readthedocs.io/en/latest/runners/index.html, respectively.

Docker

A Docker image is available at https://github.com/mirceaulinic/salt-sproxy/pkgs/container/salt-sproxy, and you can pull it, e.g., docker pull ghcr.io/mirceaulinic/salt-sproxy:master. See https://salt-sproxy.readthedocs.io/en/latest/#docker for further usage instructions and examples.

Community

Get updates on the salt-sproxy development, and chat with the project maintainer(s) and community members:

License

This project is licensed under the Apache 2.0 License - see the LICENSE file for details.

Acknowledgments

Thanks to Daniel Wallace for the inspiration.

salt-sproxy's People

Contributors

aeciopires avatar chrishills463 avatar danc86 avatar dependabot-preview[bot] avatar dependabot[bot] avatar dmacvicar avatar eliasp avatar kzorba avatar mirceaulinic avatar network-shark avatar zacho112 avatar zpell82 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

salt-sproxy's Issues

grains targeting issue with ESXI proxy module

I'm experiencing a grains targeting issue with esxi proxy minions.

preview targeting works fine:

[root@server ~]# salt-sproxy -G 'version:5.5.0' --preview-target
- esxi01
- esxi02

however, when I attempt to run an execution module using a grain tgt_type, it results in failure

[root@server ~]# salt-sproxy -G 'version:5.5.0' test.version

I receive the following error output:

jsonschema.exceptions.ValidationError: Additional properties are not allowed ('grains' was unexpected)

it's failing here in /usr/local/lib/python3.6/site-packages/salt/proxy/esxi.py

 proxy_conf = merge(opts.get('proxy', {}), __pillar__.get('proxy', {}))
 log.trace('proxy_conf = %s', proxy_conf)

 try:
     jsonschema.validate(proxy_conf, schema)
 except jsonschema.exceptions.ValidationError as exc:
     raise InvalidConfigError(exc)

The issue is that the schema does not contain a grains key
schema data

OrderedDict([('$schema', 'http://json-schema.org/draft-04/schema#'), ('title', 'Esxi Proxy Schema'), ('description', 'Esxi proxy schema'), ('type', 'object'), ('properties', OrderedDict([('proxytype', {'type': 'string', 'title': 'proxytype', 'enum': ['esxi']}), ('host', {'type': 'string', 'title': 'host', 'pattern': '[^\\s]+'}), ('vcenter', {'type': 'string', 'title': 'vcenter', 'pattern': '[^\\s]+'}), ('esxi_host', {'type': 'string', 'title': 'esxi_host'}), ('username', {'type': 'string', 'title': 'username'}), ('passwords', {'type': 'array', 'title': 'passwords', 'minItems': 1, 'items': {'type': 'string'}, 'uniqueItems': True}), ('mechanism', {'type': 'string', 'title': 'mechanism', 'enum': ['userpass', 'sspi']}), ('domain', {'type': 'string', 'title': 'domain'}), ('principal', {'type': 'string', 'title': 'principal'}), ('protocol', {'type': 'string', 'title': 'protocol'}), ('port', {'type': 'integer', 'title': 'port', 'minimum': 1})])), ('required', ['proxytype']), ('x-ordering', ['proxytype', 'host', 'vcenter', 'esxi_host', 'username', 'passwords', 'mechanism', 'domain', 'principal', 'protocol', 'port']), ('additionalProperties', False)])

however proxy_conf does contain a grains keys, hence the failure as it can't validate the schema against proxy_conf

proxy_conf data

OrderedDict([('proxytype', 'esxi'), ('host', '192.168.0.15'), ('username', 'root'), ('passwords', ['xxx']), ('grains', {'cwd': '/root/devops/sproxy/config', 'ip_gw': True, 'ip4_gw': '192.168.0.1'.....etc})])

I also get the same error if I set a static grain

preview targetting works fine:

[root@server ~]# salt-sproxy -G role:esxi --preview-target
- esxi01
- esxi02

Once I set the static grain role:esxi I can't run any execution modules because of the same error

[root@server ~]# salt-sproxy esxi01 test.version
.....
jsonschema.exceptions.ValidationError: Additional properties are not allowed ('grains' was unexpected)

proxy_conf contains the following info

OrderedDict([('proxytype', 'esxi'), ('host', '10.96.129.6'), ('username', 'root'), ('passwords', ['xxx']), ('grains', OrderedDict([('role', 'esxi')]))])

version info

[root@server ~]# salt-sproxy -V
Salt Version:
           Salt: 3000.3
    Salt SProxy: 2020.3.0
 
Dependency Versions:
        Ansible: Not Installed
           cffi: 1.9.1
       dateutil: 2.4.2
      docker-py: Not Installed
          gitdb: Not Installed
      gitpython: Not Installed
         Jinja2: 2.11.1
     junos-eznc: Not Installed
       jxmlease: 1.0.3
        libgit2: Not Installed
       M2Crypto: 0.35.2
           Mako: Not Installed
   msgpack-pure: Not Installed
 msgpack-python: 0.6.2
         NAPALM: Not Installed
       ncclient: Not Installed
        Netmiko: Not Installed
       paramiko: Not Installed
      pycparser: 2.14
       pycrypto: 2.6.1
   pycryptodome: Not Installed
         pyeapi: Not Installed
         pygit2: Not Installed
       PyNetBox: Not Installed
          PyNSO: Not Installed
         Python: 3.6.8 (default, Apr  2 2020, 13:34:55)
   python-gnupg: Not Installed
         PyYAML: 3.13
          PyZMQ: 14.7.0
            scp: Not Installed
          smmap: Not Installed
        textfsm: Not Installed
        timelib: Not Installed
        Tornado: 4.5.3
            ZMQ: 4.1.4
 
System Versions:
           dist: centos 7.8.2003 Core
         locale: UTF-8
        machine: x86_64
        release: 3.10.0-1127.8.2.el7.x86_64
         system: Linux
        version: CentOS Linux 7.8.2003 Core

Also, nodegroup targeting doesn't work at all, I'll post another issue for that later.

[BUG] NameError: name 'HAS_NETMIKO' is not defined

Hello @mirceaulinic ,

Describe the bug
thanks for your help yesterday in the slack channel. I can now successfully use netmiko.send_command , but I still have no luck running netmiko commands inside an existing napalm session.

salt-sproxy 'myhost' netmiko.send_command 'show version'

successfully return the show version
so netmiko is installed....

Steps To Reproduce
salt-sproxy 'myhost' napalm.netmiko_call send_command 'show version'

Expected behavior
should return output of show version

	Salt Version:                                                    
           Salt: 3000                                            
    Salt SProxy: 2020.3.0                                        
                                                                 
Dependency Versions:                                             
        Ansible: 2.10.5                                          
           cffi: 1.14.0                                          
       dateutil: Not Installed                                   
      docker-py: Not Installed                                   
          gitdb: Not Installed                                   
      gitpython: Not Installed                                   
         Jinja2: 2.11.1                                          
     junos-eznc: 2.2.1                                           
       jxmlease: Not Installed                                   
        libgit2: Not Installed                                   
       M2Crypto: Not Installed                                   
           Mako: Not Installed                                   
   msgpack-pure: Not Installed                                   
 msgpack-python: 0.6.2                                           
         NAPALM: 3.2.0                                           
       ncclient: 0.6.7                                           
        Netmiko: 3.3.2                                           
       paramiko: 2.7.1                                           
      pycparser: 2.19                                            
       pycrypto: 3.9.9                                           
   pycryptodome: Not Installed                                   
         pyeapi: 0.8.3                                           
         pygit2: Not Installed                                   
       PyNetBox: Not Installed                                   
          PyNSO: Not Installed                                   
         Python: 3.7.6 (default, Feb 28 2020, 14:34:05)          
   python-gnupg: Not Installed                                   
         PyYAML: 5.3.1                                           
          PyZMQ: 19.0.0                                          
            scp: 0.13.2                                          
          smmap: Not Installed                                   
        textfsm: 1.1.0                                           
        timelib: Not Installed                                   
        Tornado: 4.5.3                                           
            ZMQ: 4.3.2 

Any help is appriciate

    The minion function caused an exception: Traceback (most recent call last):                                                                
      File "/home/myuser/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages/salt_sproxy/_runners/proxy.py", line 608, in salt_call 
        ret = sa_proxy.functions[function](*args, **kwargs)                                                                                    
      File "/home/myuser/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages/salt/utils/napalm.py", line 480, in func_wrapper       
        ret = func(*args, **kwargs)                                                                                                            
      File "/home/myuser/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages/salt/modules/napalm_mod.py", line 544, in netmiko_call 
        netmiko_kwargs = netmiko_args()                                                                                                        
      File "/home/myuser/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages/salt/utils/napalm.py", line 480, in func_wrapper       
        ret = func(*args, **kwargs)                                                                                                            
      File "/home/myuser/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages/salt/modules/napalm_mod.py", line 446, in netmiko_args 
        if not HAS_NETMIKO:                                                                                                                    
    NameError: name 'HAS_NETMIKO' is not defined                                                                                               

salt-sproxy fails to parse ansible-roster return

Describe the bug
salt-sproxy fails to evaluate targets from ansible roster

Steps To Reproduce
The volumes/config_exchange contains my configs and pillars and get mounted into the container at /mnt. They are externally generated from another container into a shared volume.

docker pull mirceaulinic/salt-sproxy:allinone-2020.7.0
docker run -it -v /var/lib/docker/volumes/config_exchange/_data/salt_napalm:/mnt mirceaulinic/salt-sproxy:allinone-2020.7.0 bash

In the container i simply symlink the configs into place, removing the existing master and roster

cd /etc/salt
rm -vf master roster
ln -s /mnt/etc/salt/master .
ln -s /mnt/etc/salt/roster .

cd /srv
ln -s /mnt/srv/pillar .
ln -s /mnt/srv/salt .

These are all currently empty
/srv/salt/
/srv/salt/ext
/srv/pillar/ext

This is what the environment looks like when executing sproxy commands:

root@b3528bf2e5f8:/etc/salt# cat /etc/salt/master

pillar_roots:
  base:
    - /srv/pillar
    - /srv/pillar/ext

file_roots:
  base:
    - /srv/salt/
    - /srv/salt/ext

proxy_roster: ansible
roster_file: /etc/salt/roster

root@b3528bf2e5f8:/etc/salt# cat /etc/salt/roster
all:
  hosts:
    10.220.0.11:
    10.220.0.12:

The inventory seems to work fine

root@b3528bf2e5f8:/etc/salt# ansible-inventory -i /etc/salt/roster --list
{
    "_meta": {
        "hostvars": {
            "10.220.0.11": {},
            "10.220.0.12": {}
        }
    },
    "all": {
        "children": [
            "ungrouped"
        ]
    },
    "ungrouped": {
        "hosts": [
            "10.220.0.11",
            "10.220.0.12"
        ]
    }
}

Trying to get a preview of the targets

root@b3528bf2e5f8:/etc/salt# salt-sproxy -l debug \* --preview-target
[DEBUG   ] Reading configuration from /etc/salt/master
[DEBUG   ] Missing configuration file: /root/.saltrc
[DEBUG   ] Configuration file path: /etc/salt/master
[WARNING ] Insecure logging configuration detected! Sensitive data may be logged.
[DEBUG   ] Syncing grains
[DEBUG   ] LazyLoaded saltutil.sync_grains
[DEBUG   ] Reading configuration from /etc/salt/master
[DEBUG   ] Guessing ID. The id can be explicitly set in /etc/salt/minion
[DEBUG   ] Found minion id from generate_minion_id(): b3528bf2e5f8
[DEBUG   ] Grains refresh requested. Refreshing grains.
[DEBUG   ] Reading configuration from /etc/salt/master
[DEBUG   ] Unable to derive osmajorrelease from osrelease_info '('proxy',)'. The osmajorrelease grain will not be set.
[DEBUG   ] MasterEvent PUB socket URI: /var/run/salt/master/master_event_pub.ipc
[DEBUG   ] MasterEvent PULL socket URI: /var/run/salt/master/master_event_pull.ipc
[DEBUG   ] Initializing new IPCClient for path: /var/run/salt/master/master_event_pull.ipc
[WARNING ] /usr/local/lib/python3.6/site-packages/salt/transport/ipc.py:292: DeprecationWarning: encoding is deprecated, Use raw=False instead.
  self.unpacker = msgpack.Unpacker(encoding=encoding)

[INFO    ] Creating module dir '/var/cache/salt/master/extmods/grains'
[DEBUG   ] LazyLoaded roots.envs
[DEBUG   ] Could not LazyLoad roots.init: 'roots.init' is not available.
[DEBUG   ] Updating roots fileserver cache
[INFO    ] Syncing grains for environment 'base'
[INFO    ] Loading cache from salt://_grains, for base)
[INFO    ] Caching directory '_grains/' for environment 'base'
[DEBUG   ] Local cache dir: '/var/cache/salt/master/files/base/_grains'
[DEBUG   ] LazyLoaded local_cache.prep_jid
[INFO    ] Runner completed: 20200807113632764881
[DEBUG   ] []
[DEBUG   ] Syncing modules
[DEBUG   ] MasterEvent PUB socket URI: /var/run/salt/master/master_event_pub.ipc
[DEBUG   ] MasterEvent PULL socket URI: /var/run/salt/master/master_event_pull.ipc
[DEBUG   ] Initializing new IPCClient for path: /var/run/salt/master/master_event_pull.ipc
[INFO    ] Creating module dir '/var/cache/salt/master/extmods/modules'
[DEBUG   ] LazyLoaded roots.envs
[DEBUG   ] Could not LazyLoad roots.init: 'roots.init' is not available.
[INFO    ] Syncing modules for environment 'base'
[INFO    ] Loading cache from salt://_modules, for base)
[INFO    ] Caching directory '_modules/' for environment 'base'
[DEBUG   ] Returning file list from cache: age=3 cache_time=20 /var/cache/salt/master/file_lists/roots/base.p
[WARNING ] /usr/local/lib/python3.6/site-packages/salt/payload.py:149: DeprecationWarning: encoding is deprecated, Use raw=False instead.
  ret = msgpack.loads(msg, use_list=True, ext_hook=ext_type_decoder, encoding=encoding)

[DEBUG   ] In saltenv 'base', looking at rel_path '_modules/netbox.py' to resolve 'salt://_modules/netbox.py'
[DEBUG   ] In saltenv 'base', ** considering ** path '/var/cache/salt/master/files/base/_modules/netbox.py' to resolve 'salt://_modules/netbox.py'
[DEBUG   ] Local cache dir: '/var/cache/salt/master/files/base/_modules'
[INFO    ] Runner completed: 20200807113634956892
[DEBUG   ] []
[DEBUG   ] LazyLoaded proxy.execute
[DEBUG   ] Reading configuration from /etc/salt/master
[DEBUG   ] Guessing ID. The id can be explicitly set in /etc/salt/minion
[DEBUG   ] Found minion id from generate_minion_id(): b3528bf2e5f8
[DEBUG   ] Grains refresh requested. Refreshing grains.
[DEBUG   ] Reading configuration from /etc/salt/master
[DEBUG   ] Unable to derive osmajorrelease from osrelease_info '('proxy',)'. The osmajorrelease grain will not be set.
[DEBUG   ] MasterEvent PUB socket URI: /var/run/salt/master/master_event_pub.ipc
[DEBUG   ] MasterEvent PULL socket URI: /var/run/salt/master/master_event_pull.ipc
[DEBUG   ] Initializing new IPCClient for path: /var/run/salt/master/master_event_pull.ipc
[DEBUG   ] Computing the target using the ansible Roster
[DEBUG   ] LazyLoaded ansible.targets
[DEBUG   ] Called salt.cmd runner with minion function cmd.run
[DEBUG   ] Grains refresh requested. Refreshing grains.
[DEBUG   ] Reading configuration from /etc/salt/master
[DEBUG   ] Unable to derive osmajorrelease from osrelease_info '('proxy',)'. The osmajorrelease grain will not be set.
[DEBUG   ] LazyLoaded cmd.run
[INFO    ] Executing command 'ansible-inventory -i /etc/salt/roster --list' in directory '/root'
[DEBUG   ] stdout: {
    "_meta": {
        "hostvars": {
            "10.220.0.11": {},
            "10.220.0.12": {}
        }
    },
    "all": {
        "children": [
            "ungrouped"
        ]
    },
    "ungrouped": {
        "hosts": [
            "10.220.0.11",
            "10.220.0.12"
        ]
    }
}
[DEBUG   ] output: {
    "_meta": {
        "hostvars": {
            "10.220.0.11": {},
            "10.220.0.12": {}
        }
    },
    "all": {
        "children": [
            "ungrouped"
        ]
    },
    "ungrouped": {
        "hosts": [
            "10.220.0.11",
            "10.220.0.12"
        ]
    }
}
[DEBUG   ] LazyLoaded local_cache.prep_jid
[DEBUG   ] LazyLoaded nested.output
Exception occurred in runner proxy.execute: Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/salt/client/mixins.py", line 377, in low
    data['return'] = func(*args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/salt_sproxy/_runners/proxy.py", line 1458, in execute
    rtargets_roster = roster_modules[roster](_tgt, tgt_type=_tgt_type)
  File "/usr/local/lib/python3.6/site-packages/salt/roster/ansible.py", line 121, in targets
    __context__['inventory'] = __utils__['json.loads'](__utils__['stringutils.to_str'](inventory))
  File "/usr/local/lib/python3.6/site-packages/salt/utils/context.py", line 236, in __getitem__
    return self._dict()[key]
KeyError: 'json.loads'
[INFO    ] Runner completed: 20200807113637045024
[DEBUG   ] Runner return: Exception occurred in runner proxy.execute: Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/salt/client/mixins.py", line 377, in low
    data['return'] = func(*args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/salt_sproxy/_runners/proxy.py", line 1458, in execute
    rtargets_roster = roster_modules[roster](_tgt, tgt_type=_tgt_type)
  File "/usr/local/lib/python3.6/site-packages/salt/roster/ansible.py", line 121, in targets
    __context__['inventory'] = __utils__['json.loads'](__utils__['stringutils.to_str'](inventory))
  File "/usr/local/lib/python3.6/site-packages/salt/utils/context.py", line 236, in __getitem__
    return self._dict()[key]
KeyError: 'json.loads'

[DEBUG   ] Closing IPCMessageClient instance
[DEBUG   ] Closing IPCMessageClient instance
[DEBUG   ] Closing IPCMessageClient instance

Expected behavior
A return of all minions / targets defined in roster

$ salt-sproxy \* --preview-target
- 10.220.0.11
- 10.220.0.12

Versions Report
Print the output from salt-sproxy -V inside the backticks below:

Salt Version:
           Salt: 2019.2.0
    Salt SProxy: 2020.7.0

Dependency Versions:
        Ansible: 2.8.1
           cffi: 1.14.0
       dateutil: Not Installed
      docker-py: Not Installed
          gitdb: Not Installed
      gitpython: Not Installed
         Jinja2: 2.11.2
     junos-eznc: 0+unknown
       jxmlease: 1.0.1
        libgit2: Not Installed
       M2Crypto: Not Installed
           Mako: Not Installed
   msgpack-pure: Not Installed
 msgpack-python: 0.6.2
         NAPALM: 3.1.0
       ncclient: 0.6.7
        Netmiko: 3.1.1
       paramiko: 2.7.1
      pycparser: 2.20
       pycrypto: 2.6.1
   pycryptodome: Not Installed
         pyeapi: 0.8.3
         pygit2: Not Installed
       PyNetBox: 4.0.6
          PyNSO: Not Installed
         Python: 3.6.11 (default, Jun 30 2020, 19:44:32)
   python-gnupg: Not Installed
         PyYAML: 5.3.1
          PyZMQ: 19.0.1
            scp: 0.13.2
          smmap: Not Installed
        textfsm: 1.1.0
        timelib: Not Installed
        Tornado: 4.5.3
            ZMQ: 4.3.2

System Versions:
           dist: debian 9.12
         locale: UTF-8
        machine: x86_64
        release: 4.19.0-9-amd64
         system: Linux
        version: debian 9.12

Additional context
i tried the -dev version "mirceaulinic/salt-sproxy:allinone-dev" as well, same problem.

If i can be of any more help, please let me know.

Salt 3003.1 KeyError __runner__

Good Morning @mirceaulinic ,

the latest salt updated briked salt sproxy again. If you need more logs. No problem.

Describe the bug
Salt sproxy does not run with latest salt version 3003.1

Steps To Reproduce
Create a virtual env with salt3003.1 and salt-sproxy

pip install netmiko napalm

Expected behavior
It should work :)

Versions Report
Print the output from salt-sproxy -V inside the backticks below:

Salt Version:
           Salt: 3003.1
    Salt SProxy: 2021.6.0

Dependency Versions:
        Ansible: Not Installed
           cffi: 1.14.5
       dateutil: Not Installed
      docker-py: Not Installed
          gitdb: Not Installed
      gitpython: Not Installed
         Jinja2: 3.0.1
     junos-eznc: 2.6.1
       jxmlease: Not Installed
        libgit2: Not Installed
       M2Crypto: Not Installed
           Mako: Not Installed
   msgpack-pure: Not Installed
 msgpack-python: 1.0.2
         NAPALM: 3.3.1
       ncclient: 0.6.12
        Netmiko: 3.4.0
       paramiko: 2.7.2
      pycparser: 2.20
       pycrypto: Not Installed
   pycryptodome: 3.10.1
         pyeapi: 0.8.4
         pygit2: Not Installed
       PyNetBox: Not Installed
          PyNSO: Not Installed
         Python: 3.7.6 (default, Feb 28 2020, 14:34:05)
   python-gnupg: Not Installed
         PyYAML: 5.4.1
          PyZMQ: 22.1.0
            scp: 0.13.5
          smmap: Not Installed
        textfsm: 1.1.2
        timelib: Not Installed
        Tornado: 4.5.3
            ZMQ: 4.3.4
Package               Version
--------------------- ---------
bcrypt                3.2.0
certifi               2021.5.30
cffi                  1.14.5
chardet               4.0.0
ciscoconfparse        1.5.30
colorama              0.4.4
contextvars           2.4
cryptography          3.4.7
distro                1.5.0
dnspython             2.1.0
future                0.18.2
idna                  2.10
immutables            0.15
Jinja2                3.0.1
junos-eznc            2.6.1
lxml                  4.6.3
MarkupSafe            2.0.1
msgpack               1.0.2
napalm                3.3.1
ncclient              0.6.12
netaddr               0.8.0
netmiko               3.4.0
ntc-templates         2.1.0
paramiko              2.7.2
passlib               1.7.4
pip                   19.2.3
progressbar2          3.53.1
pycparser             2.20
pycryptodomex         3.10.1
pyeapi                0.8.4
PyNaCl                1.4.0
pyparsing             2.4.7
pyserial              3.5
python-utils          2.5.6
PyYAML                5.4.1
pyzmq                 22.1.0
requests              2.25.1
salt                  3003.1
salt-sproxy           2021.6.0
scp                   0.13.5
setuptools            41.2.0
six                   1.16.0
tenacity              7.0.0
textfsm               1.1.2
transitions           0.8.8
urllib3               1.26.6
yamlordereddictloader 0.4.0

Traceback

Exception occurred in runner proxy.execute: Traceback (most recent call last):
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/client/mixins.py", line 390, in low
    data["return"] = func(*args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 1241, in __call__
    return self.loader.run(run_func, *args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 2274, in run
    return self._last_context.run(self._run_as, _func_or_method, *args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 2289, in _run_as
    return _func_or_method(*args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages/salt_sproxy/_runners/proxy.py", line 1447, in execute
    rtargets_roster = roster_modules[roster](_tgt, tgt_type=_tgt_type)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 1241, in __call__
    return self.loader.run(run_func, *args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 2274, in run
    return self._last_context.run(self._run_as, _func_or_method, *args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 2289, in _run_as
    return _func_or_method(*args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt_sproxy/_roster/file.py", line 40, in targets
    **kwargs
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/template.py", line 99, in compile_template
    ret = render(input_data, saltenv, sls, **render_kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 1241, in __call__
    return self.loader.run(run_func, *args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 2274, in run
    return self._last_context.run(self._run_as, _func_or_method, *args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 2289, in _run_as
    return _func_or_method(*args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/renderers/jinja.py", line 79, in render
    tmp_data.get("data", "Unknown render error in jinja renderer")
salt.exceptions.SaltRenderError: Traceback (most recent call last):
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/utils/templates.py", line 262, in render_tmpl
    output = render_str(tmplstr, context, tmplpath)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/utils/templates.py", line 482, in render_jinja_tmpl
    decoded_context[key] = value.value()
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader_context.py", line 72, in value
    return loader.pack[self.name]
KeyError: '__runner__'

Question: salt-sproxy support returners ?

Hello @mirceaulinic ,

does salt-sproxy support using --return mycustom returner ?

I'm trying to use net.cli inside my returner , but from the logs I think the connection is already lost and then the execution of the command fails.

[DEBUG   ] read_channel:
[DEBUG   ] read_channel:
[DEBUG   ] write_channel: b'exit\n'
[DEBUG   ] LazyLoaded one_liner.returner
[ERROR   ] Cannot execute "cli" on mydevice as myuser. Reason: 'NoneType' object has no attribute 'send_command'!
[ERROR   ] Traceback (most recent call last):
  File "/home/myuser/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages/salt/utils/napalm.py", line 178, in call
    out = getattr(napalm_device.get('DRIVER'), method)(*args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages/napalm/ios/ios.py", line 2363, in cli
    output = self._send_command(command)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages/napalm/ios/ios.py", line 205, in _send_command
    output = self.device.send_command(command)
AttributeError: 'NoneType' object has no attribute 'send_command'

Question: unexpected kwargs in netmiko ConnectionHandler.

Hello again. Question regarding kwargs used in the netmiko_px proxy-module.

proxy_dict = opts.get('proxy', {})
...
log.info(netmiko_connection_args)

This causes grains data, as well as pillar data, to be loaded, and i'm not sure why.

[INFO ] {'device_type': 'huawei_vrpv8', 'host': 'salt-dummy', 'username': 'huawei', 'password': 'huawei', 'grains': {'salt': {'role': 'proxy'}, 'netbox': {'id': 1, 'name': 'ti430940400e460', 'display_name': 'ti430940400e460', 'device_type': {'id': 1, 'manufacturer': {'id': 1, 'name': 'Huawei', 'slug': 'huawei'}, 'model': 'Quidway S5352C-EI', 'slug': 'quidway-s5352c-ei', 'display_name': 'Huawei Quidway
S5352C-EI'}, 'device_role': {'id': 1, 'name': 'Aggregation', 'slug': 'aggregation'}, 'tenant': None, 'platform': None, 'serial': '12325123123', 'asset_tag': None, 'site': {'id': 1, 'name': 'testsite1', 'slug': 'testsite1'}, 'rack': None, 'position': None, 'face': None, 'parent_device': None, 'status': {'value': 'active', 'label': 'Active', 'id': 1}, 'primary_ip': {'id': 6, 'family': 4, 'address': '172.29.0.3/16'}, 'primary_ip4': {'id': 6, 'family': 4, 'address': '172.29.0.3/16'}, 'primary_ip6': None, 'cluster': None, 'virtual_chassis': None, 'vc_position': None, 'vc_priority': None, 'comments': '', 'local_context_data': None, 'tags': [], 'custom_fields': {}, 'config_context': {}, 'created': '2020-04-08', 'last_updated': '2020-04-14T19:55:33.893383Z'}}}

Process ti430940400e460:
Traceback (most recent call last):
File "/usr/local/lib/python3.7/multiprocessing/process.py", line 297, in _bootstrap
self.run()
File "/usr/local/lib/python3.7/multiprocessing/process.py", line 99, in run
**opts
File "/usr/local/lib/python3.7/site-packages/salt_sproxy/_runners/proxy.py", line 593, in salt_call
sa_proxy = StandaloneProxy(opts, unreachable_devices)
File "/usr/local/lib/python3.7/site-packages/salt_sproxy/_runners/proxy.py", line 425, in init
self.gen_modules()
File "/usr/local/lib/python3.7/site-packages/salt_sproxy/_runners/proxy.py", line 362, in gen_modules
proxy_init_fn(self.opts)
File "/usr/local/lib/python3.7/site-packages/salt/proxy/netmiko_px.py", line 245, in init
connection = ConnectHandler(**netmiko_connection_args)
File "/usr/local/lib/python3.7/site-packages/netmiko/ssh_dispatcher.py", line 246, in ConnectHandler
return ConnectionClass(*args, **kwargs)
TypeError: init() got an unexpected keyword argument 'grains'
ERROR: Minions returned with non-zero exit code

Modifying the netmiko_px, pop'ing the grains from the kwargs fixes the problem for me:

/ # salt-sproxy '*' netmiko.send_command "display lldp neighbor" use_textfsm=True --timeout 10
ti430940400e460:
|_
----------
capabilities:
bridge router
chassis_id:
04f9-3885-2840
local_interface:
XGigabitEthernet0/1/1
...

Is this due to some faulty configuration or arguments on my part?

Question: netbox.create_interface issue.

Don't know if this is more of an issue for the original salt-module, but since i'm using your sproxy-version of it:

The 'create_interface' function seem to missing a required argument. Netbox seem to have implemented interface 'type' as a required field. I reckon this module was implemented for an earlier version of Netbox.

salt-minion:
    The minion function caused an exception: Traceback (most recent call last):
      File "/var/cache/salt/minion/extmods/modules/netbox.py", line 110, in _add
        return getattr(getattr(nb, app), endpoint).create(**payload)
      File "/usr/local/lib/python3.7/site-packages/pynetbox/core/endpoint.py", line 287, in create
        ).post(args[0] if args else kwargs)
      File "/usr/local/lib/python3.7/site-packages/pynetbox/core/query.py", line 381, in post
        return self._make_call(verb="post", data=data)
      File "/usr/local/lib/python3.7/site-packages/pynetbox/core/query.py", line 274, in _make_call
        raise RequestError(req)
    pynetbox.core.query.RequestError: The request failed with code 400 Bad Request: {'type': ['This field is required.']}

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
      File "/usr/local/lib/python3.7/site-packages/salt/minion.py", line 1675, in _thread_return
        return_data = minion_instance.executors[fname](opts, data, func, args, kwargs)
      File "/usr/local/lib/python3.7/site-packages/salt/executors/direct_call.py", line 12, in execute
        return func(*args, **kwargs)
      File "/var/cache/salt/minion/extmods/modules/netbox_init.py", line 29, in load_devices
        __salt__['netbox.create_interface']('ti430940400e460', 'eth0')
      File "/var/cache/salt/minion/extmods/modules/netbox.py", line 775, in create_interface
        nb_interface = _add('dcim', 'interfaces', payload)
      File "/var/cache/salt/minion/extmods/modules/netbox.py", line 111, in _add
        except RequestError as e:  # pylint: disable=undefined-variable
    NameError: name 'RequestError' is not defined

Adding type to the payload, 'type: virtual', resolves the issue.

Cannot run state.apply with sproxy, returns "KeyError: '__opts__'"

Describe the bug

[root@iad1-saltlab-master-01 ~]# salt-sproxy fra2-sw-10 state.apply juniper.common.snmpv3

returns a KeyError with the latest version of sproxy.

fra2-sw-10:
    The minion function caused an exception: Traceback (most recent call last):
      File "/usr/local/lib/python3.6/site-packages/salt_sproxy/_runners/proxy.py", line 660, in salt_call
        ret = sa_proxy.functions[salt_function](*args, **kwargs)
      File "/usr/lib/python3.6/site-packages/salt/loader.py", line 1241, in __call__
        return self.loader.run(run_func, *args, **kwargs)
      File "/usr/lib/python3.6/site-packages/salt/loader.py", line 2274, in run
        return self._last_context.run(self._run_as, _func_or_method, *args, **kwargs)
      File "/usr/lib/python3.6/site-packages/contextvars/__init__.py", line 38, in run
        return callable(*args, **kwargs)
      File "/usr/lib/python3.6/site-packages/salt/loader.py", line 2289, in _run_as
        return _func_or_method(*args, **kwargs)
      File "/usr/lib/python3.6/site-packages/salt/modules/state.py", line 792, in apply_
        return sls(mods, **kwargs)
      File "/usr/lib/python3.6/site-packages/salt/modules/state.py", line 1391, in sls
        ret = st_.state.call_high(high_, orchestration_jid)
      File "/usr/lib/python3.6/site-packages/salt/state.py", line 3269, in call_high
        ret = self.call_chunks(chunks)
      File "/usr/lib/python3.6/site-packages/salt/state.py", line 2495, in call_chunks
        running = self.call_chunk(low, running, chunks)
      File "/usr/lib/python3.6/site-packages/salt/state.py", line 2856, in call_chunk
        low = self._mod_aggregate(low, running, chunks)
      File "/usr/lib/python3.6/site-packages/salt/state.py", line 852, in _mod_aggregate
        agg_opt = self.functions["config.option"]("state_aggregate")
      File "/usr/lib/python3.6/site-packages/salt/loader.py", line 1241, in __call__
        return self.loader.run(run_func, *args, **kwargs)
      File "/usr/lib/python3.6/site-packages/salt/loader.py", line 2274, in run
        return self._last_context.run(self._run_as, _func_or_method, *args, **kwargs)
      File "/usr/lib/python3.6/site-packages/contextvars/__init__.py", line 38, in run
        return callable(*args, **kwargs)
      File "/usr/lib/python3.6/site-packages/salt/loader.py", line 2289, in _run_as
        return _func_or_method(*args, **kwargs)
      File "/usr/lib/python3.6/site-packages/salt/modules/config.py", line 208, in option
        if value in __opts__:
      File "/usr/lib/python3.6/site-packages/salt/loader_context.py", line 81, in __contains__
        return item in self.value()
      File "/usr/lib/python3.6/site-packages/salt/loader_context.py", line 72, in value
        return loader.pack[self.name]
    KeyError: '__opts__'
ERROR: Minions returned with non-zero exit code

Steps To Reproduce
/srv/pillar/top.sls:

base:
  '*':
    - linux.iad1-saltlab-master-01.sproxy
  fra2-sw-10:
    - juniper.common.snmpv3

/srv/pillar/linux/iad1-saltlab-master-01/sproxy.sls:

proxy:
  proxytype: napalm
  username: <deleted>
  host: {{ opts.id }}
  multiprocessing: False
  always_alive: False
  optional_args:
    key_file: <deleted>

/srv/salt/top.sls:

base:
  fra2-sw-10:
    - juniper.common.snmpv3

/srv/salt/juniper/common/snmpv3.sls:

configure_snmpv3:
  netconfig.managed:
    - template_name: salt://juniper/templates/snmpv3.j2
    - replace: False
    - debug: True
    - test: True

If needed I can paste the jinja and static pillar, but they're working fine as I'm able to apply the same if it's running on a salt-proxy instead.

For roster I'm using a file:
/etc/salt/master.d/01-sproxy.conf:

roster: file
roster_file: /etc/salt/sproxy-devices.yaml

/etc/salt/sproxy-devices.yaml:

fra2-sw-10:
  driver: junos
  host: <deleted>

Expected behavior
It should work. :)

Versions Report
Print the output from salt-sproxy -V inside the backticks below:

Salt Version:
           Salt: 3003.3
    Salt SProxy: 2021.6.1
 
Dependency Versions:
        Ansible: Not Installed
           cffi: 1.14.5
       dateutil: 2.6.1
      docker-py: Not Installed
          gitdb: Not Installed
      gitpython: Not Installed
         Jinja2: 2.11.3
     junos-eznc: 2.5.4
       jxmlease: 1.0.3
        libgit2: Not Installed
       M2Crypto: 0.35.2
           Mako: Not Installed
   msgpack-pure: Not Installed
 msgpack-python: 0.6.2
         NAPALM: 3.2.0
       ncclient: 0.6.10
        Netmiko: 3.3.3
       paramiko: 2.7.2
      pycparser: 2.20
       pycrypto: Not Installed
   pycryptodome: Not Installed
         pyeapi: 0.8.4
         pygit2: Not Installed
       PyNetBox: Not Installed
          PyNSO: Not Installed
         Python: 3.6.8 (default, Mar 19 2021, 05:13:41)
   python-gnupg: Not Installed
         PyYAML: 5.4.1
          PyZMQ: 19.0.0
            scp: 0.13.3
          smmap: Not Installed
        textfsm: 1.1.0
        timelib: Not Installed
        Tornado: 4.5.3
            ZMQ: 4.3.4
 
System Versions:
           dist: centos 8 
         locale: UTF-8
        machine: x86_64
        release: 4.18.0-240.15.1.el8_3.x86_64
         system: Linux
        version: CentOS Linux 8

Additional context
I can run commands via the sproxy to the remote system.
For example:
salt-sproxy -l debug fra2-sw-10 net.cli "show version"
is working properly so it's not an issue with the connectivity.

salt-sapi Runner Always Returns "Please specify a Salt function to execute."

Describe the bug
Executing a simple test.ping from salt-sapi always returns "Please specify a Salt function to execute." when executing via the examples provided at https://salt-sproxy.readthedocs.io/en/latest/salt_api.html

Steps To Reproduce
General -

Master config:

external_auth:
  pam:
    '*':
      - '.*'
      - '@runner'
      - '@wheel'
      - '@jobs'

pillar_roots:
  base:
    - /srv/salt/pillar

file_roots:
  base:
  - /srv/salt/
  - /usr/local/lib/python3.6/site-packages/salt_sproxy

runner_dirs:
- /usr/local/lib/python3.6/site-packages/salt_sproxy/_runners

roster: netbox
netbox:
  url: http://localhost:8000
  token: [snip]

rest_cherrypy:
  port: 8080
  disable_ssl: True

top.sls

base:
  'lach-lab':
    - nxapi-test

nxapi-test.sls

proxy:
  proxytype: napalm
  driver: nxos
  username: admin
  password: ''
  host: {{opts.id}}
  optional_args:
    port: 20000

Execute a POST with the payload as follows:

{
    "eauth": "pam",
    "username": "lach",
    "password": "examplepassword",
    "client": "sproxy", 
    "fun": "test.ping", 
    "tgt": "lach-lab"
}

Result

[root@SYD-SALT ~]#  salt-run state.event pretty=True
salt/run/20201029112247657037/new       {
    "_stamp": "2020-10-29T11:22:48.383437",
    "fun": "runner.proxy.execute",
    "fun_args": [
        {
            "failhard": false,
            "function": "test.ping",
            "roster": "netbox",
            "show_jid": false,
            "static": true,
            "tgt": "lach-lab",
            "tgt_type": "glob"
        }
    ],
    "jid": "20201029112247657037",
    "user": "lach"
}
salt/run/20201029112247657037/ret       {
    "_stamp": "2020-10-29T11:22:48.639441",
    "fun": "runner.proxy.execute",
    "fun_args": [
        {
            "failhard": false,
            "function": "test.ping",
            "roster": "netbox",
            "show_jid": false,
            "static": true,
            "tgt": "lach-lab",
            "tgt_type": "glob"
        }
    ],
    "jid": "20201029112247657037",
    "return": "Please specify a Salt function to execute.",
    "success": true,
    "user": "lach"
}

salt-sapi debug:

[DEBUG   ] New kwargs:
[DEBUG   ] {'eauth': 'pam', 'username': 'lach', 'password': 'examplepassword', 'client': 'sproxy', 'function': 'test.ping', 'tgt': 'lach-lab', 'tgt_type': 'glob', 'static': True, 'roster': 'netbox', 'show_jid': False, 'failhard': False}
[DEBUG   ] LazyLoaded proxy.execute
[DEBUG   ] MasterEvent PUB socket URI: /var/run/salt/master/master_event_pub.ipc
[DEBUG   ] MasterEvent PULL socket URI: /var/run/salt/master/master_event_pull.ipc
[DEBUG   ] Initializing new AsyncZeroMQReqChannel for ('/etc/salt/pki/master', 'SYD-SALT_master', 'tcp://127.0.0.1:4506', 'clear')
[DEBUG   ] Connecting the Minion to the Master URI (for the return server): tcp://127.0.0.1:4506
[DEBUG   ] Trying to connect to: tcp://127.0.0.1:4506
[DEBUG   ] Closing AsyncZeroMQReqChannel instance
[DEBUG   ] Closing IPCMessageSubscriber instance
[INFO    ] 172.30.69.13 - - [29/Oct/2020:07:22:48] "POST /run HTTP/1.1" 200 58 "" ""

Expected behavior
A response similar to when executing the same function via the CLI.

salt/run/20201029112618391026/ret       {
    "_stamp": "2020-10-29T11:26:23.945759",
    "fun": "runner.proxy.execute",
    "fun_args": [
        "lach-lab",
        "test.ping",
        {
            "args": [],
            "batch_size": 4,
            "batch_wait": 0,
            "default_grains": {},
...
            "tgt_type": "glob",
            "timeout": 60,
            "use_existing_proxy": false,
            "verbose": false
        }
    ],
    "jid": "20201029112618391026",
    "return": "",
    "success": true,
    "user": "lach"
}

Versions Report
Print the output from salt-sproxy -V inside the backticks below:

[root@SYD-SALT _runners]# salt-sproxy -V
Salt Version:
           Salt: 3002
    Salt SProxy: 2020.10.0

Dependency Versions:
        Ansible: Not Installed
           cffi: 1.14.3
       dateutil: 2.6.1
      docker-py: Not Installed
          gitdb: Not Installed
      gitpython: Not Installed
         Jinja2: 2.10.1
     junos-eznc: 2.5.3
       jxmlease: Not Installed
        libgit2: Not Installed
       M2Crypto: 0.35.2
           Mako: Not Installed
   msgpack-pure: Not Installed
 msgpack-python: 0.6.2
         NAPALM: 3.2.0
       ncclient: 0.6.9
        Netmiko: 3.3.2
       paramiko: 2.7.2
      pycparser: 2.20
       pycrypto: Not Installed
   pycryptodome: Not Installed
         pyeapi: 0.8.3
         pygit2: Not Installed
       PyNetBox: 5.1.0
          PyNSO: Not Installed
         Python: 3.6.8 (default, Apr 16 2020, 01:36:27)
   python-gnupg: Not Installed
         PyYAML: 3.12
          PyZMQ: 19.0.0
            scp: 0.13.3
          smmap: Not Installed
        textfsm: 1.1.0
        timelib: Not Installed
        Tornado: 4.5.3
            ZMQ: 4.3.3

System Versions:
           dist: centos 8 Core
         locale: UTF-8
        machine: x86_64
        release: 4.18.0-193.19.1.el8_2.x86_64
         system: Linux
        version: CentOS Linux 8 Core

Additional context
I've tried setting up an environment from scratch to see if I'm missing something, or if the version of Python3 makes any difference, however no such luck. It seems the variablesalt_function in salt_sproxy/_runners/proxy.py always evaluates to False in my case. Executing salt-sproxy '*' test.ping from the CLI works fine for any number of my test devices. I hope I'm just missing something obvious :-)

Salt 3003.1 KeyError __runner__ again

@mirceaulinic Hey I'm really sorry I just tested your fix with a simple

 salt-sproxy --sync-modules -c . 'router10' net.arp 
 salt-sproxy --sync-modules -c . 'router10' net.cli 'show version'

, which works, but if I ran a custom module I still receive errors.

Exception occurred in runner proxy.execute: Traceback (most recent call last):
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/client/mixins.py", line 390, in low
    data["return"] = func(*args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 1241, in __call__
    return self.loader.run(run_func, *args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 2274, in run
    return self._last_context.run(self._run_as, _func_or_method, *args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 2289, in _run_as
    return _func_or_method(*args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages/salt_sproxy/_runners/proxy.py", line 1447, in execute
    rtargets_roster = roster_modules[roster](_tgt, tgt_type=_tgt_type)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 1241, in __call__
    return self.loader.run(run_func, *args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 2274, in run
    return self._last_context.run(self._run_as, _func_or_method, *args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 2289, in _run_as
    return _func_or_method(*args, **kwargs)
  File "/home/myuser/python/salt-sproxy/var/cache/salt/master/extmods/roster/file.py", line 40, in targets
    **kwargs
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/template.py", line 99, in compile_template
    ret = render(input_data, saltenv, sls, **render_kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 1241, in __call__
    return self.loader.run(run_func, *args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 2274, in run
    return self._last_context.run(self._run_as, _func_or_method, *args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 2289, in _run_as
    return _func_or_method(*args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/renderers/jinja.py", line 79, in render
    tmp_data.get("data", "Unknown render error in jinja renderer")
salt.exceptions.SaltRenderError: Traceback (most recent call last):
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/utils/templates.py", line 262, in render_tmpl
    output = render_str(tmplstr, context, tmplpath)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/utils/templates.py", line 482, in render_jinja_tmpl
    decoded_context[key] = value.value()
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader_context.py", line 72, in value
    return loader.pack[self.name]
KeyError: '__runner__'



[INFO    ] Runner completed: 20210702104558268378
[DEBUG   ] Runner return: Exception occurred in runner proxy.execute: Traceback (most recent call last):
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/client/mixins.py", line 390, in low
    data["return"] = func(*args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 1241, in __call__
    return self.loader.run(run_func, *args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 2274, in run
    return self._last_context.run(self._run_as, _func_or_method, *args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 2289, in _run_as
    return _func_or_method(*args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages/salt_sproxy/_runners/proxy.py", line 1447, in execute
    rtargets_roster = roster_modules[roster](_tgt, tgt_type=_tgt_type)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 1241, in __call__
    return self.loader.run(run_func, *args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 2274, in run
    return self._last_context.run(self._run_as, _func_or_method, *args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 2289, in _run_as
    return _func_or_method(*args, **kwargs)
  File "/home/myuser/python/salt-sproxy/var/cache/salt/master/extmods/roster/file.py", line 40, in targets
    **kwargs
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/template.py", line 99, in compile_template
    ret = render(input_data, saltenv, sls, **render_kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 1241, in __call__
    return self.loader.run(run_func, *args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 2274, in run
    return self._last_context.run(self._run_as, _func_or_method, *args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 2289, in _run_as
    return _func_or_method(*args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/renderers/jinja.py", line 79, in render
    tmp_data.get("data", "Unknown render error in jinja renderer")
salt.exceptions.SaltRenderError: Traceback (most recent call last):
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/utils/templates.py", line 262, in render_tmpl
    output = render_str(tmplstr, context, tmplpath)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/utils/templates.py", line 482, in render_jinja_tmpl
    decoded_context[key] = value.value()
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader_context.py", line 72, in value
    return loader.pack[self.name]
KeyError: '__runner__'

running salt-sproxy --sync-all -c . 'router01' net.facts

(3.7.6/envs/salt3003-1) myuser@XXXX:~/python/salt-sproxy/etc/salt% salt-sproxy --sync-all -c . 'router09' net.facts
Exception occurred in runner proxy.execute: Traceback (most recent call last):
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/client/mixins.py", line 390, in low
    data["return"] = func(*args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 1241, in __call__
    return self.loader.run(run_func, *args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 2274, in run
    return self._last_context.run(self._run_as, _func_or_method, *args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 2289, in _run_as
    return _func_or_method(*args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/py376/lib/python3.7/site-packages/salt_sproxy/_runners/proxy.py", line 1447, in execute
    rtargets_roster = roster_modules[roster](_tgt, tgt_type=_tgt_type)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 1241, in __call__
    return self.loader.run(run_func, *args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 2274, in run
    return self._last_context.run(self._run_as, _func_or_method, *args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 2289, in _run_as
    return _func_or_method(*args, **kwargs)
  File "/home/myuser/python/salt-sproxy/var/cache/salt/master/extmods/roster/file.py", line 40, in targets
    **kwargs
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/template.py", line 99, in compile_template
    ret = render(input_data, saltenv, sls, **render_kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 1241, in __call__
    return self.loader.run(run_func, *args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 2274, in run
    return self._last_context.run(self._run_as, _func_or_method, *args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader.py", line 2289, in _run_as
    return _func_or_method(*args, **kwargs)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/renderers/jinja.py", line 79, in render
    tmp_data.get("data", "Unknown render error in jinja renderer")
salt.exceptions.SaltRenderError: Traceback (most recent call last):
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/utils/templates.py", line 262, in render_tmpl
    output = render_str(tmplstr, context, tmplpath)
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/utils/templates.py", line 482, in render_jinja_tmpl
    decoded_context[key] = value.value()
  File "/home/myuser/.pyenv/versions/3.7.6/envs/salt3003-1/lib/python3.7/site-packages/salt/loader_context.py", line 72, in value
    return loader.pack[self.name]
KeyError: '__runner__'

target_cache default value.

Describe the bug
proxy-runner 'target_cache' has default value 'False' while docs say 'True'.

Which is the intended default?

Expected behavior
I guess it should be on by default?

Versions Report

Salt Version:
           Salt: 3001.7
    Salt SProxy: 2021.6.1

Dependency Versions:
        Ansible: Not Installed
           cffi: 1.14.6
       dateutil: 2.8.2
      docker-py: Not Installed
          gitdb: Not Installed
      gitpython: Not Installed
         Jinja2: 3.0.1
     junos-eznc: 2.6.3
       jxmlease: Not Installed
        libgit2: Not Installed
       M2Crypto: Not Installed
           Mako: Not Installed
   msgpack-pure: Not Installed
 msgpack-python: 1.0.2
         NAPALM: 3.2.0
       ncclient: 0.6.9
        Netmiko: 3.4.0
       paramiko: 2.8.0
      pycparser: 2.20
       pycrypto: Not Installed
   pycryptodome: 3.10.1
         pyeapi: 0.8.4
         pygit2: Not Installed
       PyNetBox: 6.1.3
          PyNSO: Not Installed
         Python: 3.7.10 (default, Apr 15 2021, 05:35:41)
   python-gnupg: Not Installed
         PyYAML: 5.4.1
          PyZMQ: 19.0.2
            scp: 0.14.1
          smmap: Not Installed
        textfsm: 1.1.0
        timelib: Not Installed
        Tornado: 4.5.3
            ZMQ: 4.3.2

System Versions:
           dist: alpine 3.12.7
         locale: UTF-8
        machine: x86_64
        release: 4.18.0-147.5.1.el8_1.x86_64
         system: Linux
        version: Alpine Linux 3.12.7

Additional context
Took me a bit too long to figure out why my netbox-instance was asked at all times.

targetting cached pillar data doesn't appear to be working.

Describe the bug
Targetting using cached pillar isn't working
Have populated cache, and can see relevant files in /var/cache/salt/master/minions/various/data/pillar.p
Attempting to target using -I 'thepillar:thing' isn't findint it.

Versions Report
Print the output from salt-sproxy -V inside the backticks below:

Salt Version:
           Salt: 3001
    Salt SProxy: 2020.3.0

Dependency Versions:
        Ansible: Not Installed
           cffi: 1.14.0
       dateutil: 2.6.1
      docker-py: Not Installed
          gitdb: 2.0.3
      gitpython: 2.1.8
         Jinja2: 2.11.2
     junos-eznc: 0+unknown
       jxmlease: 1.0.3
        libgit2: Not Installed
       M2Crypto: Not Installed
           Mako: Not Installed
   msgpack-pure: Not Installed
 msgpack-python: 0.5.6
         NAPALM: 3.0.1
       ncclient: 0.6.7
        Netmiko: 3.1.1
       paramiko: 2.7.1
      pycparser: 2.20
       pycrypto: Not Installed
   pycryptodome: 3.9.8
         pyeapi: 0.8.3
         pygit2: Not Installed
       PyNetBox: Not Installed
          PyNSO: Not Installed
         Python: 3.6.9 (default, Apr 18 2020, 01:56:04)
   python-gnupg: 0.4.1
         PyYAML: 5.3.1
          PyZMQ: 17.1.2
            scp: 0.13.2
          smmap: 2.0.3
        textfsm: 1.1.0
        timelib: Not Installed
        Tornado: 4.5.3
            ZMQ: 4.2.5

System Versions:
           dist: ubuntu 18.04 Bionic Beaver
         locale: UTF-8
        machine: x86_64
        release: 5.3.0-62-generic
         system: Linux
        version: Ubuntu 18.04 Bionic Beaver

Additional context
salt-sproxy patched with https://github.com/mirceaulinic/salt-sproxy/commit/a274ca009a139420858b68df733a5c2c859f534d.diff

Similar to that fix, cache.fetch minions/what data is empty, whereas cache.fetch minions/what/data pillar is populated.

/var/cache/salt/master/minions/j-host1.aaaaaaaaaa/data looks to contain binary data, which looks like this, and I can see the pillar I'm aiming for within it.

<82>¥proxy<85>©proxytype¥junos¤host®host1.aaaaaaaaa¤port^V¨password¯foopassword¤user¤foouser¥roles<91>­j-anycastpeer```

salt-sproxy works with 3004

Describe the bug
Can't run salt-sproxy

Steps To Reproduce
salt-sproxy -c . -L 'csr1000v' net.cli 'show version'

Expected behavior
Command should return show version

Error

[INFO    ] Runner completed: 20220310220153300412
[DEBUG   ] []
[DEBUG   ] Using importlib_metadata to load entry points
[DEBUG   ] LazyLoaded proxy.execute
[DEBUG   ] Reading configuration from /home/sharky/salt/etc/salt/master
[DEBUG   ] Guessing ID. The id can be explicitly set in /etc/salt/minion
[DEBUG   ] Found minion id from generate_minion_id(): debian-dev.home.lan
[DEBUG   ] Grains refresh requested. Refreshing grains.
[DEBUG   ] Reading configuration from /home/sharky/salt/etc/salt/master
[DEBUG   ] Override  __utils__: <module 'salt.loaded.int.grains.zfs' from '/home/sharky/venv/salt/lib/python3.9/site-packages/salt/grains/zfs.py'>
[DEBUG   ] /etc/resolv.conf: The domain and search keywords are mutually exclusive.
[DEBUG   ] Unable to derive osmajorrelease from osrelease_info '('proxy',)'. The osmajorrelease grain will not be set.
[DEBUG   ] Closing IPCMessageClient instance
[DEBUG   ] Closing IPCMessageClient instance
[DEBUG   ] Closing IPCMessageClient instance
[DEBUG   ] LazyLoaded zfs.is_supported
[DEBUG   ] MasterEvent PUB socket URI: /home/sharky/salt/var/run/salt/master/master_event_pub.ipc
[DEBUG   ] MasterEvent PULL socket URI: /home/sharky/salt/var/run/salt/master/master_event_pull.ipc
[ERROR   ] Unable to connect pusher: Stream is closed
Traceback (most recent call last):
  File "/home/sharky/venv/salt/lib/python3.9/site-packages/salt/utils/event.py", line 423, in connect_pull
    self.pusher.connect(timeout=timeout)
  File "/home/sharky/venv/salt/lib/python3.9/site-packages/salt/utils/asynchronous.py", line 125, in wrap
    raise exc_info[1].with_traceback(exc_info[2])
  File "/home/sharky/venv/salt/lib/python3.9/site-packages/salt/utils/asynchronous.py", line 131, in _target
    result = io_loop.run_sync(lambda: getattr(self.obj, key)(*args, **kwargs))
  File "/home/sharky/venv/salt/lib/python3.9/site-packages/salt/ext/tornado/ioloop.py", line 459, in run_sync
    return future_cell[0].result()
  File "/home/sharky/venv/salt/lib/python3.9/site-packages/salt/ext/tornado/concurrent.py", line 249, in result
    raise_exc_info(self._exc_info)
  File "<string>", line 4, in raise_exc_info
  File "/home/sharky/venv/salt/lib/python3.9/site-packages/salt/transport/ipc.py", line 342, in _connect
    yield self.stream.connect(sock_addr)
  File "/home/sharky/venv/salt/lib/python3.9/site-packages/salt/ext/tornado/gen.py", line 1056, in run
    value = future.result()
  File "/home/sharky/venv/salt/lib/python3.9/site-packages/salt/ext/tornado/concurrent.py", line 249, in result
    raise_exc_info(self._exc_info)
  File "<string>", line 4, in raise_exc_info
salt.ext.tornado.iostream.StreamClosedError: Stream is closed
[DEBUG   ] Using importlib_metadata to load entry points
[DEBUG   ] LazyLoaded roots.envs
[DEBUG   ] Could not LazyLoad roots.init: 'roots.init' is not available.
[DEBUG   ] Updating roots fileserver cache
[INFO    ] Syncing roster for environment 'base'
[INFO    ] Loading cache from salt://_roster, for base
[INFO    ] Caching directory '_roster/' for environment 'base'

Versions Report
Print the output from salt-sproxy -V inside the backticks below:

(salt) sharky@debian-dev:~/salt$ salt-sproxy -V
Salt Version:
           Salt: 3004
    Salt SProxy: 2021.6.1

Dependency Versions:
        Ansible: Not Installed
           cffi: 1.15.0
       dateutil: Not Installed
      docker-py: Not Installed
          gitdb: Not Installed
      gitpython: Not Installed
         Jinja2: 3.0.3
     junos-eznc: 2.6.3
       jxmlease: Not Installed
        libgit2: Not Installed
       M2Crypto: Not Installed
           Mako: Not Installed
   msgpack-pure: Not Installed
 msgpack-python: 1.0.3
         NAPALM: 3.3.1
       ncclient: 0.6.9
        Netmiko: 3.4.0
       paramiko: 2.9.2
      pycparser: 2.21
       pycrypto: Not Installed
   pycryptodome: 3.14.1
         pyeapi: 0.8.4
         pygit2: Not Installed
       PyNetBox: Not Installed
          PyNSO: Not Installed
         Python: 3.9.2 (default, Feb 28 2021, 17:03:44)
   python-gnupg: Not Installed
         PyYAML: 6.0
          PyZMQ: 21.0.2
            scp: 0.14.4
          smmap: Not Installed
        textfsm: 1.1.2
        timelib: Not Installed
        Tornado: 4.5.3
            ZMQ: 4.3.3

System Versions:
           dist: debian 11 bullseye
         locale: utf-8
        machine: x86_64
        release: 5.10.0-12-amd64
         system: Linux
        version: Debian GNU/Linux 11 bullseye

Additional context
Add any other context about the problem here.

custom execution modules not working

Describe the bug
Custom execution modules placed in the salt://_modules directory can not be executed.

Steps To Reproduce

  1. create custom module:
root@salt-gbone:/srv/salt# cat _modules/example.py
def first():
    return True
  1. try to run the module:
root@salt-gbone:/srv/salt# salt-sproxy cr-testing* example.first
cr-testing01.lab1:
    The minion function caused an exception: Traceback (most recent call last):
      File "/usr/local/lib/python3.7/dist-packages/salt_sproxy/_runners/proxy.py", line 641, in salt_call
        ret = sa_proxy.functions[salt_function](*args, **kwargs)
      File "/usr/lib/python3/dist-packages/salt/loader.py", line 1278, in __getitem__
        func = super(LazyLoader, self).__getitem__(item)
      File "/usr/lib/python3/dist-packages/salt/utils/lazy.py", line 108, in __getitem__
        raise KeyError(key)
    KeyError: 'example.first'
ERROR: Minions returned with non-zero exit code

Expected behavior
Expect the custom module to execute and return "True"

Versions Report

root@salt-gbone:/srv/salt# salt-sproxy -V
Salt Version:
           Salt: 3001.1
    Salt SProxy: 2020.7.0

Dependency Versions:
        Ansible: Not Installed
           cffi: 1.14.2
       dateutil: 2.7.3
      docker-py: Not Installed
          gitdb: 2.0.5
      gitpython: 2.1.11
         Jinja2: 2.10
     junos-eznc: 2.5.3
       jxmlease: Not Installed
        libgit2: 0.27.7
       M2Crypto: Not Installed
           Mako: Not Installed
   msgpack-pure: Not Installed
 msgpack-python: 0.5.6
         NAPALM: 3.1.0
       ncclient: 0.6.9
        Netmiko: 3.2.0
       paramiko: 2.7.2
      pycparser: 2.19
       pycrypto: 2.6.1
   pycryptodome: 3.6.1
         pyeapi: 0.8.3
         pygit2: 0.27.4
       PyNetBox: Not Installed
          PyNSO: Not Installed
         Python: 3.7.3 (default, Jul 25 2020, 13:03:44)
   python-gnupg: Not Installed
         PyYAML: 3.13
          PyZMQ: 17.1.2
            scp: 0.13.2
          smmap: 2.0.5
        textfsm: 1.1.0
        timelib: Not Installed
        Tornado: 4.5.3
            ZMQ: 4.3.1

System Versions:
           dist: debian 10 buster
         locale: utf-8
        machine: x86_64
        release: 4.19.0-10-amd64
         system: Linux
        version: Debian GNU/Linux 10 buster

Additional context
I followed the documentation for creating custom execution modules here:
https://docs.saltstack.com/en/latest/ref/modules/
as well as your blog:
https://mirceaulinic.net/2019-04-24-extending-napalm-salt/
https://mirceaulinic.net/2019-06-17-minionless-salt-automation/

This is my file_roots config:

file_roots:
  base:
    - /srv/salt/
    - /srv/salt/ext

Running standard modules on the minion works fine:

root@salt-gbone:/srv/salt# salt-sproxy cr-testing* test.ping
cr-testing01.lab1:
    True

Running saltutil.sync_all, saltutil.sync_modules, sys.reload_modules or saltutil.refresh_modules does not change the outcome. As I understand, running these commands should also not be necessary with salt-sproxy because the modules are loaded on runtime.

The only way I have found to make this work is to place the module either in
/usr/lib/python3/dist-packages/salt/modules/ or /usr/local/lib/python3.7/dist-packages/salt_sproxy/_modules/:

root@salt-gbone:/srv/salt# mv _modules/example.py /usr/local/lib/python3.7/dist-packages/salt_sproxy/_modules/
root@salt-gbone:/srv/salt# salt-sproxy cr-testing* example.first
cr-testing01.lab1:
    True

I'm relatively new to salt and salt-sproxy so I can't rule out that I'm missing something simple here.
However I'm unable to figure out what it might be.

[Feature] Traceback handling when connection fails

Hello @mirceaulinic

Is your feature request related to a problem? Please describe.

When running a command against a device which is offline , salt-sproxy returns the traceback (napalm connection ) .

Why not catch the expection and return only the core information ?

As far as I know salt always returns a dict .

Why not return a dict, like salt-ssh does ?

{'r1': {'stdout': '', 'stderr': 'Permission denied, no authentication information', 'retcode': 254}}

This woud feel a bit more salt like and would improve readablity

Thank You !

CLI options wishlist

Listing here some CLI options I think it'd make sense to have:

  • --saltenv ✔️ #73
  • --states-dir ✔️ #64
  • --file-root ✔️ #65
  • --pillar-root ✔️ #65
  • --timeout ✔️ #68
  • --return, --return_config, and --return_kwargs
  • --module-dirs ✔️ #65
  • replace --sync with --static ✔️ #64
  • --async
  • --quiet
  • --failhard ✔️ #68
  • --summary ✔️ #68
  • --hide-timeout ✔️ #68
  • --output-diff
  • --batch-wait ✔️ #68
  • --show-jid ✔️ #68
  • --jid
  • --verbose ✔️ #68
  • --progress ✔️ #68
  • --config-dump ✔️ #65

Suggest a minor doc change

In the docs for quick_start.rst

+Tip: When using Juniper devices, you need to enable netconf before Salt can connect to the device. This can be done by simply configuring set system services netconf ssh.

When following along at home, with fresh lab kit - it might be really helpful to mention that netconf needs to be enabled for the junos proxy/ napalm to actually work. This is probably true for Cisco too, but I wouldn't know. Appreciate you don't want to go down the prescriptive docs for everyone's problems - but this one caught me out.

The netbox execution module cannot be loaded: pynetbox library is not installed.

Describe the bug
Issue with the Netbox Roster, pynetbox is not installed according to salt-sproxy.

Steps To Reproduce
Steps to reproduce the behavior:

Follow this guide: https://salt-sproxy.readthedocs.io/en/latest/examples/netbox.html

Running on Ubuntu 18.04.2 LTS

Run: salt-sproxy '*' --preview-target -c /root/ -l debug

Expected behavior
Output of devices

Versions Report
Print the output from salt-sproxy -V inside the backticks below:

root@salt-temp01:~# salt-sproxy -V
Salt Version:
           Salt: 2019.2.0
    Salt SProxy: 2019.6.0

Dependency Versions:
        Ansible: Not Installed
           cffi: Not Installed
       dateutil: 2.6.1
      docker-py: Not Installed
          gitdb: 2.0.3
      gitpython: 2.1.8
         Jinja2: 2.10
     junos-eznc: Not Installed
       jxmlease: Not Installed
        libgit2: Not Installed
       M2Crypto: Not Installed
           Mako: 1.0.7
   msgpack-pure: Not Installed
 msgpack-python: 0.5.6
         NAPALM: Not Installed
       ncclient: Not Installed
        Netmiko: Not Installed
       paramiko: Not Installed
      pycparser: Not Installed
       pycrypto: 2.6.1
   pycryptodome: Not Installed
         pyeapi: Not Installed
         pygit2: Not Installed
       PyNetBox: 4.0.6
          PyNSO: Not Installed
         Python: 2.7.15+ (default, Nov 27 2018, 23:36:35)
   python-gnupg: 0.4.1
         PyYAML: 3.12
          PyZMQ: 16.0.2
            scp: Not Installed
          smmap: 2.0.3
        textfsm: Not Installed
        timelib: Not Installed
        Tornado: 4.5.3
            ZMQ: 4.2.5

System Versions:
           dist: Ubuntu 18.04 bionic
         locale: UTF-8
        machine: x86_64
        release: 4.15.0-55-generic
         system: Linux
        version: Ubuntu 18.04 bionic

Additional context
Debug output:

root@salt-temp01:~# pip install pynetbox
Requirement already satisfied: pynetbox in /usr/local/lib/python2.7/dist-packages
Requirement already satisfied: requests<3.0,>=2.20.0 in /usr/local/lib/python2.7/dist-packages (from pynetbox)
Requirement already satisfied: six==1.* in /usr/lib/python2.7/dist-packages (from pynetbox)
Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python2.7/dist-packages (from requests<3.0,>=2.20.0->pynetbox)
Requirement already satisfied: certifi>=2017.4.17 in /usr/lib/python2.7/dist-packages (from requests<3.0,>=2.20.0->pynetbox)
Requirement already satisfied: chardet<3.1.0,>=3.0.2 in /usr/local/lib/python2.7/dist-packages (from requests<3.0,>=2.20.0->pynetbox)
Requirement already satisfied: idna<2.9,>=2.5 in /usr/lib/python2.7/dist-packages (from requests<3.0,>=2.20.0->pynetbox)
root@salt-temp01:~# salt-sproxy '*' --preview-target -c /root/ -l debug
[DEBUG   ] Reading configuration from /root/master
[DEBUG   ] Using cached minion ID from /etc/salt/minion_id: master-salt-dev
[DEBUG   ] Missing configuration file: /root/.saltrc
[DEBUG   ] Configuration file path: /root/master
[WARNING ] Insecure logging configuration detected! Sensitive data may be logged.
[DEBUG   ] Syncing roster
[DEBUG   ] LazyLoaded saltutil.sync_roster
[DEBUG   ] Reading configuration from /root/master
[DEBUG   ] Using cached minion ID from /etc/salt/minion_id: master-salt-dev
[DEBUG   ] Grains refresh requested. Refreshing grains.
[DEBUG   ] Reading configuration from /root/master
[DEBUG   ] Unable to derive osmajorrelease from osrelease_info '(u'proxy',)'. The osmajorrelease grain will not be set.
[DEBUG   ] MasterEvent PUB socket URI: /var/run/salt/master/master_event_pub.ipc
[DEBUG   ] MasterEvent PULL socket URI: /var/run/salt/master/master_event_pull.ipc
[DEBUG   ] Popen(['git', 'version'], cwd=/root, universal_newlines=False, shell=None)
[DEBUG   ] Popen(['git', 'version'], cwd=/root, universal_newlines=False, shell=None)
[DEBUG   ] Initializing new IPCClient for path: /var/run/salt/master/master_event_pull.ipc
[DEBUG   ] Updating roots fileserver cache
[INFO    ] Syncing roster for environment 'base'
[INFO    ] Loading cache from salt://_roster, for base)
[INFO    ] Caching directory '_roster/' for environment 'base'
[DEBUG   ] In saltenv 'base', looking at rel_path '_roster/ansible.py' to resolve 'salt://_roster/ansible.py'
[DEBUG   ] In saltenv 'base', ** considering ** path '/var/cache/salt/master/files/base/_roster/ansible.py' to resolve 'salt://_roster/ansible.py'
[DEBUG   ] In saltenv 'base', looking at rel_path '_roster/netbox.py' to resolve 'salt://_roster/netbox.py'
[DEBUG   ] In saltenv 'base', ** considering ** path '/var/cache/salt/master/files/base/_roster/netbox.py' to resolve 'salt://_roster/netbox.py'
[DEBUG   ] In saltenv 'base', looking at rel_path '_roster/pillar.py' to resolve 'salt://_roster/pillar.py'
[DEBUG   ] In saltenv 'base', ** considering ** path '/var/cache/salt/master/files/base/_roster/pillar.py' to resolve 'salt://_roster/pillar.py'
[DEBUG   ] Local cache dir: '/var/cache/salt/master/files/base/_roster'
[INFO    ] Copying '/var/cache/salt/master/files/base/_roster/ansible.py' to '/var/cache/salt/master/extmods/roster/ansible.py'
[INFO    ] Copying '/var/cache/salt/master/files/base/_roster/netbox.py' to '/var/cache/salt/master/extmods/roster/netbox.py'
[INFO    ] Copying '/var/cache/salt/master/files/base/_roster/pillar.py' to '/var/cache/salt/master/extmods/roster/pillar.py'
[DEBUG   ] LazyLoaded local_cache.prep_jid
[INFO    ] Runner completed: 20190806091219170271
[DEBUG   ] Closing IPCMessageClient instance
[DEBUG   ] []
[DEBUG   ] LazyLoaded proxy.execute
[DEBUG   ] Reading configuration from /root/master
[DEBUG   ] Using cached minion ID from /etc/salt/minion_id: master-salt-dev
[DEBUG   ] Grains refresh requested. Refreshing grains.
[DEBUG   ] Reading configuration from /root/master
[DEBUG   ] Unable to derive osmajorrelease from osrelease_info '(u'proxy',)'. The osmajorrelease grain will not be set.
[DEBUG   ] MasterEvent PUB socket URI: /var/run/salt/master/master_event_pub.ipc
[DEBUG   ] MasterEvent PULL socket URI: /var/run/salt/master/master_event_pull.ipc
[DEBUG   ] Initializing new IPCClient for path: /var/run/salt/master/master_event_pull.ipc
[DEBUG   ] Computing the target using the netbox Roster
[DEBUG   ] LazyLoaded netbox.targets
[DEBUG   ] Called salt.cmd runner with minion function netbox.filter
[DEBUG   ] Grains refresh requested. Refreshing grains.
[DEBUG   ] Reading configuration from /root/master
[DEBUG   ] Unable to derive osmajorrelease from osrelease_info '(u'proxy',)'. The osmajorrelease grain will not be set.
[DEBUG   ] key: ifttt.secret_key, ret: _|-
[DEBUG   ] key: ifttt:secret_key, ret: _|-
[DEBUG   ] key: pushbullet.api_key, ret: _|-
[DEBUG   ] key: pushbullet:api_key, ret: _|-
[DEBUG   ] LazyLoaded systemd.booted
[DEBUG   ] key: victorops.api_key, ret: _|-
[DEBUG   ] key: victorops:api_key, ret: _|-
[DEBUG   ] DSC: Only available on Windows systems
[DEBUG   ] Module PSGet: Only available on Windows systems
[DEBUG   ] LazyLoaded platform.is_windows
[DEBUG   ] Could not LazyLoad netbox.filter: 'netbox' __virtual__ returned False: The netbox execution module cannot be loaded: pynetbox library is not installed.
[DEBUG   ] LazyLoaded local_cache.prep_jid
[DEBUG   ] LazyLoaded nested.output

Passed invalid arguments: string indices must be integers

Usage:

    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

[INFO    ] Runner completed: 20190806091221442670
[DEBUG   ] Closing IPCMessageClient instance
[DEBUG   ] Runner return:
Passed invalid arguments: string indices must be integers

Usage:

    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

salt_sproxy cli typo import error

Describe the bug
An "s" is missing from the from salt.utils.file import fopen line causing a double import error breaking invocation.

Steps To Reproduce

  • Install from pip3
  • Invocate from command line with any argument

Expected behavior

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/salt_sproxy/cli.py", line 34, in <module>
    from salt.utils.file import fopen
ModuleNotFoundError: No module named 'salt.utils.file'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/bin/salt-sproxy", line 11, in <module>
    sys.exit(salt_sproxy())
  File "/usr/local/lib/python3.6/dist-packages/salt_sproxy/scripts.py", line 12, in salt_sproxy
    import salt_sproxy.cli
  File "/usr/local/lib/python3.6/dist-packages/salt_sproxy/cli.py", line 40, in <module>
    from salt.utils import fopen
ImportError: cannot import name 'fopen'

Versions Report
Print the output from salt-sproxy -V inside the backticks below:
Using pip list because salt-sproxy -V results in a crash from the reported issue.

salt (3000)
salt-sproxy (2019.10.0)

Additional context
Add any other context about the problem here.

Question: Matching with grains in Ansible and Pillar rosters

Hi Mircea,

using the ansible roster I managed to have host groupings and be able to use them in salt-sproxy target selections (eg salt-sproxy -N FOO --preview-targets works as expected).

However using static grains I didn't manage to perform a match using -G ':' with both ansible and pillar rosters. Is this still not implemented?

Thanks,
Kostas

PS: I had a look at the code (eg _roster/ansible.py) but can't figure out what happens in case of tgt_type in ['grain', 'grain_pcre']...

Roster Netbox calling filter method w/o kwargs.

First, i've only dabbled with salt and netbox for a couple of days. Don't really know if this is a salt-sproxy issue or a salt issue?

The netbox runner function, "targets", uses the salt-module netbox's filter-method without key-word arguments. When running, this causes an error in the underlaying pynetbox filter_ method which requires kwargs.

salt-sproxy -l debug ti* --preview-target

or using the provided example without kwargs:

salt-run salt.cmd netbox.filter dcim devices

Exception occurred in runner salt.cmd: Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/salt/client/mixins.py", line 374, in low
data['return'] = func(*args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/salt/runners/salt.py", line 106, in cmd
if fun in functions
File "/usr/local/lib/python3.7/site-packages/salt/modules/netbox.py", line 164, in filter_
**utils'args.clean_kwargs'
File "/usr/local/lib/python3.7/site-packages/pynetbox/core/endpoint.py", line 209, in filter
"filter must be passed kwargs. Perhaps use all() instead."
ValueError: filter must be passed kwargs. Perhaps use all() instead.

Updating the salt module to use the 'all()' method, instead of filter if no kwargs present, which seems to give me the results i'm after.

Highstate errors

I have set up pillar and a state. Relevant files:

/etc/salt/master

pillar_roots:
  base:
    - /etc/salt/pillar

file_roots:
  base:
    - /etc/salt
    - /etc/salt/states

#proxy_roster: pillar

# Uncomment below settings to use Ansible inventory as roster
proxy_roster: ansible
roster_file: /etc/salt/inventory

/etc/salt/inventory

all:
  children:
    virtual:
      hosts:
        edge1-us:
          grains:
            role: pe
            site: miami
        edge1-fr:
        edge1-mf:
        edge1-gp:
        edge1-mq:
        edge1-gf:
    physical:
      hosts:
        mx240-lab:
        mx104-lab:
        mx51-lab:
        mx52-lab:

/etc/salt/states/bgp_announcements/init.sls

bgp_announcements_recipe:
  netconfig.managed:
    - template_name: salt://bgp_announcements/templates/announcements.py
    - template_engine: py
#    - debug: True

/etc/salt/states/top.sls

base:
#  'type: physical':
#     - match: pillar
#     - netconfig_bgp_announcements
# All minions with a minion_id that begins with 'mx'
  'mx*':
    - bgp_announcement

Steps To Reproduce
Running state.apply with the state as the argument works as expected

root@salt-sproxy:/# salt-sproxy mx104-lab state.apply bgp_announcements
[WARNING ] /usr/local/lib/python3.6/dist-packages/salt/modules/napalm_network.py:1902: DeprecationWarning: The 'template_user' argument to 'net.load_template' is deprecated and has been ignored

[WARNING ] /usr/local/lib/python3.6/dist-packages/salt/modules/napalm_network.py:1902: DeprecationWarning: The 'template_attrs' argument to 'net.load_template' is deprecated and has been ignored

[WARNING ] /usr/local/lib/python3.6/dist-packages/salt/modules/napalm_network.py:1902: DeprecationWarning: The 'template_group' argument to 'net.load_template' is deprecated and has been ignored

[WARNING ] /usr/local/lib/python3.6/dist-packages/salt/modules/napalm_network.py:1902: DeprecationWarning: The 'template_mode' argument to 'net.load_template' is deprecated and has been ignored

mx104-lab:
    ----------
    netconfig_|-bgp_announcements_recipe_|-bgp_announcements_recipe_|-managed:
        ----------
        __id__:
            bgp_announcements_recipe
        __run_num__:
            0
        __sls__:
            bgp_announcements
        changes:
            ----------
        comment:
            Already configured.
        duration:
            10346.073
        name:
            bgp_announcements_recipe
        result:
            True
        start_time:
            21:45:30.776380

Running state.apply with no arguments (highstate) fails with the following exceptions:

root@salt-sproxy:/# salt-sproxy '*' state.apply                                                                                                                 [101/99991]
edge1-fr:                            
    ----------                    
    no_|-states_|-states_|-None:                                                                     
        ----------                                     
        __run_num__:                                                                      
            0                 
        changes:                                                                              
            ----------                  
        comment:                                                                             
            No Top file or master_tops data matches found. Please see master log for details.
        name:                                                                                
            No States                            
        result:                     
            False                    
edge1-gp:                         
    ----------                                                                                       
    no_|-states_|-states_|-None:
        ----------
        __run_num__:
            0
        changes:
            ----------
        comment:
            No Top file or master_tops data matches found. Please see master log for details.
        name:
            No States
        result:
            False
edge1-mf:
    ----------
    no_|-states_|-states_|-None:
        ----------
        __run_num__:
            0
        changes:
            ----------
        comment:
            No Top file or master_tops data matches found. Please see master log for details.
        name:
            No States
        result:
            False
edge1-gf:                                                                                                                                                        [58/99991]
    ----------
    no_|-states_|-states_|-None:
        ----------
        __run_num__:
            0
        changes:
            ----------
        comment:
            No Top file or master_tops data matches found. Please see master log for details.
        name:
            No States
        result:
            False
[ERROR   ] 'autoload_dynamic_modules'
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/salt_sproxy/_runners/proxy.py", line 442, in salt_call
    ret = sa_proxy.functions[function](*args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/salt/modules/state.py", line 779, in apply_
    return highstate(**kwargs)
  File "/usr/local/lib/python3.6/dist-packages/salt/modules/state.py", line 1083, in highstate
    orchestration_jid=orchestration_jid)
  File "/usr/local/lib/python3.6/dist-packages/salt/state.py", line 3933, in call_highstate
    self.load_dynamic(matches)
  File "/usr/local/lib/python3.6/dist-packages/salt/state.py", line 3441, in load_dynamic
    if not self.opts['autoload_dynamic_modules']:
KeyError: 'autoload_dynamic_modules'
mx51-lab:
    None
[ERROR   ] 'autoload_dynamic_modules'
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/salt_sproxy/_runners/proxy.py", line 442, in salt_call
    ret = sa_proxy.functions[function](*args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/salt/modules/state.py", line 779, in apply_
    return highstate(**kwargs)
  File "/usr/local/lib/python3.6/dist-packages/salt/modules/state.py", line 1083, in highstate
    orchestration_jid=orchestration_jid)
  File "/usr/local/lib/python3.6/dist-packages/salt/state.py", line 3933, in call_highstate
    self.load_dynamic(matches)
  File "/usr/local/lib/python3.6/dist-packages/salt/state.py", line 3441, in load_dynamic
    if not self.opts['autoload_dynamic_modules']:
KeyError: 'autoload_dynamic_modules'
mx240-lab:                                                                                                                                                       [16/99991]
    None
[ERROR   ] 'autoload_dynamic_modules'
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/salt_sproxy/_runners/proxy.py", line 442, in salt_call
    ret = sa_proxy.functions[function](*args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/salt/modules/state.py", line 779, in apply_
    return highstate(**kwargs)
  File "/usr/local/lib/python3.6/dist-packages/salt/modules/state.py", line 1083, in highstate
    orchestration_jid=orchestration_jid)
  File "/usr/local/lib/python3.6/dist-packages/salt/state.py", line 3933, in call_highstate
    self.load_dynamic(matches)
  File "/usr/local/lib/python3.6/dist-packages/salt/state.py", line 3441, in load_dynamic
    if not self.opts['autoload_dynamic_modules']:
KeyError: 'autoload_dynamic_modules'
mx104-lab:
    None
[ERROR   ] 'autoload_dynamic_modules'
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/salt_sproxy/_runners/proxy.py", line 442, in salt_call
    ret = sa_proxy.functions[function](*args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/salt/modules/state.py", line 779, in apply_
    return highstate(**kwargs)
  File "/usr/local/lib/python3.6/dist-packages/salt/modules/state.py", line 1083, in highstate
    orchestration_jid=orchestration_jid)
  File "/usr/local/lib/python3.6/dist-packages/salt/state.py", line 3933, in call_highstate
    self.load_dynamic(matches)
  File "/usr/local/lib/python3.6/dist-packages/salt/state.py", line 3441, in load_dynamic
    if not self.opts['autoload_dynamic_modules']:
KeyError: 'autoload_dynamic_modules'
mx52-lab:
    None
edge1-us:
    ----------
    no_|-states_|-states_|-None:
        ----------
        __run_num__:
            0
        changes:
            ----------
        comment:
            No Top file or master_tops data matches found. Please see master log for details.
        name:
            No States
        result:
            False
edge1-mq:
    ----------
    no_|-states_|-states_|-None:
        ----------
        __run_num__:
            0
        changes:
            ----------
        comment:
            No Top file or master_tops data matches found. Please see master log for details.
        name:
            No States
        result:
            False

Expected behavior
salt-sproxy '*' state.apply (highstate) should apply the state to all relevant minions (mx*).

Versions Report
Print the output from salt-sproxy -V inside the backticks below:

Salt Version:         
           Salt: 2019.2.2
    Salt SProxy: 2019.10.0        
                      
Dependency Versions:                
        Ansible: 2.9.0
           cffi: 1.11.5
       dateutil: Not Installed
      docker-py: Not Installed
          gitdb: Not Installed
      gitpython: Not Installed
         Jinja2: 2.10.3
     junos-eznc: 2.2.1
       jxmlease: Not Installed
        libgit2: Not Installed
       M2Crypto: Not Installed
           Mako: Not Installed
   msgpack-pure: Not Installed
 msgpack-python: 0.6.2
         NAPALM: 2.5.0
       ncclient: 0.6.6
        Netmiko: 2.4.2
       paramiko: 2.6.0
      pycparser: 2.18
       pycrypto: 2.6.1
   pycryptodome: Not Installed
         pyeapi: 0.8.2
         pygit2: Not Installed
       PyNetBox: Not Installed
          PyNSO: Not Installed
         Python: 3.6.8 (default, Oct  7 2019, 12:59:55)
   python-gnupg: Not Installed
         PyYAML: 3.13
          PyZMQ: 18.1.0
            scp: 0.13.2
          smmap: Not Installed
        textfsm: 1.1.0
        timelib: Not Installed
        Tornado: 4.5.3
            ZMQ: 4.3.2

System Versions:
           dist: Ubuntu 18.04 bionic
         locale: UTF-8
        machine: x86_64
        release: 4.15.0-64-generic
         system: Linux
        version: Ubuntu 18.04 bionic

Additional context
The environment is a docker container with Ubuntu 18.04 environment, python3 (3.6) salt 2019.2.2 (also tried with salt 2018.3.4)

Dockerfile

FROM phusion/baseimage:0.11
MAINTAINER <my mail>

# Install min deps, helpful tools
# NAPALM, salt and salt-sproxy
RUN export DEBIAN_FRONTEND=noninteractive \
  && apt-get update \
  && apt-get install -y apt-utils \
  && apt-get install -y wget \
  && apt-get install -y iproute2 iputils-ping \
  && apt-get install -y libxslt1-dev libssl-dev libffi-dev \
  && apt-get install -y python3-dev python3-cffi python3-pip \
  && pip3 --no-cache-dir install salt=="2019.2.2" \
#  && pip3 --no-cache-dir install salt=="2018.3.4" \
  && pip3 --no-cache-dir install napalm napalm-yang \
  && pip3 --no-cache-dir install ansible \
  && pip3 --no-cache-dir install salt-sproxy

# Clean up APT when done.
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

# Ports
#EXPOSE 4505 4506

# Use baseimage-docker's init system.
CMD ["/sbin/my_init"]

Improved documentation of the -b BATCH_SIZE option

Describe the bug

Hi, Mircea!

I still use salt-sproxy (in a Docker container) and I realized that by default it connects to 4 network assets in parallel.

Looking at the salt-sproxy options, I saw that you have the option:

-b BATCH_SIZE, --batch=BATCH_SIZE, --batch-size=BATCH_SIZE
The number of devices to connect to in parallel.
Default: 4

I increased it to 128, but it still connects to only 4 assets.

alias salt-sproxy='f(){ time docker run --rm --network host -v $SALT_DIR_BASE/master:/etc/salt/master -v $SALT_PROXY_PILLAR_DIR:/etc/salt/pillar/ -v $SALT_PROXY_STATES_DIR:/srv/salt/ -v $TMP_DIR_BACKUPS:/tmp/backups/ -ti mirceaulinic/salt-sproxy:allinone-2020.10.2 salt-sproxy -b 128 $@; }; f'

When we talked via slack, you explained that the value of this option must be changed according to the amount of CPU that is available on the server that runs Salt-SProxy.

mirceaulinic: 03 Dez - 10:49 AM
Hmm -b should be the argument to increase that
The value depends on how many CPUs you have on your machine
For example, on the server I have at work, we have 64 CPUs, so -b defaults to 64
But if you provide -b 128, then 128 it should use

My server has only 4 CPU...

cat /proc/cpuinfo | grep processor
processor	: 0
processor	: 1
processor	: 2
processor	: 3

As a suggestion for improvement, could you add this information about the CPU in the next version of salt-sproxy, next to the -b option? This would make understanding this parameter more intuitive.

Thank you and good day!

Can't configure Junos 18.x using napalm

Describe the bug
Hi All,

I was using salt-sproxy for a while with our Juniper-based network, and all was working fine.

I started to find some problems with the new Junos code we use (18.x)

I can communicate with the device (net.connected, net.cli, grains....etc), but I can't configure anything on it via neither net.cli nor net.load_config/template, the device isn't reporting back any diff, and sees that the new configs are already configured, even if the new set file contains new configs not configured on the device for sure.

And I can see nothing coming back from the device via rpc-reply while debugging the request.

I tested that for multiple Juniper devices with the same code, and all are the same wrong behaviour.

For example:
- The working operational scenario:

salt-sproxy '10-220-1-9' net.cli 'show system license'
10-220-1-9:
    ----------
    comment:
    out:
        ----------
        show system license:

            License usage: none

            Licenses installed: none
    result:
        True

- The non-working configurational scenario 1, again: vlan888 isn't configured on the device 100%:

salt-sproxy '10-220-1-9' net.load_config text='set vlans vlan888 vlan-id 888'
10-220-1-9:
    ----------
    already_configured:
        True
    comment:
        Already configured.
    diff:
    loaded_config:
    result:
        True


mkh@sw220-1-9> show configuration vlans vlan888

{master:0}
mkh@sw220-1-9>

- The non-working configurational scenario 2:

root@/etc/pillar# cat /etc/salt/ext/REQ.set
set vlans vlan888 vlan-id 888


root@/etc/pillar# salt-sproxy '10-220-1-9' net.load_config filename='/etc/salt/ext/REQ.set'
10-220-1-9:
    ----------
    already_configured:
        True
    comment:
        Already configured.
    diff:
    loaded_config:
    result:
        True


mkh@sw220-1-9> show configuration vlans vlan888

{master:0}
mkh@sw220-1-9>

Within debug what I see during that is the following:

[INFO    ] [host 10.220.1.9 session-id 82730] Requesting 'ExecuteRpc'
[DEBUG   ] [host 10.220.1.9 session-id 82730] queueing <?xml version="1.0" encoding="UTF-8"?><nc:rpc xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:ff66d123-c081-487d-971f-5d7e2932524a"><lock-configuration/></nc:rpc>
[DEBUG   ] [host 10.220.1.9 session-id 82730] Sync request, will wait for timeout=60
[DEBUG   ] [host 10.220.1.9 session-id 82730] Sending message
[INFO    ] [host 10.220.1.9 session-id 82730] Sending:
<?xml version="1.0" encoding="UTF-8"?><nc:rpc xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:ff66d123-c081-487d-971f-5d7e2932524a"><lock-configuration/></nc:rpc>]]>]]>
[DEBUG   ] [host 10.220.1.9 session-id 82730] parsing netconf v1.0
[DEBUG   ] [host 10.220.1.9 session-id 82730] parsing netconf v1.0
[INFO    ] [host 10.220.1.9 session-id 82730] Received message from host
[DEBUG   ] [host 10.220.1.9 session-id 82730] Received:
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/18.2R3/junos" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:ff66d123-c081-487d-971f-5d7e2932524a">
</rpc-reply>
[DEBUG   ] [host 10.220.1.9 session-id 82730] dispatching message to different listeners: <rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/18.2R3/junos" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:ff66d123-c081-487d-971f-5d7e2932524a">
</rpc-reply>
[DEBUG   ] [host 10.220.1.9 session-id 82730] dispatching message to listener: <ncclient.operations.rpc.RPCReplyListener object at 0x7fa31e732670>
[DEBUG   ] [host 10.220.1.9 session-id 82730] Delivering to <ncclient.operations.third_party.juniper.rpc.ExecuteRpc object at 0x7fa31efeac10>
[DEBUG   ] [host 10.220.1.9 session-id 82730] dispatching message to listener: <ncclient.transport.session.NotificationHandler object at 0x7fa31e644130>
[DEBUG   ] [host 10.220.1.9 session-id 82730] dispatching message to listener: <jnpr.junos.device.DeviceSessionListener object at 0x7fa31e628370>
[INFO    ] [host 10.220.1.9 session-id 82730] Requesting 'ExecuteRpc'
[DEBUG   ] [host 10.220.1.9 session-id 82730] queueing <?xml version="1.0" encoding="UTF-8"?><nc:rpc xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:5f53421e-6d44-4c58-91e1-c19ccea38b1e"><load-configuration format="text" action="set"><configuration-set>set vlans vlan888 vlan-id 888
</configuration-set></load-configuration></nc:rpc>
[DEBUG   ] [host 10.220.1.9 session-id 82730] Sync request, will wait for timeout=60
[DEBUG   ] [host 10.220.1.9 session-id 82730] Sending message
[INFO    ] [host 10.220.1.9 session-id 82730] Sending:
<?xml version="1.0" encoding="UTF-8"?><nc:rpc xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:5f53421e-6d44-4c58-91e1-c19ccea38b1e"><load-configuration format="text" action="set"><configuration-set>set vlans vlan888 vlan-id 888
</configuration-set></load-configuration></nc:rpc>]]>]]>
[DEBUG   ] [host 10.220.1.9 session-id 82730] parsing netconf v1.0
[DEBUG   ] [host 10.220.1.9 session-id 82730] parsing netconf v1.0
[DEBUG   ] [host 10.220.1.9 session-id 82730] parsing netconf v1.0
[DEBUG   ] [host 10.220.1.9 session-id 82730] parsing netconf v1.0
[DEBUG   ] [host 10.220.1.9 session-id 82730] parsing netconf v1.0
[INFO    ] [host 10.220.1.9 session-id 82730] Received message from host
[DEBUG   ] [host 10.220.1.9 session-id 82730] Received:
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/18.2R3/junos" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:5f53421e-6d44-4c58-91e1-c19ccea38b1e">
<load-configuration-results>
<ok/>
</load-configuration-results>
</rpc-reply>
[DEBUG   ] [host 10.220.1.9 session-id 82730] dispatching message to different listeners: <rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/18.2R3/junos" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:5f53421e-6d44-4c58-91e1-c19ccea38b1e">
<load-configuration-results>
<ok/>
</load-configuration-results>
</rpc-reply>
[DEBUG   ] [host 10.220.1.9 session-id 82730] dispatching message to listener: <ncclient.operations.rpc.RPCReplyListener object at 0x7fa31e732670>
[DEBUG   ] [host 10.220.1.9 session-id 82730] Delivering to <ncclient.operations.third_party.juniper.rpc.ExecuteRpc object at 0x7fa31f160fd0>
[DEBUG   ] [host 10.220.1.9 session-id 82730] dispatching message to listener: <ncclient.transport.session.NotificationHandler object at 0x7fa31e644130>
[DEBUG   ] [host 10.220.1.9 session-id 82730] dispatching message to listener: <jnpr.junos.device.DeviceSessionListener object at 0x7fa31e628370>
[INFO    ] [host 10.220.1.9 session-id 82730] Requesting 'ExecuteRpc'
[DEBUG   ] [host 10.220.1.9 session-id 82730] queueing <?xml version="1.0" encoding="UTF-8"?><nc:rpc xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:aa19bafc-a8b9-42ee-a9ae-f18de0448176"><get-configuration compare="rollback" rollback="0" format="text"/></nc:rpc>
[DEBUG   ] [host 10.220.1.9 session-id 82730] Sync request, will wait for timeout=60
[DEBUG   ] [host 10.220.1.9 session-id 82730] Sending message
[INFO    ] [host 10.220.1.9 session-id 82730] Sending:
<?xml version="1.0" encoding="UTF-8"?><nc:rpc xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:aa19bafc-a8b9-42ee-a9ae-f18de0448176"><get-configuration compare="rollback" rollback="0" format="text"/></nc:rpc>]]>]]>
[DEBUG   ] [host 10.220.1.9 session-id 82730] parsing netconf v1.0
[DEBUG   ] [host 10.220.1.9 session-id 82730] parsing netconf v1.0
[DEBUG   ] [host 10.220.1.9 session-id 82730] parsing netconf v1.0
[INFO    ] [host 10.220.1.9 session-id 82730] Received message from host
[DEBUG   ] [host 10.220.1.9 session-id 82730] Received:
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/18.2R3/junos" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:aa19bafc-a8b9-42ee-a9ae-f18de0448176">
<configuration-information>
<configuration-output>
</configuration-output>
</configuration-information>
</rpc-reply>
[DEBUG   ] [host 10.220.1.9 session-id 82730] dispatching message to different listeners: <rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/18.2R3/junos" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:aa19bafc-a8b9-42ee-a9ae-f18de0448176">
<configuration-information>
<configuration-output>
</configuration-output>
</configuration-information>
</rpc-reply>
[DEBUG   ] [host 10.220.1.9 session-id 82730] dispatching message to listener: <ncclient.operations.rpc.RPCReplyListener object at 0x7fa31e732670>
[DEBUG   ] [host 10.220.1.9 session-id 82730] Delivering to <ncclient.operations.third_party.juniper.rpc.ExecuteRpc object at 0x7fa31f0edb80>
[DEBUG   ] [host 10.220.1.9 session-id 82730] dispatching message to listener: <ncclient.transport.session.NotificationHandler object at 0x7fa31e644130>
[DEBUG   ] [host 10.220.1.9 session-id 82730] dispatching message to listener: <jnpr.junos.device.DeviceSessionListener object at 0x7fa31e628370>
[DEBUG   ] Discarding the config
[DEBUG   ] {'result': True, 'comment': '', 'already_configured': False, 'loaded_config': '', 'diff': ''}
[INFO    ] [host 10.220.1.9 session-id 82730] Requesting 'ExecuteRpc'
[DEBUG   ] [host 10.220.1.9 session-id 82730] queueing <?xml version="1.0" encoding="UTF-8"?><nc:rpc xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:4ef1fa52-c32d-49c4-aab2-e2db867a3761"><load-configuration compare="rollback" rollback="0"/></nc:rpc>
[DEBUG   ] [host 10.220.1.9 session-id 82730] Sync request, will wait for timeout=60
[DEBUG   ] [host 10.220.1.9 session-id 82730] Sending message
[INFO    ] [host 10.220.1.9 session-id 82730] Sending:
<?xml version="1.0" encoding="UTF-8"?><nc:rpc xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:4ef1fa52-c32d-49c4-aab2-e2db867a3761"><load-configuration compare="rollback" rollback="0"/></nc:rpc>]]>]]>
[DEBUG   ] [host 10.220.1.9 session-id 82730] parsing netconf v1.0
[DEBUG   ] [host 10.220.1.9 session-id 82730] parsing netconf v1.0
[DEBUG   ] [host 10.220.1.9 session-id 82730] parsing netconf v1.0
[DEBUG   ] [host 10.220.1.9 session-id 82730] parsing netconf v1.0
[DEBUG   ] [host 10.220.1.9 session-id 82730] parsing netconf v1.0
[INFO    ] [host 10.220.1.9 session-id 82730] Received message from host
[DEBUG   ] [host 10.220.1.9 session-id 82730] Received:
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/18.2R3/junos" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:4ef1fa52-c32d-49c4-aab2-e2db867a3761">
<load-configuration-results>
<ok/>
</load-configuration-results>
</rpc-reply>
[DEBUG   ] [host 10.220.1.9 session-id 82730] dispatching message to different listeners: <rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/18.2R3/junos" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:4ef1fa52-c32d-49c4-aab2-e2db867a3761">
<load-configuration-results>
<ok/>
</load-configuration-results>
</rpc-reply>
[DEBUG   ] [host 10.220.1.9 session-id 82730] dispatching message to listener: <ncclient.operations.rpc.RPCReplyListener object at 0x7fa31e732670>
[DEBUG   ] [host 10.220.1.9 session-id 82730] Delivering to <ncclient.operations.third_party.juniper.rpc.ExecuteRpc object at 0x7fa31f160f70>
[DEBUG   ] [host 10.220.1.9 session-id 82730] dispatching message to listener: <ncclient.transport.session.NotificationHandler object at 0x7fa31e644130>
[DEBUG   ] [host 10.220.1.9 session-id 82730] dispatching message to listener: <jnpr.junos.device.DeviceSessionListener object at 0x7fa31e628370>
[INFO    ] [host 10.220.1.9 session-id 82730] Requesting 'ExecuteRpc'
[DEBUG   ] [host 10.220.1.9 session-id 82730] queueing <?xml version="1.0" encoding="UTF-8"?><nc:rpc xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:ddb0f24c-387a-4366-9703-9a618e7ad6f4"><unlock-configuration/></nc:rpc>
[DEBUG   ] [host 10.220.1.9 session-id 82730] Sync request, will wait for timeout=60
[DEBUG   ] [host 10.220.1.9 session-id 82730] Sending message
[INFO    ] [host 10.220.1.9 session-id 82730] Sending:
<?xml version="1.0" encoding="UTF-8"?><nc:rpc xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:ddb0f24c-387a-4366-9703-9a618e7ad6f4"><unlock-configuration/></nc:rpc>]]>]]>
[DEBUG   ] [host 10.220.1.9 session-id 82730] parsing netconf v1.0
[DEBUG   ] [host 10.220.1.9 session-id 82730] parsing netconf v1.0
[DEBUG   ] [host 10.220.1.9 session-id 82730] parsing netconf v1.0
[INFO    ] [host 10.220.1.9 session-id 82730] Received message from host
[DEBUG   ] [host 10.220.1.9 session-id 82730] Received:
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/18.2R3/junos" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:ddb0f24c-387a-4366-9703-9a618e7ad6f4">
</rpc-reply>
[DEBUG   ] [host 10.220.1.9 session-id 82730] dispatching message to different listeners: <rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/18.2R3/junos" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:ddb0f24c-387a-4366-9703-9a618e7ad6f4">
</rpc-reply>
[DEBUG   ] [host 10.220.1.9 session-id 82730] dispatching message to listener: <ncclient.operations.rpc.RPCReplyListener object at 0x7fa31e732670>
[DEBUG   ] [host 10.220.1.9 session-id 82730] Delivering to <ncclient.operations.third_party.juniper.rpc.ExecuteRpc object at 0x7fa31f0ed430>
[DEBUG   ] [host 10.220.1.9 session-id 82730] dispatching message to listener: <ncclient.transport.session.NotificationHandler object at 0x7fa31e644130>
[DEBUG   ] [host 10.220.1.9 session-id 82730] dispatching message to listener: <jnpr.junos.device.DeviceSessionListener object at 0x7fa31e628370>
[INFO    ] [host 10.220.1.9 session-id 82730] Requesting 'CloseSession'
[DEBUG   ] [host 10.220.1.9 session-id 82730] queueing <?xml version="1.0" encoding="UTF-8"?><nc:rpc xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:f8b65a65-5563-46b3-a7a1-36f2da78487e"><nc:close-session/></nc:rpc>
[DEBUG   ] [host 10.220.1.9 session-id 82730] Sync request, will wait for timeout=60
[DEBUG   ] [host 10.220.1.9 session-id 82730] Sending message
[INFO    ] [host 10.220.1.9 session-id 82730] Sending:
<?xml version="1.0" encoding="UTF-8"?><nc:rpc xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:f8b65a65-5563-46b3-a7a1-36f2da78487e"><nc:close-session/></nc:rpc>]]>]]>
[DEBUG   ] [host 10.220.1.9 session-id 82730] parsing netconf v1.0
[DEBUG   ] [host 10.220.1.9 session-id 82730] parsing netconf v1.0
[DEBUG   ] [host 10.220.1.9 session-id 82730] parsing netconf v1.0
[INFO    ] [host 10.220.1.9 session-id 82730] Received message from host
[DEBUG   ] [host 10.220.1.9 session-id 82730] Received:
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/18.2R3/junos" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:f8b65a65-5563-46b3-a7a1-36f2da78487e">
<ok/>
</rpc-reply>
[DEBUG   ] [host 10.220.1.9 session-id 82730] dispatching message to different listeners: <rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/18.2R3/junos" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:f8b65a65-5563-46b3-a7a1-36f2da78487e">
<ok/>
</rpc-reply>

Versions Report

Salt Version:
           Salt: 3003.3
    Salt SProxy: 2021.6.1

Dependency Versions:
        Ansible: Not Installed
           cffi: 1.14.6
       dateutil: Not Installed
      docker-py: Not Installed
          gitdb: Not Installed
      gitpython: Not Installed
         Jinja2: 3.0.2
     junos-eznc: 2.6.3
       jxmlease: 1.0.3
        libgit2: Not Installed
       M2Crypto: Not Installed
           Mako: Not Installed
   msgpack-pure: Not Installed
 msgpack-python: 1.0.2
         NAPALM: 3.3.1
       ncclient: 0.6.9
        Netmiko: 3.4.0
       paramiko: 2.8.0
      pycparser: 2.20
       pycrypto: Not Installed
   pycryptodome: 3.11.0
         pyeapi: 0.8.4
         pygit2: Not Installed
       PyNetBox: Not Installed
          PyNSO: Not Installed
         Python: 3.8.10 (default, Sep 28 2021, 16:10:42)
   python-gnupg: Not Installed
         PyYAML: 5.4.1
          PyZMQ: 22.3.0
            scp: 0.14.1
          smmap: Not Installed
        textfsm: 1.1.2
        timelib: Not Installed
        Tornado: 4.5.3
            ZMQ: 4.3.4`

Just last note that the same set file+ net commands are working for another Junos code different than 18, tested on 20.4 and 15.1 with no similar problem

Wish it is clear, and thanks in advance.

Add kwargs to returner data.

Is your feature request related to a problem? Please describe.
Using a returner for event based automation. I'd like to see the key-value arguments passed to the salt-function.

Describe the solution you'd like
Could one append kwargs to fun_args in the data sent to the returner? I believe napalm does this.

Describe alternatives you've considered
forking.

Additional context
none

napalm grains not available during template rendering

Describe the bug
Grains collected by the napalm.py script are not available during rendering of pillar SLS files

Steps To Reproduce
I have a minion with the following grains:

# salt-sproxy cr-testing* grains.get id
cr-testing01.lab1:
    cr-testing01.lab1

# salt-sproxy cr-testing* grains.get model
cr-testing01.lab1:
    VMX

adding a test pillar:

# cat /srv/pillar/shared/test.sls
foo: {{ grains.get('id') }}
bar: {{ grains.get('model') }}

# cat /srv/pillar/top.sls
base:
  '*':
    - 'shared.general'
  'cr-testing01.lab1':
    - shared.test

result:

# salt-sproxy cr-testing* pillar.get foo
cr-testing01.lab1:
    cr-testing01.lab1

# salt-sproxy cr-testing* pillar.get bar
cr-testing01.lab1:
    None

Expected behavior
Expect the "bar" pillar data to contain the information of grains['model']

Versions Report

Salt Version:
           Salt: 3001.1
    Salt SProxy: 2020.7.0

Dependency Versions:
        Ansible: Not Installed
           cffi: 1.14.2
       dateutil: 2.7.3
      docker-py: Not Installed
          gitdb: 2.0.5
      gitpython: 2.1.11
         Jinja2: 2.10
     junos-eznc: 2.5.3
       jxmlease: Not Installed
        libgit2: 0.27.7
       M2Crypto: Not Installed
           Mako: Not Installed
   msgpack-pure: Not Installed
 msgpack-python: 0.5.6
         NAPALM: 3.1.0
       ncclient: 0.6.9
        Netmiko: 3.2.0
       paramiko: 2.7.2
      pycparser: 2.19
       pycrypto: 2.6.1
   pycryptodome: 3.6.1
         pyeapi: 0.8.3
         pygit2: 0.27.4
       PyNetBox: Not Installed
          PyNSO: Not Installed
         Python: 3.7.3 (default, Jul 25 2020, 13:03:44)
   python-gnupg: Not Installed
         PyYAML: 3.13
          PyZMQ: 17.1.2
            scp: 0.13.2
          smmap: 2.0.5
        textfsm: 1.1.0
        timelib: Not Installed
        Tornado: 4.5.3
            ZMQ: 4.3.1

System Versions:
           dist: debian 10 buster
         locale: utf-8
        machine: x86_64
        release: 4.19.0-10-amd64
         system: Linux
        version: Debian GNU/Linux 10 buster

Additional context
It seems that the napalm grains (salt/grains/napalm.py) are only merged into the grains dict after the pillars have been rendered:

2020-10-13 12:34:05,142 [salt.template    :127 ][DEBUG   ][14313] Rendered data from file: /srv/pillar/shared/test.sls:
[...]
2020-10-13 12:34:08,780 [salt.loaded.ext.runners.proxy:665 ][DEBUG   ][14313] Caching Grains for cr-testing01.lab1
2020-10-13 12:34:08,780 [salt.loaded.ext.runners.proxy:666 ][DEBUG   ][14313] OrderedDict([('foo', 'bar'), ('cwd', '/root'), ('ip_gw', True), ('ip4_gw', '62.138.167.49'), ('ip6_gw', False), ('dns', {'nameservers': ['80.237.128.144', '80.237.128.145', '8.8.8.8'], 'ip4_nameservers': ['80.237.128.144', '80.237.128.145', '8.8.8.8'], 'ip6_nameservers': [], 'sortlist': [], 'domain': '', 'search': ['bb.gdinf.net', 'bb.godaddy.com', 'lab.mass.systems', 'cse.mass.systems', 'mass.systems', 'intern.hosteurope.de', 'hosteurope.de'], 'options': []}), ('fqdns', []), ('machine_id', 'f6183af91209426f812aca156ae54f5a'), ('master', 'salt'), ('hwaddr_interfaces', {'lo': '00:00:00:00:00:00', 'eth0': '02:ce:0a:5d:c0:49'}), ('id', 'cr-testing01.lab1'), ('kernelparams', [('BOOT_IMAGE', '/boot/vmlinuz-4.19.0-10-amd64'), ('root', None), ('ro', None), ('quiet', None)]), ('locale_info', {}), ('num_gpus', 0), ('gpus', []), ('kernel', 'proxy'), ('nodename', 'salt-gbone.lab.mass.systems'), ('kernelrelease', 'proxy'), ('kernelversion', 'proxy'), ('cpuarch', 'x86_64'), ('osrelease', 'proxy'), ('os', 'junos'), ('os_family', 'proxy'), ('osfullname', 'proxy'), ('osarch', 'x86_64'), ('mem_total', 0), ('virtual', 'LXC'), ('ps', 'ps -efHww'), ('osrelease_info', ('proxy',)), ('osfinger', 'proxy-proxy'), ('path', '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'), ('systempath', ['/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin']), ('pythonexecutable', '/usr/bin/python3'), ('pythonpath', ['/usr/lib/python3/dist-packages/git/ext/gitdb', '/usr/local/bin', '/usr/lib/python37.zip', '/usr/lib/python3.7', '/usr/lib/python3.7/lib-dynload', '/usr/local/lib/python3.7/dist-packages', '/usr/lib/python3/dist-packages', '/usr/lib/python3/dist-packages/gitdb/ext/smmap']), ('pythonversion', [3, 7, 3, 'final', 0]), ('saltpath', '/usr/lib/python3/dist-packages/salt'), ('saltversion', '3001.1'), ('saltversioninfo', [3001, 1]), ('zmqversion', '4.3.1'), ('disks', []), ('ssds', ['sdb', 'sda']), ('shell', '/bin/bash'), ('username', None), ('groupname', 'root'), ('pid', 14313), ('gid', 0), ('uid', 0), ('zfs_support', False), ('zfs_feature_flags', False), ('host', 'cr-testing01.lab1'), ('hostname', 'cr-testing01.lab1'), ('interfaces', ['ge-0/0/0', 'lc-0/0/0', 'pfe-0/0/0', 'pfh-0/0/0', 'ge-0/0/1', 'ge-0/0/2', 'ge-0/0/3', 'ge-0/0/4', 'ge-0/0/5', 'ge-0/0/6', 'ge-0/0/7', 'ge-0/0/8', 'ge-0/0/9', 'cbp0', 'demux0', 'dsc', 'em1', 'esi', 'fxp0', 'gre', 'ipip', 'irb', 'jsrv', 'lo0', 'lsi', 'mtun', 'pimd', 'pime', 'pip0', 'pp0', 'rbeb', 'tap', 'vtep']), ('model', 'VMX'), ('optional_args', {'config_lock': False, 'keepalive': 5}), ('serial', 'VM5B598A6585'), ('uptime', 2505569), ('vendor', 'Juniper'), ('version', '17.4R1.16')])

After modifying the test.sls like so

# cat /srv/pillar/shared/test.sls
foo: {{ grains.get('id') }}
bar: {{ grains.get('model') }}

{% for k in grains.keys() %}
{%- do salt.log.error(k) -%}
{% endfor %}

these are the grains keys available at SLS rendering:

# salt-sproxy cr-testing* pillar.get bar
[ERROR   ] cwd
[ERROR   ] ip_gw
[ERROR   ] ip4_gw
[ERROR   ] ip6_gw
[ERROR   ] dns
[ERROR   ] fqdns
[ERROR   ] machine_id
[ERROR   ] master
[ERROR   ] hwaddr_interfaces
[ERROR   ] id
[ERROR   ] kernelparams
[ERROR   ] locale_info
[ERROR   ] num_gpus
[ERROR   ] gpus
[ERROR   ] kernel
[ERROR   ] nodename
[ERROR   ] kernelrelease
[ERROR   ] kernelversion
[ERROR   ] cpuarch
[ERROR   ] osrelease
[ERROR   ] os
[ERROR   ] os_family
[ERROR   ] osfullname
[ERROR   ] osarch
[ERROR   ] mem_total
[ERROR   ] virtual
[ERROR   ] ps
[ERROR   ] osrelease_info
[ERROR   ] osfinger
[ERROR   ] path
[ERROR   ] systempath
[ERROR   ] pythonexecutable
[ERROR   ] pythonpath
[ERROR   ] pythonversion
[ERROR   ] saltpath
[ERROR   ] saltversion
[ERROR   ] saltversioninfo
[ERROR   ] zmqversion
[ERROR   ] disks
[ERROR   ] ssds
[ERROR   ] shell
[ERROR   ] username
[ERROR   ] groupname
[ERROR   ] pid
[ERROR   ] gid
[ERROR   ] uid
[ERROR   ] zfs_support
[ERROR   ] zfs_feature_flags
cr-testing01.lab1:
    None

As you can see it's missing the following keys

-host
-hostname
-interfaces
-model
-optional_args
-serial
-uptime
-vendor
-version

which as far as I can see are all gathered in napalm.py

Question: Error loading grains.napalm: "napalm""

Hello @mirceaulinic ,

salt-sproxy works fine... , but while debugging another problem I stumbled across the following line in my trace.log.

[TRACE   ] Error loading grains.napalm: "napalm"" (/root/venvs/salt-sproxy/lib/python3.7/site-packages/salt/grains/napalm.py) cannot be loaded: NAPALM is not installed: ``p
ip install napalm``

The file exists and works.

(salt-sproxy) root@debian10:/home/vagrant# ls /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt/grains/napalm.py
/root/venvs/salt-sproxy/lib/python3.7/site-packages/salt/grains/napalm.py
(salt-sproxy) root@debian10:/home/vagrant# head 10  /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt/grains/napalm.py
head: cannot open '10' for reading: No such file or directory
==> /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt/grains/napalm.py <==
# -*- coding: utf-8 -*-
'''
NAPALM Grains
=============

:codeauthor: Mircea Ulinic <[email protected]>
:maturity:   new
:depends:    napalm
:platform:   unix

Is this just a cosmetic thing ?

Because I don't waste your time I setup a brand new vm with debian and the "problem" there exists as well.

How did I install ?
1 . Used your install script.
2. pip install napalm

Systeminfo :
System Debian 10

(salt-sproxy) root@debian10:/home/vagrant# cat piplist.txt
Package        Version
-------------- ----------
bcrypt         3.1.7
certifi        2020.4.5.1
cffi           1.14.0
chardet        3.0.4
ciscoconfparse 1.5.4
colorama       0.4.3
cryptography   2.9.2
dnspython      1.16.0
future         0.18.2
idna           2.9
Jinja2         2.11.2
junos-eznc     2.2.1
lxml           4.5.0
MarkupSafe     1.1.1
msgpack        0.6.2
napalm         2.5.0
ncclient       0.6.7
netaddr        0.7.19
netmiko        2.4.2
nxapi-plumbing 0.5.2
paramiko       2.7.1
passlib        1.7.2
pip            20.1
pkg-resources  0.0.0
progressbar2   3.51.1
pycparser      2.20
pycrypto       2.6.1
pyeapi         0.8.3
pyIOSXR        0.53
PyNaCl         1.3.0
pyserial       3.4
python-utils   2.4.0
PyYAML         5.3.1
pyzmq          19.0.0
requests       2.23.0
salt           3000.2
salt-sproxy    2020.3.0
scp            0.13.2
setuptools     46.1.3
six            1.14.0
textfsm        1.1.0
urllib3        1.25.9
wheel          0.34.2
/root/venvs/salt-sproxy/lib/python3.7/site-packages/salt/ext/tornado/httputil.py:107: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
  class HTTPHeaders(collections.MutableMapping):
[DEBUG   ] Reading configuration from /etc/salt/master
[DEBUG   ] Missing configuration file: /root/.saltrc
[TRACE   ] The required configuration section, 'fluent_handler', was not found the in the configuration. Not loading the fluent logging handlers module.
[TRACE   ] None of the required configuration sections, 'logstash_udp_handler' and 'logstash_zmq_handler', were found in the configuration. Not loading the Logstash logging handlers module.
[DEBUG   ] Configuration file path: /etc/salt/master
[WARNING ] Insecure logging configuration detected! Sensitive data may be logged.
[DEBUG   ] Syncing roster
[DEBUG   ] LazyLoaded saltutil.sync_roster
[DEBUG   ] Reading configuration from /etc/salt/master
[DEBUG   ] Guessing ID. The id can be explicitly set in /etc/salt/minion
[DEBUG   ] Found minion id from generate_minion_id(): debian10.localdomain
[DEBUG   ] Grains refresh requested. Refreshing grains.
[DEBUG   ] Reading configuration from /etc/salt/master
[WARNING ] /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt/utils/dictdiffer.py:16: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
  from collections import Mapping

[TRACE   ] 'esxcli' could not be found in the following search path: '['/root/venvs/salt-sproxy/bin', '/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin']'
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False, False) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False, False) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False, False) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False, False) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False, False) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False, False) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False, False) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False, False) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Depends decorator instantiated with dep list of (False,) and kwargs {}
[TRACE   ] Error loading grains.napalm: "napalm"" (/root/venvs/salt-sproxy/lib/python3.7/site-packages/salt/grains/napalm.py) cannot be loaded: NAPALM is not installed: ``pip install napalm``
[TRACE   ] Loading core.append_domain grain
[TRACE   ] Loading core.cwd grain
[TRACE   ] Loading core.default_gateway grain
[TRACE   ] Loading core.dns grain
[TRACE   ] Loading core.fqdns grain
[TRACE   ] Loading core.get_machine_id grain
[TRACE   ] Loading core.get_master grain
[TRACE   ] Loading core.get_server_id grain
[TRACE   ] Loading core.hostname grain
[TRACE   ] Loading core.hwaddr_interfaces grain
[TRACE   ] Loading core.id_ grain
[TRACE   ] Loading core.ip4_interfaces grain
[TRACE   ] Loading core.ip6_interfaces grain
[TRACE   ] Loading core.ip_fqdn grain
[TRACE   ] Loading core.ip_interfaces grain
[TRACE   ] Loading core.linux_distribution grain
[TRACE   ] Loading core.locale_info grain
[TRACE   ] Loading core.os_data grain
[TRACE   ] 'virt-what' could not be found in the following search path: '['/root/venvs/salt-sproxy/bin', '/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin']'
[DEBUG   ] Unable to derive osmajorrelease from osrelease_info '('proxy',)'. The osmajorrelease grain will not be set.
[TRACE   ] Loading core.path grain
[TRACE   ] Loading core.pythonexecutable grain
[TRACE   ] Loading core.pythonpath grain
[TRACE   ] Loading core.pythonversion grain
[TRACE   ] Loading core.saltpath grain
[TRACE   ] Loading core.saltversion grain
[TRACE   ] Loading core.saltversioninfo grain
[TRACE   ] Loading core.zmqversion grain
[TRACE   ] Loading disks.disks grain
[TRACE   ] Device sr0 reports itself as an HDD
[TRACE   ] Device sda reports itself as an HDD
[TRACE   ] Loading extra.config grain
[TRACE   ] Loading extra.shell grain
[TRACE   ] Loading mdadm.mdadm grain
[TRACE   ] Loading minion_process.grains grain
[TRACE   ] Loading opts.opts grain
[TRACE   ] Loading zfs.zfs grain
[DEBUG   ] LazyLoaded zfs.is_supported
[TRACE   ] 'zfs-fuse' could not be found in the following search path: '['/root/venvs/salt-sproxy/bin', '/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin']'
[TRACE   ] 'zpool' could not be found in the following search path: '['/root/venvs/salt-sproxy/bin', '/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin']'
[DEBUG   ] MasterEvent PUB socket URI: /etc/salt/var/run/salt/master/master_event_pub.ipc
[DEBUG   ] MasterEvent PULL socket URI: /etc/salt/var/run/salt/master/master_event_pull.ipc
[TRACE   ] Error loading runners.bgp: The napalm-base module could not be imported
[TRACE   ] Error loading runners.nacl: libnacl import error, perhaps missing python libnacl package or should update.
[TRACE   ] Error loading runners.net: The napalm-base module could not be imported
[TRACE   ] Loaded smartos_vmadm as virtual vmadm
[TRACE   ] Error loading runners.spacewalk: No spacewalk configuration found
[TRACE   ] Error loading runners.vistara: vistara config has not been specificed in the Salt master config. See documentation for this runner.
[TRACE   ] IPCClient: Connecting to socket: /etc/salt/var/run/salt/master/master_event_pull.ipc
[TRACE   ] IPCClient: Connecting to socket: /etc/salt/var/run/salt/master/master_event_pull.ipc
[DEBUG   ] LazyLoaded roots.envs
[DEBUG   ] Could not LazyLoad roots.init: 'roots.init' is not available.
[DEBUG   ] Updating roots fileserver cache
[INFO    ] Syncing roster for environment 'base'
[INFO    ] Loading cache from salt://_roster, for base)
[INFO    ] Caching directory '_roster/' for environment 'base'
[TRACE   ] Lockfile /etc/salt/var/cache/salt/master/file_lists/roots/.base.w created
[TRACE   ] roots: Processing /srv/salt/pillar
[TRACE   ] roots: /srv/salt/pillar is not a link
[TRACE   ] roots: /srv/salt/pillar relative path is pillar
[TRACE   ] roots: Processing /srv/salt/pillar/top.sls
[TRACE   ] roots: /srv/salt/pillar/top.sls is not a link
[TRACE   ] roots: /srv/salt/pillar/top.sls relative path is pillar/top.sls
[TRACE   ] roots: Processing /srv/salt/pillar/napalm_proxy.sls
[TRACE   ] roots: /srv/salt/pillar/napalm_proxy.sls is not a link
[TRACE   ] roots: /srv/salt/pillar/napalm_proxy.sls relative path is pillar/napalm_proxy.sls
[TRACE   ] roots: Processing /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_modules
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_modules is not a link
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_modules relative path is _modules
[TRACE   ] roots: Processing /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_runners
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_runners is not a link
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_runners relative path is _runners
[TRACE   ] roots: Processing /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/__pycache__
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/__pycache__ is not a link
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/__pycache__ relative path is __pycache__
[TRACE   ] roots: Processing /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster is not a link
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster relative path is _roster
[TRACE   ] roots: Processing /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/parsers.py
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/parsers.py is not a link
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/parsers.py relative path is parsers.py
[TRACE   ] roots: Processing /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/cli.py
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/cli.py is not a link
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/cli.py relative path is cli.py
[TRACE   ] roots: Processing /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/scripts.py
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/scripts.py is not a link
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/scripts.py relative path is scripts.py
[TRACE   ] roots: Processing /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/version.py
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/version.py is not a link
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/version.py relative path is version.py
[TRACE   ] roots: Processing /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_modules/__pycache__
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_modules/__pycache__ is not a link
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_modules/__pycache__ relative path is _modules/__pycache__
[TRACE   ] roots: Processing /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_modules/netbox.py
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_modules/netbox.py is not a link
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_modules/netbox.py relative path is _modules/netbox.py
[TRACE   ] roots: Processing /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_modules/__pycache__/netbox.cpython-37.pyc
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_modules/__pycache__/netbox.cpython-37.pyc is not a link
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_modules/__pycache__/netbox.cpython-37.pyc relative path is _modules/__pycache__/netbox.cpython-37.pyc
[TRACE   ] roots: Processing /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_runners/__pycache__
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_runners/__pycache__ is not a link
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_runners/__pycache__ relative path is _runners/__pycache__
[TRACE   ] roots: Processing /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_runners/__init__.py
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_runners/__init__.py is not a link
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_runners/__init__.py relative path is _runners/__init__.py
[TRACE   ] roots: Processing /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_runners/proxy.py
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_runners/proxy.py is not a link
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_runners/proxy.py relative path is _runners/proxy.py
[TRACE   ] roots: Processing /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_runners/__pycache__/__init__.cpython-37.pyc
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_runners/__pycache__/__init__.cpython-37.pyc is not a link
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_runners/__pycache__/__init__.cpython-37.pyc relative path is _runners/__pycache__/__init__.cpython-37.pyc
[TRACE   ] roots: Processing /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_runners/__pycache__/proxy.cpython-37.pyc
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_runners/__pycache__/proxy.cpython-37.pyc is not a link
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_runners/__pycache__/proxy.cpython-37.pyc relative path is _runners/__pycache__/proxy.cpython-37.pyc
[TRACE   ] roots: Processing /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/__pycache__/scripts.cpython-37.pyc
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/__pycache__/scripts.cpython-37.pyc is not a link
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/__pycache__/scripts.cpython-37.pyc relative path is __pycache__/scripts.cpython-37.pyc
[TRACE   ] roots: Processing /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/__pycache__/parsers.cpython-37.pyc
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/__pycache__/parsers.cpython-37.pyc is not a link
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/__pycache__/parsers.cpython-37.pyc relative path is __pycache__/parsers.cpython-37.pyc
[TRACE   ] roots: Processing /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/__pycache__/version.cpython-37.pyc
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/__pycache__/version.cpython-37.pyc is not a link
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/__pycache__/version.cpython-37.pyc relative path is __pycache__/version.cpython-37.pyc
[TRACE   ] roots: Processing /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/__pycache__/cli.cpython-37.pyc
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/__pycache__/cli.cpython-37.pyc is not a link
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/__pycache__/cli.cpython-37.pyc relative path is __pycache__/cli.cpython-37.pyc
[TRACE   ] roots: Processing /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster/__pycache__
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster/__pycache__ is not a link
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster/__pycache__ relative path is _roster/__pycache__
[TRACE   ] roots: Processing /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster/pillar.py
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster/pillar.py is not a link
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster/pillar.py relative path is _roster/pillar.py
[TRACE   ] roots: Processing /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster/__init__.py
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster/__init__.py is not a link
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster/__init__.py relative path is _roster/__init__.py
[TRACE   ] roots: Processing /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster/netbox.py
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster/netbox.py is not a link
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster/netbox.py relative path is _roster/netbox.py
[TRACE   ] roots: Processing /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster/ansible.py
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster/ansible.py is not a link
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster/ansible.py relative path is _roster/ansible.py
[TRACE   ] roots: Processing /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster/file.py
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster/file.py is not a link
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster/file.py relative path is _roster/file.py
[TRACE   ] roots: Processing /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster/__pycache__/__init__.cpython-37.pyc
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster/__pycache__/__init__.cpython-37.pyc is not a link
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster/__pycache__/__init__.cpython-37.pyc relative path is _roster/__pycache__/__init__.cpython-37.pyc
[TRACE   ] roots: Processing /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster/__pycache__/ansible.cpython-37.pyc
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster/__pycache__/ansible.cpython-37.pyc is not a link
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster/__pycache__/ansible.cpython-37.pyc relative path is _roster/__pycache__/ansible.cpython-37.pyc
[TRACE   ] roots: Processing /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster/__pycache__/file.cpython-37.pyc
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster/__pycache__/file.cpython-37.pyc is not a link
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster/__pycache__/file.cpython-37.pyc relative path is _roster/__pycache__/file.cpython-37.pyc
[TRACE   ] roots: Processing /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster/__pycache__/pillar.cpython-37.pyc
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster/__pycache__/pillar.cpython-37.pyc is not a link
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster/__pycache__/pillar.cpython-37.pyc relative path is _roster/__pycache__/pillar.cpython-37.pyc
[TRACE   ] roots: Processing /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster/__pycache__/netbox.cpython-37.pyc
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster/__pycache__/netbox.cpython-37.pyc is not a link
[TRACE   ] roots: /root/venvs/salt-sproxy/lib/python3.7/site-packages/salt_sproxy/_roster/__pycache__/netbox.cpython-37.pyc relative path is _roster/__pycache__/netbox.cpython-37.pyc
[TRACE   ] Lockfile /etc/salt/var/cache/salt/master/file_lists/roots/.base.w removed
[DEBUG   ] In saltenv 'base', looking at rel_path '_roster/__init__.py' to resolve 'salt://_roster/__init__.py'
[DEBUG   ] In saltenv 'base', ** considering ** path '/etc/salt/var/cache/salt/master/files/base/_roster/__init__.py' to resolve 'salt://_roster/__init__.py'
[DEBUG   ] In saltenv 'base', looking at rel_path '_roster/ansible.py' to resolve 'salt://_roster/ansible.py'
[DEBUG   ] In saltenv 'base', ** considering ** path '/etc/salt/var/cache/salt/master/files/base/_roster/ansible.py' to resolve 'salt://_roster/ansible.py'
[DEBUG   ] In saltenv 'base', looking at rel_path '_roster/file.py' to resolve 'salt://_roster/file.py'
[DEBUG   ] In saltenv 'base', ** considering ** path '/etc/salt/var/cache/salt/master/files/base/_roster/file.py' to resolve 'salt://_roster/file.py'
[DEBUG   ] In saltenv 'base', looking at rel_path '_roster/netbox.py' to resolve 'salt://_roster/netbox.py'
[DEBUG   ] In saltenv 'base', ** considering ** path '/etc/salt/var/cache/salt/master/files/base/_roster/netbox.py' to resolve 'salt://_roster/netbox.py'
[DEBUG   ] In saltenv 'base', looking at rel_path '_roster/pillar.py' to resolve 'salt://_roster/pillar.py'
[DEBUG   ] In saltenv 'base', ** considering ** path '/etc/salt/var/cache/salt/master/files/base/_roster/pillar.py' to resolve 'salt://_roster/pillar.py'
[DEBUG   ] Local cache dir: '/etc/salt/var/cache/salt/master/files/base/_roster'
[INFO    ] Copying '/etc/salt/var/cache/salt/master/files/base/_roster/__init__.py' to '/etc/salt/var/cache/salt/master/extmods/roster/__init__.py'
[INFO    ] Copying '/etc/salt/var/cache/salt/master/files/base/_roster/ansible.py' to '/etc/salt/var/cache/salt/master/extmods/roster/ansible.py'
[INFO    ] Copying '/etc/salt/var/cache/salt/master/files/base/_roster/file.py' to '/etc/salt/var/cache/salt/master/extmods/roster/file.py'
[INFO    ] Copying '/etc/salt/var/cache/salt/master/files/base/_roster/netbox.py' to '/etc/salt/var/cache/salt/master/extmods/roster/netbox.py'
[INFO    ] Copying '/etc/salt/var/cache/salt/master/files/base/_roster/pillar.py' to '/etc/salt/var/cache/salt/master/extmods/roster/pillar.py'
[DEBUG   ] LazyLoaded local_cache.prep_jid
[TRACE   ] IPCClient: Connecting to socket: /etc/salt/var/run/salt/master/master_event_pull.ipc
[TRACE   ] IPCClient: Connecting to socket: /etc/salt/var/run/salt/master/master_event_pull.ipc
[INFO    ] Runner completed: 20200501143909284226
[DEBUG   ] []
[DEBUG   ] LazyLoaded proxy.execute
[DEBUG   ] Reading configuration from /etc/salt/master
[DEBUG   ] Guessing ID. The id can be explicitly set in /etc/salt/minion
[DEBUG   ] Found minion id from generate_minion_id(): debian10.localdomain
[DEBUG   ] Grains refresh requested. Refreshing grains.
[DEBUG   ] Reading configuration from /etc/salt/master
[TRACE   ] Error loading grains.napalm: "napalm"" (/root/venvs/salt-sproxy/lib/python3.7/site-packages/salt/grains/napalm.py) cannot be loaded: NAPALM is not installed: ``pip install napalm``
[TRACE   ] Loading core.append_domain grain
[TRACE   ] Loading core.cwd grain
[TRACE   ] Loading core.default_gateway grain
[TRACE   ] Loading core.dns grain
[TRACE   ] Loading core.fqdns grain
[TRACE   ] Loading core.get_machine_id grain
[TRACE   ] Loading core.get_master grain
[TRACE   ] Loading core.get_server_id grain
[TRACE   ] Loading core.hostname grain
[TRACE   ] Loading core.hwaddr_interfaces grain
[TRACE   ] Loading core.id_ grain
[TRACE   ] Loading core.ip4_interfaces grain
[TRACE   ] Loading core.ip6_interfaces grain
[TRACE   ] Loading core.ip_fqdn grain
[TRACE   ] Loading core.ip_interfaces grain
[TRACE   ] Loading core.linux_distribution grain
[TRACE   ] Loading core.locale_info grain
[TRACE   ] Loading core.os_data grain
[TRACE   ] 'virt-what' could not be found in the following search path: '['/root/venvs/salt-sproxy/bin', '/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin']'
[DEBUG   ] Unable to derive osmajorrelease from osrelease_info '('proxy',)'. The osmajorrelease grain will not be set.
[TRACE   ] Loading core.path grain
[TRACE   ] Loading core.pythonexecutable grain
[TRACE   ] Loading core.pythonpath grain
[TRACE   ] Loading core.pythonversion grain
[TRACE   ] Loading core.saltpath grain
[TRACE   ] Loading core.saltversion grain
[TRACE   ] Loading core.saltversioninfo grain
[TRACE   ] Loading core.zmqversion grain
[TRACE   ] Loading disks.disks grain
[TRACE   ] Device sr0 reports itself as an HDD
[TRACE   ] Device sda reports itself as an HDD
[TRACE   ] Loading extra.config grain
[TRACE   ] Loading extra.shell grain
[TRACE   ] Loading mdadm.mdadm grain
[TRACE   ] Loading minion_process.grains grain
[TRACE   ] Loading opts.opts grain
[TRACE   ] Loading zfs.zfs grain
[DEBUG   ] LazyLoaded zfs.is_supported
[TRACE   ] 'zfs-fuse' could not be found in the following search path: '['/root/venvs/salt-sproxy/bin', '/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin']'
[TRACE   ] 'zpool' could not be found in the following search path: '['/root/venvs/salt-sproxy/bin', '/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin']'
[DEBUG   ] MasterEvent PUB socket URI: /etc/salt/var/run/salt/master/master_event_pub.ipc
[DEBUG   ] MasterEvent PULL socket URI: /etc/salt/var/run/salt/master/master_event_pull.ipc
[TRACE   ] Error loading runners.bgp: The napalm-base module could not be imported
[TRACE   ] Error loading runners.nacl: libnacl import error, perhaps missing python libnacl package or should update.
[TRACE   ] Error loading runners.net: The napalm-base module could not be imported
[TRACE   ] Loaded smartos_vmadm as virtual vmadm
[TRACE   ] Error loading runners.spacewalk: No spacewalk configuration found
[TRACE   ] Error loading runners.vistara: vistara config has not been specificed in the Salt master config. See documentation for this runner.
[TRACE   ] IPCClient: Connecting to socket: /etc/salt/var/run/salt/master/master_event_pull.ipc
[TRACE   ] IPCClient: Connecting to socket: /etc/salt/var/run/salt/master/master_event_pull.ipc
[DEBUG   ] Computing the target using the file Roster
[DEBUG   ] LazyLoaded file.targets
[DEBUG   ] LazyLoaded jinja.render
[DEBUG   ] LazyLoaded yaml.render
[DEBUG   ] compile template: /etc/salt/roster
[DEBUG   ] Jinja search path: ['/etc/salt/var/cache/salt/master/files/base']
[DEBUG   ] LazyLoaded roots.envs
[DEBUG   ] Could not LazyLoad roots.init: 'roots.init' is not available.
[PROFILE ] Time (in seconds) to render '/etc/salt/roster' using 'jinja' renderer: 0.0692605972290039
[DEBUG   ] Rendered data from file: /etc/salt/roster:
device1:
  host: 172.16.173.136
  driver: ios

[DEBUG   ] Results of YAML rendering: 
OrderedDict([('device1', OrderedDict([('host', '172.16.173.136'), ('driver', 'ios')]))])
[PROFILE ] Time (in seconds) to render '/etc/salt/roster' using 'yaml' renderer: 0.0016980171203613281
[DEBUG   ] Glob matching on dict_items([('device1', {'minion_opts': OrderedDict([('host', '172.16.173.136'), ('driver', 'ios')])})]) ? *
[DEBUG   ] The target expression "*" (glob) matched the following:
[DEBUG   ] ['device1']
[DEBUG   ] LazyLoaded user.get_specific_user
[INFO    ] 1 devices matched the target, executing in 1 batches
[DEBUG   ] Executing sproxy normal run on the following devices (2 batch size):
[DEBUG   ] ['device1']
[DEBUG   ] Starting execution for device1
[DEBUG   ] LazyLoaded localfs.init_kwargs
[DEBUG   ] Cache file "/etc/salt/var/cache/salt/master/minions/device1.p" does not exist
[DEBUG   ] Grains refresh requested. Refreshing grains.
[DEBUG   ] Reading configuration from /etc/salt/master
[TRACE   ] Error loading grains.napalm: "napalm"" (/root/venvs/salt-sproxy/lib/python3.7/site-packages/salt/grains/napalm.py) cannot be loaded: NAPALM is not installed: ``pip install napalm``
[TRACE   ] Loading core.append_domain grain
[TRACE   ] Loading core.cwd grain
[TRACE   ] Loading core.default_gateway grain
[TRACE   ] Loading core.dns grain
[TRACE   ] Loading core.fqdns grain
[TRACE   ] Loading core.get_machine_id grain
[TRACE   ] Loading core.get_master grain
[TRACE   ] Loading core.get_server_id grain
[TRACE   ] Loading core.hostname grain
[TRACE   ] Loading core.hwaddr_interfaces grain
[TRACE   ] Loading core.id_ grain
[TRACE   ] Loading core.ip4_interfaces grain
[TRACE   ] Loading core.ip6_interfaces grain
[TRACE   ] Loading core.ip_fqdn grain
[TRACE   ] Loading core.ip_interfaces grain
[TRACE   ] Loading core.linux_distribution grain
[TRACE   ] Loading core.locale_info grain
[TRACE   ] Loading core.os_data grain
[TRACE   ] 'virt-what' could not be found in the following search path: '['/root/venvs/salt-sproxy/bin', '/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin']'
[DEBUG   ] Unable to derive osmajorrelease from osrelease_info '('proxy',)'. The osmajorrelease grain will not be set.
[TRACE   ] Loading core.path grain
[TRACE   ] Loading core.pythonexecutable grain
[TRACE   ] Loading core.pythonpath grain
[TRACE   ] Loading core.pythonversion grain
[TRACE   ] Loading core.saltpath grain
[TRACE   ] Loading core.saltversion grain
[TRACE   ] Loading core.saltversioninfo grain
[TRACE   ] Loading core.zmqversion grain
[TRACE   ] Loading disks.disks grain
[TRACE   ] Device sr0 reports itself as an HDD
[TRACE   ] Device sda reports itself as an HDD
[TRACE   ] Loading extra.config grain
[TRACE   ] Loading extra.shell grain
[TRACE   ] Loading mdadm.mdadm grain
[TRACE   ] Loading minion_process.grains grain
[TRACE   ] Loading opts.opts grain
[TRACE   ] Loading zfs.zfs grain
[DEBUG   ] LazyLoaded zfs.is_supported
[TRACE   ] 'zfs-fuse' could not be found in the following search path: '['/root/venvs/salt-sproxy/bin', '/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin']'
[TRACE   ] 'zpool' could not be found in the following search path: '['/root/venvs/salt-sproxy/bin', '/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin']'
[DEBUG   ] Determining pillar cache
[DEBUG   ] LazyLoaded jinja.render
[DEBUG   ] LazyLoaded yaml.render
[DEBUG   ] compile template: /srv/salt/pillar/top.sls
[DEBUG   ] Jinja search path: ['/srv/salt/pillar']
[PROFILE ] Time (in seconds) to render '/srv/salt/pillar/top.sls' using 'jinja' renderer: 0.019923925399780273
[DEBUG   ] Rendered data from file: /srv/salt/pillar/top.sls:
base:
  '*':
    - napalm_proxy

[DEBUG   ] Results of YAML rendering: 
OrderedDict([('base', OrderedDict([('*', ['napalm_proxy'])]))])
[PROFILE ] Time (in seconds) to render '/srv/salt/pillar/top.sls' using 'yaml' renderer: 0.037383317947387695
[DEBUG   ] LazyLoaded confirm_top.confirm_top
[DEBUG   ] LazyLoaded compound_match.match
[DEBUG   ] compound_match: device1 ? *
[DEBUG   ] LazyLoaded glob_match.match
[DEBUG   ] compound_match device1 ? "*" => "True"
[DEBUG   ] compile template: /srv/salt/pillar/napalm_proxy.sls
[DEBUG   ] Jinja search path: ['/srv/salt/pillar']
[PROFILE ] Time (in seconds) to render '/srv/salt/pillar/napalm_proxy.sls' using 'jinja' renderer: 0.006349802017211914
[DEBUG   ] Rendered data from file: /srv/salt/pillar/napalm_proxy.sls:
proxy:
  proxytype: napalm
  driver: ios
  host: device1
  username: cisco
  passwd: cisco
  optional_args:
    secret: cisco

[DEBUG   ] Results of YAML rendering: 
OrderedDict([('proxy', OrderedDict([('proxytype', 'napalm'), ('driver', 'ios'), ('host', 'device1'), ('username', 'cisco'), ('passwd', 'cisco'), ('optional_args', OrderedDict([('secret', 'cisco')]))]))])
[PROFILE ] Time (in seconds) to render '/srv/salt/pillar/napalm_proxy.sls' using 'yaml' renderer: 0.0039441585540771484
[TRACE   ] Loaded arista_pyeapi as virtual pyeapi
[TRACE   ] Error loading proxy.docker: Proxytype does not match: docker
[DEBUG   ] dummy proxy __virtual__() called...
[TRACE   ] Error loading proxy.esxcluster: The esxcluster proxy module did not load.
[TRACE   ] Error loading proxy.esxdatacenter: The esxdatacenter proxy module did not load.
[TRACE   ] Error loading proxy.esxi: The ESXi Proxy Minion module did not load.
[TRACE   ] 'racadm' could not be found in the following search path: '['/root/venvs/salt-sproxy/bin', '/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin']'
[TRACE   ] Error loading proxy.fx2: fx2 proxy minion needs "racadm" to be installed.
[TRACE   ] Loaded netmiko_px as virtual netmiko
[INFO    ] nxos proxy __virtual__() called...
[DEBUG   ] rest_sample proxy __virtual__() called...
[INFO    ] ssh_sample proxy __virtual__() called...
[TRACE   ] Error loading proxy.vcenter: The vcenter proxy module did not load.
[DEBUG   ] Trying to initialize the connection with the device
[DEBUG   ] Setting up NAPALM connection
[DEBUG   ] starting thread (client mode): 0x70c9f208
[DEBUG   ] Local version/idstring: SSH-2.0-paramiko_2.7.1
[DEBUG   ] Remote version/idstring: SSH-2.0-Cisco-1.25
[INFO    ] Connected (version 2.0, client Cisco-1.25)
[DEBUG   ] kex algos:['diffie-hellman-group-exchange-sha1', 'diffie-hellman-group14-sha1', 'diffie-hellman-group1-sha1'] server key:['ssh-rsa'] client encrypt:['aes128-ctr', 'aes192-ctr', 'aes256-ctr', 'aes128-cbc', '3des-cbc', 'aes192-cbc', 'aes256-cbc'] server encrypt:['aes128-ctr', 'aes192-ctr', 'aes256-ctr', 'aes128-cbc', '3des-cbc', 'aes192-cbc', 'aes256-cbc'] client mac:['hmac-sha1', 'hmac-sha1-96'] server mac:['hmac-sha1', 'hmac-sha1-96'] client compress:['none'] server compress:['none'] client lang:[''] server lang:[''] kex follows?False
[DEBUG   ] Kex agreed: diffie-hellman-group-exchange-sha1
[DEBUG   ] HostKey agreed: ssh-rsa
[DEBUG   ] Cipher agreed: aes128-ctr
[DEBUG   ] MAC agreed: hmac-sha1
[DEBUG   ] Compression agreed: none
[DEBUG   ] Got server p (2048 bits)
[DEBUG   ] kex engine KexGex specified hash_algo <built-in function openssl_sha1>
[DEBUG   ] Switch to new keys ...
[DEBUG   ] Adding ssh-rsa host key for 172.16.173.136: b'7b6dcbfe95b01f0cac8ea20f91483308'
[DEBUG   ] userauth is OK
[INFO    ] Auth banner: b"\r\n**************************************************************************\r\n* IOSv is strictly limited to use for evaluation, demonstration and IOS  *\r\n* education. IOSv is provided as-is and is not supported by Cisco's      *\r\n* Technical Advisory Center. Any use or disclosure, in whole or in part, *\r\n* of the IOSv Software or Documentation to any third party for any       *\r\n* purposes is expressly prohibited except as otherwise authorized by     *\r\n* Cisco in writing.                                                      *\r\n**************************************************************************"
[INFO    ] Authentication (password) successful!
[DEBUG   ] [chan 0] Max packet in: 32768 bytes
[DEBUG   ] [chan 0] Max packet out: 4096 bytes
[DEBUG   ] Secsh channel 0 opened.
[DEBUG   ] [chan 0] Sesch channel 0 request ok
[DEBUG   ] [chan 0] Sesch channel 0 request ok
[DEBUG   ] read_channel: 
**************************************************************************
* IOSv is strictly limited to use for evaluation, demonstration and IOS  *
* education. IOSv is provided as-is and is not supported by Cisco's      *
* Technical Advisory Center. Any use or disclosure, in whole or in part, *
* of the IOSv Software or Documentation to any third party for any       *
* purposes is expressly prohibited except as otherwise authorized by     *
* Cisco in writing.                                                      *
**************************************************************************
device1>
[DEBUG   ] read_channel: 
[DEBUG   ] read_channel: 
[DEBUG   ] read_channel: 
[DEBUG   ] write_channel: b'\n'
[DEBUG   ] read_channel: 
device1>
[DEBUG   ] read_channel: 
[DEBUG   ] read_channel: 
[DEBUG   ] In disable_paging
[DEBUG   ] Command: terminal length 0

[DEBUG   ] write_channel: b'terminal length 0\n'
[DEBUG   ] Pattern is: device1
[DEBUG   ] _read_channel_expect read_data: t
[DEBUG   ] _read_channel_expect read_data: erminal length 0
device1>
[DEBUG   ] Pattern found: device1 terminal length 0
device1>
[DEBUG   ] terminal length 0
device1>
[DEBUG   ] Exiting disable_paging
[DEBUG   ] write_channel: b'terminal width 511\n'
[DEBUG   ] Pattern is: device1
[DEBUG   ] _read_channel_expect read_data: t
[DEBUG   ] _read_channel_expect read_data: erminal width 511
device1>
[DEBUG   ] Pattern found: device1 terminal width 511
device1>
[DEBUG   ] read_channel: 
[DEBUG   ] write_channel: b'\n'
[DEBUG   ] Pattern is: device1
[DEBUG   ] _read_channel_expect read_data: 

[DEBUG   ] _read_channel_expect read_data: device1>
[DEBUG   ] Pattern found: device1 
device1>
[DEBUG   ] write_channel: b'enable\n'
[DEBUG   ] Pattern is: (device1|ssword)
[DEBUG   ] _read_channel_expect read_data: e
[DEBUG   ] _read_channel_expect read_data: nable
Password: 
[DEBUG   ] Pattern found: (device1|ssword) enable
Password: 
[DEBUG   ] write_channel: b'cisco\n'
[DEBUG   ] Pattern is: device1
[DEBUG   ] _read_channel_expect read_data: 
device1#
[DEBUG   ] Pattern found: device1 
device1#
[DEBUG   ] write_channel: b'\n'
[DEBUG   ] Pattern is: device1
[DEBUG   ] _read_channel_expect read_data: 

[DEBUG   ] _read_channel_expect read_data: device1#
[DEBUG   ] Pattern found: device1 
device1#
[DEBUG   ] Grains refresh requested. Refreshing grains.
[DEBUG   ] Reading configuration from /etc/salt/master
[TRACE   ] Loaded philips_hue as virtual hue
[TRACE   ] Loading core.append_domain grain
[TRACE   ] Loading core.cwd grain
[TRACE   ] Loading core.default_gateway grain
[TRACE   ] Loading core.dns grain
[TRACE   ] Loading core.fqdns grain
[TRACE   ] Loading core.get_machine_id grain
[TRACE   ] Loading core.get_master grain
[TRACE   ] Loading core.get_server_id grain
[TRACE   ] Loading core.hostname grain
[TRACE   ] Loading core.hwaddr_interfaces grain
[TRACE   ] Loading core.id_ grain
[TRACE   ] Loading core.ip4_interfaces grain
[TRACE   ] Loading core.ip6_interfaces grain
[TRACE   ] Loading core.ip_fqdn grain
[TRACE   ] Loading core.ip_interfaces grain
[TRACE   ] Loading core.linux_distribution grain
[TRACE   ] Loading core.locale_info grain
[TRACE   ] Loading core.os_data grain
[TRACE   ] 'virt-what' could not be found in the following search path: '['/root/venvs/salt-sproxy/bin', '/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin']'
[DEBUG   ] Unable to derive osmajorrelease from osrelease_info '('proxy',)'. The osmajorrelease grain will not be set.
[TRACE   ] Loading core.path grain
[TRACE   ] Loading core.pythonexecutable grain
[TRACE   ] Loading core.pythonpath grain
[TRACE   ] Loading core.pythonversion grain
[TRACE   ] Loading core.saltpath grain
[TRACE   ] Loading core.saltversion grain
[TRACE   ] Loading core.saltversioninfo grain
[TRACE   ] Loading core.zmqversion grain
[TRACE   ] Loading extra.config grain
[TRACE   ] Loading extra.shell grain
[TRACE   ] Loading napalm.getos grain
[TRACE   ] Loading napalm.host grain
[TRACE   ] Loading napalm.host_dns grain
[TRACE   ] Loading napalm.hostname grain
[DEBUG   ] read_channel: 
[DEBUG   ] write_channel: b'\n'
[DEBUG   ] read_channel: 
device1#
[DEBUG   ] read_channel: 
[DEBUG   ] read_channel: 
[DEBUG   ] write_channel: b'show version\n'
[DEBUG   ] read_channel: 
[DEBUG   ] read_channel: show version
Cisco IOS Software, IOSv Software (VIOS-ADVENTERPRISEK9-M), Version 15.6(2)T, RELEASE SOFTWARE (fc2)
Technical Support: http://www.cisco.com/techsupport
Copyright (c) 1986-2016 by Cisco Systems, Inc.
Compiled Tue 22-Mar-16 16:19 by prod_rel_team


ROM: Bootstrap program is IOSv

device1 uptime is 16 hours, 24 minutes
System returned to ROM by reload
System image file is "flash0:/vios-adventerprisek9-m"
Last reload reason: Unknown reason



This product contains cryptographic features and is subject to United
States and local country laws governing import, export, transfer and
use. Delivery of Cisco cryptographic products does not imply
third-party authority to import, export, distribute or use encryption.
Importers, exporters, distributors and users are responsible for
compliance with U.S. and local country laws. By using this product you
agree to comply with applicable laws and regulations. If you are unable
to comply with U.S. and local laws, return this product immediately.

A summary of U.S. laws governing Cisco cryptographic products may be found at:
http://www.cisco.com/wwl/export/crypto/tool/stqrg.html

If you require further assistance please contact us by sending email to
[email protected].

Cisco IOSv (revision 1.0) with  with 460017K/62464K bytes of memory.
Processor board ID 9SEJR9Z0HO99WUQ2NX5BB
4 Gigabit Ethernet interfaces
DRAM configuration is 72 bits wide with parity disabled.
256K bytes of non-volatile configuration memory.
2097152K bytes of ATA System CompactFlash 0 (Read/Write)
0K bytes of ATA CompactFlash 1 (Read/Write)
1024K bytes of ATA CompactFlash 2 (Read/Write)
0K bytes of ATA CompactFlash 3 (Read/Write)



Configuration register is 0x0

device1#
[DEBUG   ] read_channel: 
[DEBUG   ] write_channel: b'\n'
[DEBUG   ] read_channel: 
device1#
[DEBUG   ] read_channel: 
[DEBUG   ] read_channel: 
[DEBUG   ] write_channel: b'show hosts\n'
[DEBUG   ] read_channel: 
[DEBUG   ] read_channel: show hosts
Default domain is cisco.local
Name/address lookup uses static mappings

Codes: UN - unknown, EX - expired, OK - OK, ?? - revalidate
       temp - temporary, perm - permanent
       NA - Not Applicable None - Not defined

Host                      Port  Flags      Age Type   Address(es)
device1#
[DEBUG   ] read_channel: 
[DEBUG   ] write_channel: b'\n'
[DEBUG   ] read_channel: 
device1#
[DEBUG   ] read_channel: 
[DEBUG   ] read_channel: 
[DEBUG   ] write_channel: b'show ip interface brief\n'
[DEBUG   ] read_channel: 
[DEBUG   ] read_channel: show ip interface brief
Interface                  IP-Address      OK? Method Status                Protocol
GigabitEthernet0/0         172.16.173.136  YES DHCP   up                    up      
GigabitEthernet0/1         unassigned      YES unset  administratively down down    
GigabitEthernet0/2         unassigned      YES unset  administratively down down    
GigabitEthernet0/3         unassigned      YES unset  administratively down down    
device1#
[TRACE   ] Loading napalm.interfaces grain
[TRACE   ] Loading napalm.model grain
[TRACE   ] Loading napalm.optional_args grain
[TRACE   ] Loading napalm.serial grain
[TRACE   ] Loading napalm.uptime grain
[TRACE   ] Loading napalm.username grain
[TRACE   ] Loading napalm.vendor grain
[TRACE   ] Loading napalm.version grain
[DEBUG   ] LazyLoaded grains.ls
[DEBUG   ] write_channel: b'\n'
[DEBUG   ] Pattern is: #
[DEBUG   ] _read_channel_expect read_data: 

[DEBUG   ] _read_channel_expect read_data: device1#
[DEBUG   ] Pattern found: # 
device1#
[DEBUG   ] exit_config_mode: 
[DEBUG   ] write_channel: b'exit\n'
[DEBUG   ] EOF in transport thread
[DEBUG   ] LazyLoaded nested.output
[DEBUG   ] LazyLoaded local_cache.prep_jid
[TRACE   ] IPCClient: Connecting to socket: /etc/salt/var/run/salt/master/master_event_pull.ipc
[TRACE   ] IPCClient: Connecting to socket: /etc/salt/var/run/salt/master/master_event_pull.ipc
[DEBUG   ] LazyLoaded nested.output
[TRACE   ] data = 
[INFO    ] Runner completed: 20200501143911708911
[DEBUG   ] Runner return: 
device1:
    - SSDs
    - cpuarch
    - cwd
    - disks
    - dns
    - fqdns
    - gid
    - gpus
    - groupname
    - host
    - hostname
    - hwaddr_interfaces
    - id
    - interfaces
    - ip4_gw
    - ip6_gw
    - ip_gw
    - kernel
    - kernelrelease
    - kernelversion
    - locale_info
    - machine_id
    - master
    - mem_total
    - model
    - nodename
    - num_gpus
    - optional_args
    - os
    - os_family
    - osarch
    - osfinger
    - osfullname
    - osrelease
    - osrelease_info
    - path
    - pid
    - ps
    - pythonexecutable
    - pythonpath
    - pythonversion
    - saltpath
    - saltversion
    - saltversioninfo
    - serial
    - shell
    - uid
    - uptime
    - username
    - vendor
    - version
    - virtual
    - zfs_feature_flags
    - zfs_support
    - zmqversion
[DEBUG   ] Closing IPCMessageClient instance

Question: Is globbing supported for pillar rosters?

Versions:
salt-sproxy 2020.2.0
Salt: 3000

I have a pillar that looks like this.

top.sls:

base:
    - devices
    - proxy

proxy.sls:

proxy:
    proxytype: napalm
    driver: ios
    username: sproxy
    passwd: hunter2
    host: {{ opts.id}}.contoso.com

devices.sls

devices:
    - name: switch-alpha
    - name: switch-bravo

My /etc/salt/master has the following section:

# Pass in an alternative location for the salt-ssh roster file
#roster_file: /etc/salt/roster
roster_file: pillar

However if I run
sudo salt-sproxy '*' test.ping

No devices matched your target. Please review your tgt / tgt_type arguments, or the Roster data source

Am I doing something wrong?

This snippet from https://salt-sproxy.readthedocs.io/en/latest/roster.html
image. Seems to indicate what I'm doing should work like the salt cli.

sudo salt-sproxy \* --preview-target results in the same No devices message as above.

Running sudo salt-run pillar.show_pillar shows:

devices:
    |_
      ----------
      name:
          switch-alpha
    |_
      ----------
      name:
          switch-bravo

Salt 3004 custom modules in state module not access able

Hey @mirceaulinic

Describe the bug
I am trying to use a custom module in a state file

Running the execution module via cli does work.

Steps To Reproduce
salt-sproxy --sync-all 'xxxx' state.show_sls test_no_custom_mod

{% set custom  = salt['mymodule.my_module_func']() %}

test_output_test:
  test.show_notification:
    - name: Test
    - text: 'Test'
test_output:
  test.show_notification:
    - name: Test
    - text: {{custom}}
│[ERROR   ] Rendering exception occurred
│Traceback (most recent call last):
│  File "/home/myuser/venv/test/lib64/python3.8/site-packages/salt/utils/templates.py", line 502, in render_jinja_tmpl
│    output = template.render(**decoded_context)
│  File "/home/myuser/venv/test/lib64/python3.8/site-packages/jinja2/environment.py", line 1291, in render
│    self.environment.handle_exception()
┤  File "/home/myuser/venv/test/lib64/python3.8/site-packages/jinja2/environment.py", line 925, in handle_exception
│    raise rewrite_traceback_stack(source=source)
│  File "<template>", line 1, in top-level template code
│  File "/home/myuser/venv/test/lib64/python3.8/site-packages/jinja2/sandbox.py", line 391, in call
│    if not __self.is_safe_callable(__obj):
│  File "/home/myuser/venv/test/lib64/python3.8/site-packages/jinja2/sandbox.py", line 275, in is_safe_callable
│    getattr(obj, "unsafe_callable", False) or getattr(obj, "alters_data", False)
│jinja2.exceptions.UndefinedError: 'salt.utils.templates.AliasedLoader object' has no attribute 'mymodule.my_module_func'
│
│During handling of the above exception, another exception occurred:
│
│Traceback (most recent call last):
│  File "/home/myuser/venv/test/lib64/python3.8/site-packages/salt/utils/templates.py", line 261, in render_tmpl
│    output = render_str(tmplstr, context, tmplpath)
│  File "/home/myuser/venv/test/lib64/python3.8/site-packages/salt/utils/templates.py", line 509, in render_jinja_tmpl
│    raise SaltRenderError("Jinja variable {}{}".format(exc, out), buf=tmplstr)
│salt.exceptions.SaltRenderError: Jinja variable 'salt.utils.templates.AliasedLoader object' has no attribute 'mymodule.my_module_func'
│[CRITICAL] Rendering SLS 'base:states.mymodule.test_no_custom_mod' failed: Jinja variable 'salt.utils.templates.AliasedLoader object' has no att
│ribute 'mymodule.my_module_func'

This worked without issues on Salt 3000 . I can't recreate the problem with a regular minion.

╰─ salt-sproxy -V
Salt Version:
           Salt: 3004
    Salt SProxy: 2021.6.1

Dependency Versions:
        Ansible: Not Installed
           cffi: 1.15.0
       dateutil: Not Installed
      docker-py: Not Installed
          gitdb: Not Installed
      gitpython: Not Installed
         Jinja2: 3.0.3
     junos-eznc: 2.6.3
       jxmlease: Not Installed
        libgit2: Not Installed
       M2Crypto: Not Installed
           Mako: Not Installed
   msgpack-pure: Not Installed
 msgpack-python: 1.0.3
         NAPALM: 3.4.0
       ncclient: 0.6.9
        Netmiko: 3.4.0
       paramiko: 2.8.1
      pycparser: 2.21
       pycrypto: Not Installed
   pycryptodome: 3.14.1
         pyeapi: 0.8.4
         pygit2: Not Installed
       PyNetBox: Not Installed
          PyNSO: Not Installed
         Python: 3.8.8 (default, Aug 11 2021, 06:52:42)
   python-gnupg: Not Installed
         PyYAML: 6.0
          PyZMQ: 21.0.2
            scp: 0.14.4
          smmap: Not Installed
        textfsm: 1.1.2
        timelib: Not Installed
        Tornado: 4.5.3
            ZMQ: 4.3.3

System Versions:
           dist: rhel 8.5 Ootpa
         locale: utf-8
        machine: x86_64
        release: 4.18.0-348.23.1.el8_5.x86_64
         system: Linux
        version: Red Hat Enterprise Linux 8.5 Ootpa

AttributeError: 'IPCMessageClient' object has no attribute '_refcount_lock'

Error in running salt-sproxy docker image even on a dummy device.

Steps to reproduce the behavior:

~# cat /etc/profile | grep sproxy
alias sproxy='f(){ docker run --rm --network host -v /srv/salt/base/pillars:/etc/salt/pillar/ -ti mirceaulinic/salt-sproxy salt-sproxy $@; }; f'

~# cat /srv/salt/base/pillars/top.sls
base:

'router':
- dummy

~# cat /srv/salt/base/pillars/dummy.sls
proxy:
proxytype: dummy

~# sproxy router test.ping
Exception ignored in: <bound method IPCClient.del of <salt.transport.ipc.IPCMessageClient object at 0x7f9535ed22b0>>
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/salt/transport/ipc.py", line 369, in del
with self._refcount_lock:
AttributeError: 'IPCMessageClient' object has no attribute '_refcount_lock'
[ERROR ] An un-handled exception was caught by salt's global exception handler:
TypeError: init() got an unexpected keyword argument 'encoding'
Traceback (most recent call last):
File "/usr/local/bin/salt-sproxy", line 8, in
sys.exit(salt_sproxy())
File "/usr/local/lib/python3.6/site-packages/salt_sproxy/scripts.py", line 95, in salt_sproxy
client.run()
File "/usr/local/lib/python3.6/site-packages/salt_sproxy/cli.py", line 241, in run
'saltutil.sync_roster', kwarg={'saltenv': saltenv}, print_event=False
File "/usr/local/lib/python3.6/site-packages/salt/runner.py", line 156, in cmd
full_return)
File "/usr/local/lib/python3.6/site-packages/salt/client/mixins.py", line 243, in cmd
return self.low(fun, low, print_event=print_event, full_return=full_return)
File "/usr/local/lib/python3.6/site-packages/salt/client/mixins.py", line 417, in low
namespaced_event.fire_event(data, 'ret')
File "/usr/local/lib/python3.6/site-packages/salt/utils/event.py", line 929, in fire_event
self.event.fire_event(data, tagify(tag, base=self.base))
File "/usr/local/lib/python3.6/site-packages/salt/utils/event.py", line 721, in fire_event
if not self.connect_pull(timeout=timeout_s):
File "/usr/local/lib/python3.6/site-packages/salt/utils/event.py", line 419, in connect_pull
io_loop=self.io_loop
File "/usr/local/lib/python3.6/site-packages/salt/transport/ipc.py", line 264, in new
client.singleton_init(io_loop=io_loop, socket_path=socket_path)
File "/usr/local/lib/python3.6/site-packages/salt/transport/ipc.py", line 292, in singleton_init
self.unpacker = msgpack.Unpacker(encoding=encoding)
File "msgpack/_unpacker.pyx", line 317, in msgpack._cmsgpack.Unpacker.init
TypeError: init() got an unexpected keyword argument 'encoding'
Traceback (most recent call last):
File "/usr/local/bin/salt-sproxy", line 8, in
sys.exit(salt_sproxy())
File "/usr/local/lib/python3.6/site-packages/salt_sproxy/scripts.py", line 95, in salt_sproxy
client.run()
File "/usr/local/lib/python3.6/site-packages/salt_sproxy/cli.py", line 241, in run
'saltutil.sync_roster', kwarg={'saltenv': saltenv}, print_event=False
File "/usr/local/lib/python3.6/site-packages/salt/runner.py", line 156, in cmd
full_return)
File "/usr/local/lib/python3.6/site-packages/salt/client/mixins.py", line 243, in cmd
return self.low(fun, low, print_event=print_event, full_return=full_return)
File "/usr/local/lib/python3.6/site-packages/salt/client/mixins.py", line 417, in low
namespaced_event.fire_event(data, 'ret')
File "/usr/local/lib/python3.6/site-packages/salt/utils/event.py", line 929, in fire_event
self.event.fire_event(data, tagify(tag, base=self.base))
File "/usr/local/lib/python3.6/site-packages/salt/utils/event.py", line 721, in fire_event
if not self.connect_pull(timeout=timeout_s):
File "/usr/local/lib/python3.6/site-packages/salt/utils/event.py", line 419, in connect_pull
io_loop=self.io_loop
File "/usr/local/lib/python3.6/site-packages/salt/transport/ipc.py", line 264, in new
client.singleton_init(io_loop=io_loop, socket_path=socket_path)
File "/usr/local/lib/python3.6/site-packages/salt/transport/ipc.py", line 292, in singleton_init
self.unpacker = msgpack.Unpacker(encoding=encoding)
File "msgpack/_unpacker.pyx", line 317, in msgpack._cmsgpack.Unpacker.init
TypeError: init() got an unexpected keyword argument 'encoding'
Exception ignored in: <bound method IPCClient.del of <salt.transport.ipc.IPCMessageClient object at 0x7f9535ed2d30>>
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/salt/transport/ipc.py", line 369, in del
with self._refcount_lock:
AttributeError: 'IPCMessageClient' object has no attribute '_refcount_lock'

Versions Report
~# sproxy -V
Salt Version:
Salt: 2019.2.0
Salt SProxy: 2020.3.0

Dependency Versions:
Ansible: Not Installed
cffi: Not Installed
dateutil: Not Installed
docker-py: Not Installed
gitdb: Not Installed
gitpython: Not Installed
Jinja2: 2.11.1
junos-eznc: Not Installed
jxmlease: Not Installed
libgit2: Not Installed
M2Crypto: Not Installed
Mako: Not Installed
msgpack-pure: Not Installed
msgpack-python: 1.0.0
NAPALM: Not Installed
ncclient: Not Installed
Netmiko: Not Installed
paramiko: Not Installed
pycparser: Not Installed
pycrypto: 2.6.1
pycryptodome: Not Installed
pyeapi: Not Installed
pygit2: Not Installed
PyNetBox: Not Installed
PyNSO: Not Installed
Python: 3.6.10 (default, Feb 26 2020, 16:40:36)
python-gnupg: Not Installed
PyYAML: 5.3.1
PyZMQ: 19.0.0
scp: Not Installed
smmap: Not Installed
textfsm: Not Installed
timelib: Not Installed
Tornado: 4.5.3
ZMQ: 4.3.2

System Versions:
dist: debian 9.12
locale: UTF-8
machine: x86_64
release: 4.15.0-101-generic
system: Linux
version: debian 9.12

Seems that if we build a custom image based on salt-sproxy:2020.3.0 and downgrade msgpack in it from version 1.0.0 to 0.6.2 (pip install msgpack==0.6.2) it works as expected

build a custom image based on the following Dockerfile

~/docker/salt-sproxy-custom# cat Dockerfile
FROM mirceaulinic/salt-sproxy:2020.3.0
RUN pip install msgpack==0.6.2

~/docker/salt-sproxy-custom# cat /etc/profile | grep sproxy
alias sproxy2='f(){ docker run --rm --network host -v /srv/salt/base/pillars:/etc/salt/pillar/ -ti salt-sproxy-custom salt-sproxy $@; }; f'

~/docker/salt-sproxy-custom# sproxy2 router test.ping
[WARNING ] /usr/local/lib/python3.6/site-packages/salt/transport/ipc.py:292: DeprecationWarning: encoding is deprecated, Use raw=False instead.
self.unpacker = msgpack.Unpacker(encoding=encoding)

router:
True

Updated netbox 'filters' persists when using reactor.

Describe the bug
This only occurs when using a reactor with the runner.proxy.execute.

The variable 'netbox_filter' in the targets-function of the netbox roster is a reference to the netbox filters in the global master options. When targeting a single device or using grains-filters, the global option object is updated and stored when name or levels is set.

Example:
1: Netbox filter in master config

netbox:
  token: <token>
  url: <url>
  filters:
    role: mwtransmission

2: Reactor executing targets a single device (tgt='mw-1') the 'netbox_filter' will be

[DEBUG   ] Querying NetBox with the following filters
[DEBUG   ] {'role': 'mwtransmission', name':'mw-1'}

3: Reactor executing globbing the devices (tgt='mw*') the 'netbox_filter will still be

[DEBUG   ] Querying NetBox with the following filters
[DEBUG   ] {'role': 'mwtransmission', name':'mw-1'}

Expected behavior
The netbox filter should have the starting values of the initial master config every time the 'targets'-function of the roster interface is called.

Versions Report

Salt Version:
           Salt: 3001.7
    Salt SProxy: 2021.6.1

Dependency Versions:
        Ansible: Not Installed
           cffi: 1.14.6
       dateutil: 2.8.2
      docker-py: Not Installed
          gitdb: Not Installed
      gitpython: Not Installed
         Jinja2: 3.0.1
     junos-eznc: 2.6.3
       jxmlease: Not Installed
        libgit2: Not Installed
       M2Crypto: Not Installed
           Mako: Not Installed
   msgpack-pure: Not Installed
 msgpack-python: 1.0.2
         NAPALM: 3.2.0
       ncclient: 0.6.9
        Netmiko: 3.4.0
       paramiko: 2.8.0
      pycparser: 2.20
       pycrypto: Not Installed
   pycryptodome: 3.10.1
         pyeapi: 0.8.4
         pygit2: Not Installed
       PyNetBox: 6.1.3
          PyNSO: Not Installed
         Python: 3.7.10 (default, Apr 15 2021, 05:35:41)
   python-gnupg: Not Installed
         PyYAML: 5.4.1
          PyZMQ: 19.0.2
            scp: 0.14.1
          smmap: Not Installed
        textfsm: 1.1.0
        timelib: Not Installed
        Tornado: 4.5.3
            ZMQ: 4.3.2

System Versions:
           dist: alpine 3.12.7
         locale: UTF-8
        machine: x86_64
        release: 4.18.0-147.5.1.el8_1.x86_64
         system: Linux
        version: Alpine Linux 3.12.7

Additional context
Copying/de-referencing the options solves the issue.

netbox_filters = __opts__.get('netbox', {}).get('filters', {}).copy()

Pillar targeting broken

Describe the bug
A Minion cant be targeted by using pillars.

Steps To Reproduce
A Minion has the role "core" assigned.

# salt-sproxy cr-edge* pillar.get role
cr-edge01.mydomain.com:
    core

But it cant be targeted using -I parameter of salt-sproxy.

# salt-sproxy --preview-target -I "role:core"
No devices matched your target. Please review your tgt / tgt_type arguments, or the Roster data source
# salt-sproxy -I "role:core" test.ping
No devices matched your target. Please review your tgt / tgt_type arguments, or the Roster data source

Expected behavior
The minion responds with "True".

Versions Report

# salt-sproxy -V
Salt Version:
           Salt: 3001.1
    Salt SProxy: 2020.7.0

Dependency Versions:
        Ansible: Not Installed
           cffi: 1.14.2
       dateutil: 2.7.3
      docker-py: Not Installed
          gitdb: 2.0.5
      gitpython: 2.1.11
         Jinja2: 2.10
     junos-eznc: 2.5.3
       jxmlease: Not Installed
        libgit2: 0.27.7
       M2Crypto: Not Installed
           Mako: Not Installed
   msgpack-pure: Not Installed
 msgpack-python: 0.5.6
         NAPALM: 3.1.0
       ncclient: 0.6.9
        Netmiko: 3.2.0
       paramiko: 2.7.2
      pycparser: 2.19
       pycrypto: 2.6.1
   pycryptodome: 3.6.1
         pyeapi: 0.8.3
         pygit2: 0.27.4
       PyNetBox: Not Installed
          PyNSO: Not Installed
         Python: 3.7.3 (default, Jul 25 2020, 13:03:44)
   python-gnupg: Not Installed
         PyYAML: 3.13
          PyZMQ: 17.1.2
            scp: 0.13.2
          smmap: 2.0.5
        textfsm: 1.1.0
        timelib: Not Installed
        Tornado: 4.5.3
            ZMQ: 4.3.1

System Versions:
           dist: debian 10 buster
         locale: UTF-8
        machine: x86_64
        release: 4.19.0-10-amd64
         system: Linux
        version: Debian GNU/Linux 10 buster

Additional context
Pillar targeting is also not mentioned here: https://salt-sproxy.readthedocs.io/en/latest/targeting.html

But its part of the "salt-proxy -h" help. Is it generally supported?

salt-sproxy 'r1' network.interface returns local data

I accidentally ran salt-sproxy 'r1' network.interface surprisingly it does not return false. It returns my local machine data.

DEBUG   ] LazyLoaded network.interfaces
[DEBUG   ] LazyLoaded network.interfaces
[DEBUG   ] write_channel: b'\n'
[DEBUG   ] read_channel:
R1#
[DEBUG   ] read_channel:
[DEBUG   ] read_channel:
[DEBUG   ] write_channel: b'exit\n'
[DEBUG   ] LazyLoaded nested.output
r1:
    ----------
    awdl0:
        ----------
        hwaddr:
            8e:16:a8:3d:f4:cb
        inet6:
            |_
              ----------
              address:
                  fe80::8c16:a8ff:fe3d:f4cb
              prefixlen:
                  64
              scope:
                  0x9
        up:
            True

Steps To Reproduce
salt-sproxy 'r1' network.interface

returns the network interfaces data from my local machine

Expected behavior
salt-sproxy 'r1' network.interface should return not available or false

Versions Report

╰─ salt-sproxy -V
Salt Version:
           Salt: 3001
    Salt SProxy: 2020.7.0

Dependency Versions:
        Ansible: Not Installed
           cffi: 1.12.2
       dateutil: 2.8.0
      docker-py: Not Installed
          gitdb: 2.0.6
      gitpython: 2.1.15
         Jinja2: 2.10.1
     junos-eznc: 2.4.1
       jxmlease: Not Installed
        libgit2: Not Installed
       M2Crypto: Not Installed
           Mako: 1.0.7
   msgpack-pure: Not Installed
 msgpack-python: 0.5.6
         NAPALM: 3.0.1
       ncclient: 0.6.7
        Netmiko: 3.1.1
       paramiko: 2.7.1
      pycparser: 2.19
       pycrypto: 3.8.1
   pycryptodome: 3.9.7
         pyeapi: 0.8.3
         pygit2: Not Installed
       PyNetBox: Not Installed
          PyNSO: Not Installed
         Python: 3.6.8 (default, Nov  8 2019, 21:16:45)
   python-gnupg: 0.4.4
         PyYAML: 5.1.2
          PyZMQ: 18.0.1
            scp: 0.13.2
          smmap: 3.0.4
        textfsm: 1.1.0
        timelib: 0.2.4
        Tornado: 4.5.3
            ZMQ: 4.3.1

System Versions:
           dist: darwin 19.6.0
         locale: UTF-8
        machine: x86_64
        release: 19.6.0
         system: Darwin
        version: 10.15.6 x86_64


Additional context
Add any other context about the problem here.

Implement the --failhard CLI option

The option exists, however currently ignored. Might be a good idea to implement it.

--failhard            Stop batch execution upon first "bad" return.

Remote network device unreachable after upgrade from 2019.10.0 to 2020.3.0

Describe the bug
After upgrading from 2019.10.0 to 2020.3.0, I am unable to reach Juniper devices using the napalm module. The devices are listed in the salt pillar file as before.

Steps To Reproduce

$ cat /etc/salt/master

pillar_roots:
  base:
    - /etc/salt/pillar

$ cat /etc/salt/pillar/top.sls

base: 
  test_switch:
    - napalm_junos

$ cat /etc/salt/pillar/napalm_junos.sls

proxy:
  proxytype: napalm
  driver: junos
  host: {{ grains['id'] }}
  username: testuser
  passwd: testpass
$ salt-sproxy 'test_switch' test.ping
test_switch:
    Minion did not return. [No response]
ERROR: Minions returned with non-zero exit code

Replacing {{ grains['id'] }} with test_switch in the napalm_junos.sls file didn't resolve the issue.

Versions Report

salt-sproxy 2020.3.0
/etc/salt # salt-sproxy -V
Salt Version:
           Salt: 3000.3
    Salt SProxy: 2020.3.0

Dependency Versions:
        Ansible: Not Installed
           cffi: 1.14.0
       dateutil: Not Installed
      docker-py: Not Installed
          gitdb: Not Installed
      gitpython: Not Installed
         Jinja2: 2.10
     junos-eznc: 2.2.1
       jxmlease: 1.0.1
        libgit2: Not Installed
       M2Crypto: Not Installed
           Mako: Not Installed
   msgpack-pure: Not Installed
 msgpack-python: 0.6.2
         NAPALM: 2.5.0
       ncclient: 0.6.7
        Netmiko: 2.4.2
       paramiko: 2.7.1
      pycparser: 2.20
       pycrypto: 2.6.1
   pycryptodome: Not Installed
         pyeapi: 0.8.3
         pygit2: Not Installed
       PyNetBox: Not Installed
          PyNSO: Not Installed
         Python: 3.6.9 (default, Oct 17 2019, 11:10:22)
   python-gnupg: Not Installed
         PyYAML: 3.13
          PyZMQ: 19.0.1
            scp: 0.13.2
          smmap: Not Installed
        textfsm: 1.1.0
        timelib: Not Installed
        Tornado: 4.5.3
            ZMQ: 4.3.2

System Versions:
           dist:
         locale: UTF-8
        machine: x86_64
        release: 3.10.0-693.el7.x86_64
         system: Linux
        version: Not Installed

Unable to get example test.ping working due to name '__opts__' is not defined

Describe the bug
Attempting to make use of sproxy to reduce memory requirements of lots of proxys. Running through example in documentation and it doesn't work.

Steps To Reproduce

# /etc/salt/master

pillar_roots:
  base:
    - /srv/pillar
    - /srv/pillar/devices

# /srv/pillar/top.sls

minion1:
  - dummy

# /srv/pillar/devices/dummy.sls
proxy:
  proxytype: dummy


# salt-run pillar.show_pillar minion1
proxy:
    ----------
    proxytype:
        dummy
# salt-sproxy minion1 test.ping
[ERROR   ] Failed to import grains esxi, this is due most likely to a syntax error:
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/salt/loader.py", line 1685, in _load_module
    mod = spec.loader.load_module()
  File "<frozen importlib._bootstrap_external>", line 399, in _check_name_wrapper
  File "<frozen importlib._bootstrap_external>", line 823, in load_module
  File "<frozen importlib._bootstrap_external>", line 682, in load_module
  File "<frozen importlib._bootstrap>", line 265, in _load_module_shim
  File "<frozen importlib._bootstrap>", line 684, in _load
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/usr/lib/python3/dist-packages/salt/grains/esxi.py", line 18, in <module>
    if salt.utils.platform.is_proxy() and __opts__["proxy"]["proxytype"] == "esxi":
NameError: name '__opts__' is not defined
[ERROR   ] Failed to import grains esxi, this is due most likely to a syntax error:
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/salt/loader.py", line 1685, in _load_module
    mod = spec.loader.load_module()
  File "<frozen importlib._bootstrap_external>", line 399, in _check_name_wrapper
  File "<frozen importlib._bootstrap_external>", line 823, in load_module
  File "<frozen importlib._bootstrap_external>", line 682, in load_module
  File "<frozen importlib._bootstrap>", line 265, in _load_module_shim
  File "<frozen importlib._bootstrap>", line 684, in _load
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/usr/lib/python3/dist-packages/salt/grains/esxi.py", line 18, in <module>
    if salt.utils.platform.is_proxy() and __opts__["proxy"]["proxytype"] == "esxi":
NameError: name '__opts__' is not defined
[ERROR   ] Failed to import grains esxi, this is due most likely to a syntax error:
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/salt/loader.py", line 1685, in _load_module
    mod = spec.loader.load_module()
  File "<frozen importlib._bootstrap_external>", line 399, in _check_name_wrapper
  File "<frozen importlib._bootstrap_external>", line 823, in load_module
  File "<frozen importlib._bootstrap_external>", line 682, in load_module
  File "<frozen importlib._bootstrap>", line 265, in _load_module_shim
  File "<frozen importlib._bootstrap>", line 684, in _load
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/usr/lib/python3/dist-packages/salt/grains/esxi.py", line 18, in <module>
    if salt.utils.platform.is_proxy() and __opts__["proxy"]["proxytype"] == "esxi":
NameError: name '__opts__' is not defined
[ERROR   ] Failed to import grains esxi, this is due most likely to a syntax error:
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/salt/loader.py", line 1685, in _load_module
    mod = spec.loader.load_module()
  File "<frozen importlib._bootstrap_external>", line 399, in _check_name_wrapper
  File "<frozen importlib._bootstrap_external>", line 823, in load_module
  File "<frozen importlib._bootstrap_external>", line 682, in load_module
  File "<frozen importlib._bootstrap>", line 265, in _load_module_shim
  File "<frozen importlib._bootstrap>", line 684, in _load
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/usr/lib/python3/dist-packages/salt/grains/esxi.py", line 18, in <module>
    if salt.utils.platform.is_proxy() and __opts__["proxy"]["proxytype"] == "esxi":
NameError: name '__opts__' is not defined
minion1:
    True
# locate salt_sproxy
/usr/local/lib/python3.6/dist-packages/salt_sproxy
/usr/local/lib/python3.6/dist-packages/salt_sproxy-2020.3.0-py3.6-nspkg.pth
/usr/local/lib/python3.6/dist-packages/salt_sproxy-2020.3.0.dist-info
/usr/local/lib/python3.6/dist-packages/salt_sproxy/__pycache__
/usr/local/lib/python3.6/dist-packages/salt_sproxy/_modules
/usr/local/lib/python3.6/dist-packages/salt_sproxy/_roster
/usr/local/lib/python3.6/dist-packages/salt_sproxy/_runners
/usr/local/lib/python3.6/dist-packages/salt_sproxy/cli.py
/usr/local/lib/python3.6/dist-packages/salt_sproxy/parsers.py
/usr/local/lib/python3.6/dist-packages/salt_sproxy/scripts.py
/usr/local/lib/python3.6/dist-packages/salt_sproxy/version.py
/usr/local/lib/python3.6/dist-packages/salt_sproxy/__pycache__/cli.cpython-36.pyc
/usr/local/lib/python3.6/dist-packages/salt_sproxy/__pycache__/parsers.cpython-36.pyc
/usr/local/lib/python3.6/dist-packages/salt_sproxy/__pycache__/scripts.cpython-36.pyc
/usr/local/lib/python3.6/dist-packages/salt_sproxy/__pycache__/version.cpython-36.pyc
/usr/local/lib/python3.6/dist-packages/salt_sproxy/_modules/__pycache__
/usr/local/lib/python3.6/dist-packages/salt_sproxy/_modules/netbox.py
/usr/local/lib/python3.6/dist-packages/salt_sproxy/_modules/__pycache__/netbox.cpython-36.pyc
/usr/local/lib/python3.6/dist-packages/salt_sproxy/_roster/__init__.py
/usr/local/lib/python3.6/dist-packages/salt_sproxy/_roster/__pycache__
/usr/local/lib/python3.6/dist-packages/salt_sproxy/_roster/ansible.py
/usr/local/lib/python3.6/dist-packages/salt_sproxy/_roster/file.py
/usr/local/lib/python3.6/dist-packages/salt_sproxy/_roster/netbox.py
/usr/local/lib/python3.6/dist-packages/salt_sproxy/_roster/pillar.py
/usr/local/lib/python3.6/dist-packages/salt_sproxy/_roster/__pycache__/__init__.cpython-36.pyc
/usr/local/lib/python3.6/dist-packages/salt_sproxy/_roster/__pycache__/ansible.cpython-36.pyc
/usr/local/lib/python3.6/dist-packages/salt_sproxy/_roster/__pycache__/file.cpython-36.pyc
/usr/local/lib/python3.6/dist-packages/salt_sproxy/_roster/__pycache__/netbox.cpython-36.pyc
/usr/local/lib/python3.6/dist-packages/salt_sproxy/_roster/__pycache__/pillar.cpython-36.pyc
/usr/local/lib/python3.6/dist-packages/salt_sproxy/_runners/__init__.py
/usr/local/lib/python3.6/dist-packages/salt_sproxy/_runners/__pycache__
/usr/local/lib/python3.6/dist-packages/salt_sproxy/_runners/proxy.py
/usr/local/lib/python3.6/dist-packages/salt_sproxy/_runners/__pycache__/__init__.cpython-36.pyc
/usr/local/lib/python3.6/dist-packages/salt_sproxy/_runners/__pycache__/proxy.cpython-36.pyc
/usr/local/lib/python3.6/dist-packages/salt_sproxy-2020.3.0.dist-info/INSTALLER
/usr/local/lib/python3.6/dist-packages/salt_sproxy-2020.3.0.dist-info/LICENSE
/usr/local/lib/python3.6/dist-packages/salt_sproxy-2020.3.0.dist-info/METADATA
/usr/local/lib/python3.6/dist-packages/salt_sproxy-2020.3.0.dist-info/RECORD
/usr/local/lib/python3.6/dist-packages/salt_sproxy-2020.3.0.dist-info/WHEEL
/usr/local/lib/python3.6/dist-packages/salt_sproxy-2020.3.0.dist-info/entry_points.txt
/usr/local/lib/python3.6/dist-packages/salt_sproxy-2020.3.0.dist-info/namespace_packages.txt
/usr/local/lib/python3.6/dist-packages/salt_sproxy-2020.3.0.dist-info/top_level.txt


# locate esxi.py
/usr/lib/python3/dist-packages/salt/config/schemas/esxi.py
/usr/lib/python3/dist-packages/salt/grains/esxi.py
/usr/lib/python3/dist-packages/salt/modules/esxi.py
/usr/lib/python3/dist-packages/salt/proxy/esxi.py
/usr/lib/python3/dist-packages/salt/states/esxi.py

Expected behavior
test.ping should work.

Versions Report
Print the output from salt-sproxy -V inside the backticks below:

Salt Version:
           Salt: 3001
    Salt SProxy: 2020.3.0

Dependency Versions:
        Ansible: Not Installed
           cffi: 1.14.0
       dateutil: 2.6.1
      docker-py: Not Installed
          gitdb: 2.0.3
      gitpython: 2.1.8
         Jinja2: 2.10
     junos-eznc: 2.4.1
       jxmlease: Not Installed
        libgit2: Not Installed
       M2Crypto: Not Installed
           Mako: Not Installed
   msgpack-pure: Not Installed
 msgpack-python: 0.5.6
         NAPALM: 3.0.1
       ncclient: 0.6.7
        Netmiko: 3.1.1
       paramiko: 2.7.1
      pycparser: 2.20
       pycrypto: 2.6.1
   pycryptodome: 3.4.7
         pyeapi: 0.8.3
         pygit2: Not Installed
       PyNetBox: Not Installed
          PyNSO: Not Installed
         Python: 3.6.9 (default, Apr 18 2020, 01:56:04)
   python-gnupg: 0.4.1
         PyYAML: 3.12
          PyZMQ: 17.1.2
            scp: 0.13.2
          smmap: 2.0.3
        textfsm: 1.1.0
        timelib: Not Installed
        Tornado: 4.5.3
            ZMQ: 4.2.5

System Versions:
           dist: ubuntu 18.04 Bionic Beaver
         locale: UTF-8
        machine: x86_64
        release: 4.15.0-96-generic
         system: Linux
        version: Ubuntu 18.04 Bionic Beaver

Additional context

Add any other context about the problem here.
Salt packages coming from saltstack Ubuntu repo:
http://repo.saltstack.com/py3/ubuntu/18.04/amd64/latest

Salt-sproxy installed/upgraded with pip3.

Question: using salt-sproxy as a replacement for salt-ssh

I have tried to replace my salt-ssh usage with salt-sproxy. This means a plain git repo, with a Saltfile like described here. I had mixed success.

Changing my Saltfile from:

salt-ssh:
  config_dir: etc/salt
  max_procs: 30
  wipe_ssh: True

to

salt-sproxy:
  config_dir: etc/salt
  max_procs: 30
  wipe_ssh: True

Added some paramers to etc/salt/master

diff --git a/etc/salt/master b/etc/salt/master
index 3395db0..b81a197 100644
--- a/etc/salt/master
+++ b/etc/salt/master
@@ -1,3 +1,7 @@
+roster: file
+sync_proxy: true
+sync_executors: true
+

For some reason ssh keys and user did not work, so I added root/password to etc/salt/roster

After applying a pillar ssh.sls to all machines with the content:

proxy:
  proxytype: ssh

I got it "working". But I could only call test.ping. Anything with arguments did not return anything. After reading salt-ssh code I noticed the client was constructed differently and the args/kwargs where passed in the client. Changing it to:

diff --git a/salt_sproxy/_proxy/ssh.py b/salt_sproxy/_proxy/ssh.py
index f729b21..9a44c2f 100644
--- a/salt_sproxy/_proxy/ssh.py
+++ b/salt_sproxy/_proxy/ssh.py
@@ -105,8 +105,18 @@ def _prep_conn(opts, fun, *args, **kwargs):
     fsclient = salt.fileclient.FSClient(opts)
     # TODO: Have here more options to simplify the usage, through features like
     # auto-expand the path to the priv key, auto-discovery, etc.
+    argv = [fun]
+    argv.extend([salt.utils.json.dumps(arg) for arg in args])
+    argv.extend(
+        [
+            "{0}={1}".format(
+                salt.utils.stringutils.to_str(key), salt.utils.json.dumps(val)
+            )
+            for key, val in six.iteritems(kwargs)
+        ]
+    )
     conn = salt.client.ssh.Single(
-        opts, [fun], opts['id'], fsclient=fsclient, **opts['proxy']
+        opts, argv, opts['id'], fsclient=fsclient, **opts['proxy']
     )
     conn.args = args
     conn.kwargs = kwargs

allowed me to call more functions. I did not succeed with state.apply but at least cmd.run is working with and without the patch. grain.items works but I swear it broke in some of the combinations I tested.

Without the patch I get:

[ERROR   ] [rpi02] Passed invalid arguments: run() missing 1 required positional argument: 'cmd'.  

and the module documentation as output.

Note: I haven't tested running this from a proper master.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.