saltstack / salt

Software to automate the management and configuration of any infrastructure or application at scale. Install Salt from the Salt package repositories here:
https://docs.saltproject.io/salt/install-guide/en/latest/
Apache License 2.0
14.21k stars 5.48k forks source link

[BUG] Netmiko proxy module multi_call behavior is broken on salt-sproxy #59158

Open benfiedler opened 3 years ago

benfiedler commented 3 years ago

Description Invoking netmiko.multi_call and providing a dictionary with keys 'name', 'args' and/or 'kwargs' results in a python error

Setup Pillar: somehost1.sls

proxy:
  proxytype: netmiko
  device_type: linux
  ip: 127.0.0.5
  username: root
  password: w34k

Steps to Reproduce the behavior salt-sproxy 'somehost1' netmiko.multi_call "{'name': 'send_command', 'kwargs': {'command_string': 'echo part one'}}" "{'name': 'send_command', 'kwargs': {'command_string':'echo part two'}}"

You get

      File "/usr/local/lib/python3.7/dist-packages/netmiko/base_connection.py", line 496, in _read_channel
        if self.remote_conn.recv_ready():
    AttributeError: 'NoneType' object has no attribute 'recv_ready'

And alternatively if you use args and kwargs is not specified within the dictionary:

TypeError: send_command() argument after ** must be a mapping, not list

Expected behavior Should receive a list of output of each command similar to we get if running salt-sproxy 'somehost1' netmiko.call method="send_command" command_string="echo part one"

Versions Report

# pip3 show salt-sproxy
Name: salt-sproxy
Version: 2020.10.2

# salt --versions-report
Salt Version:
          Salt: 3002.2

Dependency Versions:
          cffi: 1.14.4
      cherrypy: Not Installed
      dateutil: 2.7.3
     docker-py: Not Installed
         gitdb: 2.0.5
     gitpython: 2.1.11
        Jinja2: 2.10
       libgit2: Not Installed
      M2Crypto: Not Installed
          Mako: Not Installed
       msgpack: 0.5.6
  msgpack-pure: Not Installed
  mysql-python: Not Installed
     pycparser: 2.20
      pycrypto: 2.6.1
  pycryptodome: 3.6.1
        pygit2: Not Installed
        Python: 3.7.3 (default, Jul 25 2020, 13:03:44)
  python-gnupg: Not Installed
        PyYAML: 3.13
         PyZMQ: 17.1.2
         smmap: 2.0.5
       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-13-amd64
        system: Linux
       version: Debian GNU/Linux 10 buster

I have tested a very simple patch successfully in the same environment as above. The patch does:

  1. Default kwargs to an empty dictionary instead of an empty list
  2. Call the netmiko method via the magic __proxy__ method if available (in the same fashion that netmiko.call operates)
  3. Provide a CLI example of multi_call as it is not very intuitive

I could use some help in writing a test procedure however, my dev experience is minimal..

kgbsd commented 3 years ago

same issue here, but works fine if I downgrade salt proxy, and leave master at 3002. from: py37-salt-3002.2_1 to: py37-salt-2019-2019.2.5_1

kgbsd commented 3 years ago

no sproxy here, just straight salt.

master is at 3002 saltminionhost-01:$ pkg info -x salt py37-salt-2019-2019.2.5_1

saltmaster-01:# salt junos_srx napalm.netmiko_multi_call "{'name': 'send_command', 'kwargs': {'command_string': 'show version'}}" junos_srx:

upgrade minionhost to latest salt:

saltminionhost-01:# pkg info -x salt py37-salt-3002.2_1

saltmaster-01:# salt junos_srx napalm.netmiko_multi_call "{'name': 'send_command', 'kwargs': {'command_string': 'show version'}}" junos_srx: The minion function caused an exception: Traceback (most recent call last): File "/usr/local/lib/python3.7/site-packages/salt/metaproxy/proxy.py", line 477, in thread_return 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 "/usr/local/lib/python3.7/site-packages/salt/utils/napalm.py", line 508, in func_wrapper ret = func(*args, *kwargs) File "/usr/local/lib/python3.7/site-packages/salt/modules/napalm_mod.py", line 576, in netmiko_multi_call return salt["netmiko.multi_call"](methods, kwargs) File "/usr/local/lib/python3.7/site-packages/salt/loader.py", line 1283, in getitem func = super().getitem(item) File "/usr/local/lib/python3.7/site-packages/salt/utils/lazy.py", line 110, in getitem return self._dict[key] KeyError: 'netmiko.multi_call' ERROR: Minions returned with non-zero exit code saltmaster-01:#

pillar data does not change, proxy is started with: /usr/local/bin/python3.7 /usr/local/bin/salt-proxy --proxyid junos_srx -c /usr/local/etc/salt -d

I'm not using sproxy, regular salt which is broken [which in turn breaks sproxy also?].

benfiedler commented 3 years ago

I'm not using sproxy, regular salt which is broken [which in turn breaks sproxy also?].

That seems plausible; I only very recently started using proxies and salt-sproxy seems to relieve a lot of headache regarding proxy+port management so I jumped straight into using it.

Napalm is another module that seems to implement the netmiko multicall function in very different manner than netmiko module
¯\_( ͡° ͜ʖ ͡°)\

I think we need someone more familiar with salt modules to take a look.