Using the Salt REST API¶
To be able to use the Salt HTTP API, similarly to Event-Driven Automation and Orchestration, you will need to have the Salt Master running, and, of course, also the Salt API service.
As the core functionality if based on the Proxy Runner, check out first
the notes from The Proxy Runner to understand how to have the proxy
Runner
available on your Master.
The Salt API configuration is unchanged from the usual approaches: see https://docs.saltstack.com/en/latest/ref/netapi/all/salt.netapi.rest_cherrypy.html how to configure and https://docs.saltstack.com/en/latest/ref/cli/salt-api.html how to start up the salt-api process.
Suppose we have the following configuration:
/etc/salt/master
rest_cherrypy:
port: 8080
ssl_crt: /etc/pki/tls/certs/localhost.crt
ssl_key: /etc/pki/tls/certs/localhost.key
Hint
Consider looking at the Salt REST API example for a more complete example on configuring the Salt API, however the official Salt documentation should always be used as the reference.
After starting the salt-api process, we should get the following:
$ curl -i localhost:8080
HTTP/1.1 200 OK
Content-Type: application/json
Server: CherryPy/18.1.1
Date: Wed, 05 Jun 2019 07:58:32 GMT
Allow: GET, HEAD, POST
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: GET, POST
Access-Control-Allow-Credentials: true
Vary: Accept-Encoding
Content-Length: 146
{"return": "Welcome", "clients": ["local", "local_async", "local_batch", "local_subset", "runner", "runner_async", "ssh", "wheel", "wheel_async"]}
That means the Salt API is ready to receive requests.
To invoke a command on a (network) device managed through Salt, you can use the
proxy
Runner to invoke commands on, e.g.,
$ curl -sS localhost:8080/run -H 'Accept: application/x-yaml' \
-d eauth='pam' \
-d username='mircea' \
-d password='pass' \
-d client='runner' \
-d fun='proxy.execute' \
-d tgt='minion1' \
-d function='test.ping' \
-d sync=True
return:
- minion1: true
Note that the execution is at the /run
endpoint, with the following
details:
username
,password
,eauth
as configured in theexternal_auth
. See https://docs.saltstack.com/en/latest/topics/eauth/index.html for more details and how to configure external authentication.client
is runner, as we’re going to use theproxy
Runner.fun
is the name of the Runner function, in this case_runners.proxy.execute()
.tgt
is the Minion ID / device name to target.function
is the Salt function to execute on the targeted device(s).sync
is set asTrue
as the execution must be synchronous because we’re waiting for the output to be returned back over the API. Otherwise, if we only need to invoke the function without expecting an output, we don’t need to pass this argument.
This HTTP request is the equivalent of CLI from the example salt-sproxy 101:
$ salt-sproxy minion1 test.ping
It works in the same way when execution function on actual devices, for
instance when gathering the ARP table from a Juniper router (the equivalent
of the salt-sproxy juniper-router net.arp
CLI from the example
salt-sproxy with network devices):
$ curl -sS localhost:8080/run -H 'Accept: application/x-yaml' \
-d eauth='pam' \
-d username='mircea' \
-d password='pass' \
-d client='runner' \
-d fun='proxy.execute' \
-d tgt='juniper-router' \
-d function='net.arp' \
-d sync=True
return:
- juniper-router:
comment: ''
out:
- age: 891.0
interface: fxp0.0
ip: 10.96.0.1
mac: 92:99:00:0A:00:00
- age: 1001.0
interface: fxp0.0
ip: 10.96.0.13
mac: 92:99:00:0A:00:00
- age: 902.0
interface: em1.0
ip: 128.0.0.16
mac: 02:42:AC:12:00:02
result: true
Or when updating the configuration:
$ curl -sS localhost:8080/run -H 'Accept: application/x-yaml' \
-d eauth='pam' \
-d username='mircea' \
-d password='pass' \
-d client='runner' \
-d fun='proxy.execute' \
-d tgt='juniper-router' \
-d function='net.load_config' \
-d text='set system ntp server 10.10.10.1' \
-d test=True \
-d sync=True
return:
- juniper-router:
already_configured: false
comment: Configuration discarded.
diff: '[edit system]
+ ntp {
+ server 10.10.10.1;
+ }'
loaded_config: ''
result: true
$ curl -sS localhost:8080/run -H 'Accept: application/x-yaml' \
-d eauth='pam' \
-d username='mircea' \
-d password='pass' \
-d client='runner' \
-d fun='proxy.execute' \
-d tgt='juniper-router' \
-d function='net.load_config' \
-d text='set system ntp server 10.10.10.1' \
-d sync=True
return:
- juniper-router:
already_configured: false
comment: ''
diff: '[edit system]
+ ntp {
+ server 10.10.10.1;
+ }'
loaded_config: ''
result: true
You can follow the same methodology with any other Salt function (including States) that you might want to execute against a device, without having a (Proxy) Minion running.