Add documentation for proxy minion ssh

This commit is contained in:
Aditya Kulkarni 2015-10-19 13:30:35 -04:00
parent 07cac0b434
commit 7c8f236115
2 changed files with 260 additions and 0 deletions

View file

@ -24,6 +24,9 @@ and discovery, control, status, remote execution, and state management.
See the :doc:`Proxy Minion Walkthrough </topics/proxyminion/demo>` for an end-to-end
demonstration of a working proxy minion.
See the :doc:`Proxy Minion SSH Walkthrough </topics/proxyminion/ssh>` for an end-to-end
demonstration of a working SSH proxy minion.
New in 2015.8.2
---------------
@ -540,3 +543,178 @@ And then in salt.proxy.rest_sample.py we find
:glob:
demo
SSH Proxymodules
----------------
See above for a general introduction to writing proxy modules.
All of the guidelines that apply to REST are the same for SSH.
This sections specifically talks about the SSH proxy module and
explains the working of the example proxy module ``ssh_sample``.
Here is a simple example proxymodule used to interface to a device over SSH.
Code for the SSH shell is in the `salt-contrib GitHub repository <https://github.com/saltstack/salt-contrib/proxyminion_ssh_example>`_
This proxymodule enables "package" installation.
.. code-block:: python
# -*- coding: utf-8 -*-
'''
This is a simple proxy-minion designed to connect to and communicate with
a server that exposes functionality via SSH.
This can be used as an option when the device does not provide
an api over HTTP and doesn't have the python stack to run a minion.
'''
from __future__ import absolute_import
# Import python libs
import json
import logging
# Import Salt's libs
from salt.utils.vt_helper import SSHConnection
from salt.utils.vt import TerminalException
# This must be present or the Salt loader won't load this module
__proxyenabled__ = ['ssh_sample']
DETAILS = {}
# Want logging!
log = logging.getLogger(__file__)
# This does nothing, it's here just as an example and to provide a log
# entry when the module is loaded.
def __virtual__():
'''
Only return if all the modules are available
'''
log.info('ssh_sample proxy __virtual__() called...')
return True
def init(opts):
'''
Required.
Can be used to initialize the server connection.
'''
try:
DETAILS['server'] = SSHConnection(host=__opts__['proxy']['host'],
username=__opts__['proxy']['username'],
password=__opts__['proxy']['password'])
# connected to the SSH server
out, err = DETAILS['server'].sendline('help')
except TerminalException as e:
log.error(e)
return False
def shutdown(opts):
'''
Disconnect
'''
DETAILS['server'].close_connection()
def parse(out):
'''
Extract json from out.
Parameter
out: Type string. The data returned by the
ssh command.
'''
jsonret = []
in_json = False
for ln_ in out.split('\n'):
if '{' in ln_:
in_json = True
if in_json:
jsonret.append(ln_)
if '}' in ln_:
in_json = False
return json.loads('\n'.join(jsonret))
def package_list():
'''
List "packages" by executing a command via ssh
This function is called in response to the salt command
..code-block::bash
salt target_minion pkg.list_pkgs
'''
# Send the command to execute
out, err = DETAILS['server'].sendline('pkg_list')
# "scrape" the output and return the right fields as a dict
return parse(out)
def package_install(name, **kwargs):
'''
Install a "package" on the REST server
'''
cmd = 'pkg_install ' + name
if 'version' in kwargs:
cmd += '/'+kwargs['version']
else:
cmd += '/1.0'
# Send the command to execute
out, err = DETAILS['server'].sendline(cmd)
# "scrape" the output and return the right fields as a dict
return parse(out)
def package_remove(name):
'''
Remove a "package" on the REST server
'''
cmd = 'pkg_remove ' + name
# Send the command to execute
out, err = DETAILS['server'].sendline(cmd)
# "scrape" the output and return the right fields as a dict
return parse(out)
Connection Setup
################
The ``init()`` method is responsible for connection setup. It uses the ``host``, ``username`` and ``password`` config variables defined in the pillar data. The ``prompt`` kwarg can be passed to ``SSHConnection`` if your SSH server's prompt differs from the example's prompt ``(Cmd)``. Instantiating the ``SSHConnection`` class establishes an SSH connection to the ssh server (using Salt VT).
Command execution
#################
The ``package_*`` methods use the SSH connection (established in ``init()``) to send commands out to the SSH server. The ``sendline()`` method of ``SSHConnection`` class can be used to send commands out to the server. In the above example we send commands like ``pkg_list`` or ``pkg_install``. You can send any SSH command via this utility.
Output parsing
##############
Output returned by ``sendline()`` is a tuple of strings representing the stdout and the stderr respectively. In the toy example shown we simply scrape the output and convert it to a python dictionary, as shown in the ``parse`` method. You can tailor this method to match your parsing logic.
Connection teardown
###################
The ``shutdown`` method is responsible for calling the ``close_connection()`` method of ``SSHConnection`` class. This ends the SSH connection to the server.
For more information please refer to class `SSHConnection`_.
.. toctree::
:maxdepth: 2
:glob:
ssh
.. _SSHConnection: https://github.com/saltstack/salt/blob/b8271c7512da7e048019ee26422be9e7d6b795ab/salt/utils/vt_helper.py#L28

View file

@ -0,0 +1,82 @@
========================================
Salt Proxy Minion SSH End-to-End Example
========================================
The following is walkthrough that documents how to run a sample SSH service
and configure one or more proxy minions to talk to and control it.
1. This walkthrough uses a custom SSH shell to provide an end to end example.
Any other shells can be used too.
2. Setup the proxy command shell as shown https://github.com/saltstack/salt-contrib/tree/master/proxyminion_ssh_example
Now, configure your salt-proxy.
1. Edit ``/etc/salt/proxy`` and add an entry for your master's location
.. code-block:: yaml
master: localhost
add_proxymodule_to_opts: False
multiprocessing: False
2. On your salt-master, ensure that pillar is configured properly. Select an ID
for your proxy (in this example we will name the proxy with the letter 'p'
followed by the port the proxy is answering on). In your pillar topfile,
place an entry for your proxy:
.. code-block:: yaml
base:
'p8000':
- p8000
This says that Salt's pillar should load some values for the proxy ``p8000``
from the file /srv/pillar/p8000.sls (if you have not changed your default pillar_roots)
3. In the pillar root for your base environment, create this file:
.. code-block:: yaml
p8000.sls
---------
proxy:
proxytype: ssh_sample
host: saltyVM
username: salt
password: badpass
4. Make sure your salt-master is running.
5. Start the salt-proxy in debug mode
.. code-block:: bash
salt-proxy --proxyid=p8000 -l debug
6. Accept your proxy's key on your salt-master
.. code-block:: bash
salt-key -y -a p8000
The following keys are going to be accepted:
Unaccepted Keys:
p8000
Key for minion p8000 accepted.
7. Now you should be able to run commands on your proxy.
.. code-block:: bash
salt p8000 pkg.list_pkgs
8. The SSH shell implements a degenerately simple pkg.
To "install" a package, use a standard
``pkg.install``. If you pass '==' and a verrsion number after the package
name then the service will parse that and accept that as the package's
version.