• 从零开始搭建Salt Web之封装salt-api接口


    salt-api现在已经正常运行,接下来则是实现通过调用salt-api来执行salt命令。

    调用salt-api执行命令时,记得携带c_path参数

    因为salt中自带了tornado这个库,所以决定基于tornado.httpclient来封装HTTP请求。

    交互模式:

    >>> import json
    >>> from tornado.httpclient import HTTPClient, HTTPRequest
    >>> client = HTTPClient()
    # 请求头中声明通过json提交内容
    >>> headers = {'Content-Type': 'application/json'} 
    >>> body1 = {'username': 'salttest', 'password': 'password', 'eauth': 'pam'}
    >>> url = 'https://localhost:8090/'
    # 这里指定需指定validate_vert=False, 否则HTTPClient无法访问https
    >>> request1 = HTTPRequest(url=url+'login', method='POST', headers=headers, body=json.dumps(body), validate_cert=False)
    >>> response1 = client.fetch(request1)
    >>> response1.body
    '{"return": [{"perms": [".*"], "start": 1488443323.968138, 
    "token": "0daf377b4611db***8419f515d18744338", 
    "expire": 1488486523.968139, "user": "uyun", "eauth": "pam"}]}'
    >>> headers['X-Auth-Token'] = '0daf377b4611db***8419f515d18744338'
    >>> body2 = {'client': 'local', 'tgt': '*', 'fun': 'test.ping', 'c_path': '/root/SaltWeb/conf'}
    >>> request2 = HTTPRequest(url=url, method='POST', headers=headers, body=json.dumps(body), validate_cert=False)
    >>> response2 = client.fetch(request2)
    >>> response2.body
    '{"return": [{"10.1.240.213": "localhost.localdomain"}]}'
    

    以上就是大致流程,接下来对操作进行简单的封装。

    # coding: utf-8
    import json
    from urlparse import urljoin
    from tornado.httpclient import HTTPClient, HTTPRequest, HTTPError
    
    
    class SaltClient(object):
        def __init__(self, url, username, password, c_path=None):
            self._url = url
            self._un = username
            self._pw = password
            self._cpath = c_path
    
            self._token = None
        
        @property
        def headers(self):
            headers = {'Content-Type': 'application/json',
                       'Accept': 'application/json'}
            if self._token:
                headers['X-Auth-Token'] = self._token
            return headers
        
        def get_token(self):
            url = urljoin(self._url, 'login')
            params = {'username': self._un,
                    'password': self._pw,
                    'eauth': 'pam'}
            response = self.post(url, params)
            return response['return'][0]['token']
        
        def _request(self, url, method, body, validate_cert=False, **kwargs):
            return HTTPRequest(url=url,
                               method=method,
                               headers=self.headers,
                               body=json.dumps(body),
                               validate_cert=validate_cert,
                               **kwargs)
        
        def post(self, url, params):
            client = HTTPClient()
            try:
                request = self._request(url, 'POST', params)
                response = client.fetch(request).body
            except HTTPError as e:
                if e.code == 401:
                    self._token = self.get_token()
                    response = self.post(url, params)
                else:
                    raise
            if isinstance(response, str):
                response = json.loads(response)
            return response
        
        def cmd(self, client, tgt, fun, arg=None, **kwargs):
            params = {'client': client, 'tgt': tgt, 'fun': fun}
            if arg:
                params['arg'] = arg
            if self._cpath:
                params['c_path'] = self._cpath
            ret = self.post(self._url, params)
            return ret['return']
    

    逻辑很简单,主要通过调用cmd()方法执行命令,因为token存在时效性,当token过期时,
    调用命令会抛出401错误授权的异常,捕获到之后重新获取一次token,依次循环。

  • 相关阅读:
    决策树(chap3)Machine Learning In Action学习笔记
    AdaBoost-Machine Learning In Action学习笔记
    支持向量机-Machine Learning In Action学习笔记
    Alamofire 4.0 迁移指南
    从VSS到SVN再到Git 记Git的基本操作
    倍杀测量者
    P3166 数三角形
    APIO2014 序列分割(斜率优化好题)
    P3694 邦邦的大合唱站队
    ACwing 298 栅栏(单调队列DP)
  • 原文地址:https://www.cnblogs.com/agnewee/p/6492887.html
Copyright © 2020-2023  润新知