salt-api 使用(福利版)

寫在前面的話:html

  salt-api是一個基於Cherrypy(python的一個web框架)的Rest API程序。node

  注意:CherryPy版本3.2.5到3.7.x有一個已知的SSL追溯請使用3.2.3版本或最新的10.x版本。python

1、salt認證

依賴:git

  salt-api依賴的模塊是Cherrypy,用於支持websockets的ws4py python模塊(可選)github

安裝及配置:
web

  salt-api 運行在Salt Master程序的機器上。json

  1. 安裝salt-api,須要確保salt-api 與salt版本一致。api

  2. 安裝Cherrypy,ws4py(可選)。數組

  3. 生成自簽名證書(可選)。建議使用安全的HTTPS鏈接,由於salt eauth 身份驗證憑證將經過線路發送。緩存

      ①.安裝 pyOpenSSL 包。

      ②.使用create_self_signed_cert() 執行功能生成自簽名證書。

salt-call --local tls.create_self_signed_cert

  4. 編輯配置文件添加至少一個外部認證用戶或組。詳情這裏

  5. salt-master配置文件添加以下配置來啓用rest_cherrypy模塊。

rest_cherrypy:
  port: 8000
  ssl_crt: /etc/pki/tls/certs/localhost.crt
  ssl_key: /etc/pki/tls/certs/localhost.key

  6. 重啓salt-master 進程。

  7. 重啓salt-api 進程。

2、使用

開始使用之路吧。

  首先是服務端認證,經過每一個請求傳遞會話令牌來執行身份驗證,token經過Login URL生成。

token認證採用兩種方法發送:一種是hearder頭添加認證token,另外一種做爲會話cookie。

用法:

  請求主體必須是一組命令。使用此工做流程來構建命令:

    1. 選擇一個客戶端界面。

    2. 選擇一個功能。

    3.填寫所選客戶端所需的其他參數。

client字段是對Salt的python api中使用的主要python類的引用。

  local:向本地發送命令的「本地」使用。等同於salt 命令。

  runner:調用master的runner 模塊。等同於salt-run命令。

  wheel:調用master的wheel模塊。wheel沒有知己額的CLI命令,它一般廣利Master-side資源,例如狀態文件,支柱文件,salt配置文件,以及salt-key相似的功能。

 

在執行LocalClient,它須要將命令轉發給Minions,因此須要tgt參數來指定minionid.

           也須要arg(數組)和kwarg(以前)參數,這些值被髮送到minions並用做請求函數的參數。

RunnerClient和WheelClient直接在Master上執行,所以不須要接受這些參數。

header頭設置

  REST接口在接受什麼樣的數據格式以及它將返回什麼格式(例如,JSON,YAML,urlencoded)方面是靈活的

    經過包含Content-type頭來指定請求正文中的數據格式。

    使用Accept頭指定相應主體所需的數據格式。

關於CherryPy的併發

  CherryPy服務器是一個生成就緒的線程HTTP服務器,用Python編寫。它使用線程池來處理HTTP請求,因此不適合維護大量的併發同步鏈接,在配置默認設置的中等硬件上,他最高大約30到50個併發鏈接。

  注意:每一個salt的命令運行都會啓動一個實例化的進程(LocalClient),它將本身的監聽器實例化爲salt事件總線,併發出本身的週期性salturil.find_job查詢來肯定Minion是否仍在運行該命令,不徹底是一個輕量級操做。

超時

  CherryPy還能夠設置HTTP超時時間。LocalClient和RunnerClient均可以在頂級關鍵字(timeout)中設置本身的超時參數。

異步操做

  因爲性能開銷和HTTP超時,長時間運行上述操做,可使用local_asyn,runner_asyn,wheel_asyn進行異步方式運行更能節省開銷。執行結果能夠經過 /jobs/<jid> URL 從緩存中獲取,也可使用salt的Rerutner 系統收集到數據存儲中。

  /events URL專門用戶處理長時間運行的HTTP請求,幷包含了做業返回的salt事件總線,但該操做具備不一樣步性。

性能調整

  設置thread_pool和socket_queue_size 能夠用來增長處理傳入請求的rest_cherrypy的能力。設置這些配置時須要留意RAM的使用狀況以及可用文件句柄。因爲salt-api是基於salt使用,同時還須要考慮salt的性能。

下面福利時間:

  下面的代碼大概整合了一些常用的api,送給你們。

 

    未完待續。。。

  1 #!/usr/bin/env python
  2 # -*- coding:utf-8 -*-
  3 __author__ = '40kuai'
  4 __version__ = 'v0.0.1'
  5 """
  6 1. 整合 salt-api 功能
  7 2. 獲取token屢次使用,發現token過時後從新獲取token從當前失敗任務從新繼續執行
  8 3. 可選:出現接口或服務異常(501),本次操做嘗試幾回從新執行
  9 arg 爲模塊須要傳入的參數,kwargs爲pillar或grains參數。
 10 
 11 分爲如下幾個類:
 12     1. salt-api 方法類
 13     2. 發送請求的類
 14 """
 15 
 16 from urlparse import urljoin
 17 import requests
 18 
 19 
 20 class Salt_Api():
 21     def __init__(self, url, username, password):
 22         self.url = url
 23         self._username = username
 24         self._password = password
 25         self.get_token()
 26 
 27     def get_token(self, eauth='pam', ):
 28         """獲取salt-api使用的token"""
 29         get_token_url = urljoin(self.url, 'login')
 30         json_data = {'username': self._username, 'password': self._password, 'eauth': eauth}
 31         token_obj = requests.post(get_token_url, json=json_data, verify=False)
 32         if token_obj.status_code != 200:
 33             raise Exception(token_obj.status_code)
 34         self.token = token_obj.json()['return'][0]['token']
 35 
 36     def post(self, prefix='/', json_data=None, headers=None):
 37         post_url = urljoin(self.url, prefix)
 38         if headers is None:
 39             headers = {'X-Auth-Token': self.token, 'Accept': 'application/json'}
 40         else:
 41             headers = {'X-Auth-Token': self.token, }.update(headers)
 42         post_requests = requests.post(post_url, json=json_data, headers=headers, verify=False)
 43         return post_requests.json()
 44 
 45     def get(self, prefix='/', json_data=None, headers=None):
 46         post_url = urljoin(self.url, prefix)
 47         if headers is None:
 48             headers = {'X-Auth-Token': self.token, 'Accept': 'application/json'}
 49         else:
 50             headers = {'X-Auth-Token': self.token, }.update(headers)
 51         get_requests = requests.get(post_url, json=json_data, headers=headers, verify=False)
 52         return get_requests.json()
 53 
 54     def get_all_key(self):
 55         """獲取全部minion的key"""
 56         json_data = {'client': 'wheel', 'fun': 'key.list_all'}
 57         content = self.post(json_data=json_data)
 58         minions = content['return'][0]['data']['return']['minions']
 59         minions_pre = content['return'][0]['data']['return']['minions_pre']
 60         return minions, minions_pre
 61 
 62     def accept_key(self, minion_id):
 63         """認證minion_id,返回Ture or False"""
 64         json_data = {'client': 'wheel', 'fun': 'key.accept', 'match': minion_id}
 65         content = self.post(json_data=json_data)
 66         return content['return'][0]['data']['success']
 67 
 68     def delete_key(self, node_name):
 69         """刪除minion_id,返回Ture or False"""
 70         json_data = {'client': 'wheel', 'fun': 'key.delete', 'match': node_name}
 71         content = self.post(json_data=json_data)
 72         return content['return'][0]['data']['success']
 73 
 74     def host_remote_module(self, tgt, fun, arg=None):
 75         """根據主機執行函數或模塊,模塊的參數爲arg"""
 76         json_data = {'client': 'local', 'tgt': tgt, 'fun': fun, }
 77         if arg:
 78             json_data.update({'arg': arg})
 79         content = self.post(json_data=json_data)
 80         return content['return']
 81 
 82     def group_remote_module(self, tgt, fun, arg=None):
 83         """根據分組執行函數或模塊,模塊的參數爲arg"""
 84         json_data = {'client': 'local', 'tgt': tgt, 'fun': fun, 'expr_form': 'nodegroup'}
 85         if arg:
 86             json_data.update({'arg': arg})
 87         content = self.post(json_data=json_data)
 88         return content['return']
 89 
 90     def host_sls_async(self, tgt, arg):
 91         '''主機異步sls '''
 92         json_data = {'client': 'local_async', 'tgt': tgt, 'fun': 'state.sls', 'arg': arg}
 93         content = self.post(json_data=json_data)
 94         return content['return']
 95 
 96     def group_sls_async(self, tgt, arg):
 97         '''分組異步sls '''
 98         json_data = {'client': 'local_async', 'tgt': tgt, 'fun': 'state.sls', 'arg': arg, 'expr_form': 'nodegroup'}
 99         content = self.post(json_data=json_data)
100         return content['return']
101 
102     def server_hosts_pillar(self, tgt, arg, **kwargs):
103         '''針對主機執行sls and pillar '''
104         print kwargs
105         kwargs = {'pillar': kwargs['kwargs']}
106         json_data = {"client": "local", "tgt": tgt, "fun": "state.sls", "arg": arg, "kwarg": kwargs}
107         content = self.post(json_data=json_data)
108         return content['return']
109 
110     def server_group_pillar(self, tgt, arg, **kwargs):
111         '''分組進行sls and pillar'''
112         kwargs = {'pillar': kwargs['kwargs']}
113         json_data = {'client': 'local', 'tgt': tgt, 'fun': 'state.sls', 'arg': arg, 'expr_form': 'nodegroup',
114                      'kwarg': kwargs}
115         content = self.post(json_data=json_data)
116         return content['return']
117 
118     def jobs_all_list(self):
119         '''打印全部jid緩存'''
120         json_data = {"client": "runner", "fun": "jobs.list_jobs"}
121         content = self.post(json_data=json_data)
122         return content['return']
123 
124     def jobs_jid_status(self, jid):
125         '''查看jid運行狀態'''
126         json_data = {"client": "runner", "fun": "jobs.lookup_jid", "jid": jid}
127         content = self.post(json_data=json_data)
128         return content['return']
129 
130     def keys_minion(self, hostname):
131         """Show the list of minion keys or detail on a specific key"""
132         content = self.get('keys/%s' % hostname)
133         return content
134 
135 
136 if __name__ == '__main__':
137     url = 'https://local:8000/'
138     obj = Salt_Api(url, 'username', 'password')
139     print obj.keys_minion('minionid')
salt-api
相關文章
相關標籤/搜索