saltstack配置salt-api

salt-api时saltstack官方提供的一个REST API格式的项目,使salt与第三方系统集成变的尤为简单,下面来介绍一下如何配置salt-api与如何使用salt-api获取想要的信息。

安装

1、在master上面安装salt-api
yum install salt-api -y
2、出与安全考虑,官方建议使用https协议,因为salt eauth 身份验证凭证将通过线路发送,因此我们需要安装pyOpenSSL
yum install pyOpenSSL -y
3、自签名证书,生产环境中我们可以购买证书

执行:salt-call --local tls.create_self_signed_cert
local:
    Created Private Key: "/etc/pki/tls/certs/localhost.key." Created Certificate: "/etc/pki/tls/certs/localhost.crt."

4、添加api配置到salt-master配置文件

cd /e	tc/salt/master.d
vim api.conf
写入:
rest_cherrypy:
  host: 172.25.66.1
  port: 8000
  ssl_crt: /etc/pki/tls/certs/localhost.crt
  ssl_key: /etc/pki/tls/certs/localhost.key 

5、创建saltpai用户,并设置密码
saltstack配置salt-api_第1张图片
6、在slat-master配置文件中添加验证,并且在include目录中创建auth.conf文件

cd /etc/salt/master.d
vim auth.conf
写入:
external_auth:
  pam:
    saltapi:
      - .*
      - '@wheel'
      - '@runner'
      - '@jobs' 

7、重启master并且启动salt-api
saltstack配置salt-api_第2张图片
8、查看salt-api端口
saltstack配置salt-api_第3张图片

使用

9、验证salt-api服务,并且获取token(salt-api重启后token会失效,需要重新获取)

curl -sSk https://172.25.66.1:8000/login \
>  -H 'Accept: application/x-yaml' \
>  -d username='saltapi' \
>  -d password='saltapi' \
>  -d eauth='pam'
return:
- eauth: pam
  expire: 1559314837.2068679
  perms:
  - .*
  - '@wheel'
  - '@runner'
  - '@jobs'
  start: 1559271637.2068679
  token: 7d9c0982294905a896d9035a9130db055b9d81a6
  user: saltapi

saltstack配置salt-api_第4张图片
10、通过slat-api执行test.ping测试master与minion的连通性

curl -sSk https://172.25.66.1:8000 \
>  -H 'Accept: application/x-yaml' \		# 以yaml格式输出
>  -H 'X-Auth-Token: 7d9c0982294905a896d9035a9130db055b9d81a6' \
>  -d client=local \
>  -d tgt='*' \			# 测试所有minion
>  -d fun=test.ping

saltstack配置salt-api_第5张图片
11、使用salt-api执行cmd.run执行minion中的命令

curl -sSk https://172.25.66.1:8000 \
>  -H 'Accept: application/x-yaml' \
>  -H 'X-Auth-Token: 7d9c0982294905a896d9035a9130db055b9d81a6' \
>  -d client=local \
>  -d tgt='*' \
>  -d fun='cmd.run' -d arg='date'

saltstack配置salt-api_第6张图片
12、通过salt-api执行状态模块(通过salt-api向minion推送脚本安装服务)
我们向server4中推送apache服务,使用我们之前写好的apache.sls脚本

curl -sSk https://172.25.66.1:8000 \
>  -H 'Accept:application/x-yaml' \
>  -H 'X-Auth-Token:ef9ad72a71071a4db893783441b98d3ab8e2b0d4' \
>  -d tgt='*' \
>  -d client=local \
>  -d fun='state.sls' \
>  -d arg='httpd.apache'

saltstack配置salt-api_第7张图片
13、以json格式输出

curl -sSk https://172.25.66.1:8000 \
>  -H 'Accept:application/json' \
>  -H 'X-Auth-Token:ef9ad72a71071a4db893783441b98d3ab8e2b0d4' \
>  -d client=local \
>  -d tgt='*' \
>  -d fun='cmd.run' \
>  -d arg='w'

saltstack配置salt-api_第8张图片
14、利用salt-api获取grains信息

curl -sSk https://172.25.66.1:8000/minions/server2 \
>  -H 'Accept:application/x-yaml' \
>  -H 'X-Auth-Token:ef9ad72a71071a4db893783441b98d3ab8e2b0d4'

saltstack配置salt-api_第9张图片
15、使用python脚本请求salt-api

# -*- 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.66.1:8000',username='saltapi',password='saltapi')
    sapi.token_id()
    print sapi.list_all_key() 	# 打印master中所有已经获得key的minion
    #sapi.delete_key('test-01')
    #sapi.accept_key('test-01')
    sapi.deploy('*','httpd.apache')	 # 调用salt-api向所有节点推送apache.sls批量安装apache
    #print sapi.remote_noarg_execution('test-01','grains.items')

if __name__ == '__main__':
    main()

16、执行python脚本
saltstack配置salt-api_第10张图片
17、我们将server1中的httpd服务卸载,然后重新执行saltapi.py,查看httpd服务是否安装
saltstack配置salt-api_第11张图片

你可能感兴趣的:(运维)