利用api接口来实现SaltStack推送,管理集群是非常方便的手段,下面我们尝试利用API来实现Salt的功能
如果server2和server3没有开启salt-minion服务,请先开启
1.在server1安装salt-api服务
[root@server1 _modules]# yum install -y salt-api
2.配置签名证书
[root@server1 private]# pwd
/etc/pki/tls/private
[root@server1 private]# openssl genrsa 1024
Generating RSA private key, 1024 bit long modulus
...............++++++
.......++++++
e is 65537 (0x10001)
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQCzrpte2JFC/GPysF+V2muRiwV/8skS1IlqK78Q4Q80AB5VmLLc
M+zOH9plombmE29+VcS3NBGEufM3jntw/5GvNZ/3c1k71N1wq6rxJCFmA6nB7p8M
yHCoYt7C4zVSS8+FegOZyREIVoo8XbO9BYsmktdn7YJO9hwVf/tO/MGlcQIDAQAB
AoGAeTzLYQfHm+comUwgcsBZ7G5dW6O5wJbf0V+LIBx7YZ7i2OabaLEwizQ67HDT
9VIP3LKKdQMQ/vlo/oeJCwmmheyi89m3BcuCnpCqjAURhqy9/7EnvPzhHM9zoHjY
ghOVCX2WBb9+76Sf06jwJkGIVmD+P9xVSsgL0u0/znmO7zECQQDce/ro87nbi5Kb
td/rh3s05fojIANvf3U1ComWH6bxm7joTLtSDSXwq2NjAOe0Z+Q0d2yKb9KZF15t
fG199W+jAkEA0KAU68cp0uxV23orXhVYX4m/I5yYdCmfpJNE4HkQr8W6WkeIxoJN
mA3+U7cHgu7s0bdNRzUuFcu1bAEp1GaX2wJAdpnGVUrNfhhtC49g3PwqvUC8NerB
jld8f8SkT/nEvpBqfaLQ3IkwEG7Q7m+NM9Dyw3o+C5WtLiaQ58oXx7qfiwJAZYxG
Iq4C8aQP9pD04wrIxVgrLY5ftss75cO5VvoW4TgBiUggj1+FnWnSTbVddqINq9bp
SqvcDsflOvkl/zkg2QJAVsWl747oN6DEwfk9HpC2vCH3cUTG1XOm4hVsRaDlB87I
ENVAHWNc1urfHY7OFo58/HfzGW64+Cx3RSIRht85/w==
-----END RSA PRIVATE KEY-----
[root@server1 private]# openssl genrsa 1024 > localhost.key
localhost.key
[root@server1 private]# cd ..
[root@server1 tls]# cd certs
[root@server1 certs]# make testcert
3.编辑api.conf和auth.conf
[root@server1 certs]# cd /etc/salt/master.d/
[root@server1 master.d]# vim api.conf ##指定证书密钥和端口
rest_cherrypy:
port: 8000
ssl_crt: /etc/pki/tls/certs/localhost.crt
ssl_key: /etc/pki/tls/private/localhost.key
[root@server1 master.d]# vim auth.conf ##指定认证信息
external_auth:
pam:
saltapi:
- .*
- '@wheel'
- '@runner'
- '@jobs'
4.创建用户并设置密码(一会会在测试端用到)
[root@server1 master.d]# useradd saltapi
[root@server1 master.d]# passwd saltapi ##设置密码我这里设置的是redhat
5.打开salt-api,重启salt-master,并查看是否监听8000端口
[root@server1 master.d]# systemctl start salt-api
[root@server1 master.d]# systemctl restart salt-master
[root@server1 master.d]# netstat -antlp | grep 8000
在物理机上测试
1.验证服务并获得token
[root@foundation26 ~]# curl -sSk https://172.25.26.1:8000/login -H 'Accept: application/x-yaml' -d username=saltapi -d password=redhat -d eauth=pamreturn:
- eauth: pam
expire: 1560904131.582978
perms:
- .*
- '@wheel'
- '@runner'
- '@jobs'
start: 1560860931.582977
token: 6aa3c12d01267fff18ace925922c6d397d309a07
2.利用token号测试
[root@foundation26 ~]# curl -sSk https://172.25.26.1:8000 -H 'Accept: application/x-yaml' -H 'X-Auth-Token: 6aa3c12d01267fff18ace925922c6d397d309a07' -d client=local -d tgt='*' -d fun=test.ping
return:
- server2: true
server3: true
3.配置python脚本测试能否成功
[root@foundation26 ~]# vim saltapi.py
# -*- coding: utf-8 -*-
import urllib2,urllib
import time
try:
import json
except ImportError:
import simplejson as json
class SaltAPI(object):
__token_id = ''
def __init__(self,url,username,password):
self.__url = url.rstrip('/')
self.__user = username
self.__password = password
def token_id(self):
''' user login and get token id '''
params = {'eauth': 'pam', 'username': self.__user, 'password': self.__password}
encode = urllib.urlencode(params)
obj = urllib.unquote(encode)
content = self.postRequest(obj,prefix='/login')
try:
self.__token_id = content['return'][0]['token']
except KeyError:
raise KeyError
def postRequest(self,obj,prefix='/'):
url = self.__url + prefix
headers = {'X-Auth-Token' : self.__token_id}
req = urllib2.Request(url, obj, headers)
opener = urllib2.urlopen(req)
content = json.loads(opener.read())
return content
def list_all_key(self):
params = {'client': 'wheel', 'fun': 'key.list_all'}
obj = urllib.urlencode(params)
self.token_id()
content = self.postRequest(obj)
minions = content['return'][0]['data']['return']['minions']
minions_pre = content['return'][0]['data']['return']['minions_pre']
return minions,minions_pre
def delete_key(self,node_name):
params = {'client': 'wheel', 'fun': 'key.delete', 'match': node_name}
obj = urllib.urlencode(params)
self.token_id()
content = self.postRequest(obj)
ret = content['return'][0]['data']['success']
return ret
def accept_key(self,node_name):
params = {'client': 'wheel', 'fun': 'key.accept', 'match': node_name}
obj = urllib.urlencode(params)
self.token_id()
content = self.postRequest(obj)
ret = content['return'][0]['data']['success']
return ret
def remote_noarg_execution(self,tgt,fun):
''' Execute commands without parameters '''
params = {'client': 'local', 'tgt': tgt, 'fun': fun}
obj = urllib.urlencode(params)
self.token_id()
content = self.postRequest(obj)
ret = content['return'][0][tgt]
return ret
def remote_execution(self,tgt,fun,arg):
''' Command execution with parameters '''
params = {'client': 'local', 'tgt': tgt, 'fun': fun, 'arg': arg}
obj = urllib.urlencode(params)
self.token_id()
content = self.postRequest(obj)
ret = content['return'][0][tgt]
return ret
def target_remote_execution(self,tgt,fun,arg):
''' Use targeting for remote execution '''
params = {'client': 'local', 'tgt': tgt, 'fun': fun, 'arg': arg, 'expr_form': 'nodegroup'}
obj = urllib.urlencode(params)
self.token_id()
content = self.postRequest(obj)
jid = content['return'][0]['jid']
return jid
def deploy(self,tgt,arg):
''' Module deployment '''
params = {'client': 'local', 'tgt': tgt, 'fun': 'state.sls', 'arg': arg}
obj = urllib.urlencode(params)
self.token_id()
content = self.postRequest(obj)
return content
def async_deploy(self,tgt,arg):
''' Asynchronously send a command to connected minions '''
params = {'client': 'local_async', 'tgt': tgt, 'fun': 'state.sls', 'arg': arg}
obj = urllib.urlencode(params)
self.token_id()
content = self.postRequest(obj)
jid = content['return'][0]['jid']
return jid
def target_deploy(self,tgt,arg):
''' Based on the node group forms deployment '''
params = {'client': 'local_async', 'tgt': tgt, 'fun': 'state.sls', 'arg': arg, 'expr_form': 'nodegroup'}
obj = urllib.urlencode(params)
self.token_id()
content = self.postRequest(obj)
jid = content['return'][0]['jid']
return jid
def main():
sapi = SaltAPI(url="https://172.25.26.1:8000",username="saltapi",password="redhat")
##配置api接口及相关信息
#sapi.token_id()
print sapi.list_all_key() ##列出所有节点
#sapi.delete_key('test-01')
#sapi.accept_key('test-01')
#sapi.deploy('server3','nginx.service')
#print sapi.remote_noarg_execution('test-01','grains.items')
if __name__ == '__main__':
main()
成功列出
[root@foundation26 ~]# python saltapi.py ##测试成功
([u'server2', u'server3'], [])
更改python文件后再次测试
[root@foundation4 ~]# vim saltapi.py
def main():
sapi = SaltAPI(url="https://172.25.26.1:8000",username="saltapi",password="redhat")
#sapi.token_id()
#print sapi.list_all_key()
#sapi.delete_key('test-01')
#sapi.accept_key('test-01')
sapi.deploy('server3','nginx.service')
##在server3上开启nginx,这里需要我们之前在server1上配置saltstack一键化部署nginx服务的service.sls相关文件
#print sapi.remote_noarg_execution('test-01','grains.items')
2.先关闭server3的nginx(消除实验影响)
[root@server3 ~]# systemctl stop nginx
[root@server3 ~]# curl server3
curl: (7) Failed connect to server3:80; Connection refused
3.测试运行
[root@foundation26 ~]# python saltapi.py
4.在server3查看是否开启
[root@server3 ~]# curl server3
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@server3 ~]# curl server3
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>