zoukankan      html  css  js  c++  java
  • saltstack-REST_CHERRYPYI接口

    https://docs.saltstack.com/en/latest/ref/netapi/all/salt.netapi.rest_cherrypy.html#rest-cherrypy

    安装:

    以下步骤都是在 Salt Master daemon上执行。

    yum install pyOpenSSL -y
    yum install salt-api -y
    salt-call tls.create_self_signed_cert
    #安装SSL,API,生成cert证书
    

      

    [root@webmaster master.d]# cat /etc/salt/master.d/api.conf 
    rest_cherrypy:  
      port: 8080
      ssl_crt: /etc/pki/tls/certs/localhost.crt  
      ssl_key: /etc/pki/tls/certs/localhost.key
    external_auth:  
      pam:  
        saltapi:            
          - .*
          - '@wheel'
          - '@runner'
    #配置api接口
    

     

    useradd -M -s /sbin/nologin saltapi
    echo 'saltapi_password'|passwd saltapi --stdin
    systemctl start salt-api
    #创建账户,启动api
    

      

    systemctl restart salt-master
    #重启salt
    

      

    认证:

    认证就是每个请求传递一个session token。token由login URl产生。

    使用自定义请求头传递token,名为:X-Auth-Token

    [root@webmaster master.d]# curl -k https://192.168.10.10:8080/login  -H "Accept: application/x-yaml" -d username='saltapi' -d password='saltapi_password' -d eauth='pam' 
    return:
    - eauth: pam
      expire: 1544643349.771802
      perms:
      - .*
      - '@wheel'
      - '@runner'
      start: 1544600149.771802
      token: 431584acdd199e5d1013f853a6066a896b177ed7
      user: saltapi
    #连接测试
    #生成token
    

      

    调用API

    逻辑是,先使用用户名和密码拿到一个token,然后拿这个token去调用api

    curl -k https://192.168.10.10:8080  -H "Accept: application/x-yaml" -H "X-Auth-Token: f6e4e2313a9ab06153fc5c4e065cb9e9e94a86b9" -d client='local' -d tgt='192.168.10.10' -d fun='cmd.run'  -d arg='netstat -lntp| wc -l'
    

      

     

    saltapi.py

    #python3x
    import urllib,json
    import urllib.request
    import urllib.parse
    import ssl
    
    ssl._create_default_https_context = ssl._create_unverified_context
    
    
    class SaltAPI(object):
        __token_id = ''
    
        def __init__(self,url,username,password):
            self.__url = url.rstrip('/')
            self.__user = username
            self.__password = password
    
        def token_id(self):
            """
                用户登陆和获取token
            :return:
            """
            params = {'eauth': 'pam', 'username': self.__user, 'password': self.__password}
            encode = urllib.parse.urlencode(params)
            obj = urllib.parse.unquote(encode).encode('utf-8')
            content = self.postRequest(obj, prefix='/login')
            try:
                self.__token_id = content['return'][0]['token']
            except KeyError:
                raise KeyError
    
        def postRequest(self,obj,prefix='/'):
            url = self.__url + prefix
            headers = {'X-Auth-Token': self.__token_id}
            req = urllib.request.Request(url, obj, headers)
            opener = urllib.request.urlopen(req)
            content = json.loads(opener.read().decode('utf-8'))
            return content
    
        def list_all_key(self):
            """
                获取包括认证、未认证salt主机
            """
    
            params = {'client': 'wheel', 'fun': 'key.list_all'}
            obj = urllib.parse.urlencode(params).encode('utf-8')
            self.token_id()
            content = self.postRequest(obj)
            minions = content['return'][0]['data']['return']['minions']
            minions_pre = content['return'][0]['data']['return']['minions_pre']
            return minions, minions_pre
    
        def delete_key(self, node_name):
            '''
                拒绝salt主机
            '''
    
            params = {'client': 'wheel', 'fun': 'key.delete', 'match': node_name}
            obj = urllib.parse.urlencode(params).encode('utf-8')
            self.token_id()
            content = self.postRequest(obj)
            ret = content['return'][0]['data']['success']
            return ret
    
        def accept_key(self,node_name):
            '''
                接受salt主机
            '''
    
            params = {'client': 'wheel', 'fun': 'key.accept', 'match': node_name}
            obj = urllib.parse.urlencode(params).encode('utf-8')
            self.token_id()
            content = self.postRequest(obj)
            ret = content['return'][0]['data']['success']
            return ret
    
        def salt_get_jid_ret(self,jid):
            """
                通过jid获取执行结果
            :param jid: jobid
            :return: 结果
            """
            params = {'client':'runner', 'fun':'jobs.lookup_jid', 'jid': jid}
            obj = urllib.parse.urlencode(params).encode('utf-8')
            self.token_id()
            content = self.postRequest(obj)
            ret = content['return'][0]
            return ret
    
        def salt_running_jobs(self):
            """
                获取运行中的任务
            :return: 任务结果
            """
            params = {'client':'runner', 'fun': 'jobs.active'}
            obj = urllib.parse.urlencode(params).encode('utf-8')
            self.token_id()
            content = self.postRequest(obj)
            ret = content['return'][0]
            return ret
    
        def remote_noarg_execution_sigle(self, tgt, fun):
            """
                单台minin执行命令没有参数
            :param tgt: 目标主机
            :param fun:  执行模块
            :return: 执行结果
            """
            params = {'client': 'local', 'tgt': tgt, 'fun': fun}
            obj = urllib.parse.urlencode(params).encode('utf-8')
            self.token_id()
            content = self.postRequest(obj)
            # print(content)
            # {'return': [{'salt-master': True}]}
            ret = content['return'][0]
            return ret
    
        def remote_execution_single(self, tgt, fun, arg):
            """
                单台minion远程执行,有参数
            :param tgt: minion
            :param fun: 模块
            :param arg: 参数
            :return: 执行结果
            """
            params = {'client': 'local', 'tgt': tgt, 'fun': fun, 'arg': arg}
            obj = urllib.parse.urlencode(params).encode('utf-8')
            self.token_id()
            content = self.postRequest(obj)
            # print(content)
            # {'return': [{'salt-master': 'root'}]}
            ret = content['return']
            return ret
    
        def remote_async_execution_module(self, tgt, fun, arg):
            """
                远程异步执行模块,有参数
            :param tgt: minion list
            :param fun: 模块
            :param arg: 参数
            :return: jobid
            """
            params = {'client': 'local_async', 'tgt': tgt, 'fun': fun, 'arg': arg, 'expr_form': 'list'}
            obj = urllib.parse.urlencode(params).encode('utf-8')
            self.token_id()
            content = self.postRequest(obj)
            # print(content)
            # {'return': [{'jid': '20180131173846594347', 'minions': ['salt-master', 'salt-minion']}]}
            jid = content['return'][0]['jid']
            return jid
    
        def remote_execution(self, tgt, fun, arg):
            """
                远程执行模块,有参数
            :param tgt: minion list
            :param fun: 模块
            :param arg: 参数
            :return: dict, {'minion1': 'ret', 'minion2': 'ret'}
            """
            params = {'client': 'local', 'tgt': tgt, 'fun': fun, 'arg': arg, 'expr_form': 'list'}
            obj = urllib.parse.urlencode(params).encode('utf-8')
            self.token_id()
            content = self.postRequest(obj)
            # print(content)
            # {'return': [{'salt-master': 'root', 'salt-minion': 'root'}]}
            ret = content['return'][0]
            return ret
    
        def salt_state(self, tgt, arg, expr_form):
            '''
            sls文件
            '''
            params = {'client': 'local', 'tgt': tgt, 'fun': 'state.sls', 'arg': arg, 'expr_form': expr_form}
            obj = urllib.parse.urlencode(params).encode('utf-8')
            self.token_id()
            content = self.postRequest(obj)
            ret = content['return'][0]
            return ret
    
        def salt_alive(self, tgt):
            '''
            salt主机存活检测
            '''
            params = {'client': 'local', 'tgt': tgt, 'fun': 'test.ping'}
            obj = urllib.parse.urlencode(params).encode('utf-8')
            self.token_id()
            content = self.postRequest(obj)
            ret = content['return'][0]
            return ret
    
    
    def main():
    
        sapi = SaltAPI(url='ip:port',username='username',password='password')
        # name = sapi.remote_execution('*','cmd.run','df')
        #
        # print(name)
    
    if __name__ == '__main__':
        main()
    

      

  • 相关阅读:
    诺基亚为 Qt 增添 LGPL 授权选择
    Web Beans (JSR299): Q&A with Specification Lead Gavin King
    Web Beans (JSR299): Q&A with Specification Lead Gavin King
    诺基亚为 Qt 增添 LGPL 授权选择
    使用 Hibernate 进行大数据量的性能测试
    略谈如何在对话框创建视图类画图
    JBoss Seam 框架下的单元测试
    领域模型设计讨论与研究
    JBoss Seam 框架下的单元测试
    The use of FS/GS registers
  • 原文地址:https://www.cnblogs.com/jabbok/p/10024917.html
Copyright © 2011-2022 走看看