saltapi脚本实例

本文已默认你已经搭建好了salt-api环境,如果未搭好,请参考安装salt api

直接上脚本

# -*- coding: utf-8 -*-
# author: itimor

import requests
import datetime

salt_info = {
    "url": "http://localhost:8080",
    "username": "salt",
    "password": "123"
}


class SaltAPI(object):
    def __init__(self, url, username, password):
        self.__url = url
        self.__username = username
        self.__password = password
        self.__header = dict()
        self.__header["Accept"] = "application/json"
        self.token_s_time = ''
        self.__token = self.get_token()

    def get_token(self, prefix='/login'):
        """
        登录获取token
        """

        data = {
            "username": self.__username,
            "password": self.__password,
            "eauth": "pam"
        }
        loginurl = self.__url + prefix
        req = requests.post(loginurl, data=data, headers=self.__header, verify=False)
        try:
            token = req.json()["return"][0]["token"]
            self.token_s_time = datetime.datetime.now()
            return token
        except KeyError:
            raise KeyError

    def salt_request(self, data, prefix='/'):
        """
        接收请求,返回结果
        """

        token_e_time = datetime.datetime.now()
        print("token_e_time: %s" % token_e_time)
        print("token_s_time: %s" % self.token_s_time)

        if (token_e_time - self.token_s_time).seconds/3600 > 3:
            print("salt-api token is Expired")
            self.get_token()

        url = self.__url + prefix
        self.__header["X-Auth-Token"] = self.__token

        # 传入data参数字典,data为None 则方法为get,有date为post方法
        if data:
            req = requests.post(url, data=data, headers=self.__header, verify=False)
        else:
            req = requests.get(url, headers=self.__header)

        return req.json()

    def list_key(self):
        """
        获取包括认证、未认证salt主机
        """

        prefix = '/keys'
        content = self.salt_request(None, prefix)

        accepted = content['return']['minions']
        denied = content['return']['minions_denied']
        unaccept = content['return']['minions_pre']
        rejected = content['return']['minions_rejected']
        return {"accepted": accepted, "denied": denied, "unaccept": unaccept, "rejected": rejected}

    def accept_key(self, key_id):
        """
        接受salt主机
        """

        data = {'client': 'wheel', 'fun': 'key.accept', 'match': key_id}
        content = self.salt_request(data)
        ret = content['return'][0]['data']['success']
        return ret

    def delete_key(self, key_id):
        """
        删除salt主机
        """

        data = {'client': 'wheel', 'fun': 'key.delete', 'match': key_id}
        content = self.salt_request(data)
        ret = content['return'][0]['data']['success']
        return ret

    def minions_status(self):
        """
        salt主机存活检测
        """

        data = {'client': 'runner', 'fun': 'manage.status'}
        content = self.salt_request(data)
        ret = content['return'][0]

        up = ret['up']
        down = ret['down']
        ups = []
        downs = []
        for host in up:
            ups.append({'hostname': host, 'status': 'up'})
        for host in down:
            downs.append({'hostname': host, 'status': 'down'})
        ret['up'] = ups
        ret['down'] = downs
        return ret

    def remote_cmd(self, tgt, fun, client='local_async', expr_form='list', arg='', **kwargs):
        """
        异步执行远程命令、部署模块
        """

        data = {'client': client, 'tgt': tgt, 'fun': 'cmd.run', 'arg': arg, 'expr_form': expr_form}
        content = self.salt_request(data)
        ret = content['return'][0]['jid']
        print(content)
        return ret

    def get_result(self, jid):
        """
        通过jid获取执行结果
        """

        data = {'client': 'runner', 'fun': 'jobs.lookup_jid', 'jid': jid}
        content = self.salt_request(data)
        ret = content['return'][0]
        return ret

    def get_job_info(self, jid=''):
        """
        获取任务的详细执行信息
        """

        if jid:
            prefix = '/jobs/' + jid
        else:
            prefix = '/jobs'

        content = self.salt_request(None, prefix)
        ret = content['return'][0]
        return ret

    def running_jobs(self):
        """
        获取运行中的任务
        """

        data = {'client': 'runner', 'fun': 'jobs.active'}
        content = self.salt_request(data)
        ret = content['return'][0]
        return ret

    def check_job(self, jid):
        """
        检查任务是否已经执行并成功退出
        """

        data = {'client': 'runner', 'fun': 'jobs.exit_success', 'jid': jid}
        content = self.salt_request(data)
        ret = content['return'][0]
        return ret

    def remote_server_info(self, tgt, args=('fqdn', 'os', 'ipv4', 'cpu_model', 'mem_total')):
        """
        获取远程主机信息
        """

        data = {'client': 'local', 'tgt': tgt, 'fun': 'grains.items'}
        content = self.salt_request(data)
        items = content['return'][0][tgt]
        ret = dict()
        for item in args:
            ret[item] = items[item]
        return ret


def main():
    sapi = SaltAPI(url=salt_info["url"], username=salt_info["username"], password=salt_info["password"])
    # cmd = 'netstat'
    tgt = 'sh-aa-01'
    # jid = sapi.remote_cmd(tgt=tgt, fun='cmd.run', arg=cmd)
    # print(jid)
    print(sapi.remote_server_info(tgt))


if __name__ == '__main__':
    main()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 143,639评论 1 302
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 61,591评论 1 258
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 95,050评论 0 213
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 41,169评论 0 180
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 48,976评论 1 258
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 38,876评论 1 178
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 30,476评论 2 273
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,229评论 0 167
  • 想象着我的养父在大火中拼命挣扎,窒息,最后皮肤化为焦炭。我心中就已经是抑制不住地欢快,这就叫做以其人之道,还治其人...
    爱写小说的胖达阅读 29,095评论 6 234
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 32,579评论 0 213
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,356评论 2 215
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 30,698评论 1 232
  • 白月光回国,霸总把我这个替身辞退。还一脸阴沉的警告我。[不要出现在思思面前, 不然我有一百种方法让你生不如死。]我...
    爱写小说的胖达阅读 24,272评论 0 32
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,168评论 2 214
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 31,605评论 3 210
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,645评论 0 9
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,035评论 0 166
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 33,609评论 2 232
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 33,698评论 2 233

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,385评论 25 707
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,003评论 18 139
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,091评论 6 345
  • 第八章 上一章 第七章 (八) 在这一天中,周围亲戚都相继知道了这件事,纷纷前来探望。按照家乡人的礼节,各自买来水...
    安戈洛阅读 193评论 0 0
  • Android 进阶到高级 - 突破篇 欢迎访问我的博客:Android 解忧杂货店 GitHub :https:...
    Android解忧杂货店阅读 3,078评论 2 40