neulab/tldr huggingface dataset:
alive(opts): Another optional function, it is used together with the proxy_keep_alive option (default: True). This function should return a boolean value corresponding to the state of the connection.  If the connection is down, will try to restart (shutdown followed by init). The polling frequency is controlled using the proxy_keep_alive_interval option, in minutes.
grains(): Rather than including grains in /srv/salt/_grains or in the standard install directories for grains, grains can be computed and returned by this function.  This function will be called automatically if proxy_merge_grains_in_module is set to True in /etc/salt/proxy.  This variable defaults to True in the release code-named 2017.7.0.
Pre 2015.8 the proxymodule also must have an id() function.  2015.8 and following don't use this function because the proxy's id is required on the command line.
Here is an example proxymodule used to interface to a very simple REST server. Code for the server is in the salt-contrib GitHub repository.
This proxymodule enables "service" enumeration, starting, stopping, restarting, and status; "package" installation, and a ping.
# -*- coding: utf-8 -*- """ This is a simple proxy-minion designed to connect to and communicate with the bottle-based web service contained in https://github.com/saltstack/salt-contrib/tree/master/proxyminion_rest_example """ from __future__ import absolute_import
# Import python libs import logging import salt.utils.http
HAS_REST_EXAMPLE = True
# This must be present or the Salt loader won't load this module __proxyenabled__ = ["rest_sample"]
# Variables are scoped to this module so we can have persistent data # across calls to fns in here. GRAINS_CACHE = {} 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.debug("rest_sample proxy __virtual__() called...") return True
def _complicated_function_that_determines_if_alive(): return True
# Every proxy module needs an 'init', though you can # just put DETAILS['initialized'] = True here if nothing # else needs to be done.
def init(opts): log.debug("rest_sample proxy init() called...") DETAILS["initialized"] = True
# Save the REST URL DETAILS["url"] = opts["proxy"]["url"]
# Make sure the REST URL ends with a '/' if not DETAILS["url"].endswith("/"): DETAILS["url"] += "/"
def alive(opts): """ This function returns a flag with the connection state. It is very useful when the proxy minion establishes the communication via a channel that requires a more elaborated keep-alive mechanism, e.g. NETCONF over SSH. """ log.debug("rest_sample proxy alive() called...") return _complicated_function_that_determines_if_alive()
def initialized(): """ Since grains are loaded in many different places and some of those places occur before the proxy can be initialized, return whether our init() function has been called """ return DETAILS.get("initialized", False)
def grains(): """ Get the grains from the proxied device """ if not DETAILS.get("grains_cache", {}): r = salt.utils.http.query( DETAILS["url"] + "info", decode_type="json", decode=True ) DETAILS["grains_cache"] = r["dict"] return DETAILS["grains_cache"]
def grains_refresh(): """ Refresh the grains from the proxied device """ DETAILS["grains_cache"] = None return grains()
def fns(): return { "details": "This key is here because a function in " "grains/rest_sample.py called fns() here in the proxymodule." }
def service_start(name): """ Start a "service" on the REST server """ r = salt.utils.http.query( DETAILS["url"] + "service/start/" + name, decode_type="json", decode=True ) return r["dict"]
def service_stop(name): """ Stop a "service" on the REST server """ r = salt.utils.http.query( DETAILS["url"] + "service/stop/" + name, decode_type="json", decode=True ) return r["dict"]
def service_restart(name): """ Restart a "service" on the REST server """ r = salt.utils.http.query( DETAILS["url"] + "service/restart/" + name, decode_type="json", decode=True ) return r["dict"]
def service_list(): """ List "services" on the REST server """ r = salt.utils.http.query( DETAILS["url"] + "service/list", decode_type="json", decode=True ) return r["dict"]
def service_status(name): """ Check if a service is running on the REST server """ r = salt.utils.http.query( DETAILS["url"] + "service/status/" + name, decode_type="json", decode=True ) return r["dict"]
def package_list(): """ List "packages" installed on the REST server """ r = salt.utils.http.query( DETAILS["url"] + "package/list", decode_type="json", decode=True ) return r["dict"]
def package_install(name, **kwargs): """ Install a "package" on the REST server """ cmd = DETAILS["url"] + "package/install/" + name if kwargs.get("version", False): cmd += "/" + kwargs["version"] else: cmd += "/1.0" r = salt.utils.http.query(cmd, decode_type="json", decode=True) return r["dict"]
def fix_outage(): r = salt.utils.http.query(DETAILS["url"] + "fix_outage") return r
def uptodate(name):
""" Call the REST endpoint to see if the packages on the "server" are up to date. """ r = salt.utils.http.query( DETAILS["url"] + "package/remove/" + name, decode_type="json", decode=True ) return r["dict"]
def package_remove(name):
""" Remove a "package" on the REST server """ r = salt.utils.http.query( DETAILS["url"] + "package/remove/" + name, decode_type="json", decode=True ) return r["dict"]
def package_status(name): """ Check the installation status of a package on the REST server """ r = salt.utils.http.query( DETAILS["url"] + "package/status/" + name, decode_type="json", decode=True ) return r["dict"]
def ping(): """ Is the REST server up? """ r = salt.utils.http.query(DETAILS["url"] + "ping", decode_type="json", decode=True) try: return r["dict"].get("ret", False) except Exception: return False
def shutdown(opts): """ For this proxy shutdown is a no-op """ log.debug("rest_sample proxy shutdown() called...")
Grains are data about minions.  Most proxied devices will have a paltry amount of data as compared to a typical Linux server.  By default, a proxy minion will have several grains taken from the host.  Salt core code requires values for kernel, os, and os_family--all of these are forced to be proxy for proxy-minions.
To add others to your proxy minion for a particular device, create a file in salt/grains named [proxytype].py and place inside it the different functions that need to be run to collect the data you are interested in. Here's an example.  Note the function below called proxy_functions.  It demonstrates how a grains function can take a single argument, which will be set to the value of __proxy__.  Dunder variables are not yet injected into Salt processes at the time grains are loaded, so this enables us to get a handle to the proxymodule so we can cross-call the functions therein used to communicate with the controlled device.
Note that as of 2016.3, grains values can also be calculated in a function called grains() in the proxymodule itself.  This might be useful if a proxymodule author wants to keep all the code for the proxy interface in the same place instead of splitting it between the proxy and grains directories.
This function will only be called automatically if the configuration variable proxy_merge_grains_in_module is set to True in the proxy configuration file (default /etc/salt/proxy).  This variable defaults to True in the release code-named 2017.7.0.
The __proxyenabled__ directive In previous versions of Salt the __proxyenabled__ directive controlled loading of all Salt modules for proxies (e.g. grains, execution modules, state modules).  From 2016.3 on, the only modules that respect __proxyenabled__ are grains and proxy modules.  These modules need to be told which proxy they work with.
__proxyenabled__ is a list, and can contain a single '*' to indicate a grains module works with all proxies.
Example from salt/grains/rest_sample.py:
# -*- coding: utf-8 -*- """ Generate baseline proxy minion grains """ from __future__ import absolute_import import salt.utils.platform
__proxyenabled__ = ["rest_sample"]
__virtualname__ = "rest_sample"
def __virtual__(): try: if ( salt.utils.platform.is_proxy() and __opts__["proxy"]["proxytype"] == "rest_sample" ): return __virtualname__ except KeyError: pass
Salt Proxy Minion End-to-End Example The following is walkthrough that documents how to run a sample REST service and configure one or more proxy minions to talk to and control it.
1. Ideally, create a Python virtualenv in which to run the REST service. This is not strictly required, but without a virtualenv you will need to install bottle via pip globally on your system
2. Clone https://github.com/saltstack/salt-contrib and copy the contents of the directory proxyminion_rest_example somewhere on a machine that is reachable from the machine on which you want to run the salt-proxy. This machine needs Python 2.7 or later.
3. Install bottle version 0.12.8 via pip or easy_install
pip install bottle==0.12.8
4. Run python rest.py --help for usage
5. Start the REST API on an appropriate port and IP.
6. Load the REST service's status page in your browser by going to the IP/port combination (e.g. http://127.0.0.1:8000)
7. You should see a page entitled "Salt Proxy Minion" with two sections, one for "services" and one for "packages" and you should see a log entry in the terminal where you started the REST process indicating that the index page was retrieved. [image]
Now, configure your salt-proxy.
1. Edit /etc/salt/proxy and add an entry for your master's location
master: localhost
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:
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 the p8000.sls file with the following contents:
proxy: proxytype: rest_sample url: http://<IP your REST listens on>:port
In other words, if your REST service is listening on port 8000 on 127.0.0.1 the 'url' key above should say url: http://127.0.0.1:8000
4. Make sure your salt-master is running.
5. Start the salt-proxy in debug mode
salt-proxy --proxyid=p8000 -l debug
6. Accept your proxy's key on your salt-master
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 ping your proxy.  When you ping, you should see a log entry in the terminal where the REST service is running.
salt p8000 test.version
8. The REST service implements a degenerately simple pkg and service provider as well as a small set of grains.  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.
9. Try running salt p8000 grains.items to see what grains are available. You can target proxies via grains if you like.
10. You can also start and stop the available services (apache, redbull, and postgresql with service.start, etc.
11. States can be written to target the proxy.  Feel free to experiment with them.
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.
This proxymodule enables "package" installation.
# -*- 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 salt.utils.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 = {}
# 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...")
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 salt.utils.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
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)
def package_remove(name): """ Remove a "package" on the REST server """ cmd = "pkg_remove " + name
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.
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
master: localhost multiprocessing: False
proxy: proxytype: ssh_sample host: saltyVM username: salt password: badpass
7. Now you should be able to run commands on your proxy.
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. New in version 2015.8.3.
Proxy Minion Beacon The salt proxy beacon is meant to facilitate configuring multiple proxies on one or many minions. This should simplify configuring and managing multiple salt-proxy processes.
1. On your salt-master, ensure that pillar is configured properly. Select an ID for your proxy (in this example we will name the proxy 'p8000').  In your pillar topfile, place an entry for your proxy:
2. In the pillar root for your base environment, create the p8000.sls file with the following contents:
proxy: # set proxytype for your proxymodule proxytype: ssh_sample host: saltyVM username: salt password: badpass
This should complete the proxy setup for p8000
3. Configure the salt_proxy beacon
beacons: salt_proxy: - proxies: p8000: {} p8001: {}
Once this beacon is configured it will automatically start the salt-proxy process. If the salt-proxy process is terminated the beacon will re-start it.
4. Accept your proxy's key on your salt-master
5. Now you should be able to run commands on your proxy.
salt p8000 pkg.list_pkgs New in version 2015.8.2.
Proxy Minion States Salt proxy state can be used to deploy, configure and run a salt-proxy instance on your minion. Configure proxy settings on the master side and the state configures and runs salt-proxy on the remote end.
3. Create the following state in your state tree (let's name it salt_proxy.sls)
salt-proxy-configure: salt_proxy.configure_proxy: - proxyname: p8000 - start: True # start the process if it isn't running
4. Make sure your salt-master and salt-minion are running.
5. Run the state salt_proxy on the minion where you want to run salt-proxy
Example using state.sls to configure and run salt-proxy
# salt device_minion state.sls salt_proxy
This starts salt-proxy on device_minion
Network automation is a continuous process of automating the configuration, management and operations of a computer network. Although the abstraction could be compared with the operations on the server side, there are many particular challenges, the most important being that a network device is traditionally closed hardware able to run proprietary software only. In other words, the user is not able to install the salt-minion package directly on a traditional network device. For these reasons, most network devices can be controlled only remotely via proxy minions or using the Salt SSH. However, there are also vendors producing whitebox equipment (e.g. Arista, Cumulus) or others that have moved the operating system in the container (e.g. Cisco NX-OS, Cisco IOS-XR), allowing the salt-minion to be installed directly on the platform.
New in Carbon (2016.11) The methodologies for network automation have been introduced in 2016.11.0. Network automation support is based on proxy minions.
• NAPALM proxy
• Junos proxy
• Cisco NXOS
• Cisco NSO
NAPALM NAPALM (Network Automation and Programmability Abstraction Layer with Multivendor support) is an opensourced Python library that implements a set of functions to interact with different router vendor devices using a unified API.  Being vendor-agnostic simplifies operations, as the configuration and interaction with the network device does not rely on a particular vendor.  [image]
Beginning with 2017.7.0, the NAPALM modules have been transformed so they can run in both proxy and regular minions. That means, if the operating system allows, the salt-minion package can be installed directly on the network gear.  The interface between the network operating system and Salt in that case would be the corresponding NAPALM sub-package.
For example, if the user installs the salt-minion on a Arista switch, the only requirement is napalm-eos.
The following modules are available in 2017.7.0:
• NAPALM grains
• NET execution module - Networking basic features
• NTP execution module
• BGP execution module
• Routes execution module
• SNMP execution module
• Users execution module
• Probes execution module
• NTP peers management state
• SNMP configuration management state
• Users management state
• Netconfig state module - Manage the configuration of network devices using arbitrary templates and the Salt-specific advanced templating methodologies.
• Network ACL execution module - Generate and load ACL (firewall) configuration on network devices.
• Network ACL state - Manage the firewall configuration. It only requires writing the pillar structure correctly!
• NAPALM YANG execution module - Parse, generate and load native device configuration in a standard way, using the OpenConfig/IETF models. This module contains also helpers for the states.
• NAPALM YANG state module - Manage the network device configuration according to the YANG models (OpenConfig or IETF).
• NET finder - Runner to find details easily and fast. It's smart enough to know what you are looking for. It will search in the details of the network interfaces, IP addresses, MAC address tables, ARP tables and LLDP neighbors.
• BGP finder - Runner to search BGP neighbors details.
• NAPALM syslog - Engine to import events from the napalm-logs library into the Salt event bus. The events are based on the syslog messages from the network devices and structured following the OpenConfig/IETF YANG models.
• NAPALM Helpers - Generic helpers for NAPALM-related operations. For example, the Compliance report function can be used inside the state modules to compare the expected and the existing configuration.
Getting started Install NAPALM - follow the notes and check the platform-specific dependencies.
Salt's Pillar system is ideally suited for configuring proxy-minions (though they can be configured in /etc/salt/proxy as well).  Proxies can either be designated via a pillar file in pillar_roots, or through an external pillar.  External pillars afford the opportunity for interfacing with a configuration management system, database, or other knowledgeable system that may already contain all the details of proxy targets. To use static files in pillar_roots, pattern your files after the following examples:
/etc/salt/pillar/top.sls
base: router1: - router1 router2: - router2 switch1: - switch1 switch2: - switch2 cpe1: - cpe1
/etc/salt/pillar/router1.sls
proxy: proxytype: napalm driver: junos host: r1.bbone.as1234.net username: my_username password: my_password
/etc/salt/pillar/router2.sls
proxy: proxytype: napalm driver: iosxr host: r2.bbone.as1234.net username: my_username password: my_password optional_args: port: 22022
/etc/salt/pillar/switch1.sls
proxy: proxytype: napalm driver: eos host: sw1.bbone.as1234.net username: my_username password: my_password optional_args: enable_password: my_secret
/etc/salt/pillar/switch2.sls
proxy: proxytype: napalm driver: nxos host: sw2.bbone.as1234.net username: my_username password: my_password
/etc/salt/pillar/cpe1.sls
proxy: proxytype: napalm driver: ios host: cpe1.edge.as1234.net username: '' password: '' optional_args: use_keys: True auto_rollback_on_error: True
CLI examples Display the complete running configuration on router1:
$ sudo salt 'router1' net.config source='running'
Retrieve the NTP servers configured on all devices:
$ sudo salt '*' ntp.servers router1: ---------- comment: out: - 1.2.3.4 result: True cpe1: ---------- comment: out: - 1.2.3.4 result: True switch2: ---------- comment: out: - 1.2.3.4 result: True router2: ---------- comment: out: - 1.2.3.4 result: True switch1: ---------- comment: out: - 1.2.3.4 result: True
Display the ARP tables on all Cisco devices running IOS-XR 5.3.3:
$ sudo salt -G 'os:iosxr and version:5.3.3' net.arp
Return operational details for interfaces from Arista switches:
$ sudo salt -C 'sw* and os:eos' net.interfaces
Execute traceroute from the edge of the network:
$ sudo salt 'router*' net.traceroute 8.8.8.8 vrf='CUSTOMER1-VRF'
Verbatim display from the CLI of Juniper routers:
$ sudo salt -C 'router* and G@os:junos' net.cli 'show version and haiku'
Retrieve the results of the RPM probes configured on Juniper MX960 routers:
$ sudo salt -C 'router* and G@os:junos and G@model:MX960' probes.results
Return the list of configured users on the CPEs:
$ sudo salt 'cpe*' users.config
Using the BGP finder, return the list of BGP neighbors that are down:
$ sudo salt-run bgp.neighbors up=False
Using the NET finder, determine the devices containing the pattern "PX-1234-LHR" in their interface description:
$ sudo salt-run net.find PX-1234-LHR
Cross-platform configuration management example: NTP Assuming that the user adds the following two lines under file_roots:
file_roots: base: - /etc/salt/pillar/ - /etc/salt/templates/ - /etc/salt/states/
Define the list of NTP peers and servers wanted:
/etc/salt/pillar/ntp.sls
ntp.servers: - 1.2.3.4 - 5.6.7.8 ntp.peers: - 10.11.12.13 - 14.15.16.17
Include the new file: for example, if we want to have the same NTP servers on all network devices, we can add the following line inside the top.sls file:
'*': - ntp
base: '*': - ntp router1: - router1 router2: - router2 switch1: - switch1 switch2: - switch2 cpe1: - cpe1
Or include only where needed:
base: router1: - router1 - ntp router2: - router2 - ntp switch1: - switch1 switch2: - switch2 cpe1: - cpe1
Define the cross-vendor template:
/etc/salt/templates/ntp.jinja
{%- if grains.vendor|lower == 'cisco' %} no ntp {%- for server in servers %} ntp server {{ server }} {%- endfor %} {%- for peer in peers %} ntp peer {{ peer }} {%- endfor %} {%- elif grains.os|lower == 'junos' %} system { replace: ntp { {%- for server in servers %} server {{ server }}; {%- endfor %} {%- for peer in peers %} peer {{ peer }}; {%- endfor %} } } {%- endif %}
Define the SLS state file, making use of the Netconfig state module:
/etc/salt/states/router/ntp.sls
ntp_config_example: netconfig.managed: - template_name: salt://ntp.jinja - peers: {{ pillar.get('ntp.peers', []) | json }} - servers: {{ pillar.get('ntp.servers', []) | json }}
Run the state and assure NTP configuration consistency across your multi-vendor network:
$ sudo salt 'router*' state.sls router.ntp
Besides CLI, the state can be scheduled or executed when triggered by a certain event.
JUNOS Juniper has developed a Junos specific proxy infrastructure which allows remote execution and configuration management of Junos devices without having to install SaltStack on the device. The infrastructure includes:
• Junos execution module
• Junos state module
• Junos syslog engine
The execution and state modules are implemented using junos-eznc (PyEZ). Junos PyEZ is a microframework for Python that enables you to remotely manage and automate devices running the Junos operating system.
Getting started Install PyEZ on the system which will run the Junos proxy minion.  It is required to run Junos specific modules.
pip install junos-eznc
Next, set the master of the proxy minions.
/etc/salt/proxy
master: <master_ip>
Add the details of the Junos device. Device details are usually stored in salt pillars. If the you do not wish to store credentials in the pillar, one can setup passwordless ssh.
/srv/pillar/vmx_details.sls
proxy: proxytype: junos host: <hostip> username: user passwd: secret123
Map the pillar file to the proxy minion. This is done in the top file.
base: vmx: - vmx_details
NOTE: Before starting the Junos proxy make sure that netconf is enabled on the Junos device. This can be done by adding the following configuration on the Junos device.
set system services netconf ssh
Start the salt master.
Then start the salt proxy.
salt-proxy --proxyid=vmx -l debug
Once the master and junos proxy minion have started, we can run execution and state modules on the proxy minion. Below are few examples.
CLI examples For detailed documentation of all the junos execution modules refer: Junos execution module
Display device facts.
$ sudo salt 'vmx' junos.facts
Refresh the Junos facts. This function will also refresh the facts which are stored in salt grains. (Junos proxy stores Junos facts in the salt grains)
$ sudo salt 'vmx' junos.facts_refresh
Call an RPC.
$ sudo salt 'vmx' junos.rpc 'get-interface-information' '/var/log/interface-info.txt' terse=True
Install config on the device.
$ sudo salt 'vmx' junos.install_config 'salt://my_config.set'
Shutdown the junos device.
$ sudo salt 'vmx' junos.shutdown shutdown=True in_min=10
State file examples For detailed documentation of all the junos state modules refer: Junos state module
Executing an RPC on Junos device and storing the output in a file.
/srv/salt/rpc.sls
get-interface-information: junos: - rpc - dest: /home/user/rpc.log - interface_name: lo0
Lock the junos device, load the configuration, commit it and unlock the device.
/srv/salt/load.sls
lock the config: junos.lock
salt://configs/my_config.set: junos: - install_config - timeout: 100 - diffs_file: 'var/log/diff'
commit the changes: junos: - commit
unlock the config: junos.unlock
According to the device personality install appropriate image on the device.
/srv/salt/image_install.sls
{% if grains['junos_facts']['personality'] == MX %} salt://images/mx_junos_image.tgz: junos: - install_os - timeout: 100 - reboot: True {% elif grains['junos_facts']['personality'] == EX %} salt://images/ex_junos_image.tgz: junos: - install_os - timeout: 150 {% elif grains['junos_facts']['personality'] == SRX %} salt://images/srx_junos_image.tgz: junos: - install_os - timeout: 150 {% endif %}
Junos Syslog Engine Junos Syslog Engine is a Salt engine which receives data from various Junos devices, extracts event information and forwards it on the master/minion event bus. To start the engine on the salt master, add the following configuration in the master config file.  The engine can also run on the salt minion.
/etc/salt/master
engines: - junos_syslog: port: xxx
For junos_syslog engine to receive events, syslog must be set on the Junos device.  This can be done via following configuration:
set system syslog host <ip-of-the-salt-device> port xxx any any
The Salt Virt cloud controller capability was initially added to Salt in version 0.14.0 as an alpha technology.
The initial Salt Virt system supports core cloud operations:
• Virtual machine deployment
• Inspection of deployed VMs
• Virtual machine migration
• Network profiling
• Automatic VM integration with all aspects of Salt
• Image Pre-seeding
Many features are currently under development to enhance the capabilities of the Salt Virt systems.
NOTE: It is noteworthy that Salt was originally developed with the intent of using the Salt communication system as the backbone to a cloud controller.  This means that the Salt Virt system is not an afterthought, simply a system that took the back seat to other development. The original attempt to develop the cloud control aspects of Salt was a project called butter.  This project never took off, but was functional and proves the early viability of Salt to be a cloud controller.
WARNING: Salt Virt does not work with KVM that is running in a VM. KVM must be running on the base hardware.
Salt Virt Tutorial A tutorial about how to get Salt Virt up and running has been added to the tutorial section:
Cloud Controller Tutorial
The Salt Virt Runner The point of interaction with the cloud controller is the virt runner. The virt runner comes with routines to execute specific virtual machine routines.
Reference documentation for the virt runner is available with the runner module documentation:
Virt Runner Reference
Based on Live State Data The Salt Virt system is based on using Salt to query live data about hypervisors and then using the data gathered to make decisions about cloud operations. This means that no external resources are required to run Salt Virt, and that the information gathered about the cloud is live and accurate.
Deploy from Network or Disk Virtual Machine Disk Profiles Salt Virt allows for the disks created for deployed virtual machines to be finely configured. The configuration is a simple data structure which is read from the config.option function, meaning that the configuration can be stored in the minion config file, the master config file, or the minion's pillar.
This configuration option is called virt.disk. The default virt.disk data structure looks like this:
virt.disk: default: - system: size: 8192 format: qcow2 model: virtio
NOTE: The format and model does not need to be defined, Salt will default to the optimal format used by the underlying hypervisor, in the case of kvm this it is qcow2 and virtio.
This configuration sets up a disk profile called default. The default profile creates a single system disk on the virtual machine.
Define More Profiles Many environments will require more complex disk profiles and may require more than one profile, this can be easily accomplished:
virt.disk: default: - system: size: 8192 database: - system: size: 8192 - data: size: 30720 web: - system: size: 1024 - logs: size: 5120
This configuration allows for one of three profiles to be selected, allowing virtual machines to be created with different storage needs of the deployed vm.
Virtual Machine Network Profiles Salt Virt allows for the network devices created for deployed virtual machines to be finely configured. The configuration is a simple data structure which is read from the config.option function, meaning that the configuration can be stored in the minion config file, the master config file, or the minion's pillar.
This configuration option is called virt:nic. By default the virt:nic option is empty but defaults to a data structure which looks like this:
virt: nic: default: eth0: bridge: br0 model: virtio
NOTE: The model does not need to be defined, Salt will default to the optimal model used by the underlying hypervisor, in the case of kvm this model is virtio
This configuration sets up a network profile called default. The default profile creates a single Ethernet device on the virtual machine that is bridged to the hypervisor's br0 interface. This default setup does not require setting up the virt:nic configuration, and is the reason why a default install only requires setting up the br0 bridge device on the hypervisor.
Define More Profiles Many environments will require more complex network profiles and may require more than one profile, this can be easily accomplished:
virt: nic: dual: eth0: bridge: service_br eth1: bridge: storage_br single: eth0: bridge: service_br triple: eth0: bridge: service_br eth1: bridge: storage_br eth2: bridge: dmz_br all: eth0: bridge: service_br eth1: bridge: storage_br eth2: bridge: dmz_br eth3: bridge: database_br dmz: eth0: bridge: service_br eth1: bridge: dmz_br database: eth0: bridge: service_br eth1: bridge: database_br
This configuration allows for one of six profiles to be selected, allowing virtual machines to be created which attach to different network depending on the needs of the deployed vm.
salt-api salt-api Start interfaces used to remotely connect to the salt master
Synopsis salt-api
Description The Salt API system manages network api connectors for the Salt Master
-d, --daemon Run the salt-api as a daemon
--pid-file=PIDFILE Specify the location of the pidfile. Default: /var/run/salt-api.pid
Logging Options Logging options which override any settings defined on the configuration files.
-l LOG_LEVEL, --log-level=LOG_LEVEL Console logging log level. One of all, garbage, trace, debug, info, warning, error, quiet. Default: warning.
--log-file=LOG_FILE Log file path. Default: /var/log/salt/api.
--log-file-level=LOG_LEVEL_LOGFILE Logfile logging log level. One of all, garbage, trace, debug, info, warning, error, quiet. Default: warning.
See also salt-api(7) salt(7) salt-master(1)
salt-call salt-call Synopsis salt-call [options]
Description The salt-call command is used to run module functions locally on a minion instead of executing them from the master. Salt-call is used to run a Standalone Minion, and was originally created for troubleshooting.
The Salt Master is contacted to retrieve state files and other resources during execution unless the --local option is specified.
NOTE: salt-call commands execute from the current user's shell context, while salt commands execute from the system's default context.
--hard-crash Raise any original exception rather than exiting gracefully Default: False
-g, --grains Return the information generated by the Salt grains
-m MODULE_DIRS, --module-dirs=MODULE_DIRS Specify an additional directory to pull modules from.  Multiple directories can be provided by passing -m /--module-dirs multiple times.
-d, --doc, --documentation Return the documentation for the specified module or for all modules if none are specified
--master=MASTER Specify the master to use. The minion must be authenticated with the master. If this option is omitted, the master options from the minion config will be used. If multi masters are set up the first listed master that responds will be used.
--return RETURNER Set salt-call to pass the return data to one or many returner interfaces.  To use many returner interfaces specify a comma delimited list of returners.
--local Run salt-call locally, as if there was no master running.
--file-root=FILE_ROOT Set this directory as the base file root.
--pillar-root=PILLAR_ROOT Set this directory as the base pillar root.
--retcode-passthrough Exit with the salt call retcode and not the salt binary retcode
--metadata Print out the execution metadata as well as the return. This will print out the outputter data, the return code, etc.
--id=ID Specify the minion id to use. If this option is omitted, the id option from the minion config will be used.
--skip-grains Do not load grains.
--refresh-grains-cache Force a refresh of the grains cache
--log-file=LOG_FILE Log file path. Default: /var/log/salt/minion.
See also salt(1) salt-master(1) salt-minion(1)
salt salt Synopsis salt '*' [ options ] sys.doc
salt -E '.*' [ options ] sys.doc cmd
salt -G 'os:Arch.*' [ options ] test.version
salt -C 'G@os:Arch.* and webserv* or G@kernel:FreeBSD' [ options ] test.version
Description Salt allows for commands to be executed across a swath of remote systems in parallel. This means that remote systems can be both controlled and queried with ease.
-t TIMEOUT, --timeout=TIMEOUT The timeout in seconds to wait for replies from the Salt minions. The timeout number specifies how long the command line client will wait to query the minions and check on running jobs. Default: 5
-s, --static By default as of version 0.9.8 the salt command returns data to the console as it is received from minions, but previous releases would return data only after all data was received. Use the static option to only return the data with a hard timeout and after all minions have returned.  Without the static option, you will get a separate JSON string per minion which makes JSON output invalid as a whole.
--async Instead of waiting for the job to run on minions only print the job id of the started execution and complete.
--subset=SUBSET Execute the routine on a random subset of the targeted minions. The minions will be verified that they have the named function before executing. The SUBSET argument is the count of the minions to target.
-v VERBOSE, --verbose Turn on verbosity for the salt call, this will cause the salt command to print out extra data like the job id.
--hide-timeout Instead of showing the return data for all minions. This option prints only the online minions which could be reached.
-b BATCH, --batch-size=BATCH Instead of executing on all targeted minions at once, execute on a progressive set of minions. This option takes an argument in the form of an explicit number of minions to execute at once, or a percentage of minions to execute on.
--batch-wait=BATCH_WAIT Wait the specified time in seconds after each job is done before freeing the slot in the batch of the next one.
--batch-safe-limit=BATCH_SAFE_LIMIT Execute the salt job in batch mode if the job would have executed on at least this many minions.
--batch-safe-size=BATCH_SAFE_SIZE Batch size to use for batch jobs created by --batch-safe-limit.
-a EAUTH, --auth=EAUTH Pass in an external authentication medium to validate against. The credentials will be prompted for. The options are auto, keystone, ldap, and pam. Can be used with the -T option.
-T, --make-token Used in conjunction with the -a option. This creates a token that allows for the authenticated user to send commands without needing to re-authenticate.
--return=RETURNER Choose an alternative returner to call on the minion, if an alternative returner is used then the return will not come back to the command line but will be sent to the specified return system. The options are carbon, cassandra, couchbase, couchdb, elasticsearch, etcd, hipchat, local, local_cache, memcache, mongo, mysql, odbc, postgres, redis, sentry, slack, sms, smtp, sqlite3, syslog, and xmpp.
-d, --doc, --documentation Return the documentation for the module functions available on the minions
--args-separator=ARGS_SEPARATOR Set the special argument used as a delimiter between command arguments of compound commands. This is useful when one wants to pass commas as arguments to some of the commands in a compound command.
--log-file=LOG_FILE Log file path. Default: /var/log/salt/master.
Target Selection The default matching that Salt utilizes is shell-style globbing around the minion id. See https://docs.python.org/3/library/fnmatch.html#module-fnmatch.
-E, --pcre The target expression will be interpreted as a PCRE regular expression rather than a shell glob.
-L, --list The target expression will be interpreted as a comma-delimited list; example: server1.foo.bar,server2.foo.bar,example7.quo.qux
-G, --grain The target expression matches values returned by the Salt grains system on the minions. The target expression is in the format of '<grain value>:<glob expression>'; example: 'os:Arch*'
This was changed in version 0.9.8 to accept glob expressions instead of regular expression. To use regular expression matching with grains, use the --grain-pcre option.
--grain-pcre The target expression matches values returned by the Salt grains system on the minions. The target expression is in the format of '<grain value>:< regular expression>'; example: 'os:Arch.*'
-N, --nodegroup Use a predefined compound target defined in the Salt master configuration file.
-R, --range Instead of using shell globs to evaluate the target, use a range expression to identify targets. Range expressions look like %cluster.
Using the Range option requires that a range server is set up and the location of the range server is referenced in the master configuration file.
-C, --compound Utilize many target definitions to make the call very granular. This option takes a group of targets separated by and or or. The default matcher is a glob as usual. If something other than a glob is used, preface it with the letter denoting the type; example: 'webserv* and G@os:Debian or E@db*' Make sure that the compound target is encapsulated in quotes.
-I, --pillar Instead of using shell globs to evaluate the target, use a pillar value to identify targets. The syntax for the target is the pillar key followed by a glob expression: "role:production*"
-S, --ipcidr Match based on Subnet (CIDR notation) or IPv4 address.
NOTE: If using --out=json, you will probably want --static as well.  Without the static option, you will get a separate JSON string per minion which makes JSON output invalid as a whole.  This is due to using an iterative outputter. So if you want to feed it to a JSON parser, use --static as well.
See also salt(7) salt-master(1) salt-minion(1)
salt-cloud salt-cp salt-cp Copy a file or files to one or more minions
Synopsis salt-cp '*' [ options ] SOURCE [SOURCE2 SOURCE3 ...] DEST
salt-cp -E '.*' [ options ] SOURCE [SOURCE2 SOURCE3 ...] DEST
salt-cp -G 'os:Arch.*' [ options ] SOURCE [SOURCE2 SOURCE3 ...] DEST
Description salt-cp copies files from the master to all of the Salt minions matched by the specified target expression.
NOTE: salt-cp uses Salt's publishing mechanism. This means the privacy of the contents of the file on the wire is completely dependent upon the transport in use. In addition, if the master or minion is running with debug logging, the contents of the file will be logged to disk.
In addition, this tool is less efficient than the Salt fileserver when copying larger files. It is recommended to instead use cp.get_file to copy larger files to minions. However, this requires the file to be located within one of the fileserver directories.
Changed in version 2016.3.7,2016.11.6,2017.7.0: Compression support added, disable with -n. Also, if the destination path ends in a path separator (i.e. /,  or \ on Windows, the desitination will be assumed to be a directory. Finally, recursion is now supported, allowing for entire directories to be copied.
Changed in version 2016.11.7,2017.7.2: Reverted back to the old copy mode to preserve backward compatibility. The new functionality added in 2016.6.6 and 2017.7.0 is now available using the -C or --chunked CLI arguments. Note that compression, recursive copying, and support for copying large files is only available in chunked mode.
-C, --chunked Use new chunked mode to copy files. This mode supports large files, recursive directories copying and compression.
New in version 2016.11.7,2017.7.2.
-n, --no-compression Disable gzip compression in chunked mode.
New in version 2016.3.7,2016.11.6,2017.7.0.
salt-extend salt-extend A utilty to generate extensions to the Salt source-code. This is used for :
• Adding new execution modules, state modules
• Adding unit tests to existing modules
• Adding integration tests to existing modules
Synopsis salt-extend --help
Description salt-extend is a templating tool for extending SaltStack. If you're looking to add a module to SaltStack, then the salt-extend utility can guide you through the process.
You can use Salt Extend to quickly create templated modules for adding new behaviours to some of the module subsystems within Salt.
Salt Extend takes a template directory and merges it into a SaltStack source code directory.
See also: Salt Extend.
Options --extension, -e The extension type you want to develop, e.g. module, module_unit, state
--salt-directory, -o The path to the salt installation, defaults to .
--name, -n The module name for the new module
--description, -d A description of the new extension
--no-merge Don't merge the new module into the Salt source directory specified by --salt-directory, save to a temporary directory and print the directory path
--debug Print debug messages to stdout
See also salt-api(1) salt-call(1) salt-cloud(1) salt-cp(1) salt-key(1) salt-main(1) salt-master(1) salt-minion(1) salt-run(1) salt-ssh(1) salt-syndic(1)
salt-key salt-key Synopsis salt-key [ options ]
Description Salt-key executes simple management of Salt server public keys used for authentication.
On initial connection, a Salt minion sends its public key to the Salt master. This key must be accepted using the salt-key command on the Salt master.
Salt minion keys can be in one of the following states:
• unaccepted: key is waiting to be accepted.
• accepted: key was accepted and the minion can communicate with the Salt master.
• rejected: key was rejected using the salt-key command. In this state the minion does not receive any communication from the Salt master.
• denied: key was rejected automatically by the Salt master.  This occurs when a minion has a duplicate ID, or when a minion was rebuilt or had new keys generated and the previous key was not deleted from the Salt master. In this state the minion does not receive any communication from the Salt master.
To change the state of a minion key, use -d to delete the key and then accept or reject the key.
-u USER, --user=USER Specify user to run salt-key
--hard-crash Raise any original exception rather than exiting gracefully. Default is False.
-q, --quiet Suppress output
-y, --yes Answer 'Yes' to all questions presented, defaults to False
--rotate-aes-key=ROTATE_AES_KEY Setting this to False prevents the master from refreshing the key session when keys are deleted or rejected, this lowers the security of the key deletion/rejection operation. Default is True.
Actions -l ARG, --list=ARG List the public keys. The args pre, un, and unaccepted will list unaccepted/unsigned keys. acc or accepted will list accepted/signed keys. rej or rejected will list rejected keys. Finally, all will list all keys.
-L, --list-all List all public keys. (Deprecated: use --list all)
-a ACCEPT, --accept=ACCEPT Accept the specified public key (use --include-all to match rejected keys in addition to pending keys). Globs are supported.
-A, --accept-all Accepts all pending keys.