saltstack(二)--- salt-api

salt-api有两种,一种是封装好的函数,直接在命令行或者python代码中调用;第二种是封装好的http协议的api,需要启动一个服务端
 
以下操作均在centos7下实现,centos6不能直接引入salt
 
master端需要安装一个包,minion端不需要安装
 
yum install -y salt-api

 

1. 加载master配置文件(master端)

In [1]: import salt.config

In [2]: __opts__ = salt.config.client_config('/etc/salt/master')

In [3]: __opts__['timeout']                                        
Out[3]: 5

 

2. 加载minion配置文件(minion)

In [1]: import salt.config

In [2]: __opts__ = salt.config.minion_config('/etc/salt/minion')

In [3]: __opts__['id']
Out[3]: '192.168.123.107'

In [4]: __opts__['master']
Out[4]: '192.168.123.106'

 

3. master端执行模块

In [4]: import salt.client    
                                    
In [5]: localclient = salt.client.LocalClient()  
                 
In [6]: localclient.cmd('*', 'test.ping')
Out[6]: {'192.168.123.107': True}

In [8]: localclient.cmd('*', 'cmd.run', ['w'])                         
Out[8]: {'192.168.123.107': ' 15:52:17 up  1:10,  2 users,  load average: 0.00, 0.01, 0.05\nUSER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT\nroot     tty1                      14:42    1:08m  0.05s  0.05s -bash\nroot     pts/0    192.168.123.34   14:45    2:01   0.42s  0.35s /usr/bin/python2 /usr/bin/ipython'}

In [9]: localclient.cmd('*', ['cmd.run', 'test.ping'], [['whoami'], []])              //一次执行多个模块
Out[9]: {'192.168.123.107': {'cmd.run': 'root', 'test.ping': True}}

 

4. 自定义模块

[root@localhost salt]# mkdir -p /srv/salt/
[root@localhost salt]# cd /srv/salt/
[root@localhost salt]# mkdir _modules           //目录名必须为_modules,自定义的模块放到这个目录下
[root@localhost salt]# cd _modules/
[root@localhost _modules]# cat jd.py           //里面想写什么逻辑写什么逻辑
#!/usr/bin/env python

def hello(name):
    return {'name': name}

[root@localhost _modules]# salt '*' saltutil.sync_modules            //把模块下发到minion
192.168.123.107:
    - modules.jd

[root@localhost _modules]# salt '*' jd.hello python                  //在命令行调用
192.168.123.107:
    ----------
    name:
        python

In [4]: localclient.cmd('*', 'jd.hello', ['python'])                //在api调用
Out[4]: {'192.168.123.107': {'name': 'python'}}

 

5. saltstack的异步调用

有时调用一个自定义模块,这个模块执行很长(例如编译安装mysql的模块),master需要一直等待执行,这种场景适合使用异步处理
master执行一个任务,获得一个id,把id丢入消息队列中(zeromq),隔段时间再去取
 
异步调用只能在master端上用,而且要使用runner
[root@localhost ~]# mkdir /srv/salt/_runner                           //创建runner目录
[root@localhost ~]# cd /srv/salt/_runner/
[root@localhost _runner]# vim /etc/salt/master                        //配置文件定义目录路径
......
# Add any additional locations to look for master runners:
runner_dirs: ['/srv/salt/_runner']
......

[root@localhost _runner]# systemctl restart salt-master

-------------------------------------------------------------------------------->
[root@localhost _runner]# cat getresult.py
#!/usr/bin/env python

import time
import salt.config
import salt.client

def get(minion, function, params):
    __opts__ = salt.config.client_config('/etc/salt/master')
    conf_file = __opts__['conf_file']
    localclient = salt.client.LocalClient(conf_file)                       //因为minion端也有salt.client方法(而且不同于master的用法),如果作为module下发到minion执行,会报错
    jid = localclient.cmd_async(minion, function, params.split(','))
    #jid = localclient.cmd_async('*', 'cmd.run', ['df -h'])
    wait_time = 0
    sleep_interval = 1
    while wait_time < __opts__['timeout']:
        print('wait {0} seconds'.format(wait_time))
        result = localclient.get_cache_returns(jid)
        if result:
            print(type(result))
            return result
        time.sleep(sleep_interval)                                       //把任务放到队列中,从队列取,都需要时间,所以需要阻塞(休眠)
        wait_time += sleep_interval

----------------------------------------------------------------------------->
[root@localhost _runner]# cat /srv/salt/_modules/jd.py
#!/usr/bin/env python

def hello(name):
    return {'name': name}

--------------------------------------------------------------------------->

[root@localhost _runner]# salt-run getresult.get 192.168.123.107 jd.hello 'python'                       //在命令行调用不成功,在httpapi中可以成功调用
wait 0 seconds
wait 1 seconds
<type 'dict'>
192.168.123.107:
    ----------
    out:
        nested
    ret:
        Passed invalid arguments to jd.hello: hello() takes exactly 1 argument (6 given)
        None

[root@localhost _runner]# salt-run getresult.get 192.168.123.107 jd.hello 'p'     
wait 0 seconds
wait 1 seconds
<type 'dict'>
192.168.123.107:
    ----------
    ret:
        ----------
        name:
            p
[root@localhost _runner]# salt-run getresult.get 192.168.123.107 jd.meminfo
wait 0 seconds
wait 1 seconds
<type 'dict'>
192.168.123.107:
    ----------
    ret:
        ----------
        MemAvailable:
            627.125M

 

如果自定义模块不需要参数,则_runner不需要params

[root@bogon _modules]# cat jd.py
#!/usr/bin/env python

import codecs

def meminfo():
    with codecs.open('/proc/meminfo') as fd:
        for line in fd:
            if line.startswith('MemAvailable'):
                result = str(int(line.split()[1])/1024.0) + 'M'
                return {'MemAvailable': result}
[root@bogon _runner]# cat testparam.py
#!/usr/bin/env python

import time
import salt.client

def get_no_param(minion, function):
    __opts__ = salt.config.client_config('/etc/salt/master')
    conf_file = __opts__['conf_file']
    localclient = salt.client.LocalClient(conf_file)
    jid = localclient.cmd_async(minion, function)
    wait_time = 0
    sleep_interval = 1
    while wait_time < __opts__['timeout']:
        print('wait {0} seconds'.format(wait_time))
        result = localclient.get_cache_returns(jid)
        if result:
            print(type(result))
            return result
        time.sleep(sleep_interval)
        wait_time += sleep_interval

 

[root@bogon _runner]# salt-run testparam.get_no_param 192.168.0.126 jd.meminfo
192.168.0.126:
    ----------
    ret:
        ----------
        MemAvailable:
            615.9921875M

 

在api中执行salt-run

In [1]: import salt.config

In [2]: import salt.runner

In [3]: __opts__ = salt.config.client_config('/etc/salt/master')

In [4]: runnerclient = salt.runner.RunnerClient(__opts__)

In [20]: runnerclient.cmd('manage.status')
down:
up:
    - 192.168.123.107
Out[20]: {'down': [], 'up': ['192.168.123.107']}

In [21]: runnerclient.cmd('testparam.get_no_param', ['*', 'jd.meminfo'])
wait 0 seconds
wait 1 seconds
<type 'dict'>
192.168.123.107:
    ----------
    ret:
        ----------
        MemAvailable:
            626.6328125M
Out[21]: {'192.168.123.107': {'ret': {'MemAvailable': '626.6328125M'}}}

>>> runnerclient.cmd('testparam.get', ['*', 'jd.hello', 'aaa'])
wait 0 seconds
wait 1 seconds
<type 'dict'>
192.168.0.126:
    ----------
    ret:
        ----------
        name:
            aaa
{'192.168.0.126': {'ret': {'name': 'aaa'}}}

 

6. minion上执行salt命令

服务端是salt,客户端上是salt-call

[root@localhost ~]# salt-call test.ping
local:
    True

 

在api里调用

In [1]: import salt.client  

In [2]: caller = salt.client.Caller('/etc/salt/minion')

In [4]: caller.cmd('test.ping')
Out[4]: True

 

7. salt的内置变量__salt__

__salt__是一个字典,是salt的全局变量,不是写模块的时候自定义的,写模块的时候直接拿来就用
只要定义的模块下发到minion,就可以使用salt变量
 
格式:__salt__['function'](params)
用法:在一个模块里调用另一个模块
[root@localhost _modules]# cat jd.py
#!/usr/bin/env python

import codecs

def hello(name):
    return {'name': name}

def foo(name):
    return __salt__['jd.hello'](name)         //调用jd.hello函数

---------------------------------------------------------------------------->
[root@localhost _modules]# salt '*' saltutil.sync_modules
192.168.123.107:
    - modules.jd

---------------------------------------------------------------------------->
[root@localhost _modules]# salt '*' jd.foo bar
192.168.123.107:
    ----------
    name:
        bar

---------------------------------------------------------------------------->
In [24]: import salt.client

In [25]: localclient = salt.client.LocalClient()     

In [27]: localclient.cmd('*', 'jd.foo', ['bar'])
Out[27]: {'192.168.123.107': {'name': 'bar'}}

 

转载于:https://www.cnblogs.com/tobeone/p/8434930.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值