ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

saltstack jid快查方案

2021-02-07 14:59:42  阅读:131  来源: 互联网

标签:jid return 快查 format self mysql saltstack salt


1 py2

1.1 采用mysql缓存

mysql -uroot -p'your mysql password'
# salt.sql详见3.1
source salt.sql

yum install python-devel mysql-devel
# 由于salt的python包内没有pip,需要弄个额外的pip来装,
带pip的python2路径/pip install MySQL-python --target=/usr/lib64/python2.7/site-packages

vim /etc/salt/master
# MySQL
mysql.host: 'localhost'
mysql.user: 'root'
mysql.pass: 'your mysql password'
mysql.db: 'salt'
mysql.port: 3306
# Master Job Cache
master_job_cache: mysql


service salt-master restart

1.2 快查脚本

# 脚本详见3.2
/usr/bin/python2.7 look_up_jid_quick_py2.py -j 20210107092826457769,20210108111130922376 [-p]
-j: 指定jid(可多个)
-p: 指定打印方式(非必传) default-默认 json-json列表格式 normal-普通打印

2 py3

2.1 采用mysql缓存

mysql -uroot -p'your mysql password'
# salt.sql详见3.1
source salt.sql

/usr/bin/pip3 install pymysql

vim /etc/salt/master
# MySQL
mysql.host: 'localhost'
mysql.user: 'root'
mysql.pass: 'your mysql password'
mysql.db: 'salt'
mysql.port: 3306
# Master Job Cache
master_job_cache: mysql


systemctl restart salt-master

2.2 快查脚本

# 脚本详见3.3
/usr/bin/python3.6 look_up_jid_quick_py3.py -j 20210107092826457769,20210108111130922376 [-p]
-j: 指定jid(可多个)
-p: 指定打印方式(非必传) default-默认 json-json列表格式 normal-普通打印

3 脚本与文件

3.1 salt.sql

CREATE DATABASE  `salt`
  DEFAULT CHARACTER SET utf8
  DEFAULT COLLATE utf8_general_ci;

USE `salt`;

--
-- Table structure for table `jids`
--

DROP TABLE IF EXISTS `jids`;
CREATE TABLE `jids` (
  `jid` varchar(255) NOT NULL,
  `load` mediumtext NOT NULL,
  UNIQUE KEY `jid` (`jid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE INDEX jid ON jids(jid) USING BTREE;

--
-- Table structure for table `salt_returns`
--

DROP TABLE IF EXISTS `salt_returns`;
CREATE TABLE `salt_returns` (
  `fun` varchar(50) NOT NULL,
  `jid` varchar(255) NOT NULL,
  `return` mediumtext NOT NULL,
  `id` varchar(255) NOT NULL,
  `success` varchar(10) NOT NULL,
  `full_ret` mediumtext NOT NULL,
  `alter_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  KEY `id` (`id`),
  KEY `jid` (`jid`),
  KEY `fun` (`fun`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Table structure for table `salt_events`
--

DROP TABLE IF EXISTS `salt_events`;
CREATE TABLE `salt_events` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`tag` varchar(255) NOT NULL,
`data` mediumtext NOT NULL,
`alter_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`master_id` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
KEY `tag` (`tag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

3.2 py2脚本

# -*- coding: utf-8 -*-
import MySQLdb
import json
import argparse
import subprocess
import time

base = "cat /etc/salt/master|grep mysql.{witch}|grep -v '#mysql.{witch}'|sed 's/mysql.{witch}: //g'|sed \"s/'//g\""
mysql_host_getter = base.format(witch="host")
mysql_user_getter = base.format(witch="user")
mysql_pwd_getter = base.format(witch="pass")
mysql_db_getter = base.format(witch="db")


# mysql_search_base = "mysql -u{user} -h {host} -p'{pwd}' -e 'select * from {db}.salt_returns where jid=\"{jid}\"\G'|grep full_ret:|sed 's/  full_ret: //g'"

class Db(object):
    """
    数据库操作类
    """

    def __init__(self, host='localhost', db='salt', port=3306, user='root', passwd='123456'):
        self.host = host
        self.port = port
        self.user = user
        self.passwd = passwd
        self.db = db
        try:
            self.conn = MySQLdb.connect(host=self.host, port=self.port, user=self.user, passwd=self.passwd, db=self.db)
            self.cursor = self.conn.cursor()
        except Exception as err:
            raise SystemError("数据库连接失败:{}".format(err))

    def execute(self, sql, error=True):
        """
        执行SQL
        :param sql: SQL语句
        :param error: False表示忽略错误,True将会触发错误
        :return:
        """
        try:
            self.cursor.execute(sql)
        except Exception as err:
            print("执行SQL: {}".format(sql))
            self.conn.rollback()
            if error:
                raise SystemError("错误信息:{}".format(err))
            print("错误信息:{}".format(err))
        else:
            self.conn.commit()

    def executemany(self, sql, param, error=True):
        """
        执行SQL
        :param sql: SQL语句
        :param param: 需要填充到SQL中的参数
        :param error: False忽略错误
        :return:
        """
        try:
            self.cursor.executemany(sql, param)
        except Exception as err:
            print("执行SQL: {}".format(sql))
            self.conn.rollback()
            if error:
                raise SystemError("错误信息:{}".format(err))
            print("错误信息:{}".format(err))
        else:
            self.conn.commit()

    def fetchall(self):
        return self.cursor.fetchall()

    def fetchone(self):
        return self.cursor.fetchone()

    def close(self):
        self.cursor.close()
        self.conn.close()

    def __del__(self):
        self.close()


def runner(cmd):
    """
    基本运行
    :param cmd: 命令
    :return: 结果,错误信息,状态码
    """
    # print(cmd)
    p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                         universal_newlines=True, shell=True)
    out, err = p.communicate()
    out = out.strip()
    return out, err, p.returncode


class SaltCache(object):
    def __init__(self):
        self.host = runner(mysql_host_getter)[0].strip()
        self.user = runner(mysql_user_getter)[0].strip()
        self.pwd = runner(mysql_pwd_getter)[0].strip()
        self.db = runner(mysql_db_getter)[0].strip()
        if self.if_use_cache():
            self.conn = Db(host=self.host, db=self.db, user=self.user, passwd=self.pwd)

    def if_use_cache(self):
        return self.host and self.user and self.pwd and self.db

    def get_jids(self, jids):
        jids = jids.strip().rstrip(',')
        jid_lis = jids.split(',')
        if len(jid_lis) == 1:
            sql = 'select full_ret from salt.salt_returns where jid = "{}"'.format(jid_lis[0])
        else:
            sql = 'select full_ret from salt.salt_returns where jid in {}'.format(str(tuple(jid_lis)))
        self.conn.execute(sql=sql)
        return self.conn.fetchall()


def get_full_return(jid):
    """
    获取完整输出
    :param jid: jid
    :return:
    """
    salt_cache = SaltCache()
    if salt_cache.if_use_cache():
        ret = salt_cache.get_jids(jid)
        return ret
    else:
        print 'salt没有配置mysql缓存'
        exit(1)


def print_for_runner(ret):
    """
    打印显示结果
    :param ret: 结果
    :return:
    """
    for r in ret:
        print_one_full_ret(r)


def print_one_full_ret(full_ret):
    """
    打印一个full_ret结果
    :param full_ret: 完整结果
    :return:
    """
    msg = ''
    # msg = 'tgt: {}\n'.format(tgt)
    for k in full_ret.keys():
        msg += '{}: {}\n'.format(k, full_ret[k])
    info = "{split}\n{msg}{split}".format(
        split="*" * 50,
        msg=msg
    )
    print info


def format_(data):
    """
    选取内容格式化输出
    :param data: 数据
    :return:
    """
    new_lis = []
    for d in data:
        d_ = json.loads(d[0])
        # print d_
        new_lis.append({
            'cmd': d_['fun_args'][0],
            'jid': d_['jid'],
            'out': d_['return'],
            'tgt': d_['id'],
            'status': d_['retcode'],
            'run_time': format_time(d_['_stamp'])
        })
    return new_lis


def format_time(t):
    time_array = time.strptime(t, "%Y-%m-%dT%H:%M:%S.%f")
    return time.strftime("%Y-%m-%d %H:%M:%S", time_array)


def print_un_result_jids(jids, result):
    """
    打印尚未查到结果的jid
    :param jids: 传入的jid
    :param result: 结果
    :return:
    """
    return_lis = []
    jid_lis = jids.split(',')
    for r in result:
        return_lis.append(r['jid'])
    un_return_lis = list(set(jid_lis) - set(return_lis))
    print '未查到结果的jid: {}'.format(','.join(un_return_lis))


def get_options():
    usage = """
    /usr/bin/python2.7 %(prog)s -j 20210107092826457769,20210108111130922376 [-p]
    -j: 指定jid
    -p: 指定打印方式(非必传) default-默认 json-json列表格式 normal-普通打印
    """
    parser = argparse.ArgumentParser(usage=usage)
    parser.add_argument('-j', '--jid', dest='jid', required=True)
    parser.add_argument('-p', '--printf', choices=['default', 'json', 'normal'], dest='printf', default='default')
    option = parser.parse_args()
    return option


def entry():
    import time
    start = time.time()
    option = get_options()
    result = get_full_return(option.jid)
    result = format_(result)

    # tgt = option.tgt
    # print option.jid
    if option.printf == 'normal':
        print_for_runner(result)
    elif option.printf == "default":
        if result:
            for r in result:
                print json.dumps(r, ensure_ascii=False)
        else:
            print {}
    else:
        print json.dumps(result, ensure_ascii=False)
    print_un_result_jids(option.jid, result)
    end = time.time()
    print '耗时:{}s'.format(round(end - start, 2))


if __name__ == '__main__':
    entry()

3.3 py3脚本

# -*- coding: utf-8 -*-
import pymysql
import json
import argparse
import subprocess
import time

base = "cat /etc/salt/master|grep mysql.{witch}|grep -v '#mysql.{witch}'|sed 's/mysql.{witch}: //g'|sed \"s/'//g\""
mysql_host_getter = base.format(witch="host")
mysql_user_getter = base.format(witch="user")
mysql_pwd_getter = base.format(witch="pass")
mysql_db_getter = base.format(witch="db")


# mysql_search_base = "mysql -u{user} -h {host} -p'{pwd}' -e 'select * from {db}.salt_returns where jid=\"{jid}\"\G'|grep full_ret:|sed 's/  full_ret: //g'"

class Db(object):
    """
    数据库操作类
    """

    def __init__(self, host='localhost', db='salt', port=3306, user='root', passwd='123456'):
        self.host = host
        self.port = port
        self.user = user
        self.passwd = passwd
        self.db = db
        try:
            self.conn = pymysql.connect(host=self.host, port=self.port, user=self.user, passwd=self.passwd, db=self.db)
            self.cursor = self.conn.cursor()
        except Exception as err:
            raise SystemError("数据库连接失败:{}".format(err))

    def execute(self, sql, error=True):
        """
        执行SQL
        :param sql: SQL语句
        :param error: False表示忽略错误,True将会触发错误
        :return:
        """
        try:
            self.cursor.execute(sql)
        except Exception as err:
            print("执行SQL: {}".format(sql))
            self.conn.rollback()
            if error:
                raise SystemError("错误信息:{}".format(err))
            print("错误信息:{}".format(err))
        else:
            self.conn.commit()

    def executemany(self, sql, param, error=True):
        """
        执行SQL
        :param sql: SQL语句
        :param param: 需要填充到SQL中的参数
        :param error: False忽略错误
        :return:
        """
        try:
            self.cursor.executemany(sql, param)
        except Exception as err:
            print("执行SQL: {}".format(sql))
            self.conn.rollback()
            if error:
                raise SystemError("错误信息:{}".format(err))
            print("错误信息:{}".format(err))
        else:
            self.conn.commit()

    def fetchall(self):
        return self.cursor.fetchall()

    def fetchone(self):
        return self.cursor.fetchone()

    def close(self):
        self.cursor.close()
        self.conn.close()

    def __del__(self):
        self.close()


def runner(cmd):
    """
    基本运行
    :param cmd: 命令
    :return: 结果,错误信息,状态码
    """
    # print(cmd)
    p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                         universal_newlines=True, shell=True)
    out, err = p.communicate()
    out = out.strip()
    return out, err, p.returncode


class SaltCache(object):
    def __init__(self):
        self.host = runner(mysql_host_getter)[0].strip()
        self.user = runner(mysql_user_getter)[0].strip()
        self.pwd = runner(mysql_pwd_getter)[0].strip()
        self.db = runner(mysql_db_getter)[0].strip()
        if self.if_use_cache():
            self.conn = Db(host=self.host, db=self.db, user=self.user, passwd=self.pwd)

    def if_use_cache(self):
        return self.host and self.user and self.pwd and self.db

    def get_jids(self, jids):
        jids = jids.strip().rstrip(',')
        jid_lis = jids.split(',')
        if len(jid_lis) == 1:
            sql = 'select full_ret from salt.salt_returns where jid = "{}"'.format(jid_lis[0])
        else:
            sql = 'select full_ret from salt.salt_returns where jid in {}'.format(str(tuple(jid_lis)))
        self.conn.execute(sql=sql)
        return self.conn.fetchall()


def get_full_return(jid):
    """
    获取完整输出
    :param jid: jid
    :return:
    """
    salt_cache = SaltCache()
    if salt_cache.if_use_cache():
        ret = salt_cache.get_jids(jid)
        return ret
    else:
        print('salt没有配置mysql缓存')
        exit(1)


def print_for_runner(ret):
    """
    打印显示结果
    :param ret: 结果
    :return:
    """
    for r in ret:
        print_one_full_ret(r)


def print_one_full_ret(full_ret):
    """
    打印一个full_ret结果
    :param full_ret: 完整结果
    :return:
    """
    msg = ''
    # msg = 'tgt: {}\n'.format(tgt)
    for k in full_ret.keys():
        msg += '{}: {}\n'.format(k, full_ret[k])
    info = "{split}\n{msg}{split}".format(
        split="*" * 50,
        msg=msg
    )
    print(info)


def format_(data):
    """
    选取内容格式化输出
    :param data: 数据
    :return:
    """
    new_lis = []
    for d in data:
        d_ = json.loads(d[0])
        # print d_
        new_lis.append({
            'cmd': d_['fun_args'][0],
            'jid': d_['jid'],
            'out': d_['return'],
            'tgt': d_['id'],
            'status': d_['retcode'],
            'run_time': format_time(d_['_stamp'])
        })
    return new_lis


def format_time(t):
    time_array = time.strptime(t, "%Y-%m-%dT%H:%M:%S.%f")
    return time.strftime("%Y-%m-%d %H:%M:%S", time_array)


def print_un_result_jids(jids, result):
    """
    打印尚未查到结果的jid
    :param jids: 传入的jid
    :param result: 结果
    :return:
    """
    return_lis = []
    jid_lis = jids.split(',')
    for r in result:
        return_lis.append(r['jid'])
    un_return_lis = list(set(jid_lis) - set(return_lis))
    print('未查到结果的jid: {}'.format(','.join(un_return_lis)))


def get_options():
    usage = """
    /usr/bin/python2.7 %(prog)s -j 20210107092826457769,20210108111130922376 [-p]
    -j: 指定jid
    -p: 指定打印方式(非必传) default-默认 json-json列表格式 normal-普通打印
    """
    parser = argparse.ArgumentParser(usage=usage)
    parser.add_argument('-j', '--jid', dest='jid', required=True)
    parser.add_argument('-p', '--printf', choices=['default', 'json', 'normal'], dest='printf', default='default')
    option = parser.parse_args()
    return option


def entry():
    import time
    start = time.time()
    option = get_options()
    result = get_full_return(option.jid)
    result = format_(result)

    # tgt = option.tgt
    # print option.jid
    if option.printf == 'normal':
        print_for_runner(result)
    elif option.printf == "default":
        for r in result:
            print(json.dumps(r, ensure_ascii=False))
    else:
        print(json.dumps(result, ensure_ascii=False))
    print_un_result_jids(option.jid, result)
    end = time.time()
    print('耗时:{}s'.format(round(end - start, 2)))


if __name__ == '__main__':
    entry()

标签:jid,return,快查,format,self,mysql,saltstack,salt
来源: https://blog.csdn.net/weixin_42871902/article/details/113740849

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有