salt-api 使用(福利版)


寫在前面的話:

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

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

一、salt認證

依賴:

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

安裝及配置:

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

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

  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 進程。

二、使用

開始使用之路吧。

  首先是服務端認證,通過每個請求傳遞會話令牌來執行身份驗證,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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM