zoukankan      html  css  js  c++  java
  • 从零开始搭建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,依次循环。

  • 相关阅读:
    二分图 洛谷P2055 [ZJOI2009]假期的宿舍
    并查集 洛谷P1640 [SCOI2010]连续攻击游戏
    贪心 洛谷P2870 Best Cow Line, Gold
    贪心 NOIP2013 积木大赛
    快速幂 NOIP2013 转圈游戏
    倍增LCA NOIP2013 货车运输
    树形DP 洛谷P2014 选课
    KMP UVA1328 Period
    动态规划入门 BZOJ 1270 雷涛的小猫
    KMP POJ 2752Seek the Name, Seek the Fame
  • 原文地址:https://www.cnblogs.com/agnewee/p/6492887.html
Copyright © 2011-2022 走看看