天天看点

57. Python saltstack 二次开发(2)

回顾上一节:

grains 和 pillar 都是定义他们的属性的

grains 定义在minion端(定义完必须重启minion,才能生效)

pillar  定义在master端(无需重启即可生效)

saltstack的api

Salt-api有两种方式:

第一种:是函数的形式,有人家定义好的函数,我们可以直接调用,直接写python代码调用函数或者类就可以了。

第二种:形式是salt-api有封装好的http协议的,我们需要启动一个服务端。

登录官网查看文档:

文档内容,如下:

安装salt-api:

<code>yum </code><code>install</code> <code>–y salt-api</code>

1.加载master的配置文件

<code>import</code>  <code>salt.config</code>

<code>master_opts </code><code>=</code> <code>salt.config.client_config(</code><code>'/etc/salt/master'</code><code>)</code>

<code>print</code><code>(</code><code>'master_opts'</code><code>)</code>

master端,如果想查看配置文件的参数属性:

2. 加载minion的配置文件

<code>import</code> <code>salt.config</code>

<code>minion_opts </code><code>=</code> <code>salt.config.minion_config(</code><code>'/etc/salt/minion'</code><code>)</code>

<code>print</code> <code>(</code><code>'minion_opts'</code><code>)</code>

minion端,想看配置文件内的参数属性:

3. 在master上执行各种模块:

<code>&gt;&gt;&gt; </code><code>import</code> <code>salt.client</code>

<code>&gt;&gt;&gt; local </code><code>=</code> <code>salt.client.LocalClient(</code><code>'/etc/salt/minion'</code><code>)</code>

<code>&gt;&gt;&gt; local.cmd(</code><code>'*'</code><code>, </code><code>"test.ping"</code><code>)</code>

返回:

<code>{</code><code>'192.168.48.129'</code><code>: True}</code>

执行命令:

<code>&gt;&gt; local.cmd(</code><code>'*'</code><code>, </code><code>"cmd.run"</code><code>, </code><code>"w"</code><code>)</code>

【返回的是一个字典形式,很容易后期处理数据用】

<code>{</code><code>'192.168.48.129'</code><code>: </code><code>' 12:17:38 up  5:58,  1 user,  load average: 0.00, 0.01, 0.05\nUSER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT\nroot     pts/0    192.168.48.1     11:14    2:50   0.89s  0.89s python'</code><code>}</code>

如果一次要执行多个模块:

一种方式:

<code>&gt;&gt;&gt; local.cmd(</code><code>'*'</code><code>, [</code><code>'test.ping'</code><code>, </code><code>'cmd.run'</code><code>], [[], [</code><code>'whoami'</code><code>]])</code>

结果:

<code>{</code><code>'192.168.48.129'</code><code>: {</code><code>'test.ping'</code><code>: True, </code><code>'cmd.run'</code><code>: </code><code>'root'</code><code>}}</code>

【test.ping 对应 [](空列表),cmd.run 对应 whoami 命令】

另一种方式:(不推荐这样用,还不如调两次,这样逻辑性不好)

<code>&gt;&gt;&gt; local.cmd(</code><code>'*'</code><code>, [</code><code>'test.ping'</code><code>, </code><code>'cmd.run'</code><code>], [[], [</code><code>'w; df -h'</code><code>]])</code>

自定义的模块:

模块目录必须创建:

<code>mkdir</code> <code>-p </code><code>/srv/salt/_modules</code>

<code>cd</code>  <code>/srv/salt/_modules</code>

创建 jd.py 文件:

vim jd.py

<code>#!/usr/bin/python</code>

<code>#coding:utf-8</code>

<code>def</code> <code>hello(name):</code>

<code>return</code> <code>{</code><code>"name"</code><code>: name}</code>

写完所有module要记得同步一下:

<code>salt </code><code>'*'</code> <code>saltutil.sync_all    </code><code>#同步所有</code>

或者

<code>salt </code><code>'*'</code> <code>saltutil.sync_modules    </code><code>#只同步modules</code>

执行命令获取结果:

<code># salt '*' jd.hello  ajing</code>

结果输出,如图:

python交互界面中这样获取:

Master端执行salt-run

如果对于执行时间过长,没法直接返回的情况,我们就可以通过异步执行的形式进行返回 cmd_async 和 get_cache_returns()

先使用salt-run命令:

(1)命令行使用salt-run查看服务器状态

<code># salt-run manage.status</code>

返回结果:

<code>down:</code>

<code>up:</code>

<code>- 192.168.48.129</code>

(2)使用 runner 模块查看客户端服务器状态:

<code>import</code> <code>salt.runner</code>

<code>__opts__ </code><code>=</code> <code>salt.config.client_config(</code><code>'/etc/salt/master'</code><code>)</code>

<code>runermaster </code><code>=</code> <code>salt.runner.RunnerClient(__opts__)</code>

<code>runnerMaster.cmd(</code><code>'jobs.list_jobs'</code><code>, [])</code>

<code>runnerMaster.cmd(</code><code>'manage.status'</code><code>)</code>

<code>{</code><code>'down'</code><code>: [], </code><code>'up'</code><code>: [</code><code>'192.168.48.129'</code><code>]}</code>

【以下例子代码只能只能在master上执行,而且是只能在master上才可以使用】

vim test.py

<code>import</code> <code>salt.client</code>

<code>def</code> <code>get_result(sleep_interval</code><code>=</code><code>1</code><code>):</code>

<code>    </code><code>__opts__ </code><code>=</code> <code>salt.config.client_config(</code><code>'/etc/salt/master'</code><code>)</code>

<code>    </code><code>localclient </code><code>=</code> <code>salt.client.LocalClient(__opts__)</code>

<code>    </code><code>jid </code><code>=</code> <code>localclient.cmd_async(</code><code>"*"</code><code>, cmd.run, </code><code>'df -h'</code><code>)</code>

<code>    </code><code>#returns = localclient.get_cache_returns(jid)</code>

<code>    </code><code>wait_time </code><code>=</code> <code>0</code>

<code>    </code><code>while</code> <code>sleep_interval &lt; __opts__[</code><code>'timeout'</code><code>]:</code>

<code>        </code><code>results </code><code>=</code> <code>localclient.get_cache_returns(jid)</code>

<code>            </code><code>if</code> <code>returns:</code>

<code>                </code><code>return</code> <code>results</code>

<code>            </code><code>wait_time </code><code>+</code><code>=</code> <code>sleep_interval</code>

这个 test.py 文件的位置是在 /srv/salt/_runner 里面,图中为定义 _runner 的目录位置 (文件:/etc/salt/master)

先创建 _runner 目录,修改文件 /etc/salt/master 的 runner路径参数:

记得重启master服务

通过python命令测试并确认目录位置:

【补充】

客户端的获取结果的方式为:

<code>caller </code><code>=</code> <code>salt.client.Caller(</code><code>'/etc/salt/minion'</code><code>)</code>

<code>caller.cmd(</code><code>"test.ping"</code><code>)</code>

得到结果:

<code>True</code>

所以,对比一下master端和minion端获取值的方式不同:

<code>local</code> <code>= salt.client.LocalClient(</code><code>'/etc/salt/minion'</code><code>)</code><code>#master端</code>

<code>对比:</code>

<code>caller = salt.client.Caller(‘</code><code>/etc/salt/minion</code><code>’)</code><code>#minion端,无法使用LocalClient</code>

类似shell命令的salt-call,可以在minion端执行salt的命令,测试连通性等操作。

Salt的内置环境变量:

在python的交互环境中,这些变量是不生效的,只有在自定义的模块,活着salt执行时才生效

(1)__opts__         #配置文件,类型等 最常用

(2)__salt__          #执行、调用 modules  最常用

举例:

<code>__salt__[</code><code>'cmd.run'</code><code>](</code><code>'fdisk -l'</code><code>)        </code><code>##__salt__[模块](参数)</code>

<code>__salt__[</code><code>'network.ip_addrs'</code><code>]()       </code><code>##同上</code>

【__salt__是个字典,它里面装了minion上所有的modules,__salt__的key是一个个的模块名称,value则是模块里面的一个个函数】

看个例子看看内建模块是怎么调用的:

vim /srv/salt/_modules/foo.py

<code>def</code> <code>foo(name):</code>

<code>    </code><code>return</code> <code>"I am %s"</code> <code>%</code> <code>name</code>

cheng.py 也是定义的一个模块,目的是通过调用__salt__调用上面定义的那个foo模块中的foo函数

vim /srv/salt/_modules/cheng.py

<code>def</code> <code>cheng(name):</code>

<code>    </code><code>return</code> <code>__salt__[</code><code>'foo.foo'</code><code>](name)</code>

ok,同步一下模块:

<code>salt </code><code>'*'</code> <code>saltutil.sync_modules</code>

同步完成

<code>salt</code><code>-</code><code>minion:</code>

<code>    </code><code>-</code> <code>modules.cheng</code>

<code>    </code><code>-</code> <code>modules.foo</code>

看一下结果:

<code>salt </code><code>'*'</code> <code>cheng.cheng Lilith</code>

<code>    </code><code>I am Lilith</code>

通过这个例子,可以知道怎么调用__salt__里面的函数了。

(3)__pillar__ 之前说过,pillar很少用到

(4)__grains__ grains 比pillar还要少用到

举例1:

<code>import</code> <code>salt.loader</code>

<code>__opts__ </code><code>=</code> <code>salt.config.minion_config(</code><code>"/etc/salt/minion"</code><code>)</code>

<code>__grains__ </code><code>=</code> <code>salt.loader.grains(__opts__)</code>

<code>__grains__[</code><code>'id'</code><code>]</code>

获得结果:

<code>192.168.48.129</code>

举例2:

<code>__opts__ </code><code>=</code> <code>salt.config.minion_config(</code><code>'/etc/salt/minion'</code><code>)</code>

<code>__opts__[</code><code>'grains'</code><code>] </code><code>=</code> <code>__grains__</code>

<code>__utils__ </code><code>=</code> <code>salt.loader.utils(__opts__)</code>

<code>__salt__ </code><code>=</code> <code>salt.loader.minion_mods(__opts__, utils</code><code>=</code><code>__utils__)</code>

<code>__salt__[</code><code>'test.ping'</code><code>]()</code>

(5)__context__

<code>if</code> <code>not</code> <code>'cp.fileclient'</code> <code>in</code> <code>__context__:</code>

<code>    </code><code>__context__[</code><code>'cp.fileclient'</code><code>] </code><code>=</code> <code>salt.fileclient.get_file_client(__opts__)</code>

<code></code>

本文转自 听丶飞鸟说 51CTO博客,原文链接:http://blog.51cto.com/286577399/2068913