saltstack(九)returner
终于来了个重量级的,returner这东西简直是个神器啊。再也不用盯着管理端的屏幕看了,直接用returner这东西,把返回的结果同时保存在文件或者数据库里面一份。
returner支持很多输出,比如各种各样的数据库,mysql,redis,monggodb。也支持输入到文件,或者/var/local/syslog里面。
returner的工作过程是咋样的呢?楼主根据自己的实践总结了一下
1。其实,也就是当我们把自定义的returner同步到minion上面去后,
2.然后我们在master上执行一些操作,并指定return的对象,比如salt '*' cmd.run 'ls' --return mysql
3.这个时候,master上面发送过来的命令会在,mininon上面执行。minion上执行完命令后,产生一个结果,在salt里面这个结果用ret表示,
4.这个结果一方面会按照通常的方式返回给master并在master的屏幕上面输出打印。
5.另一方面,ret这个结果会传给我们自定义的returner,然后在minion端执行returner,
6.执行returner产生的结果就是把最终的结果导入文件或者数据库,这个和returner里面怎么写有关了。
7.第二方面怎么玩,和master就不搭嘎了。
8.注意:咱们returner里面咱们定义的文件或者数据库都是相对于minion来说,比如说我们把结果写入文件/tmp/returner里面,这个/tmp/returner是minion上面的,而不是在master上面的。楼主调试这个功能的时候,开始没搞清这层关系,吃了不小哦亏。
9.其实,returner可以任意的定义,我们在里面定义了啥,它就可以干什么活,比如我们可以定义
邮件,短信报警模块等等
官方地址:
https://github.com/saltstack/salt/blob/develop/salt/returners/mysql.py
我们先测试一下return接口是否能够正常使用。同时看一下,我们自定义的returner究竟接受到什么样的数据?
自定义returner默认路径是/srv/salt/_returners
mkdir /srv/salt/_returners
看一下测试returner
root@salt-master:~# cat /srv/salt/_returners/local.py from __future__ import print_function def returner(ret): print(ret) root@salt-master:~#
好了,这个时候,咱们为了看得清楚点。到minion上面,以debug的模块启动minion
root@salt-client:~# /etc/init.d/salt-minion Usage: /etc/init.d/salt-minion {start|stop|status|restart|force-reload} root@salt-client:~# /etc/init.d/salt-minion stop [ ok ] Stopping salt minion control daemon: salt-minion. root@ansible:~# salt-minion -l debug
OK,master端同步一下returners
root@salt-master:~# salt '*' saltutil.sync_returners salt-client: root@salt-master:~# salt '*' cmd.run 'hostname' --return local salt-client: salt-client root@salt-master:~#
到minion端看一下debug的信息。看到了没,大括号里面的东西,就是minion执行完毕后,返回给master
或者返回给returner的东西。结构都是这个样子的
大伙应该都看得懂,jid,函数名,函数参数,等等信息
[INFO ] Returning information for job: 20140624162233869962
{'fun_args': ['hostname'], 'jid': '20140624162233869962', 'return': 'ansible',
'retcode': 0, 'success': True, 'fun': 'cmd.run', 'id': 'ansible'}
好了,这个东西出来了说明咱们的returner是木有问题的。
下面看一下,怎么把结果return到文件或者日志里面吧
先看看文件吧
楼主的returner代码
root@salt-master:~# cat /srv/salt/_returners/file.py
import json
import time
def returner(ret):
now = time.localtime()
now = time.strftime("%Y-%m-%d %H:%M:%S",now)
result_file = '/tmp/returner'
result = file(result_file,'a+')
result.write('At'+str(json.dumps(now))+'\n')
result.write(str(json.dumps(ret))+'\n')
result.close()
同步一下returner
root@salt-master:~# salt '*' saltutil.sync_returners
ansible:
- returners.file
执行个命令并return到file
root@salt-master:~# salt '*' cmd.run 'hostname' --return file
ansible:
ansible
好查看一下minion上面的结果
root@salt-master:~# salt '*' cmd.run 'cat /tmp/returner'
ansible:
At"2014-06-24 04:09:23"
{"fun_args": ["hostname"], "jid": "20140624164743457542", "return": "ansible", "retcode": 0, "success": true, "fun": "cmd.run", "id": "ansible"}
At"2014-06-24 04:09:47"
{"fun_args": ["hostname"], "jid": "20140624164807042671", "return": "ansible", "retcode": 0, "success": true, "fun": "cmd.run", "id": "ansible"}
At"2014-06-24 04:10:59"
{"fun_args": ["hostname"], "jid": "20140624164918774162", "return": "ansible", "retcode": 0, "success": true, "fun": "cmd.run", "id": "ansible"}
root@salt-master:~#
OK,搞定,再看看return到syslog
看一下代码,这里用到里前几篇说过的虚拟模块
root@salt-master:~# cat /srv/salt/_returners/syslog.py
import json
try:
import syslog
HAS_SYSLOG = True
except ImportError:
HAS_SYSLOG = False
__virtualname__ = 'syslog'
def __virtual__():
if not HAS_SYSLOG:
return False
return __virtualname__
def returner(ret):
syslog.syslog(syslog.LOG_INFO, 'salt-minion: {0}'.format(json.dumps(ret)))
同步一下returner
root@salt-master:~# salt '*' saltutil.sync_returners
ansible:
- returners.syslog
执行个命令玩玩
root@salt-master:~# salt '*' cmd.run 'hostname' --return syslog
ansible:
ansible
看一下minion上的syslog日志。
root@salt-master:~# salt '*' cmd.run 'grep 'jid' /var/log/syslog'
ansible:
Jun 24 04:15:19 ansible salt-minion: salt-minion: {"fun_args":
["hostname"], "jid": "20140624165338927188", "return": "ansible",
"retcode": 0, "success": true, "fun": "cmd.run", "id": "ansible"}
root@salt-master:~#
OK,搞定,不过感觉放在syslog不太好吧,syslog还有别的很多其他的日志消息。觉得,放文件的话,最后弄个空文件放。
OK,下面该搞搞数据库,楼主只玩过mysql数据库,所以没得选择了。
这个例子基本上算是,按照官网上来的,楼主在本地跑通就这个样子。
注意:楼主的数据库是建立在master上面的,所以待会要需要远程连接
先看一下建表语句:
CREATE DATABASE `salt`
DEFAULT CHARACTER SET utf8
DEFAULT COLLATE utf8_general_ci;
USE `salt`;
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;
看一下,returner吧
root@salt-master:~# cat /srv/salt/_returners/mysql_return.py
import json
import time
try:
import MySQLdb
HAS_MYSQL = True
except ImportError:
HAS_MYSQL = False
__virtualname__ = 'mysql'
def __virtual__():
if not HAS_MYSQL:
return False
else:
return __virtualname__
def returner(ret):
conn=MySQLdb.connect(host='10.240.161.98',user='root',passwd='123456',db='salt',
port=3306)
cursor=conn.cursor()
sql = 'INSERT INTO salt_returns(`fun`,`jid`,`return`,`id`,`success`,`full_ret`)
VALUES (%s,%s,%s,%s,%s,%s)'
cursor.execute(sql % (str(json.dumps(ret['fun'])),str(json.dumps(ret['jid'])),
str(json.dumps(ret['return'])),str(json.dumps(ret['id'])),
'"'+str(ret['success'])+'"',"'"+json.dumps(ret)+"'"))
conn.commit()
cursor.close()
conn.close()
root@salt-master:~#
同步并执行一下
root@salt-master:~# salt '*' saltutil.sync_returners salt-minion: - returners.mysql_return root@salt-master:~# salt '*' cmd.run 'ls' --return=mysql salt-minion: 1 123 dec1.py root@salt-master:~#
看一下数据库。
root@salt-master:~# mysql -uroot -p"123456" -e "select * from salt.salt_returns\G" *************************** 1. row *************************** fun: cmd.run jid: 20140625105655939721 return: 1 123 dec1.py id: salt-minion success: True full_ret: {"fun_args": ["ls"], "jid": "20140625105655939721", "return": "1 123 dec1.py", "retcode": 0, "success": true, "fun": "cmd.run", "id": "salt-minion"} alter_time: 2014-06-25 10:56:55 root@salt-master:~#
ok,成功了
转载于:https://blog.51cto.com/lixcto/1430638