使用salt-api来搭建salt自动化平台
发表于:2024-12-12 作者:千家信息网编辑
千家信息网最后更新 2024年12月12日,一、介绍通常使用saltstack都是在master的服务器上直接命令操作,这个对于运维人员来说不是什么大事,但是也会有出错的时候,而一旦出错,就会有不可挽回的后果。二、框架这里使用django框架,
千家信息网最后更新 2024年12月12日使用salt-api来搭建salt自动化平台
一、介绍
通常使用saltstack都是在master的服务器上直接命令操作,这个对于运维人员来说不是什么大事,但是也会有出错的时候,而一旦出错,就会有不可挽回的后果。
二、框架
这里使用django框架,通过对salt-api的封装,传入命令,执行api,将结果返回到页面上显示。注意:为了防止误操作,我们对传入的命令进行了检查,所有被定义的危险命令将不会被执行。(我这里为了简单,所以定义了可以被执行的命令。),前端使用了jquery+ajax的方式来不刷新页面就将结果显示在页面上的方式。
三、salt-api的安装
网上教程很多,我这里就不再废话了。
四、django代码
1)、整体结构
2)、salt_api.py(这里参照了github上dzhops的代码)
# -*- coding: utf-8 -*-import urllib2, urllib, jsonimport requestsimport jsonimport sslssl._create_default_https_context = ssl._create_unverified_contextclass 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
# -*- coding: utf-8 -*-from __future__ import unicode_literalsfrom django.shortcuts import renderfrom django.shortcuts import HttpResponse,HttpResponseRedirect,render_to_responsefrom models import *from saltapi import salt_apifrom django.http import JsonResponseimport jsondef 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
# -*- coding: utf-8 -*-from __future__ import unicode_literalsfrom 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
salt平台
五、效果
1)、单个key执行
2)、多个key执行
3)、当命令不被许可时:
六、总结
写的比较简陋,而且现在这个版本并不支持类似于192.168.1.1+,192.168.1.*这种正则匹配,后续会继续增加。
命令
结果
页面
utf-8
处理
代码
字符
字符串
方式
框架
检查
平台
简陋
危险
主机
人员
内容
前端
单个
参数
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
网络安全hw报告
数据库检索的实例
网络安全数字产业
杨紫 网络安全
打开远程桌面连接远程服务器
项目管理在软件开发中的地位
网络安全广播稿小学生
行式数据库 列式数据库
软件开发中怎么插入表格
涉密网络安全教育心得体会
网络技术端口是什么意思
爱琳诗篇苹果服务器开服时间
网络安全的手抄报电子版
qq网络技术赚钱
网络安全法律条规
编译wincc服务数据库
中免日上互联网科技公司
舟山嵌入式软件开发流程八个步骤
怎么看邮箱服务器地址
软件开发中挡板是啥
服务器对连
香港服务器怎么申请微信功能
我家云停止超级硬盘后数据库
上海大修管理软件开发公司
湖州长兴软件开发
数据中心服务器密码设置规则
有线电视网络安全制度
帝国cms数据库配置不一样
微博注销后数据库还在吗
怎么实现前端和数据库互动