saltstack(七)返回值
一、自定义创建模块
1
2
3
4
5
6
7
8
|
[root@localhost:] # tree -L 3 salt salt ├── etc ├── _grains │ ├── dmp_scribe.py │ └── zabbix_conf.py ├── _modules │ └── ip.py |
通过上图可以看到已经创建了一个名为ip.py文件,看看相关内容:
1
2
3
4
5
6
7
8
9
10
|
#!/usr/bin/env python import commands def eth1(): ip = {} cmd = "ifconfig eth1|grep inet|awk '{print $2}'|awk -F : '{print $2}'" ip2 = commands.getoutput(cmd).strip() ip[ 'ip' ] = ip2 return ip |
定义模块我们没有在/srv/salt/top.sls文件中新增模块名,现在把写好的模块同步到你需要执行的机器上,可以全部同步,也可以针对性的同步
这里只演示同步一台
1
2
3
|
salt '192.168.10.128' saltutil.sync_modules 192.168 . 10.128 : - modules.ip |
在master执行编写的模块,由于不依赖state.sls文件,所以执行时命令也有变化,在主要命令后面跟模块名●函数名
1
2
3
4
5
|
[root@localhost _modules] # salt '192.168.10.128' ip.eth1 192.168 . 10.128 : - - - - - - - - - - ip: 192.168 . 10.128 |
二、屏幕返回值输出到指定的位置
saltstack执行命令时默认的返回值都是打印在当前屏幕上的,如果一次执行多台机器,怎么查看这些记录,为了更方便的查看这些返回结果的信息,这就用到了salt的returners功能了。关于详细介绍请参考官网地址:http://docs.saltstack.cn/ref/returners/index.html?highlight=returners
在/srv/salt目录下创建_returners目录,将自己编写的模块都可以存放在该目录下。
1
2
3
4
5
|
├── _returners │ ├── local_return.py #输出到文件 │ ├── mysql_log.py #输出到数据库 │ ├── nohup.out │ ├── salt_event_to_mysql.py |
在_returners目录下创建了两个文件,一个是local_return.py:表示把执行结果存在在本地
一个是mysql_log.py:表示把结果存放在mysql数据库中
1、返回结果存放到本地
1
2
3
4
5
6
7
8
|
#coding:utf-8 def __virtual__(): '''调用时的名字''' return "local_return" def returner(ret): f = open ( '/var/log/salt/local_returner.log' , 'a+' ) f.write( str (ret)[ 1 : - 1 ] + '\n' ) f.close() |
和自建模块一样,在编写完returners之后,也要同步到客户端的,同步的规则和自建模块一样。
1
|
salt '192.168.10.128' saltutil.sync_returners |
在执行完上面的语句后,执行salt ‘192.168.10.128’cmd.run 'uptime' --return local_return
验证结果是否已经输出到文件中
2、返回结果存放在mysql中
官方默认returners中已经包含了mysql的returners,我们先直接利用官方原生的mysql returners,里面有创建相关表的语句。
官方的mysql returners源码在https://github.com/saltstack/salt/blob/develop/salt/returners/mysql.py
mysql服务器192.168.10.129:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
#在mysql服务器上创建表 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; |
给相关salt表赋予访问权限:
1
|
GRANT ALL PRIVILEGES ON salt. * TO 'salt' @localhost IDENTIFIED BY 'saltt' ; |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
mysql> show databases; + - - - - - - - - - - - - - - - - - - - - + | Database | + - - - - - - - - - - - - - - - - - - - - + | information_schema | | salt | + - - - - - - - - - - - - - - - - - - - - + 2 rows in set ( 0.00 sec) mysql> use salt mysql> show tables; + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + | Tables_in_salt | + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + | jids | | salt_returners | + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + |
因为要把客户端执行命令的结果直接返回给mysql服务器,所以客户端也要配置mysql信息的,我们以192.168.10.128为例,在salt的配置文件中加入如下信息,你也可以把它单独写在一个文件中。为了方便管理推荐写在单独文件中:
1
2
3
4
5
6
|
#/etc/salt/minion.d/mysql.conf mysql.host: '192.168.1.204' mysql.user: 'salt' mysql. pass : 'salt' mysql.db: 'salt' mysql.port: 3306 |
然后在master上执行命令,如下:
1
2
|
salt '192.168.10.128' cmd.run 'uptime' - - return local_return salt '192,168.10.128' cmd.run 'uptime' - - return mysql |
注意这里用的是salt官网原生的mysql returners,并没有使用自己定义的mysql_log returners ,我们看看数据库中的记录:(图片是借鉴大神的图片)
第一句是刚创建好表时的结果,可以看到数据库中已经有一条记录了,下面自己定义一个mysql_log returners来试试:
1
|
salt '192.168.10.128' cmd.run 'hostname' - - return mysql_log |
我们来数据库中查看一下记录:
下面附上定义的mysql_log.py:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
#/usr/bin/python #coding:utf-8 from contextlib import contextmanager import sys import json import logging # Import third party libs try : import MySQLdb HAS_MYSQL = True except ImportError: HAS_MYSQL = False log = logging.getLogger(__name__) def __virtual__(): if not HAS_MYSQL: return False return "mysql_log" def _get_options(): ''' Returns options used for the MySQL connection. ''' defaults = { 'host' : '192.168.1.204' , 'user' : 'salt' , 'pass' : 'salt' , 'db' : 'salt' , 'port' : 3306 } _options = {} # Ensure port is an int for attr in defaults: _attr = __salt__[ 'config.option' ]( 'mysql.{0}' . format (attr)) if not _attr: log.debug( 'Using default for MySQL {0}' . format (attr)) _options[attr] = defaults[attr] continue _options[attr] = _attr return _options @contextmanager def _get_serv(commit = False ): ''' Return a mysql cursor ''' _options = _get_options() conn = MySQLdb.connect(host = _options[ 'host' ], user = _options[ 'user' ], passwd = _options[ 'pass' ], db = _options[ 'db' ], port = _options[ 'port' ]) cursor = conn.cursor() try : yield cursor except MySQLdb.DatabaseError as err: error, = err.args sys.stderr.write( str (error)) cursor.execute( "ROLLBACK" ) raise err else : if commit: cursor.execute( "COMMIT" ) else : cursor.execute( "ROLLBACK" ) finally : conn.close() def returner(ret): ''' Return data to a mysql server ''' 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' ], str (ret[ 'return' ]), ret[ 'id' ], ret[ 'success' ], json.dumps(ret))) |
三、基于Salt Event系统构建Master端returner
上面我们介绍Saltstack的returner是由minion端主动连接returners完成执行结果的存储,在部分场景下并不能满足需求,由于salt底层已构建了一套Event系统,所有的操作均会产生event,因此基于Salt Event系统构建Master端returner成为一种可能。
SaltStack Event 系统 官网地址:http://docs.saltstack.com/en/latest/topics/event/index.html
SaltStack Event 系统监听events测试:http://pengyao.org/saltstack_event_system_listen_events.html
环境说明:
测试结构:Master/Minions结构
Salt Version:2015.8.8.2
本次测试结果将存放在mysql中
前置配置:
安装Mysqldb依赖: yum -y install MySQL-Python
配置本次测试需要使用的数据库及用户:
1
2
3
4
5
6
|
# 创建salt数据库 mysql - e 'create database salt' # 创建用于连接salt数据库的用户 mysql - e '"grant all on salt.* to salt@localhost identified by "salt_pass' ; # 将数据库配置添加至master配置文件中 echo - e "\n\n# MySQL\nmysql.host: 'localhost'\nmysql.user: 'salt'\nmysql.pass: 'salt_pass'\nmysql.db: 'salt'\nmysql.port: 3306" >> / etc / salt / master |
为了与salt自带的mysql returners兼容,本次直接使用mysql returners对应的数据库表结构:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
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; |
编写returners:salt_event_to_mysql.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
#!/bin/env python #coding=utf8 # Import python libs import json # Import salt modules import salt.config import salt.utils.event # Import third party libs import MySQLdb __opts__ = salt.config.client_config( '/etc/salt/master' ) # Create MySQL connect conn = MySQLdb.connect(host = __opts__[ 'mysql.host' ], user = __opts__[ 'mysql.user' ], passwd = __opts__[ 'mysql.pass' ], db = __opts__[ 'mysql.db' ], port = __opts__[ 'mysql.port' ]) cursor = conn.cursor() # Listen Salt Master Event System event = salt.utils.event.MasterEvent(__opts__[ 'sock_dir' ]) for eachevent in event.iter_events(full = True ): ret = eachevent[ 'data' ] if "salt/job/" in eachevent[ 'tag' ]: # Return Event if ret.has_key( 'id' ) and ret.has_key( 'return' ): # Igonre saltutil.find_job event if ret[ 'fun' ] = = "saltutil.find_job" : continue sql = '''INSERT INTO `salt_returns` (`fun`, `jid`, `return`, `id`, `success`, `full_ret` ) VALUES (%s, %s, %s, %s, %s, %s)''' cursor.execute(sql, (ret[ 'fun' ], ret[ 'jid' ], json.dumps(ret[ 'return' ]), ret[ 'id' ], ret[ 'success' ], json.dumps(ret))) cursor.execute( "COMMIT" ) # Other Event else : pass |
运行编写的returner: Python salt_event_to_mysql.py
测试:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
salt '*' test.ping #开启一个终端,运行salt指令 #输出为: salt - minion - 01.example .com: True #检查mysql数据库,查询salt_returns表数据: mysql salt - e "select * from salt_returns\G" #输出为: * * * * * * * * * * * * * * * * * * * * * * * * * * * 1. row * * * * * * * * * * * * * * * * * * * * * * * * * * * fun: test.ping jid: 20140417161103569310 return : true id : salt - minion - 01.example .com success: 1 full_ret: { "fun_args" : [], "jid" : "20140417161103569310" , "return" : true, "retcode" : 0 , "success" : true, "cmd" : "_return" , "_stamp" : "2014-04-17T16:11:03.584859" , "fun" : "test.ping" , "id" : "salt-minion-01.example.com" } alter_time: 2014 - 04 - 17 16 : 11 : 03 #入库成功 |
saltstack(七)返回值的更多相关文章
- Python第七天 函数 函数参数 函数里的变量 函数返回值 多类型传值 函数递归调用 匿名函数 内置函数
Python第七天 函数 函数参数 函数里的变量 函数返回值 多类型传值 函数递归调用 匿名函数 内置函数 目录 Pycharm使用技巧(转载) Python第一天 ...
- (转)SpringMVC学习(七)——Controller类的方法返回值
http://blog.csdn.net/yerenyuan_pku/article/details/72511844 本文所有案例代码的编写均建立在前文SpringMVC学习(六)——SpringM ...
- 无废话Android之activity的生命周期、activity的启动模式、activity横竖屏切换的生命周期、开启新的activity获取他的返回值、利用广播实现ip拨号、短信接收广播、短信监听器(6)
1.activity的生命周期 这七个方法定义了Activity的完整生命周期.实现这些方法可以帮助我们监视其中的三个嵌套生命周期循环: (1)Activity的完整生命周期 自第一次调用onCrea ...
- Action的返回值类型总结
Action的返回值 MVC 中的 ActionResult是其他所有Action返回类型的基类,下面是我总结的返回类型,以相应的帮助方法: 下面是这些方法使用的更详细的例子 一.返回View ...
- c#中命令copy已退出,返回值为1
c#中命令copy已退出,返回值为1 本正经的道:董姐刚才你说的修心养性其中的'修心'我 有孕在身刚好由戴梦瑶顶替了她的位置按照的指示 ╋旆呆 湎术葶页 邾箕砜笳 烦璜卿廑 奶奶个腿儿的等下次非让你 ...
- SSM-SpringMVC-21:SpringMVC中处理器方法之返回值Object篇
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 今天要记录的是处理方法,返回值为Object的那种,我给它分了一下类: 1.返回值为Object数值(例如1) ...
- springMVC对于Controller返回值的可选类型
2018-01-11 对于springMVC处理方法支持支持一系列的返回方式: (1)ModelAndView (2)Model (3)ModelMap (4)Map (5)View (6)Stri ...
- 总结day7 ---- 函数的内容 ,初识,返回值,进阶(一)
内容大纲: 一: 函数识别 二: 函数的结构 三: 函数的返回值, 四: 函数的参数 五: 动态参数 六: 形参的顺序 七: 名称空间 八: 作用域 九: 加载顺序和取值顺序 十: 内置函数 十一: ...
- mybatis Mapper 中resultType使用方法及返回值为Map的写法
mybatis学习(七)——resultType解析 resultType是sql映射文件中定义返回值类型,返回值有基本类型,对象类型,List类型,Map类型等.现总结一下再解释 总结: resul ...
随机推荐
- LD_LIBRARY_PATH设置问题
今天突然遇到设置LD_LIBRARY_PATH的问题,,发现在.bashrc和/etc/profile中添加 exportLD_LIBRARY_PATH = path_name:$LD_LIBRARY ...
- PCB 2019年IT工作主题【降本增效】 词云
降本增效是IT部门永恒的主题,从自身做起.踏踏实实把工作做好 在线词云制作软件: https://wordart.com/create
- Hdu 3487 play the chain
Description 瑶瑶很喜欢玩项链,她有一根项链上面有很多宝石,宝石从1到n编号. 首先,项链上的宝石的编号组成一个序列:1,2,3,...,n. 她喜欢两种操作: 1.CUT a b c:他会 ...
- 水题 CodeForces 137A Postcards and photos
题目传送门 /* 水! */ #include <cstdio> #include <cstring> #include <algorithm> using nam ...
- 【转】Spark:Master High Availability(HA)高可用配置的2种实现
原博文出自于: 感谢! Spark Standalone集群是Master-Slaves架构的集群模式,和大部分的Master-Slaves结构集群一样,存在着Master单点故障的问题.如何解决这个 ...
- cocos creator 场景如何透明,多个canvas层级显示
转载地址:https://forum.cocos.com/t/creator-canvas/55373/14 Creator 版本:1.7 目标平台:WEB MOBILE 项目需要,页面做了多个Can ...
- Laravel5.1学习笔记23 Eloquent 序列化
Eloquent: Serialization Introduction Basic Usage Hiding Attributes From JSON Appending Values To JSO ...
- Android屏幕尺寸与度量单位(px,dp,sp)简介
MarkdownPad Document *:first-child { margin-top: 0 !important; } body>*:last-child { margin-botto ...
- 项目经验——Sql server 数据库的备份和还原____还原数据库提示“介质集有2个介质簇,但只提供了1个。必须提供所有成员” .
在对数据库备份与还原的过程中,我遇到一个问题“介质集有2个介质簇,但只提供了1个.必须提供所有成员”,下面详细的介绍一下遇到问题的经过与问题解决的方法! 一.备份与还原遇到的问题描述与解决方法: 前两 ...
- Java 基础入门随笔(11) JavaSE版——继承、覆盖、抽象类
1.面向对象的特征二:继承 定义: 指一个对象直接使用另一对象的属性和方法. 继承好处: 1.提供代码的复用性. 2.让类与类直接产生了关系,给第三个特征多态提供了前提. java中支持单继承.不直接 ...