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.
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.
See the salt-api project to access Salt externally via a REST interface. It uses Salt's Python interface documented below and is also useful as a reference implementation.
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, minion_id=False)¶Reads in the minion configuration file and sets up special options
This is useful for Minion-side operations, such as the
Caller
class, and manually running the loader
interface.
import salt.client
minion_opts = salt.config.minion_config('/etc/salt/minion')
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, whitelist=None, loaded_base_name=None)¶Load execution modules
Returns a dictionary of execution modules appropriate for the current system by evaluating the __virtual__() function in each module.
import salt.config
import salt.loader
__opts__ = salt.config.minion_config('/etc/salt/minion')
__grains__ = salt.loader.grains(__opts__)
__opts__['grains'] = __grains__
__salt__ = salt.loader.minion_mods(__opts__)
__salt__['test.ping']()
salt.loader.
raw_mod
(opts, name, functions)¶Returns a single module loaded raw and bypassing the __virtual__ function
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, whitelist=None)¶Returns the state modules
import salt.config
import salt.loader
__opts__ = salt.config.minion_config('/etc/salt/minion')
statemods = salt.loader.states(__opts__, None)
salt.loader.
grains
(opts, force_refresh=False)¶Return the functions for the dynamic grains and the values for the static grains.
import salt.config
import salt.loader
__opts__ = salt.config.minion_config('/etc/salt/minion')
__grains__ = salt.loader.grains(__opts__)
print __grains__['id']
salt.client.
LocalClient
(c_path='/etc/salt/master', mopts=None, skip_perm_errors=False)¶The interface used by the salt CLI tool on the Salt Master
LocalClient
is used to send a command to Salt minions to execute
execution modules and return the results to the
Salt Master.
Importing and using LocalClient
must 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. (Unless external_auth
is configured and
authentication credentials are included in the execution).
import salt.client
local = salt.client.LocalClient()
local.cmd('*', 'test.fib', [10])
cmd
(tgt, fun, arg=(), timeout=None, expr_form='glob', ret='', 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: |
|
---|---|
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=(), expr_form='glob', ret='', 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=(), expr_form='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', bat='10%')
>>> for ret in returns:
... print(ret)
{'jerry': {...}}
{'dave': {...}}
{'stewart': {...}}
cmd_iter
(tgt, fun, arg=(), timeout=None, expr_form='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.
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, expr_form='glob', ret='', kwarg=None, **kwargs)¶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=(), expr_form='glob', ret='', kwarg=None, sub=3, cli=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: | sub -- The number of systems to execute on |
---|
>>> SLC.cmd_subset('*', 'test.ping', sub=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=(), expr_form='glob', ret='', timeout=None, kwarg=None, **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_data or an empty
dictionary on failure. The pub_data contains 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.client.
Caller
(c_path='/etc/salt/minion', mopts=None)¶Caller
is the same interface used by the salt-call
command-line tool on the Salt Minion.
Importing and using Caller
must 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.function('test.ping')
# Or call objects directly
caller.sminion.functions['cmd.run']('ls -l')
Note, a running master or minion daemon is not required to use this class.
Running salt-call --local
simply sets file_client
to
'local'
. The same can be achieved at the Python level by including that
setting in a minion config file.
Instantiate a new Caller() instance using a file system path to the minion config file:
caller = salt.client.Caller('/path/to/custom/minion_config')
caller.sminion.functions['grains.items']()
Instantiate a new Caller() instance using a dictionary of the minion config:
New in version 2014.7.0: Pass the minion config as a dictionary.
import salt.client
import salt.config
opts = salt.config.minion_config('/etc/salt/minion')
opts['file_client'] = 'local'
caller = salt.client.Caller(mopts=opts)
caller.sminion.functions['grains.items']()
function
(fun, *args, **kwargs)¶Call a single salt function
salt.runner.
RunnerClient
(opts)¶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 RunnerClient
must 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_auth
can be used to authenticate calls. The
eauth user must be authorized to execute runner modules: (@runner
).
Only the master_call()
below supports eauth.
async
(fun, low, user='UNKNOWN')¶Execute the function in a multiprocess and return the event tag to use to watch for the return
cmd
(fun, arg, pub_data=None, kwarg=None)¶Execute a runner 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_auth
is configured
and the user is authorized to execute runner functions: (@runner
).
runner.eauth_async({
'fun': 'jobs.list_jobs',
'username': 'saltdev',
'password': 'saltdev',
'eauth': 'pam',
})
cmd_sync
(low, timeout=None)¶Execute a runner function synchronously; eauth is respected
This function requires that external_auth
is configured
and the user is authorized to execute runner functions: (@runner
).
runner.eauth_sync({
'fun': 'jobs.list_jobs',
'username': 'saltdev',
'password': 'saltdev',
'eauth': 'pam',
})
salt.wheel.
WheelClient
(opts=None)¶An interface to Salt's wheel modules
Wheel modules interact with various parts of the Salt Master.
Importing and using WheelClient
must 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. Unless external_auth
is configured and the user
is authorized to execute wheel functions: (@wheel
).
async
(fun, low, user='UNKNOWN')¶Execute the function in a multiprocess and return the event tag to use to watch for the return
cmd
(fun, **kwargs)¶Execute a wheel function
>>> opts = salt.config.master_config('/etc/salt/master')
>>> wheel = salt.wheel.Wheel(opts)
>>> wheel.call_func('key.list_all')
{'local': ['master.pem', 'master.pub'],
'minions': ['jerry'],
'minions_pre': [],
'minions_rejected': []}
cmd_async
(low)¶Execute a wheel function asynchronously; eauth is respected
This function requires that external_auth
is configured
and the user is authorized to execute runner functions: (@wheel
).
>>> 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)¶Execute a wheel function synchronously; eauth is respected
This function requires that external_auth
is 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'}}
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(names=['myinstance'], provider='my-ec2-config',
kwargs={'image': 'ami-1624987f', 'size': 'Micro Instance',
'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, **kwargs)¶Pass in a location for a map to execute
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': {u'backups_active': 'False',
u'created_at': '2014-09-04T18:10:15Z',
u'droplet': {u'event_id': 31000502,
u'id': 2530006,
u'image_id': 5140006,
u'name': u'minion01',
u'size_id': 66},
u'id': '2530006',
u'image_id': '5140006',
u'ip_address': '107.XXX.XXX.XXX',
u'locked': 'True',
u'name': 'minion01',
u'private_ip_address': None,
u'region_id': '4',
u'size_id': '66',
u'status': 'new'}}
query
(query_type='list_nodes')¶Query basic instance information
select_query
(query_type='list_nodes_select')¶Query select instance information