Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Using salt-api to build salt Automation platform

2025-04-02 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/03 Report--

I. introduction

Usually, using saltstack is a direct command operation on master's server, which is not a big deal for operators, but there are also times when mistakes occur, and once errors occur, there will be irreparable consequences.

II. Framework

Here we use the django framework to encapsulate salt-api, pass in commands, execute api, and return the results to the page for display. Note: to prevent misoperation, we have checked the incoming commands and all defined dangerous commands will not be executed. (I define commands that can be executed here for simplicity. The front end uses the jquery+ajax way to display the results on the page without refreshing the page.

III. Installation of salt-api

There are many online tutorials, so I won't talk any more nonsense here.

4. Django code

1), overall structure

2), salt_api.py (here we refer to the code of dzhops on github)

#-*-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 = {' XMaiAuthTokencodes:''} 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 = {'XMaiAuthTokencodes: 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 controls Minion The returned result is content, not jid The target parameter tgt is a string of the following format:'*'or '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):' 'returns all Minion keys Accepted, to be accepted, and rejected : return: [upright localizations, upright minions rejected wheel', upright minions prevalent, upright 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):''specify the processing of Minion keys : param keystrings: the minion id string to be processed;: param action: the processing to be performed, such as accept, reject, delete : 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): accept the key sent by Minion : 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):' 'delete 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: "Please check whether the command is correct or the command is overprivileged Please contact the administrator! " } 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' command') status = models.CharField (max_length=20, verbose_name=u' status') 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 uplink% s% s% s'% (self.jid) Self.id, self.return_field) class record (models.Model): time = models.DateTimeField (u 'time', auto_now_add=True) comment = models.CharField (max_length=128, blank=True, default='', null=True, verbose_name=u "record") def _ _ unicode__ (self): return upright% s% s'% (self.time, self.comment)

5), index.html

Salt host: command: execute $("# 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);})})

5. Effect

1), single key execution

2), multiple key execution

3) when the order is not allowed:

VI. Summary

It is poorly written, and the current version does not support regular matching like 192.168.1.1, 192.168.1.*, which will continue to increase later.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report