一、介紹
創(chuàng)新互聯(lián)建站提供高防服務(wù)器、云服務(wù)器、香港服務(wù)器、服務(wù)器托管等
通常使用saltstack都是在master的服務(wù)器上直接命令操作,這個對于運維人員來說不是什么大事,但是也會有出錯的時候,而一旦出錯,就會有不可挽回的后果。
二、框架
這里使用django框架,通過對salt-api的封裝,傳入命令,執(zhí)行api,將結(jié)果返回到頁面上顯示。注意:為了防止誤操作,我們對傳入的命令進行了檢查,所有被定義的危險命令將不會被執(zhí)行。(我這里為了簡單,所以定義了可以被執(zhí)行的命令。),前端使用了jquery+ajax的方式來不刷新頁面就將結(jié)果顯示在頁面上的方式。
三、salt-api的安裝
網(wǎng)上教程很多,我這里就不再廢話了。
四、django代碼
1)、整體結(jié)構(gòu)
2)、salt_api.py(這里參照了github上dzhops的代碼)
# -*- 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,返回的結(jié)果是內(nèi)容,不是jid; 目標(biāo)參數(shù)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發(fā)過來的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_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:"請檢查命令是否正確或命令超權(quán)限,請聯(lián)系管理員!"} return JsonResponse(data, safe=False) else: return render_to_response('index.html')
4)、models.py
# -*- 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'狀態(tài)') 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
<!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" ></div> <div>命令:<input type="text" name="cmd" value="" id="b" ></div> <div><button type="button" id="fb">執(zhí)行</button></div> <div > <textarea type="text" 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執(zhí)行
2)、多個key執(zhí)行
3)、當(dāng)命令不被許可時:
六、總結(jié)
寫的比較簡陋,而且現(xiàn)在這個版本并不支持類似于192.168.1.1+,192.168.1.*這種正則匹配,后續(xù)會繼續(xù)增加。
當(dāng)前名稱:使用salt-api來搭建salt自動化平臺
本文網(wǎng)址:http://aaarwkj.com/article38/igcgpp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供Google、手機網(wǎng)站建設(shè)、云服務(wù)器、網(wǎng)站制作、移動網(wǎng)站建設(shè)、建站公司
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)