saltstack_API接口
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()
saltstack_API接口的更多相关文章
- App开发:模拟服务器数据接口 - MockApi
为了方便app开发过程中,不受服务器接口的限制,便于客户端功能的快速测试,可以在客户端实现一个模拟服务器数据接口的MockApi模块.本篇文章就尝试为使用gradle的android项目设计实现Moc ...
- 干货来袭-整套完整安全的API接口解决方案
在各种手机APP泛滥的现在,背后都有同样泛滥的API接口在支撑,其中鱼龙混杂,直接裸奔的WEB API大量存在,安全性令人堪优 在以前WEB API概念没有很普及的时候,都采用自已定义的接口和结构,对 ...
- 12306官方火车票Api接口
2017,现在已进入春运期间,真的是一票难求,深有体会.各种购票抢票软件应运而生,也有购买加速包提高抢票几率,可以理解为变相的黄牛.对于技术人员,虽然写一个抢票软件还是比较难的,但是还是简单看看123 ...
- Java基础Map接口+Collections工具类
1.Map中我们主要讲两个接口 HashMap 与 LinkedHashMap (1)其中LinkedHashMap是有序的 怎么存怎么取出来 我们讲一下Map的增删改查功能: /* * Ma ...
- Java基础Map接口+Collections
1.Map中我们主要讲两个接口 HashMap 与 LinkedHashMap (1)其中LinkedHashMap是有序的 怎么存怎么取出来 我们讲一下Map的增删改查功能: /* * Ma ...
- java基础_集合List与Set接口
List接口继承了Collection的方法 当然也有自己特有的方法向指定位置添加元素 add(索引,添加的元素); 移除指定索引的元素 remove(索引) 修改指定索引的元素 set ...
- 【WCF】自定义错误处理(IErrorHandler接口的用法)
当被调用的服务操作发生异常时,可以直接把异常的原始内容传回给客户端.在WCF中,服务器传回客户端的异常,通常会使用 FaultException,该异常由这么几个东东组成: 1.Action:在服务调 ...
- PHP以接口方式实现多重继承(完全模拟)--学习笔记
1.UML类图: 2.PHP代码: <?php /** * Created by PhpStorm. * User: andy * Date: 16-11-23 * Time: 下午7:57 ...
- 【微框架】Maven +SpringBoot 集成 阿里大鱼 短信接口详解与Demo
Maven+springboot+阿里大于短信验证服务 纠结点:Maven库没有sdk,需要解决 Maven打包找不到相关类,需要解决 ps:最近好久没有写点东西了,项目太紧,今天来一篇 一.本文简介 ...
随机推荐
- CentOS软件管理之源代码以及RPM软件包管理
在Linux系统下,对于软件包的管理有多种机制,有源代码方式.RPM软件包管理方式以及YUM软件管理方式,本篇随笔将详细讲解CentOS下源代码形式安装软件以及RPM软件包管理机制 一.源代码形式 首 ...
- 随滚动条滚动,动态修改元素class
页面某块内容当页面滚动时,固定在浏览器的一个位置 其实就是改变了便签的class,修改了css属性设置position: fixed:fixed属性可以让便签固定在浏览器某一位置(记得引用jquery ...
- MySQL丨分页查询
直奔主题 一.sql语句:select * from table limit startPageNum,everyPageNum 1)语句解析: table:你要查询的表 startPageNum:从 ...
- ubuntu16.04 跑Apollo Demo
1.安装docker(参考网址:https://docs.docker.com/install/linux/docker-ce/ubuntu/) Uninstall old versions Olde ...
- 文件的打开函数第一类--fopen()
fopen函数用来打开一个文件,其调用的一般形式为: 文件指针名=fopen(文件名,使用文件方式); 其中, “文件指针名”必须是被说明为FILE 类型的指针变量: “文件名”是被打开文件的 ...
- 洛谷P3385判负环——spfa
题目:https://www.luogu.org/problemnew/show/P3385 两种方法,dfs和bfs: 一开始写的dfs,要把dis数组初值赋成0,这样从一个连着负边的点开始搜: 在 ...
- rsync(三)算法原理和工作流程分析
在开始分析算法原理之前,简单说明下rsync的增量传输功能. 假设待传输文件为A,如果目标路径下没有文件A,则rsync会直接传输文件A,如果目标路径下已存在文件A,则发送端视情况决定是否要传输文件A ...
- MSTAR SETBOX 常用API
HASHKEY: HashKey需要替换两个文件:“Customer_info.h”与“libecos.a” 1.MApi_DigiTuner_TPSGetLock() //判断是否有信号 2._Za ...
- HDU2874(LCA应用:求两点之间距离,图不连通)
Connections between cities Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (J ...
- HDU2639(01背包第K大)
Bone Collector II Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...