使用salt-api来搭建salt自动化平台
一、介绍
通常使用saltstack都是在master的服务器上直接命令操作,这个对于运维人员来说不是什么大事,但是也会有出错的时候,而一旦出错,就会有不可挽回的后果。
二、框架
这里使用django框架,通过对salt-api的封装,传入命令,执行api,将结果返回到页面上显示。注意:为了防止误操作,我们对传入的命令进行了检查,所有被定义的危险命令将不会被执行。(我这里为了简单,所以定义了可以被执行的命令。),前端使用了jquery+ajax的方式来不刷新页面就将结果显示在页面上的方式。
三、salt-api的安装
网上教程很多,我这里就不再废话了。
四、django代码
1)、整体结构
2)、salt_api.py(这里参照了github上dzhops的代码)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
# -*- coding: utf-8 -*-
import urllib2, urllib, json
import requests
import json
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
class SaltAPI( object ):
def __init__( self , url, username, password):
self .__url = url.rstrip( '/' )
self .__user = username
self .__password = password
self .__token_id = self .saltLogin()
def saltLogin( self ):
params = { 'eauth' : 'pam' , 'username' : self .__user, 'password' : self .__password}
encode = urllib.urlencode(params)
obj = urllib.unquote(encode)
headers = { 'X-Auth-Token' : ''}
url = self .__url + '/login'
req = urllib2.Request(url, obj, headers)
opener = urllib2.urlopen(req)
content = json.loads(opener.read())
try :
token = content[ 'return' ][ 0 ][ 'token' ]
return 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 masterToMinionContent( self , tgt, fun, arg):
'''
Master控制Minion,返回的结果是内容,不是jid;
目标参数tgt是一个如下格式的字符串:'*' 或 'zhaogb-201'
'''
if tgt = = '*' :
params = { 'client' : 'local' , 'tgt' : tgt, 'fun' : fun, 'arg' : arg}
else :
params = { 'client' : 'local' , 'tgt' : tgt, 'fun' : fun, 'arg' : arg, 'expr_form' : 'list' }
obj = urllib.urlencode(params)
content = self .postRequest(obj)
result = content[ 'return' ][ 0 ]
return result
def allMinionKeys( self ):
'''
返回所有Minion keys;
分别为 已接受、待接受、已拒绝;
:return: [u'local', u'minions_rejected', u'minions_denied', u'minions_pre', u'minions']
'''
params = { 'client' : 'wheel' , 'fun' : 'key.list_all' }
obj = urllib.urlencode(params)
content = self .postRequest(obj)
minions = content[ 'return' ][ 0 ][ 'data' ][ 'return' ][ 'minions' ]
minions_pre = content[ 'return' ][ 0 ][ 'data' ][ 'return' ][ 'minions_pre' ]
minions_rej = content[ 'return' ][ 0 ][ 'data' ][ 'return' ][ 'minions_rejected' ]
# return minions, minions_pre, minions_rej
return minions
def actionKyes( self , keystrings, action):
'''
对Minion keys 进行指定处理;
:param keystrings: 将要处理的minion id字符串;
:param action: 将要进行的处理,如接受、拒绝、删除;
:return:
{"return": [{"tag": "salt/wheel/20160322171740805129", "data": {"jid": "20160322171740805129", "return": {}, "success": true, "_stamp": "2016-03-22T09:17:40.899757", "tag": "salt/wheel/20160322171740805129", "user": "zhaogb", "fun": "wheel.key.delete"}}]}
'''
func = 'key.' + action
params = { 'client' : 'wheel' , 'fun' : func, 'match' : keystrings}
obj = urllib.urlencode(params)
content = self .postRequest(obj)
ret = content[ 'return' ][ 0 ][ 'data' ][ 'success' ]
return ret
def acceptKeys( self , keystrings):
'''
接受Minion发过来的key;
:return:
'''
params = { 'client' : 'wheel' , 'fun' : 'key.accept' , 'match' : keystrings}
obj = urllib.urlencode(params)
content = self .postRequest(obj)
ret = content[ 'return' ][ 0 ][ 'data' ][ 'success' ]
return ret
def deleteKeys( self , keystrings):
'''
删除Minion keys;
:param node_name:
:return:
'''
params = { 'client' : 'wheel' , 'fun' : 'key.delete' , 'match' : keystrings}
obj = urllib.urlencode(params)
content = self .postRequest(obj)
ret = content[ 'return' ][ 0 ][ 'data' ][ 'success' ]
return ret
|
3)、views.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.shortcuts import render
from django.shortcuts import HttpResponse,HttpResponseRedirect,render_to_response
from models import *
from saltapi import salt_api
from django.http import JsonResponse
import json
def index(request):
accect = []
context = accect_cmd.objects.values()
for i in context:
accect.append(i[ "command" ])
if request.method = = "POST" :
key = request.POST.get( 'key' )
cmd = request.POST.get( 'cmd' )
if cmd.split( )[ 0 ] in accect:
spi = salt_api.SaltAPI( 'https://ip:8000' , 'username' , 'password' )
result2 = spi.masterToMinionContent(key, 'cmd.run' , cmd)
return JsonResponse(result2, safe = False )
else :
data = {key: "请检查命令是否正确或命令超权限,请联系管理员!" }
return JsonResponse(data, safe = False )
else :
return render_to_response( 'index.html' )
|
4)、models.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
# Create your models here.
class accect_cmd(models.Model):
command = models.CharField(max_length = 50 , unique = True , verbose_name = u '命令' )
status = models.CharField(max_length = 20 , verbose_name = u '状态' )
def __unicode__( self ):
return u '{0} {1}' . format ( self .command, self .status)
class SaltReturns(models.Model):
fun = models.CharField(max_length = 50 )
jid = models.CharField(max_length = 255 )
return_field = models.TextField(db_column = 'return' )
success = models.CharField(max_length = 10 )
full_ret = models.TextField()
alter_time = models.DateTimeField()
class Meta:
managed = False
db_table = 'salt_returns'
def __unicode__( self ):
return u '%s %s %s' % ( self .jid, self . id , self .return_field)
class record(models.Model):
time = models.DateTimeField(u '时间' , auto_now_add = True )
comment = models.CharField(max_length = 128 , blank = True , default = '', null = True , verbose_name = u "记录" )
def __unicode__( self ):
return u '%s %s' % ( self .time, self .comment)
|
5)、index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
<!DOCTYPE html>
< html lang = "en" >
< head >
< meta charset = "UTF-8" >
< title >salt平台</ title >
< script src = "/static/jquery-2.1.1.min.js" ></ script >
</ head >
< body >
< form action = "/salt/index/" method = "POST" id = "form" >
< div >主机:< input type = "text" name = "key" value = "" id = "a" style = "width: 200px" ></ div >
< div >命令:< input type = "text" name = "cmd" value = "" id = "b" style = "width: 200px" ></ div >
< div >< button type = "button" id = "fb" >执行</ button ></ div >
< div style = "height: 300px;margin-top: 15px;" >
< textarea type = "text" style = "width: 60%;height: 300px" disabled = "disabled" class = "left" name = "comment" id = "c" ></ textarea >
</ div >
</ form >
</ body >
< script >
$("#fb").click(function () {
$.post("/salt/index/",{
key:$("#a").val(),
cmd: $("#b").val(),
},
function (response,status,xhr) {
$("#c").html('')
$.each(response,function (key,val) {
var c = "\r\n"+key+ ":\r\n" + val;
$("#c").append(c);
})
}
)
})
</ script >
</ html >
|
五、效果
1)、单个key执行
2)、多个key执行
3)、当命令不被许可时:
六、总结
写的比较简陋,而且现在这个版本并不支持类似于192.168.1.1+,192.168.1.*这种正则匹配,后续会继续增加。
本文转自 sykmiao 51CTO博客,原文链接:http://blog.51cto.com/syklinux/1981943,如需转载请自行联系原作者
使用salt-api来搭建salt自动化平台相关推荐
- 利用Node-js搭建前端自动化平台
我们在前面< Node.js的本质 >一文中初步了解Node.js后,发现它功能很多呀,这么牛逼的东西赶紧学习.然而我一直翻看网上各种的教程,文档,都是什么学习node内核呀,API呀,n ...
- 使用 Railway 和 Supabase 零成本搭建 n8n 自动化平台
在前文使用自动化工作流聚合信息摄入和输出中,我介绍了如何在 NAS 提供的 Docker 环境安装 n8n,以及 n8n workflow 的使用方式.经过 3 个月的使用,我有了一些新的体会和尝试, ...
- 第八届中国R语言会议(上海会场)精彩演讲视频 《借助API快速搭建自然语言处理平台》
雪晴数据网 [演讲摘要] 如今,很多实验室和机构开放了自然语言处理方面的API.用户借助这些API,可以快速开发NLP方面的产品.NLPApiTools包将整合这些平台的计算资源,提供R语言的借口和扩 ...
- 构建MySQL自动化平台思路
本人在日常工作中,用Python写了一个DB平台. 下面简单地嗦一嗦目前的主要思路和未来展望吧~ 目前主要功能支持: 下一个迭代版本: 高可用模块:打算使用(??和MGR),作者不想用MHA,无理由. ...
- 网课搜题API接口搭建教程
网课搜题API接口搭建教程 本平台优点: 多题库查题.独立后台.响应速度快.全网平台可查.功能最全! 1.想要给自己的公众号获得查题接口,只需要两步! 2.题库: 查题校园题库:查题校园题库后台(点击 ...
- 搭建or部署接口自动化平台从零到一的过程
接口自动化部署or搭建目录 前言 搭建 前端环境 后端环境 部署 部署环境 前端部署 后端部署 第一种方式后端部署 第二种方式后端部署 前言 首先感谢cheeath大佬的支持和帮助,自动化平台成功在服 ...
- 编写shell脚本实现自动化搭建安装LNMP平台全过程配置详解
注意:如果是输入的是字母的或者是输入等于0时,则会出现以下两种情况!!! 查看端口: 进到Nginx根目录查看创建好的测试网页: 注意:关闭防火墙或者设置防火墙规则!!! 访问Nginx网页: 访问P ...
- 手把手教你搭建数据库服务器平台 | DBA VS 自动化运维,究竟谁与争锋?
现代化的程度越高,对数据库的依赖性越大.数据安全性和系统的安全性也就越大,比如公司业务系统.数据库是直接的存储地方,宕机带来的损失可能是按分钟或者秒算的.而谁对这些数据库负责--DBA.所以很多公司, ...
- uni-app实战之社区交友APP(11)API环境搭建和登录API开发
文章目录 前言 一.后端API环境搭建 1.后端线上环境部署 2.Postman安装使用 3.PyCharm和数据库管理 4.创建项目 5.数据库创建和配置 二.API开发准备 1.数据表设计 2.封 ...
- python测试开发自学教程-自动化平台测试开发:Python测试开发实战_PDF电子书
因资源下载地址容易失效,请加微信号359049049直接领取,直接发最新下载地址. 前言 ======================================================= ...
最新文章
- 【跃迁之路】【552天】程序员高效学习方法论探索系列(实验阶段309-2018.08.11)...
- python判断括号有效,在Python中检查括号是否平衡
- 求封闭曲线面积vc代码_圆锥曲线综合5个类型,逐一突破
- python中RabbitMQ的使用(路由键模糊匹配)
- EntityFramework Core自动返回SQL语句
- firefox 和 ie 事件处理的细节,研究,再研究-----书写同时兼容ie和ff的事件处理代码...
- yii2 html编辑器,浅析Yii2集成富文本编辑器redactor实例教程
- 程序中使用log4J打印信息的两种方式
- List的ToLookup 分组方法
- 升级到Firefox 3.0后解决扩展版本不兼容的方法
- 将编译器的代码快速转存为图片
- import sys
- java——获取网页源代码
- <!DOCTYPE>解读
- MOSFET开关管的结构以及在MATLAB中的连接
- KS检验、qq图、Scalability可扩展性
- PHP程序员需要注意的代码规范PSR有哪些?
- Joy Catalog
- OpenGL ES之三——绘制纯色背景
- 平面设计师都在用的素材网站(素材灵感一步到位)