saltstack中的api接口

利用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>

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值