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:最近好久没有写点东西了,项目太紧,今天来一篇 一.本文简介 ...
随机推荐
- (转)Android--UI之ImageView
前言 这篇博客聊一聊在Android下ImageView的使用,在此篇博客中,会讲解到ImageView的一些属性的使用,以及ImageView展示图片的放大.缩小.旋转等操作.最后再讲解一下Andr ...
- php mcrypt加密实例
<?php //当前mcrypt支持的加密模型 $modes_list = mcrypt_list_modes(); // Array // ( // [0] => cbc // [1] ...
- haproxy官方配置文档地址
http://cbonte.github.io/haproxy-dconv/1.6/configuration.html#4-option%20http-keep-alive
- linux系统配置之网络配置(centos)
CentOS---网络配置详解 一.配置文件详解在RHEL或者CentOS等Redhat系的Linux系统里,跟网络有关的主要设置文件如下: /etc/host.conf 配置域名服务 ...
- python 复制文件流程
例子代码: [root@master script]# vim copy_file.py #!/usr/bin/python # -*- coding:utf-8 -*- old_file_name ...
- codevs 3095 黑心的市长
3095 黑心的市长 时间限制: 1 s 空间限制: 32000 KB 题目等级 : 钻石 Diamond 题目描述 Description A市有一条长Nkm的高速公路.有M个人各自想承包 ...
- Markdown Reader 插件改造
Markdown Reader 是一款比较好用的浏览markdown文件的chrome插件 插件地址:https://chrome.google.com/webstore/detail/markdow ...
- asio socket设置 server地址与端口的两种方式
1. 用解释器的方法, 常用来解析域名, 如 // query("www.163.com","80"), 也可以 query("www.163.co ...
- jni中c代码调用java代码
原理是使用反射的机制 java中反射的例子: Class<?> forName = Class.forName("com.example.ndkcallback.DataProv ...
- 【原】Cache Buffer Chain 第四篇
作者:david_zhang@sh [转载时请以超链接形式标明文章] 链接:http://www.cnblogs.com/david-zhang-index/p/3873357.html [测试1]低 ...