Python client API#
Salt provides several entry points for interfacing with Python applications.
These entry points are often referred to as *Client() APIs. Each client
accesses different parts of Salt, either from the master or from a minion. Each
client is detailed below.
Note
For Tiamat-bundled Salt distribution, you need to use the bundled Python runtime as the system Python won't be able to access Salt internals.
To execute scripts via bundled Python runtime, either run the script with
/path/to/salt python script.py or use #!/path/to/salt python shebang
See also
There are many ways to access Salt programmatically.
Salt can be used from CLI scripts as well as via a REST interface.
See Salt's outputter system to retrieve structured data from Salt as JSON, or as shell-friendly text, or many other formats.
See the state.event runner to utilize
Salt's event bus from shell scripts.
Salt's netapi module provides access to Salt externally via a REST interface. Review the netapi module documentation for more information.
Salt's opts dictionary#
Some clients require access to Salt's opts dictionary. (The dictionary
representation of the master or
minion config files.)
A common pattern for fetching the opts dictionary is to defer to
environment variables if they exist or otherwise fetch the config from the
default location.
- salt.config.client_config(path, env_var='SALT_CLIENT_CONFIG', defaults=None)#
Load Master configuration data
Usage:
import salt.config master_opts = salt.config.client_config('/etc/salt/master')
Returns a dictionary of the Salt Master configuration file with necessary options needed to communicate with a locally-running Salt Master daemon. This function searches for client specific configurations and adds them to the data from the master configuration.
This is useful for master-side operations like
LocalClient.
- salt.config.minion_config(path, env_var='SALT_MINION_CONFIG', defaults=None, cache_minion_id=False, ignore_config_errors=True, minion_id=None, role='minion')#
Reads in the minion configuration file and sets up special options
This is useful for Minion-side operations, such as the
Callerclass, and manually running the loader interface.import salt.config minion_opts = salt.config.minion_config('/etc/salt/minion')
Salt's Loader Interface#
Modules in the Salt ecosystem are loaded into memory using a custom loader
system. This allows modules to have conditional requirements (OS, OS version,
installed libraries, etc) and allows Salt to inject special variables
(__salt__, __opts__, etc).
Most modules can be manually loaded. This is often useful in third-party Python
apps or when writing tests. However some modules require and expect a full,
running Salt system underneath. Notably modules that facilitate
master-to-minion communication such as the mine,
publish, and peer execution
modules. The error KeyError: 'master_uri' is a likely indicator for this
situation. In those instances use the Caller class
to execute those modules instead.
Each module type has a corresponding loader function.
- salt.loader.minion_mods(opts, context=None, utils=None, whitelist=None, initial_load=False, loaded_base_name=None, notify=False, static_modules=None, proxy=None, pillar=None, file_client=None)#
Load execution modules
Returns a dictionary of execution modules appropriate for the current system by evaluating the __virtual__() function in each module.
- Parameters:
opts (dict) -- The Salt options dictionary
context (dict) -- A Salt context that should be made present inside generated modules in __context__
utils (dict) -- Utility functions which should be made available to Salt modules in __utils__. See utils_dirs in salt.config for additional information about configuration.
whitelist (list) -- A list of modules which should be whitelisted.
initial_load (bool) -- Deprecated flag! Unused.
loaded_base_name (str) -- The imported modules namespace when imported by the salt loader.
notify (bool) -- Flag indicating that an event should be fired upon completion of module loading.
Example:
import salt.config import salt.loader __opts__ = salt.config.minion_config('/etc/salt/minion') __grains__ = salt.loader.grains(__opts__) __opts__['grains'] = __grains__ __utils__ = salt.loader.utils(__opts__) __salt__ = salt.loader.minion_mods(__opts__, utils=__utils__) __salt__['test.ping']()
- salt.loader.raw_mod(opts, name, functions, mod='modules', loaded_base_name=None)#
Returns a single module loaded raw and bypassing the __virtual__ function
- Parameters:
Example:
import salt.config import salt.loader __opts__ = salt.config.minion_config('/etc/salt/minion') testmod = salt.loader.raw_mod(__opts__, 'test', None) testmod['test.ping']()
- salt.loader.states(opts, functions, utils, serializers, whitelist=None, proxy=None, context=None, loaded_base_name=None, file_client=None, minion_mods=None)#
Returns the state modules
- Parameters:
opts (dict) -- The Salt options dictionary
functions (LazyLoader) -- A LazyLoader instance returned from
minion_mods(or, in a resource context, fromresource_modules). This becomes__salt__for state modules.runners (LazyLoader) -- A LazyLoader instance returned from
runner.utils (LazyLoader) -- A LazyLoader instance returned from
utils.serializers (LazyLoader) -- An optional LazyLoader instance returned from
serializers.proxy (LazyLoader) -- An optional LazyLoader instance returned from
proxy.whitelist (list) -- A list of modules which should be whitelisted.
context (dict) -- A Salt context that should be made present inside generated modules in __context__
loaded_base_name (str) -- The imported modules namespace when imported by the salt loader.
minion_mods (LazyLoader) -- Optional escape-hatch loader for the managing minion's modules. Packed as
__minion__so state modules running in a resource context can call back into the managing minion explicitly. Typically the result ofsalt.loader.minion_mods(opts).
import salt.config import salt.loader __opts__ = salt.config.minion_config('/etc/salt/minion') statemods = salt.loader.states(__opts__, None, None)
- salt.loader.grains(opts, force_refresh=False, proxy=None, context=None, loaded_base_name=None)#
Return the functions for the dynamic grains and the values for the static grains.
- Parameters:
opts (dict) -- The Salt options dictionary
force_refresh (bool) -- Force the refresh of grains
context (dict) -- A Salt context that should be made present inside generated modules in __context__
proxy (LazyLoader) -- An optional LazyLoader instance returned from
proxy.loaded_base_name (str) -- The imported modules namespace when imported by the salt loader.
Since grains are computed early in the startup process, grains functions do not have __salt__ or __proxy__ available. At proxy-minion startup, this function is called with the proxymodule LazyLoader object so grains functions can communicate with their controlled device.
import salt.config import salt.loader __opts__ = salt.config.minion_config('/etc/salt/minion') __grains__ = salt.loader.grains(__opts__) print __grains__['id']
- salt.loader.grain_funcs(opts, proxy=None, context=None, loaded_base_name=None)#
Returns the grain functions
- Parameters:
opts (dict) -- The Salt options dictionary
context (dict) -- A Salt context that should be made present inside generated modules in __context__
proxy (LazyLoader) -- An optional LazyLoader instance returned from
proxy.loaded_base_name (str) --
- The imported modules namespace when imported
by the salt loader.
import salt.config import salt.loader __opts__ = salt.config.minion_config('/etc/salt/minion') grainfuncs = salt.loader.grain_funcs(__opts__)
Salt's Client Interfaces#
LocalClient#
- class salt.client.LocalClient(c_path='/etc/salt/master', mopts=None, skip_perm_errors=False, io_loop=None, keep_loop=False, auto_reconnect=False, listen=False)#
The interface used by the salt CLI tool on the Salt Master
LocalClientis used to send a command to Salt minions to execute execution modules and return the results to the Salt Master.Importing and using
LocalClientmust be done on the same machine as the Salt Master and it must be done using the same user that the Salt Master is running as. (Unlessexternal_authis configured and authentication credentials are included in the execution).Note
The LocalClient uses a Tornado IOLoop, this can create issues when using the LocalClient inside an existing IOLoop. If creating the LocalClient in partnership with another IOLoop either create the IOLoop before creating the LocalClient, or when creating the IOLoop use ioloop.current() which will return the ioloop created by LocalClient.
import salt.client local = salt.client.LocalClient() local.cmd('*', 'test.fib', [10])
- cmd(tgt, fun, arg=(), timeout=None, tgt_type='glob', ret='', jid='', full_return=False, kwarg=None, **kwargs)#
Synchronously execute a command on targeted minions
The cmd method will execute and wait for the timeout period for all minions to reply, then it will return all minion data at once.
>>> import salt.client >>> local = salt.client.LocalClient() >>> local.cmd('*', 'cmd.run', ['whoami']) {'jerry': 'root'}
With extra keyword arguments for the command function to be run:
local.cmd('*', 'test.arg', ['arg1', 'arg2'], kwarg={'foo': 'bar'})
Compound commands can be used for multiple executions in a single publish. Function names and function arguments are provided in separate lists but the index values must correlate and an empty list must be used if no arguments are required.
>>> local.cmd('*', [ 'grains.items', 'sys.doc', 'cmd.run', ], [ [], [], ['uptime'], ])
- Parameters:
tgt (string or list) -- Which minions to target for the execution. Default is shell glob. Modified by the
tgt_typeoption.fun (string or list of strings) --
The module and function to call on the specified minions of the form
module.function. For exampletest.pingorgrains.items.- Compound commands
Multiple functions may be called in a single publish by passing a list of commands. This can dramatically lower overhead and speed up the application communicating with Salt.
This requires that the
argparam is a list of lists. Thefunlist and thearglist must correlate by index meaning a function that does not take arguments must still have a corresponding empty list at the expected index.
arg (list or list-of-lists) -- A list of arguments to pass to the remote function. If the function takes no arguments
argmay be omitted except when executing a compound command.timeout -- Seconds to wait after the last minion returns but before all minions return.
tgt_type --
The type of
tgt. Allowed values:glob- Bash glob completion - Defaultpcre- Perl style regular expressionlist- Python list of hostsgrain- Match based on a grain comparisongrain_pcre- Grain comparison with a regexpillar- Pillar data comparisonpillar_pcre- Pillar data comparison with a regexnodegroup- Match on nodegrouprange- Use a Range server for matchingcompound- Pass a compound match stringipcidr- Match based on Subnet (CIDR notation) or IPv4 address.
Changed in version 2017.7.0: Renamed from
expr_formtotgt_typeret -- The returner to use. The value passed can be single returner, or a comma delimited list of returners to call in order on the minions
kwarg -- A dictionary with keyword arguments for the function.
full_return -- Output the job return only (default) or the full return including exit code and other job metadata.
kwargs --
Optional keyword arguments. Authentication credentials may be passed when using
external_auth.For example:
local.cmd('*', 'test.ping', username='saltdev', password='saltdev', eauth='pam'). Or:local.cmd('*', 'test.ping', token='5871821ea51754fdcea8153c1c745433')
- Returns:
A dictionary with the result of the execution, keyed by minion ID. A compound command will return a sub-dictionary keyed by function name.
- cmd_async(tgt, fun, arg=(), tgt_type='glob', ret='', jid='', kwarg=None, **kwargs)#
Asynchronously send a command to connected minions
The function signature is the same as
cmd()with the following exceptions.- Returns:
A job ID or 0 on failure.
>>> local.cmd_async('*', 'test.sleep', [300]) '20131219215921857715'
- cmd_batch(tgt, fun, arg=(), tgt_type='glob', ret='', kwarg=None, batch='10%', **kwargs)#
Iteratively execute a command on subsets of minions at a time
The function signature is the same as
cmd()with the following exceptions.- Parameters:
batch -- The batch identifier of systems to execute on
- Returns:
A generator of minion returns
>>> returns = local.cmd_batch('*', 'state.highstate', batch='10%') >>> for ret in returns: ... print(ret) {'jerry': {...}} {'dave': {...}} {'stewart': {...}}
- cmd_iter(tgt, fun, arg=(), timeout=None, tgt_type='glob', ret='', kwarg=None, **kwargs)#
Yields the individual minion returns as they come in
The function signature is the same as
cmd()with the following exceptions.Normally
cmd_iter()does not yield results for minions that are not connected. If you want it to return results for disconnected minions set expect_minions=True in kwargs.- Returns:
A generator yielding the individual minion returns
>>> ret = local.cmd_iter('*', 'test.ping') >>> for i in ret: ... print(i) {'jerry': {'ret': True}} {'dave': {'ret': True}} {'stewart': {'ret': True}}
- cmd_iter_no_block(tgt, fun, arg=(), timeout=None, tgt_type='glob', ret='', kwarg=None, show_jid=False, verbose=False, **kwargs)#
- Yields the individual minion returns as they come in, or None
when no returns are available.
The function signature is the same as
cmd()with the following exceptions.- Returns:
A generator yielding the individual minion returns, or None when no returns are available. This allows for actions to be injected in between minion returns.
>>> ret = local.cmd_iter_no_block('*', 'test.ping') >>> for i in ret: ... print(i) None {'jerry': {'ret': True}} {'dave': {'ret': True}} None {'stewart': {'ret': True}}
- cmd_subset(tgt, fun, arg=(), tgt_type='glob', ret='', kwarg=None, subset=3, cli=False, progress=False, full_return=False, **kwargs)#
Execute a command on a random subset of the targeted systems
The function signature is the same as
cmd()with the following exceptions.- Parameters:
subset -- The number of systems to execute on
cli -- When this is set to True, a generator is returned, otherwise a dictionary of the minion returns is returned
>>> SLC.cmd_subset('*', 'test.ping', subset=1) {'jerry': True}
- get_cli_returns(jid, minions, timeout=None, tgt='*', tgt_type='glob', verbose=False, show_jid=False, **kwargs)#
Starts a watcher looking at the return data for a specified JID
- Returns:
all of the information for the JID
- get_event_iter_returns(jid, minions, timeout=None)#
Gather the return data from the event system, break hard when timeout is reached.
- run_job(tgt, fun, arg=(), tgt_type='glob', ret='', timeout=None, jid='', kwarg=None, listen=False, **kwargs)#
Asynchronously send a command to connected minions
Prep the job directory and publish a command to any targeted minions.
- Returns:
A dictionary of (validated)
pub_dataor an empty dictionary on failure. Thepub_datacontains the job ID and a list of all minions that are expected to return data.
>>> local.run_job('*', 'test.sleep', [300]) {'jid': '20131219215650131543', 'minions': ['jerry']}
Salt Caller#
- class salt.client.Caller(c_path='/etc/salt/minion', mopts=None)#
Calleris the same interface used by the salt-call command-line tool on the Salt Minion.Changed in version 2015.8.0: Added the
cmdmethod for consistency with the other Salt clients. The existingfunctionandsminion.functionsinterfaces still exist but have been removed from the docs.Importing and using
Callermust be done on the same machine as a Salt Minion and it must be done using the same user that the Salt Minion is running as.Usage:
import salt.client caller = salt.client.Caller() caller.cmd('test.ping')
Note, a running master or minion daemon is not required to use this class. Running
salt-call --localsimply setsfile_clientto'local'. The same can be achieved at the Python level by including that setting in a minion config file.New in version 2014.7.0: Pass the minion config as the
moptsdictionary.import salt.client import salt.config __opts__ = salt.config.minion_config('/etc/salt/minion') __opts__['file_client'] = 'local' caller = salt.client.Caller(mopts=__opts__)
- cmd(fun, *args, **kwargs)#
Call an execution module with the given arguments and keyword arguments
Changed in version 2015.8.0: Added the
cmdmethod for consistency with the other Salt clients. The existingfunctionandsminion.functionsinterfaces still exist but have been removed from the docs.caller.cmd('test.arg', 'Foo', 'Bar', baz='Baz') caller.cmd('event.send', 'myco/myevent/something', data={'foo': 'Foo'}, with_env=['GIT_COMMIT'], with_grains=True)
Salt Proxy Caller#
- class salt.client.ProxyCaller(c_path='/etc/salt/proxy', mopts=None)#
ProxyCalleris the same interface used by the salt-call with the args--proxyid <proxyid>command-line tool on the Salt Proxy Minion.Importing and using
ProxyCallermust be done on the same machine as a Salt Minion and it must be done using the same user that the Salt Minion is running as.Usage:
import salt.client caller = salt.client.ProxyCaller() caller.cmd('test.ping')
Note, a running master or minion daemon is not required to use this class. Running
salt-call --localsimply setsfile_clientto'local'. The same can be achieved at the Python level by including that setting in a minion config file.import salt.client import salt.config __opts__ = salt.config.proxy_config('/etc/salt/proxy', minion_id='quirky_edison') __opts__['file_client'] = 'local' caller = salt.client.ProxyCaller(mopts=__opts__)
Note
To use this for calling proxies, the
is_proxy functionsrequires that--proxyidbe an argument on the commandline for the script this is used in, or that the stringproxyis in the name of the script.- cmd(fun, *args, **kwargs)#
Call an execution module with the given arguments and keyword arguments
caller.cmd('test.arg', 'Foo', 'Bar', baz='Baz') caller.cmd('event.send', 'myco/myevent/something', data={'foo': 'Foo'}, with_env=['GIT_COMMIT'], with_grains=True)
RunnerClient#
- class salt.runner.RunnerClient(opts, context=None)#
The interface used by the salt-run CLI tool on the Salt Master
It executes runner modules which run on the Salt Master.
Importing and using
RunnerClientmust be done on the same machine as the Salt Master and it must be done using the same user that the Salt Master is running as.Salt's
external_authcan be used to authenticate calls. The eauth user must be authorized to execute runner modules: (@runner). Only themaster_call()below supports eauth.- asynchronous(fun, low, user='UNKNOWN', pub=None, local=True)#
Execute the function in a multiprocess and return the event tag to use to watch for the return
- cmd(fun, arg=None, pub_data=None, kwarg=None, print_event=True, full_return=False)#
Execute a function
>>> opts = salt.config.master_config('/etc/salt/master') >>> runner = salt.runner.RunnerClient(opts) >>> runner.cmd('jobs.list_jobs', []) { '20131219215650131543': { 'Arguments': [300], 'Function': 'test.sleep', 'StartTime': '2013, Dec 19 21:56:50.131543', 'Target': '*', 'Target-type': 'glob', 'User': 'saltdev' }, '20131219215921857715': { 'Arguments': [300], 'Function': 'test.sleep', 'StartTime': '2013, Dec 19 21:59:21.857715', 'Target': '*', 'Target-type': 'glob', 'User': 'saltdev' }, }
- cmd_async(low)#
Execute a runner function asynchronously; eauth is respected
This function requires that
external_authis configured and the user is authorized to execute runner functions: (@runner).runner.cmd_async({ 'fun': 'jobs.list_jobs', 'username': 'saltdev', 'password': 'saltdev', 'eauth': 'pam', })
- cmd_sync(low, timeout=None, full_return=False)#
Execute a runner function synchronously; eauth is respected
This function requires that
external_authis configured and the user is authorized to execute runner functions: (@runner).runner.cmd_sync({ 'fun': 'jobs.list_jobs', 'username': 'saltdev', 'password': 'saltdev', 'eauth': 'pam', })
WheelClient#
- class salt.wheel.WheelClient(opts, context=None)#
An interface to Salt's wheel modules
Wheel modules interact with various parts of the Salt Master.
Importing and using
WheelClientmust be done on the same machine as the Salt Master and it must be done using the same user that the Salt Master is running as. Unlessexternal_authis configured and the user is authorized to execute wheel functions: (@wheel).Usage:
import salt.config import salt.wheel opts = salt.config.master_config('/etc/salt/master') wheel = salt.wheel.WheelClient(opts)
- asynchronous(fun, low, user='UNKNOWN', pub=None, local=True)#
Execute the function in a multiprocess and return the event tag to use to watch for the return
- cmd(fun, arg=None, pub_data=None, kwarg=None, print_event=True, full_return=False)#
Execute a function
>>> wheel.cmd('key.finger', ['jerry']) {'minions': {'jerry': '5d:f6:79:43:5e:d4:42:3f:57:b8:45:a8:7e:a4:6e:ca'}}
- cmd_async(low)#
Execute a function asynchronously; eauth is respected
This function requires that
external_authis configured and the user is authorized>>> wheel.cmd_async({ 'fun': 'key.finger', 'match': 'jerry', 'eauth': 'auto', 'username': 'saltdev', 'password': 'saltdev', }) {'jid': '20131219224744416681', 'tag': 'salt/wheel/20131219224744416681'}
- cmd_sync(low, timeout=None, full_return=False)#
Execute a wheel function synchronously; eauth is respected
This function requires that
external_authis configured and the user is authorized to execute runner functions: (@wheel).>>> wheel.cmd_sync({ 'fun': 'key.finger', 'match': 'jerry', 'eauth': 'auto', 'username': 'saltdev', 'password': 'saltdev', }) {'minions': {'jerry': '5d:f6:79:43:5e:d4:42:3f:57:b8:45:a8:7e:a4:6e:ca'}}
CloudClient#
- class salt.cloud.CloudClient(path=None, opts=None, config_dir=None, pillars=None)#
The client class to wrap cloud interactions
- action(fun=None, cloudmap=None, names=None, provider=None, instance=None, kwargs=None)#
Execute a single action via the cloud plugin backend
Examples:
client.action(fun='show_instance', names=['myinstance']) client.action(fun='show_image', provider='my-ec2-config', kwargs={'image': 'ami-10314d79'} )
- create(provider, names, **kwargs)#
Create the named VMs, without using a profile
Example:
client.create(provider='my-ec2-config', names=['myinstance'], image='ami-1624987f', size='t1.micro', ssh_username='ec2-user', securitygroup='default', delvol_on_destroy=True)
- destroy(names)#
Destroy the named VMs
- extra_action(names, provider, action, **kwargs)#
Perform actions with block storage devices
Example:
client.extra_action(names=['myblock'], action='volume_create', provider='my-nova', kwargs={'voltype': 'SSD', 'size': 1000} ) client.extra_action(names=['salt-net'], action='network_create', provider='my-nova', kwargs={'cidr': '192.168.100.0/24'} )
- full_query(query_type='list_nodes_full')#
Query all instance information
- list_images(provider=None)#
List all available images in configured cloud systems
- list_locations(provider=None)#
List all available locations in configured cloud systems
- list_sizes(provider=None)#
List all available sizes in configured cloud systems
- low(fun, low)#
Pass the cloud function and low data structure to run
- map_run(path=None, **kwargs)#
To execute a map
- min_query(query_type='list_nodes_min')#
Query select instance information
- profile(profile, names, vm_overrides=None, **kwargs)#
Pass in a profile to create, names is a list of vm names to allocate
vm_overrides is a special dict that will be per node options overrides
Example:
>>> client= salt.cloud.CloudClient(path='/etc/salt/cloud') >>> client.profile('do_512_git', names=['minion01',]) {'minion01': {'backups_active': 'False', 'created_at': '2014-09-04T18:10:15Z', 'droplet': {'event_id': 31000502, 'id': 2530006, 'image_id': 5140006, 'name': 'minion01', 'size_id': 66}, 'id': '2530006', 'image_id': '5140006', 'ip_address': '107.XXX.XXX.XXX', 'locked': 'True', 'name': 'minion01', 'private_ip_address': None, 'region_id': '4', 'size_id': '66', 'status': 'new'}}
- query(query_type='list_nodes')#
Query basic instance information
- select_query(query_type='list_nodes_select')#
Query select instance information
SSHClient#
- class salt.client.ssh.client.SSHClient(c_path='/etc/salt/master', mopts=None, disable_custom_roster=False)#
Create a client object for executing routines via the salt-ssh backend
New in version 2015.5.0.
- cmd(tgt, fun, arg=(), timeout=None, tgt_type='glob', kwarg=None, **kwargs)#
Execute a single command via the salt-ssh subsystem and return all routines at once
New in version 2015.5.0.
- cmd_iter(tgt, fun, arg=(), timeout=None, tgt_type='glob', ret='', kwarg=None, **kwargs)#
Execute a single command via the salt-ssh subsystem and return a generator
New in version 2015.5.0.