https://docs.saltstack.com/en/latest/ref/netapi/all/salt.netapi.rest_cherrypy.html#rest-cherrypy

安装:

以下步骤都是在 Salt Master daemon上执行。

yum install pyOpenSSL -y
yum install salt-api -y
salt-call tls.create_self_signed_cert
#安装SSL,API,生成cert证书

  

[root@webmaster master.d]# cat /etc/salt/master.d/api.conf
rest_cherrypy:
port: 8080
ssl_crt: /etc/pki/tls/certs/localhost.crt
ssl_key: /etc/pki/tls/certs/localhost.key
external_auth:
pam:
saltapi:
- .*
- '@wheel'
- '@runner'
#配置api接口

 

useradd -M -s /sbin/nologin saltapi
echo 'saltapi_password'|passwd saltapi --stdin
systemctl start salt-api
#创建账户,启动api

  

systemctl restart salt-master
#重启salt

  

认证:

认证就是每个请求传递一个session token。token由login URl产生。

使用自定义请求头传递token,名为:X-Auth-Token

[root@webmaster master.d]# curl -k https://192.168.10.10:8080/login  -H "Accept: application/x-yaml" -d username='saltapi' -d password='saltapi_password' -d eauth='pam'
return:
- eauth: pam
expire: 1544643349.771802
perms:
- .*
- '@wheel'
- '@runner'
start: 1544600149.771802
token: 431584acdd199e5d1013f853a6066a896b177ed7
user: saltapi
#连接测试
#生成token

  

调用API

逻辑是,先使用用户名和密码拿到一个token,然后拿这个token去调用api

curl -k https://192.168.10.10:8080  -H "Accept: application/x-yaml" -H "X-Auth-Token: f6e4e2313a9ab06153fc5c4e065cb9e9e94a86b9" -d client='local' -d tgt='192.168.10.10' -d fun='cmd.run'  -d arg='netstat -lntp| wc -l'

  

saltapi.py

#python3x
import urllib,json
import urllib.request
import urllib.parse
import ssl ssl._create_default_https_context = ssl._create_unverified_context 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):
"""
用户登陆和获取token
:return:
"""
params = {'eauth': 'pam', 'username': self.__user, 'password': self.__password}
encode = urllib.parse.urlencode(params)
obj = urllib.parse.unquote(encode).encode('utf-8')
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 = urllib.request.Request(url, obj, headers)
opener = urllib.request.urlopen(req)
content = json.loads(opener.read().decode('utf-8'))
return content def list_all_key(self):
"""
获取包括认证、未认证salt主机
""" params = {'client': 'wheel', 'fun': 'key.list_all'}
obj = urllib.parse.urlencode(params).encode('utf-8')
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):
'''
拒绝salt主机
''' params = {'client': 'wheel', 'fun': 'key.delete', 'match': node_name}
obj = urllib.parse.urlencode(params).encode('utf-8')
self.token_id()
content = self.postRequest(obj)
ret = content['return'][0]['data']['success']
return ret def accept_key(self,node_name):
'''
接受salt主机
''' params = {'client': 'wheel', 'fun': 'key.accept', 'match': node_name}
obj = urllib.parse.urlencode(params).encode('utf-8')
self.token_id()
content = self.postRequest(obj)
ret = content['return'][0]['data']['success']
return ret def salt_get_jid_ret(self,jid):
"""
通过jid获取执行结果
:param jid: jobid
:return: 结果
"""
params = {'client':'runner', 'fun':'jobs.lookup_jid', 'jid': jid}
obj = urllib.parse.urlencode(params).encode('utf-8')
self.token_id()
content = self.postRequest(obj)
ret = content['return'][0]
return ret def salt_running_jobs(self):
"""
获取运行中的任务
:return: 任务结果
"""
params = {'client':'runner', 'fun': 'jobs.active'}
obj = urllib.parse.urlencode(params).encode('utf-8')
self.token_id()
content = self.postRequest(obj)
ret = content['return'][0]
return ret def remote_noarg_execution_sigle(self, tgt, fun):
"""
单台minin执行命令没有参数
:param tgt: 目标主机
:param fun: 执行模块
:return: 执行结果
"""
params = {'client': 'local', 'tgt': tgt, 'fun': fun}
obj = urllib.parse.urlencode(params).encode('utf-8')
self.token_id()
content = self.postRequest(obj)
# print(content)
# {'return': [{'salt-master': True}]}
ret = content['return'][0]
return ret def remote_execution_single(self, tgt, fun, arg):
"""
单台minion远程执行,有参数
:param tgt: minion
:param fun: 模块
:param arg: 参数
:return: 执行结果
"""
params = {'client': 'local', 'tgt': tgt, 'fun': fun, 'arg': arg}
obj = urllib.parse.urlencode(params).encode('utf-8')
self.token_id()
content = self.postRequest(obj)
# print(content)
# {'return': [{'salt-master': 'root'}]}
ret = content['return']
return ret def remote_async_execution_module(self, tgt, fun, arg):
"""
远程异步执行模块,有参数
:param tgt: minion list
:param fun: 模块
:param arg: 参数
:return: jobid
"""
params = {'client': 'local_async', 'tgt': tgt, 'fun': fun, 'arg': arg, 'expr_form': 'list'}
obj = urllib.parse.urlencode(params).encode('utf-8')
self.token_id()
content = self.postRequest(obj)
# print(content)
# {'return': [{'jid': '20180131173846594347', 'minions': ['salt-master', 'salt-minion']}]}
jid = content['return'][0]['jid']
return jid def remote_execution(self, tgt, fun, arg):
"""
远程执行模块,有参数
:param tgt: minion list
:param fun: 模块
:param arg: 参数
:return: dict, {'minion1': 'ret', 'minion2': 'ret'}
"""
params = {'client': 'local', 'tgt': tgt, 'fun': fun, 'arg': arg, 'expr_form': 'list'}
obj = urllib.parse.urlencode(params).encode('utf-8')
self.token_id()
content = self.postRequest(obj)
# print(content)
# {'return': [{'salt-master': 'root', 'salt-minion': 'root'}]}
ret = content['return'][0]
return ret def salt_state(self, tgt, arg, expr_form):
'''
sls文件
'''
params = {'client': 'local', 'tgt': tgt, 'fun': 'state.sls', 'arg': arg, 'expr_form': expr_form}
obj = urllib.parse.urlencode(params).encode('utf-8')
self.token_id()
content = self.postRequest(obj)
ret = content['return'][0]
return ret def salt_alive(self, tgt):
'''
salt主机存活检测
'''
params = {'client': 'local', 'tgt': tgt, 'fun': 'test.ping'}
obj = urllib.parse.urlencode(params).encode('utf-8')
self.token_id()
content = self.postRequest(obj)
ret = content['return'][0]
return ret def main(): sapi = SaltAPI(url='ip:port',username='username',password='password')
# name = sapi.remote_execution('*','cmd.run','df')
#
# print(name) if __name__ == '__main__':
main()

  

最新文章

  1. 课堂Java小程序(加减乘除与验证码)
  2. 100114B
  3. sublime text 3之快捷键操作
  4. ExpandableListView 里面嵌套GridView实现高度自适应
  5. NOI 题库 1792
  6. Node.js ejs中文手册
  7. pkill killall kill pidof
  8. jquery append 动态添加的元素事件on 不起作用的解决方案
  9. MysqL_SELECT FOR UPDATE详解
  10. Vue中引入bootstrap导致的CSS问题
  11. Page4:线性系统的运动求解以及脉冲响应矩阵与传递函数的关系[Linear System Theory]
  12. Zabbix3.4.7监控windows进程
  13. 经典矩阵快速幂之二-----hdu2157(走k步到
  14. python图像处理:pytesseract和PIL
  15. Linux下安装Phantomjs
  16. inline函数的作用
  17. BZOJ.4516.[SCOI2016]幸运数字(线性基 点分治)
  18. 由ConcurrentLinkedQueue扯到线程安全 待整理
  19. dbtool一bug跟踪记
  20. 摘:常用函数(包括:宽字符函数、普通C函数 )

热门文章

  1. linux LVM:物理卷逻辑卷
  2. Android系统编译错误Note: Some input files use or override a deprecated API. 解决办法【转】
  3. 人生苦短之Python函数的健壮性
  4. 步入C编程的第一天
  5. AttributeError: module 'tensorflow' has no attribute 'sub'
  6. 纯js实现省市级联效果
  7. Java网络编程Socket通信
  8. BZOJ_4010_[HNOI2015]菜肴制作_拓扑排序+贪心
  9. tinymix
  10. centos7使用ceph-deploy部署ceph