SaltStack自带将执行的命令及返回结果入库的功能,这里我使用的是mysql库。
环境:
RHEL AS5.8 64位
Mysql 5.5
Salt 2014.7.0
首先介绍官方的标准实现方式,在mysql中建立salt所使用的用户,然后建立salt库、保存执行命令相关信息的jids表和保存命令执行结果的salt_returns表。创建库及表的命令如下,这个salt官方给出的标准:
#########################################
本文出自Guibin的博客,http://guibin.blog.51cto.com/8909901/1606747
由Guibin原创,转载请注明出处,我会不定期对本博文进行修正。
#########################################
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; -- -- 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;
安装数据库驱动:
yum install -y python26-mysqldb
声明数据库类型、数据库相关信息,在master配置中增加如下内容,然后重启master使配置生效:
# vi /etc/salt/master
master_job_cache: mysql
#MySQL
mysql.host: '127.0.0.1'
mysql.user: 'micro'
mysql.pass: 'blog'
mysql.db: 'salt'
mysql.port: 3306
这时执行个命令测试下:
# salt 'zhaogb-201' test.ping
先查看库中执行命令的相关信息(我的mysql用户没有设置密码):
[root@localhost returners]# mysql salt -e 'select * from jids\G' *************************** 1. row *************************** jid: 20150121174905627607 load: {"tgt_type": "glob", "jid": "20150121174905627607", "cmd": "publish", "tgt": "zhaogb-201", "kwargs": {"show_timeout": false, "show_jid": false}, "ret": "", "user": "root", "arg": [], "fun": "test.ping"}
再查看命令返回的结果:
[root@localhost returners]# mysql salt -e 'select * from salt_returns\G' *************************** 1. row *************************** fun: test.ping jid: 20150121174905627607 return: true id: zhaogb-201 success: 1 full_ret: {"fun_args": [], "jid": "20150121174905627607", "return": true, "retcode": 0, "success": true, "cmd": "_return", "_stamp": "2015-01-21T17:49:09.942590", "fun": "test.ping", "id": "zhaogb-201"} alter_time: 2015-01-21 17:49:09
这是常规的使用,如果有些特殊需求,就需要进行二次开发,比如使用salt执行更新应用程序配置文件的时候,配置文件中有GB2312编码的字符,夹杂在return的字典中,与utf-8编码的字符混合,这时候入库就会失败,会报json.dumps遇到错误。
我采用的解决方案是在salt源码的基础上进行修改,修改了入库模块mysql.py的returner、save_load方法。以下代码解决两个问题:
1. 命令执行结果入库,若是执行的state.sls或state.highstate,则判断return键的值是否是gb2312编码,若是,则转为UTF8,然后再入库;
2. 执行的命令入库时,剔除超时的saltutil.find_job命令;
代码如下:
def returner(ret):
'''
Return data to a mysql server
'''
#################### 2015-01-26 #############################
try:
testJson = json.dumps(ret['return'])
except:
if ret['fun'] == 'state.sls' or ret['fun'] == 'state.highstate':
for retK,retV in ret['return'].iteritems():
if isinstance(ret['return'][retK], dict):
for retK2,retV2 in ret['return'][retK].iteritems():
if retK2 == 'changes':
if isinstance(ret['return'][retK][retK2], dict):
for retK3,retV3 in ret['return'][retK]['changes'].iteritems():
if retK3 == 'diff':
try:
testJson22 = json.dumps(ret['return'][retK]['changes'][retK3])
except:
ret['return'][retK]['changes'][retK3] = retV3.decode('gb2312').encode('utf-8')
else:
continue
else:
continue
else:
continue
#################### 2015-01-26 #############################
with _get_serv(commit=True) as cur:
sql = '''INSERT INTO `salt_returns`
(`fun`, `jid`, `return`, `id`, `success`, `full_ret` )
VALUES (%s, %s, %s, %s, %s, %s)'''
cur.execute(sql, (ret['fun'], ret['jid'],
json.dumps(ret['return']),
ret['id'],
ret['success'],
json.dumps(ret)))
def save_load(jid, load):
'''
Save the load to the specified jid id
'''
####### editt 2015.01.21 ###########
if load['fun'] == "saltutil.find_job":
pass
else:
with _get_serv(commit=True) as cur:
sql = '''INSERT INTO `jids`
(`jid`, `load`)
VALUES (%s, %s)'''
cur.execute(sql, (jid, json.dumps(load)))
转载于:https://blog.51cto.com/guibin/1606747