[saltstack]二次开发和扩展

SALT API 

salt 支持restful API和本地接口api

API基础

安装配置 

yum install gcc make python-devel libffi-devel
yum install salt-api -y​

  使用RESTful API 接口访问salt:

需要安装独立的 SALT-API 程序 

rm -rf /etc/pki/tls/certs/localhost.crt 
salt-call tls.create_self_signed_cert

local:
    Created Private Key: "/etc/pki/tls/certs/localhost.key." 
    Created Certificate: "/etc/pki/tls/certs/localhost.crt."
# useradd -M -s /sbin/nologin saltapi
# echo "xxxxxxxx"|passwd saltapi --stdin​

  

# 配置文件

/etc/salt/master.d/api.conf
    rest_cherrypy:
    port: 8000
  #  ssl_crt: /etc/pki/tls/certs/localhost.crt
  #  ssl_key: /etc/pki/tls/certs/localhost.key
eauth.conf 
    external_auth:
        pam: #认证方式
        saltapi: #用户名​

  

/etc/init.d/salt-api start
注意把 start stop 之间加个 sleep ,貌似restart的时候 容易失败

启动salt-api之前好像还需要把salt-master也重启一下才行。否则会报401 Unauthorized

 

通过cherrypy API调用

# 用户权限

# 用以获取 token
curl -k https://192.168.102.74:8000/login \
-H "Accept: application/x-yaml" \
-d username='saltapi' \
-d password='xxxxxxx' \
-d eauth='pam'

# 使用token访问
curl -k https://192.168.102.74:8000 \
-H "Accept: application/json" \
-H "X-Auth-Token: cffda36ae00eb32045ae71d3d7934a1ab98c75ed" \
-d client='local' \
-d tgt='website1' \
-d fun='cmd.run' \
-d arg="uptime"

  

cmd_async是异步执行的,不用等待,直接返回一个jid

异步获取结果

# params = {'client':'runner','fun':'jobs.lookup_jid','jid':'20160215133245031359'}
# params = {'client':'local_async', 'fun':'state.sls', 'arg':'prod.nginx.service','tgt':'platddb7'}
结果:
{u'outputter': u'highstate', u'data': {u'platddb7........................'}

  

开发举例:

def subscribe_return(func):
    """
    提供给salt异步方法的装饰器,用于根据jid从redis获取每个minion的执行结果
    需要传入一个handler函数处理订阅到的每条消息
    :return: {'success': True, 'return': 'Wed Oct 30 18:29:49 CST 2019', 'retcode': 0, 'jid': '20191030182949404233', 'fun': 'cmd.run', 'fun_args': ['date'], 'id': 'zijie-test-1'}
    """
    @wraps(func)
    def get_job_result(*args, **kwargs):
        timeout = kwargs.get('timeout', 60)
        jid = func(*args)
        tgt = args[1]
        handler = kwargs.get('handler', None)
        print(locals())
        rs = RedisSubscribe(tgt, 'ret:' + jid, handler)
        return rs.subscribe(timeout)
    return get_job_result


    @subscribe_return
    def async_remote_execution(self, tgt: list, fun, arg, handler=None, timeout=60):
        """
        异步执行
        :param tgt:
        :param arg:
        :param handler: 处理每个minion return数据的方法
        :return: 20190514155309184714
        """
        jid = self.asyncPostRequest(client='local_async',
                                    tgt=tgt,
                                    fun=fun,
                                    ret='redis_pub',
                                    tgt_type='list',
                                    arg=arg)
        return jid
     

  

 

local.cmd 调用master本地接口

wheel接口(管理、配置saltmaster)

import salt.config
import salt.wheel
opts = salt.config.master_config('/etc/salt/master')
wheel = salt.wheel.WheelClient(opts)


# key 操作
>>> wheel.cmd('key.accept', ['minion1'])
{'minions': ['minion1']}
# 异步命令
>>> wheel.cmd_async({'fun': 'key.delete', 'match': 'minion1'})
{'jid': '20160826201244808521', 'tag': 'salt/wheel/20160826201244808521'}

# 同步命令
>>> wheel.cmd('key.list',['accepted'])  
>>> wheel.cmd('key.delete',[minion_id])  

  

 

def list_all_key(self):
    params={'client':'wheel','fun':'key.list_all'}
    obj=urllib.urlencode(params)
    content = self.postRequest(obj)
    minions = content['return'][0]['data']['return']['minions'] 
    minions_pre = content['return'][0]['data']['return']['minions_pre']
    return minons,minions_pre

params={'client':'wheel','fun':'key.delete','match':node_name}
params={'client':'wheel','fun':'key.accept','match':node_name}
client:
>>> import salt.client
>>> local = salt.client.LocalClient()
>>> local.cmd('*', 'cmd.run', ['whoami'])
local.cmd('*', 'test.ping')

  

自2017.x版本后 参数expr_form ==> tgt_type
# 组
local.cmd('website','cmd.run',['ls -al'],expr_form='nodegroup')

# minion列表
local.cmd(hosts,'test.ping',[],expr_form='list')

# 多个命令
client.cmd('*', ['cmd.run', 'test.ping', 'test.echo'], [['ls -l'], [], ['foo']])

# cmd.script
local.cmd('website1','cmd.script',['salt://MyScript.sh','-o'])

>>> local.cmd('website1','cmd.run',['su - ecp -c whoami'])
{'website1': 'ecp'}

# salt-ssh 的调用方法
from salt.client.ssh.client import SSHClient
client = SSHClient()
print client.cmd(tgt='192.168.21.1', fun='test.ping') 
{'192.168.21.1': {'fun_args': [], 'jid': '20151120134918813118', 'return': True, 'retcode': 0, 'fun': 'test.ping', 'id': '192.168.21.1'}}
print client.cmd(tgt='192.168.21.1', fun='cmd.run',arg=['uptime']) 
{'192.168.21.1': {'fun_args': ['uptime'], 'jid': '20151121062535759565', 'return': ' 06:25:35 up 18 days, 15:33, 0 users, load average: 0.13, 0.11, 0.09', 'retcode': 0, 'fun': 'cmd.run', 'id': '192.168.21.1'}}
  
import salt.grains.core
hostname = salt.grains.core.hostname()['fqdn']

# 查看本地是不是有这个命令
>>> import salt.utils
>>> salt.utils.which('dig')
'/usr/bin/dig'

# 自带的json方法
import salt.utils.json
salt.utils.json.dumps(ret)

  

 

 

  

posted @ 2019-12-20 23:11  richardzgt  阅读(457)  评论(0编辑  收藏  举报