Salt-API安装配置及使用
SaltStack 官方提供有REST API格式的 salt-api 项目,将使Salt与第三方系统集成变得尤为简单。本文讲带你了解如何安装配置Salt-API, 如何利用Salt-API获取想要的信息。
具体使用请参考:salt-api手册
环境说明
- 操作系统环境: CentOS 6.4/ Centos 7
- Salt Master/Minion版本: 0.17.2, Master IP地址为172.25.254.135, 用于本次测试的Minion ID为 minion.example.com
实施
安装
1 2
| yum install https://repo.saltstack.com/yum/redhat/salt-repo-latest-1.el7.noarch.rpm yum install salt-master
|
1 2 3 4 5 6
| 安装salt-api pip install salt-api # 下载服务维护脚本 wget https://raw.github.com/saltstack/salt-api/develop/pkg/rpm/salt-api -O /etc/init.d/salt-api chmod +x /etc/init.d/salt-api chkconfig salt-api on
|
配置Salt-API
生成自签名证书(用于ssl)
1 2 3 4 5 6
| cd /etc/pki/tls/certs # 生成自签名证书, 过程中需要输入key密码及RDNs make testcert cd /etc/pki/tls/private/ # 解密key文件,生成无密码的key文件, 过程中需要输入key密码,该密码为之前生成证书时设置的密码 openssl rsa -in localhost.key -out salt_nopass.key
|
Salt-API配置
1 2
| useradd -M -s /sbin/nologin salt echo "salt" | passwd salt —stdin
|
- 配置eauth, /etc/salt/master.d/eauth.conf
1 2 3 4 5 6
| external_auth: pam: salt: #此处的用户与上述创建的用户一致 - .* - '@wheel' - '@runner'
|
- 配置Salt-API, /etc/salt/master.d/api.conf
1 2 3 4
| rest_cherrypy: port: 8000 #开放端口 ssl_crt: /etc/pki/tls/certs/localhost.crt ssl_key: /etc/pki/tls/private/salt_nopass.key
|
service salt-api start
Salt-API使用
Login
1 2 3 4
| curl -k https://172.25.254.135:8000/login -H "Accept: application/x-yaml" \ -d username='salt' \ -d password='salt' \ -d eauth='pam'
|
1 2 3 4 5 6 7 8 9 10
| return: - eauth: pam expire: 1470786521.466763 perms: - .* - '@wheel' - '@runner' start: 1470743321.466762 token: f59484ca66f52173fb34742fc014f7dc5b027bdd user: salt
|
其中 token 后边的串为认证成功后获取的token串,之后可以不用再次输入密码,直接使用本Token即可
查询Minion的信息
1 2 3
| curl -k https://172.25.254.135:8000/minions/minion.example.com \ -H "Accept: application/x-yaml" \ -H "X-Auth-Token: f59484ca66f52173fb34742fc014f7dc5b027bdd"
|
其中 X-Auth-Token 后边的串为之前Login获取到的Token串, 如果请求的URL不包含 minion.example.com ,则请求的为所有Minion的信息
1 2 3 4 5 6 7 8 9 10 11 12
| return: - minion.example.com: SSDs: [] biosreleasedate: 12/10/2013 biosversion: X450LCP.205 cpu_flags: - fpu - vme - de - pse - tsc 略
|
远程执行模块
1 2 3 4 5 6
| curl -k https://172.25.254.135:8000/ \ -H "Accept: application/x-yaml" \ -H "X-Auth-Token: f59484ca66f52173fb34742fc014f7dc5b027bdd" \ -d client='local' \ -d tgt='*' \ -d fun='test.ping'
|
1 2
| return: - minion.example.com: true
|
运行runner
1 2 3 4 5
| curl -k https://172.25.254.135:8000/ \ -H "Accept: application/x-yaml" \ -H "X-Auth-Token: f59484ca66f52173fb34742fc014f7dc5b027bdd" \ -d client='runner' \ -d fun='manage.status'
|
1 2 3 4
| return: - down: [] up: - minion.example.com
|
总结
Salt API几乎涵盖了所有的salt操作,功能强劲,尤其是需要salt和第三方系统集成的场景
背后的原理
学过socket编程的同学都知道,server端接受客户端传送的数据,如果用户输入命令的话,那么调用os.popen(command,mode)等,是可以执行命令的,并且将结果返回给客户端。那么就能完成一个基于socket的远程控制系统。
本地API
saltstack是用python写成,我们可以在安装salt的主机上,通过python调用
1 2 3 4
| In [1]: import salt.client In [2]: local = salt.client.LocalClient() In [3]: local.cmd("*",'cmd.run',['whoami']) Out[3]: {'minion.example.com': 'root'}
|
1 2 3 4 5 6 7 8 9
| In [1]: import salt.client In [2]: caller = salt.client.Caller() In [3]: caller.cmd('test.ping') Out[3]: True In [4]: caller.function('test.ping') #早期版本不支持 caller.cmd Out[4]: True
|
1 2 3 4 5 6 7 8 9 10
| In [6]: import salt.config In [7]: opts =salt.config.master_config('/etc/salt/master') In [8]: runner = salt.runner.R salt.runner.Runner salt.runner.RunnerClient In [8]: runner = salt.runner.RunnerClient(opts) In [9]: runner.cmd('jobs.list_jobs',[])
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| 20160809195307041368: ---------- Arguments: Function: grains.items StartTime: 2016, Aug 09 19:53:07.041368 Target: * Target-type: glob User: salt Out[9]: {'20160809195307041368': {'Arguments': [], 'Function': 'grains.items', 'StartTime': '2016, Aug 09 19:53:07.041368', 'Target': '*', 'Target-type': 'glob', 'User': 'salt'}, '20160809195645164703': {'Arguments': [], 'Function': 'test.ping', 'StartTime': '2016, Aug 09 19:56:45.164703', 'Target': '*', 'Target-type': 'glob', 'User': 'salt'}, '20160809200031579904': {'Arguments': [], 'Function': 'test.ping', 'StartTime': '2016, Aug 09 20:00:31.579904', 'Target': '*', 'Target-type': 'glob', 'User': 'root'}, '20160809200943103937': {'Arguments': ['whoami'], 'Function': 'cmd.run', 'StartTime': '2016, Aug 09 20:09:43.103937', 'Target': '*', 'Target-type': 'glob', 'User': 'root'}}
|
实现
salt-api 是用 Tornado 封装了一个程式,通过继承tornado.web.RequestHandler,获取传递参数
然后根据参数,调用不同的salt命令,返回结果
简易实现如下
import tornado.ioloop
import tornado.web
class SaltAPI(tornado.web.RequestHandler):
def get(self):
self.write("Hello, world")
def post(self):
data = simplejson.loads(self.request.body)
获取数据
调用 salt
self.write(ruselt)
application = tornado.web.Application([
(r"/", SaltAPI),
])
if __name__ == "__main__":
application.listen(8000)
tornado.ioloop.IOLoop.instance().start()
更具体的实现,可以看salt-api源码
地址: salt-api