A REST API FOR SALT
截止當前,cherrypy的REST API方案是最爲成熟的,也是Salt官方更爲推薦使用的一個REST API實現方案。
您也可以參考在Github上維護的這一份技術資料:rest_cherrypy
文章目錄
Install and configuration - 安裝與配置
depends - 必需依賴
-
CherryPy Python module.
注意: 有一個已知的 SSL traceback 功能bug存在於 CherryPy versions 3.2.5 到 3.7.x之間的版本中,請使用版本 3.2.3 或者是最新的 10.x 版本。
optdepends - 可選依賴
- ws4py Python module for websockets support.
client_libraries - 客戶端工具
- Java: https://github.com/SUSE/salt-netapi-client
- Python: https://github.com/saltstack/pepper
setup - 安裝 REST_CHERRYPY
以下所有步驟均在運行Salt Master守護程序的計算機上執行。 配置則整合進了master配置文件中。
- 安裝
salt-api
。 (此步驟在OS和Linux發行版之間有所不同。某些軟件包系統有一個分離的軟件包,其他軟件包系統在主Salt軟件包中包含salt-api。確保salt-api --version
輸出與salt --version
輸出信息相匹配。) - 安裝 CherryPy。(閱讀以上部分中的版本使用警告。)
- 可選的配置: 生成自籤的 SSL 證書。強烈建議使用安全的HTTPS連接,因爲Salt eauth身份驗證憑據將通過網絡發送。
- 安裝 PyOpenSSL 軟件包。
- 使用執行模塊函數 create_self_signed_cert() 生成一個自籤的數據證書。
salt-call --local tls.create_self_signed_cert
- 按照 External Authentication System - 使用外部身份認證系統,編輯master配置以創建至少一個支持外部身份驗證的用戶或組。
- 使用下面一個面向生產環境的示例編輯master配置,以啓用
rest_cherrypy
模塊。 (根據需要調整證書路徑,或禁用SSL(不推薦!)。
rest_cherrypy:
port: 8000
ssl_crt: /etc/pki/tls/certs/localhost.crt
ssl_key: /etc/pki/tls/certs/localhost.key
- 重啓
salt-master
服務進程。 - 啓動
salt-api
服務進程。
configuration - 配置 REST_CHERRYPY
下面詳細介紹了所有可用的配置選項。 這些設置用於配置CherryPy HTTP服務器,在使用外部服務器(例如Apache或Nginx)時不適用。
-
port
必需配置項。指定webserver的服務端口。
-
host
0.0.0.0
HTTP服務器偵聽的套接字接口。
-
debug
False
在開發模式下啓動Web服務器。 當底層代碼更改時,它將重新加載自身,並輸出更多的調試信息。
-
log_access_file
寫入HTTP訪問日誌的文件的路徑。
New in version 2016.11.0.
-
log_error_file
寫入HTTP錯誤日誌的文件的路徑。
New in version 2016.11.0.
-
ssl_crt
定義 SSL 證書文件的路徑。 (See below)
-
ssl_key
定義SSL certificate 證書的私鑰文件的路徑。 (See below)
-
ssl_chain
(使用PyOpenSSL時是可選的)傳遞給Context.load_verify_locationsr 的證書鏈。
-
disable_ssl
一個禁用SSL的配置項。警告: 你的 Salt 認證信息將會以明文發送!
-
webhook_disable_auth
False
Webhook URL默認情況下需要身份驗證,但是不能始終將外部服務配置爲發送身份驗證。 請參閱下文中的Webhook文檔以獲取有關保護此接口的建議。
-
webhook_url/hook
配置Webhook入口點的URL端點。
-
thread_pool
100
定義在線程池中使用的併發線程數。
-
socket_queue_size
30
指定HTTP連接隊列的最大值。
-
expire_responses
True
是否檢查並殺死超過默認超時時間的HTTP響應。
自2016.11.9,2017.7.3,2018.3.0版本以來已棄用:CherryPy中的expire_responses
功能上等同於CherryPy中的timeout_monitor
參數,在>=12.0.0的CherryPy版本中不再受支持。
-
max_request_body_size
1048576
HTTP request 請求允許攜帶的最大數據。
-
collect_stats
False
檢查和報告CherryPy服務器的統計數據。
報告可以通過訪問/stats
URL端點地址獲取。 -
stats_disable_auth
False
訪問
/stats
端點時不需要提供訪問認證信息。New in version 2018.3.0.
-
static
靜態HTML/JavaScript/CSS/image資產的文件系統路徑。
-
static_path
/static
訪問
static
設置中指定的目錄中提供靜態資產時使用的URL前綴。 -
enable_sessions
True
啓用或禁用所有依賴會話cookie的端點。 這對於執行僅基於headers的身份驗證可能很有用。
New in version 2017.7.0.
-
app
index.html
HTML文件的文件系統路徑,它將用作靜態文件。 這對於引導單頁JavaScript應用程序很有用。
警告! 如果將此選項設置爲自定義Web應用程序,則使用基於cookie的身份驗證的任何內容都容易受到XSRF攻擊。 建議發送自定義
X-Auth-Token
標頭,並考慮禁用enable_sessions
設置。Changed in version 2017.7.0: 增加一個 proof-of-concept JavaScript 單頁應用。
-
app_path
/app
用於提供在應用程序設置中指定的HTML文件的URL前綴。 這應該是一個不包含斜槓的簡單名稱。
指定路徑之後的所有路徑信息都將被忽略; 這對於使用HTML5歷史記錄API的應用程序很有用。
-
root_prefix
/
指向應用程序主入口點的URL路徑。 這對於從同一URL提供多個應用程序很有用。
Authentication - 認證
通過向每個請求傳遞會話令牌來執行認證的操作。 令牌是通過名爲Login的URL生成的。
令牌可以通過以下兩種方式之一發送:作爲自定義header或作爲會話cookie。 對於支持cookie的客戶端,後者要方便得多。
-
包括一個名爲
X-Auth-Token
屬性的自定義header。例如,使用curl:
curl -sSk https://localhost:8000/login \ -H 'Accept: application/x-yaml' \ -d username=saltdev \ -d password=saltdev \ -d eauth=pam
從輸出中複製
token
令牌值,並將其包含在後續的請求操作中:curl -sSk https://localhost:8000 \ -H 'Accept: application/x-yaml' \ -H 'X-Auth-Token: 697adbdc8fe971d09ae4c2a3add7248859c87079'\ -d client=local \ -d tgt='*' \ -d fun=test.ping
-
通過Cookie發送。 對於可以自動處理cookie支持的HTTP客戶端(例如瀏覽器),此選項會很方便。
例如,使用curl:
# Write the cookie file: curl -sSk https://localhost:8000/login \ -c ~/cookies.txt \ -H 'Accept: application/x-yaml' \ -d username=saltdev \ -d password=saltdev \ -d eauth=auto # Read the cookie file: curl -sSk https://localhost:8000 \ -b ~/cookies.txt \ -H 'Accept: application/x-yaml' \ -d client=local \ -d tgt='*' \ -d fun=test.ping
另外一個在Python中使用 requests類庫的例子:
>>> import requests >>> session = requests.Session() >>> session.post('http://localhost:8000/login', json={ 'username': 'saltdev', 'password': 'saltdev', 'eauth': 'auto', }) <Response [200]> >>> resp = session.post('http://localhost:8000', json=[{ 'client': 'local', 'tgt': '*', 'fun': 'test.arg', 'arg': ['foo', 'bar'], 'kwarg': {'baz': 'Baz!'}, }]) >>> resp.json() {u'return': [{ ...snip... }]}
See also:你還可以使用 Run URL來傳遞session會話數據,作爲POST數據中的一項鍵值。
Usage - 用法
該接口直接公開作爲Salt的Python API使用。 CLI可用的一切功能也都可以通過Python API實現。 命令是在Salt Master上執行。
根URL(/
)類似於RPC,因爲它在請求正文中接受有關要執行哪些Salt函數的指令,並且在響應中包含這些函數調用的結果。
例如:
% curl -sSi https://localhost:8000 -H 'Content-type: application/json' -d '[{
"client": "local",
"tgt": "*",
"fun": "test.ping"
}]'
HTTP/1.1 200 OK
Content-Type: application/json
[...snip...]
{"return": [{"jerry": true}]}
請求主體必須是命令數組。 使用下面這樣的工作流程來構建命令:
- 選擇一個客戶端接口
- 選擇一個功能函數
- 填充調用該接口需要提供的其它參數
client
字段是對Salt的Python API中使用的主要Python類的引用。詳情可以閱讀完整的客戶端API文檔,但簡而言之:
- “local” 使用LocalClient,它向Minions發送命令。等同於
salt
CLI命令。 - “runner” 使用RunnerClient,它在Master服務器上調用runner程序模塊。等同於使用
salt-run
CLI命令。 - “wheel” 使用WheelClient調用Master模塊上的wheel模塊。Wheel模塊沒有直接的CLI等效項,但是它們通常管理Master-side端資源,例如狀態文件、pillar文件、Salt配置文件,並且key wheel module模塊具有與
salt-key
CLI命令相似的管理功能。
大多數客戶端具有諸如同步執行或異步執行之類的變體,以及諸如批處理執行之類的其他變體。請參閱客戶端接口的完整列表。
每個客戶端需要不同的參數,有時具有不同的語法。例如,LocalClient
需要tgt
參數,因爲它將命令轉發給Minions,而其他客戶端接口則不需要。 LocalClient
還使用arg
(數組)和kwarg
(字典)參數,因爲這些值也需要被髮送到Minions,並用於在那裏執行請求的功能。 RunnerClient
和WheelClient
直接在Master服務器上執行,因此不需要或不接受這些參數。
閱讀上面鏈接的客戶端文檔中的方法簽名,但是希望有一個示例可以幫助說明該概念。這個例子使用Salt執行兩個函數-使用LocalClient執行的test.arg execution函數和使用RunnerClient執行的test.arg Runner函數;注意每個命令的結構不同。兩者的結果合併並作爲一個響應返回。
% curl -b ~/cookies.txt -sSi localhost:8000 -H 'Content-type: application/json' -d '
[
{
"client": "local",
"tgt": "*",
"fun": "test.arg",
"arg": ["positional arg one", "positional arg two"],
"kwarg": {
"keyword arg one": "Hello from a minion",
"keyword arg two": "Hello again from a minion"
}
},
{
"client": "runner",
"fun": "test.arg",
"keyword arg one": "Hello from a master",
"keyword arg two": "Runners do not support positional args"
}
]
'
HTTP/1.1 200 OK
[...snip...]
{
"return": [
{
"jerry": {
"args": [
"positional arg one",
"positional arg two"
],
"kwargs": {
"keyword arg one": "Hello from a minion",
"keyword arg two": "Hello again from a minion",
[...snip...]
}
},
[...snip; other minion returns here...]
},
{
"args": [],
"kwargs": {
"keyword arg two": "Runners do not support positional args",
"keyword arg one": "Hello from a master"
}
}
]
}
另一個例子, 這次使用更常見的功能函數:
curl -b /tmp/cookies.txt -sSi localhost:8000 -H 'Content-type: application/json' -d '
[
{
"client": "local",
"tgt": "*",
"fun": "state.sls",
"kwarg": {
"mods": "apache",
"pillar": {
"lookup": {
"wwwdir": "/srv/httpd/htdocs"
}
}
}
},
{
"client": "runner",
"fun": "cloud.create",
"provider": "my-ec2-provider",
"instances": "my-centos-6",
"image": "ami-1624987f",
"delvol_on_destroy", true
}
]
'
HTTP/1.1 200 OK
[...snip...]
{
"return": [
{
"jerry": {
"pkg_|-install_apache_|-httpd_|-installed": {
[...snip full state return here...]
}
}
[...snip other minion returns here...]
},
{
[...snip full salt-cloud output here...]
}
]
}
Content negotiation - 內容協商
這個REST接口可以靈活接受各種數據格式,以及可以傳回的格式(例如JSON,YAML和urlencoded)。
- 通過包含Content-Type header來指定請求正文中的數據格式。
- 使用Accept header爲響應主體指定所需的數據格式。
對於大多數HTTP請求,我們建議使用JSON格式。 urlencoded數據很簡單,不能表示複雜的數據結構 - 而這對於某些Salt命令來說通常是必需的,例如啓動使用Pillar數據的狀態運行。 Salt的CLI工具可以將在CLI處傳遞的字符串重新格式化爲複雜的數據結構,並且該行爲也可以通過salt-api起作用,但這可能很脆弱。因爲salt-api可以接受JSON,所以最好僅發送JSON。
下面是發送urlencoded數據的示例:
curl -sSik https://localhost:8000 \
-b ~/cookies.txt \
-d client=runner \
-d fun='jobs.lookup_jid' \
-d jid='20150129182456704682'
注意:urlencoded數據警告
-
每個HTTP請求只能發送一個命令。
-
多次重複
arg
參數將導致這些參數組合到一個列表中。注意,一些流行的框架和語言(特別是jQuery,PHP和Ruby on Rails)會自動將空括號附加到重複的查詢字符串參數上。 例如,
?foo[]=fooone&foo[]=footwo
。,而這是不支持的。請發送?foo=fooone&foo=footwo
,或者發送JSON或YAML。
關於使用curl
的注意事項
curl的-d
標誌不會自動對可能影響密碼和包含必須編碼字符的其他數據的數據進行urlencode。 請改用--data-urlencode
標誌。 例如。:
curl -ksi http://localhost:8000/login \
-H "Accept: application/json" \
-d username='myapiuser' \
--data-urlencode password='1234+' \
-d eauth='pam'
Performance Expectations and Recommended Usage
性能期望和推薦用法
該模塊提供了Salt的Python API的精簡包裝。 通過rest_cherrypy執行Salt命令直接類似於通過Salt的CLI(也使用Python API)執行Salt命令-它們共享相同的語義、性能特徵以及98%的相同代碼。 作爲一個經驗法則:如果您不打算在CLI上執行此操作,請也不要通過此API進行操作。
Long-Running HTTP Connections - 需要長時間運行的HTTP連接
CherryPy服務器是用Python編寫的可用於生產環境的線程HTTP服務器。 因爲它利用線程池來處理HTTP請求,所以它不適合維護大量併發的同步連接。 在具有默認設置的中型硬件設備上,它應該在大約30到50個併發連接時達到性能頂峯。
這麼長時間運行的Salt同步過程也不理想。 像在CLI中一樣,每次Salt命令運行都會啓動一個實例化自己的LocalClient
的進程,該進程實例化自己對Salt事件總線的偵聽器,併發出自己的定期saltutil.find_job
查詢以確定Minion是否仍在運行該命令 。 不完全是輕量級的操作。
Timeouts - 超時
除了上述用於長時間運行的連接的資源開銷外,CherryPy服務器,使用的任何HTTP客戶端以及介於兩者之間的任何硬件(例如代理、網關或負載均衡器)都有常用的HTTP超時語義。 可以將rest_cherrypy配置爲不通過expire_responses
設置使長響應超時,並且LocalClient和RunnerClient都有自己的超時參數,可以將其作爲頂級關鍵字傳遞:
curl -b /tmp/cookies.txt -sSi localhost:8000 -H 'Content-type: application/json' -d '
[
{
"client": "local",
"tgt": "*",
"fun": "test.sleep",
"kwarg": {"length": 30},
"timeout": 60
},
{
"client": "runner",
"fun": "test.sleep",
"kwarg": {"s_time": 30},
"timeout": 60
}
]
'
Best Practices - 最佳實踐
考慮到上述長時間運行的操作的性能開銷和HTTP超時,使用Salt和salt-api的最有效、最可擴展的方法是使用local_async
,runner_async
和wheel_async
客戶端異步運行命令。
運行異步作業可以使LocalClient
每秒處理的命令數量增加3倍
,而RunnerClient
每秒處理的命令數量增加17倍
,此外,網絡流量和內存需求也要少得多。可以通過/jobs/<jid>
端點從Salt的作業緩存中獲取作業返回,或者可以使用Salt的Returner
系統將其收集到數據存儲中。
/events
端點專門用於處理長時間運行的HTTP連接,它公開了Salt的事件總線,其中包括作業返回。首先觀看此端點,然後再執行異步Salt命令,是使用rest_cherrypy
的最輕便和可擴展的方式,同時仍實時接收作業返回。但這要求客戶端能夠正確處理該工作流的固有異步性。
Performance Tuning - 性能調優
可以使用thread_pool
和socket_queue_size
設置來增加rest_cherrypy處理傳入請求的能力。測試這些設置的更改時,請密切注意RAM使用情況以及可用的文件句柄。由於salt-api是Salt的Python API的簡單包裝,因此在測試時也請注意Salt的性能。
Future Plans - 未來的計劃
既然Salt已經在內部使用Tornado併發庫,我們計劃通過利用現有流程和事件偵聽器來提高API的性能,並使用輕量級協程來促進更多同時HTTP連接和更好地支持同步操作。可以在 issue 26505 中跟蹤該工作,但是在該問題解決之前,rest_cherrypy將仍然是官方推薦的REST API。
Deployment
部署方式的說明
rest_cherrypy
netapi模塊是標準的Python WSGI應用程序。 可以採用以下兩種方法之一進行部署。
使用CherryPy服務器的salt-api
默認配置是在Salt master節點上面使用salt-api運行此模塊以啓動基於Python的CherryPy服務器。 該服務器是輕量級的、多線程的、使用SSL加密的,應該被認爲可以投入生產。 有關性能預期,請參見以上部分。
使用符合WSGI的Web服務器
該模塊可以部署在任何與WSGI兼容的服務器上,例如具有mod_wsgi的Apache或具有FastCGI的Nginx,僅舉兩個(有很多)。
注意,外部WSGI服務器直接處理URL、路徑和SSL證書。 rest_cherrypy
配置選項將被忽略,並且salt-api
守護程序根本不需要運行。 請記住,除非強制執行SSL,否則Salt身份驗證憑據將以明文形式發送!
Apache虛擬主機的配置示例:
<VirtualHost *:80>
ServerName example.com
ServerAlias *.example.com
ServerAdmin [email protected]
LogLevel warn
ErrorLog /var/www/example.com/logs/error.log
CustomLog /var/www/example.com/logs/access.log combined
DocumentRoot /var/www/example.com/htdocs
WSGIScriptAlias / /path/to/salt/netapi/rest_cherrypy/wsgi.py
</VirtualHost>
REST URI Reference
Salt CherryPy REST URI接口參考資料
/
class salt.netapi.rest_cherrypy.app.LowDataAdapter
這是Salt的REST API接口的主要入口端點。
- GET()
下面是關於該API的使用說明。
GET /
- Request Headers
- Accept – 期望的響應數據格式
- Status Codes
- 200 – success
- 401 – authentication required
- 406 – requested Content-Type not available
request請求的使用示例:
curl -i localhost:8000
GET / HTTP/1.1
Host: localhost:8000
Accept: application/json
response響應:
Content-Type: application/json
- POST(**kwargs)
/login
class salt.netapi.rest_cherrypy.app.Login(*args, **kwargs)
登錄並獲取一個會話令牌。參數使用方法請參考 Authentication information 。
- GET()
顯示登錄接口令牌。
GET /login
有關如何登錄的說明。
- Status Codes
- 200 – success
- 401 – authentication required
- 406 – requested Content-Type not available
request請求的使用示例:
curl -i localhost:8000/login
GET /login HTTP/1.1
Host: localhost:8000
Accept: text/html
response響應:
HTTP/1.1 200 OK
Content-Type: text/html
- POST(**kwargs)
針基於Salt的eauth系統進行身份驗證。
POST /login
- Request Headers - 請求頭
- X-Auth-Token – 從Login步驟中得到的會話令牌
- Accept – 期望的響應數據格式
- Content-Type – 請求正文中使用的數據格式
- Form Parameters - 表單參數
- eauth – the eauth backend configured for the user
- username – username
- password – password
- Status Codes - 狀態碼
- 200 – success
- 401 – authentication required
- 406 – requested Content-Type not available
request請求的使用示例:
curl -si localhost:8000/login \
-c ~/cookies.txt \
-H "Accept: application/json" \
-H "Content-type: application/json" \
-d '{
"username": "saltuser",
"password": "saltuser",
"eauth": "auto"
}'
POST / HTTP/1.1
Host: localhost:8000
Content-Length: 42
Content-Type: application/json
Accept: application/json
{"username": "saltuser", "password": "saltuser", "eauth": "auto"}
response響應:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 206
X-Auth-Token: 6d1b722e
Set-Cookie: session_id=6d1b722e; expires=Sat, 17 Nov 2012 03:23:52 GMT; Path=/
{"return": {
"token": "6d1b722e",
"start": 1363805943.776223,
"expire": 1363849143.776224,
"user": "saltuser",
"eauth": "pam",
"perms": [
"grains.*",
"status.*",
"sys.*",
"test.*"
]
}}
/logout
class salt.netapi.rest_cherrypy.app.Logout
清除或使會話令牌失效的工具類。
- POST()
銷燬當前活動的會話並使會話cookie過期
/minions
class salt.netapi.rest_cherrypy.app.Minions
可以用於對minions進行配置管理的URLs。
- GET(mid=None)
可用於獲取minions列表或獲取minion詳細信息的便捷URL。
GET /minions/(mid)
- Request Headers
- X-Auth-Token – a session token from Login.
- Accept – the desired response format.
- Status Codes
- 200 – success
- 401 – authentication required
- 406 – requested Content-Type not available
request請求的使用示例:
curl -i localhost:8000/minions/ms-3
GET /minions/ms-3 HTTP/1.1
Host: localhost:8000
Accept: application/x-yaml
response響應:
HTTP/1.1 200 OK
Content-Length: 129005
Content-Type: application/x-yaml
return:
- ms-3:
grains.items:
...
- POST(**kwargs)
啓動一個執行命令並立即返回job id 。
POST /minions
- Request Headers
- X-Auth-Token – a session token from Login.
- Accept – the desired response format.
- Content-Type – the format of the request body.
- Response Headers
- Content-Type – the format of the response body; depends on the Accept request header.
- Status Codes
-
200 – success
-
400 – bad or malformed request
-
401 – authentication required
-
406 – requested Content-Type not available
描述Salt命令內容的
lowstate
數據必須在請求正文中發送。client
選項將被設置爲local_async()
。
-
request請求的使用示例:
curl -sSi localhost:8000/minions \
-b ~/cookies.txt \
-H "Accept: application/x-yaml" \
-d '[{"tgt": "*", "fun": "status.diskusage"}]'
POST /minions HTTP/1.1
Host: localhost:8000
Accept: application/x-yaml
Content-Type: application/json
tgt=*&fun=status.diskusage
response響應:
HTTP/1.1 202 Accepted
Content-Length: 86
Content-Type: application/x-yaml
return:
- jid: '20130603122505459265'
minions: [ms-4, ms-3, ms-2, ms-1, ms-0]
_links:
jobs:
- href: /jobs/20130603122505459265
/jobs
class salt.netapi.rest_cherrypy.app.Jobs
- GET(jid=None, timeout=’’)
一個方便使用的URL,用於獲取先前運行的作業的列表或從單個作業中獲取返回數據。
GET /jobs/(jid)
列出作業列表或顯示作業緩存中的單個作業的詳細信息。
- Request Headers
- X-Auth-Token – a session token from Login.
- Accept – the desired response format.
- Status Codes
- 200 – success
- 401 – authentication required
- 406 – requested Content-Type not available
request請求的使用示例:
curl -i localhost:8000/jobs
GET /jobs HTTP/1.1
Host: localhost:8000
Accept: application/x-yaml
response響應:
HTTP/1.1 200 OK
Content-Length: 165
Content-Type: application/x-yaml
return:
- '20121130104633606931':
Arguments:
- '3'
Function: test.fib
Start Time: 2012, Nov 30 10:46:33.606931
Target: jerry
Target-type: glob
request請求的使用示例:
curl -i localhost:8000/jobs/20121130104633606931
GET /jobs/20121130104633606931 HTTP/1.1
Host: localhost:8000
Accept: application/x-yaml
response響應:
HTTP/1.1 200 OK
Content-Length: 73
Content-Type: application/x-yaml
info:
- Arguments:
- '3'
Function: test.fib
Minions:
- jerry
Start Time: 2012, Nov 30 10:46:33.606931
Target: '*'
Target-type: glob
User: saltdev
jid: '20121130104633606931'
return:
- jerry:
- - 0
- 1
- 1
- 2
- 6.9141387939453125e-06
/run
class salt.netapi.rest_cherrypy.app.Run
繞過常規的session處理,運行管理命令。
salt-api不執行授權,是由Salt的eauth系統執行授權。 Local/Runner/WheelClient都可以接受username
/password
/eauth
或者 token
kwargs ,然後交由eauth系統執行檢查。 rest_cherrypy
中的會話機制僅將會話與Salt eauth令牌配對,然後自動將Token
kwarg傳入。
如果您已經有一個Salt eauth token了(可能是由Auth Runner模塊中的mk_token函數生成的),則沒有理由再使用sessions。
該URL端點接受用使用username, password, eauth這三個參數,或者是一個 token
kwarg關鍵字參數,並且根本不使用sessions。
- POST(**kwargs)
繞過常規的session處理,運行管理命令。除此之外,該URL端點與root URL (/)相同。
POST /run
描述Salt命令的lowstate數據數組必須在請求正文中發送。
- Status Codes
- 200 – success
- 400 – bad or malformed request
- 401 – authentication required
- 406 – requested Content-Type not available
request請求的使用示例:
curl -sS localhost:8000/run \
-H 'Accept: application/x-yaml' \
-H 'Content-type: application/json' \
-d '[{
"client": "local",
"tgt": "*",
"fun": "test.ping",
"username": "saltdev",
"password": "saltdev",
"eauth": "auto"
}]'
或者是使用 Salt Eauth token:
curl -sS localhost:8000/run \
-H 'Accept: application/x-yaml' \
-H 'Content-type: application/json' \
-d '[{
"client": "local",
"tgt": "*",
"fun": "test.ping",
"token": "<salt eauth token here>"
}]'
POST /run HTTP/1.1
Host: localhost:8000
Accept: application/x-yaml
Content-Length: 75
Content-Type: application/json
[{"client": "local", "tgt": "*", "fun": "test.ping", "username": "saltdev", "password": "saltdev", "eauth": "auto"}]
response響應:
HTTP/1.1 200 OK
Content-Length: 73
Content-Type: application/x-yaml
return:
- ms-0: true
ms-1: true
ms-2: true
ms-3: true
ms-4: true
/run
enpoint也可以用於使用salt-ssh
子系統執行命令。
使用salt-ssh時,不應提供eauth認證憑據。 相反地,身份驗證應由SSH層本身處理。 使用salt-ssh客戶端時也不需要運行Salt Master。 相反,Salt配置目錄中只能存在一個roster名冊文件。
所有SSH客戶端請求都是同步執行的。
SSH客戶端請求的示例:
curl -sS localhost:8000/run \
-H 'Accept: application/x-yaml' \
-d client='ssh' \
-d tgt='*' \
-d fun='test.ping'
POST /run HTTP/1.1
Host: localhost:8000
Accept: application/x-yaml
Content-Length: 75
Content-Type: application/x-www-form-urlencoded
client=ssh&tgt=*&fun=test.ping
SSH response響應:
return:
- silver:
fun: test.ping
fun_args: []
id: silver
jid: '20141203103525666185'
retcode: 0
return: true
success: true
/events
class salt.netapi.rest_cherrypy.app.Events
對外暴露Salt的事件總線。
Salt master主機上的事件總線對外暴露了各種各樣的東西,特別是在master主機上開始執行時,以及在minions最終返回其結果時。 該URL提供了運行中的Salt基礎結構的一個實時信息窗口。
See also: Events & Reactor
- GET(token=None, salt_token=None)
Salt master事件總線的一個HTTP流。
該流按照服務器發送事件(SSE)規範進行格式化。 每個事件的格式均爲JSON。
GET /events
- Status Codes
- 200 – success
- 401 – authentication required
- 406 – requested Content-Type not available
- Query Parameters
- token – 可選參數,包含通常通過X-Auth-Token header提供的token,以便允許在EventSource API中不包含CORS支持的瀏覽器中進行跨域請求。 例如。,
curl -NsS localhost:8000/events?token=308650d
- salt_token – 可選參數,包含原始Salt eauth令牌(不要與/login URL返回的令牌混淆)。 例如,
curl -NsS localhost:8000/events?salt_token=30742765
- token – 可選參數,包含通常通過X-Auth-Token header提供的token,以便允許在EventSource API中不包含CORS支持的瀏覽器中進行跨域請求。 例如。,
request請求示例:
curl -NsS localhost:8000/events
GET /events HTTP/1.1
Host: localhost:8000
response響應:
注意,tag
字段不是規範的一部分。 符合SSE的客戶端應忽略未知字段。 此添加使不兼容的客戶端僅監視某些標籤,而不必每次都反序列化JSON對象。
HTTP/1.1 200 OK
Connection: keep-alive
Cache-Control: no-cache
Content-Type: text/event-stream;charset=utf-8
retry: 400
tag: salt/job/20130802115730568475/new
data: {'tag': 'salt/job/20130802115730568475/new', 'data': {'minions': ['ms-4', 'ms-3', 'ms-2', 'ms-1', 'ms-0']}}
tag: salt/job/20130802115730568475/ret/jerry
data: {'tag': 'salt/job/20130802115730568475/ret/jerry', 'data': {'jid': '20130802115730568475', 'return': True, 'retcode': 0, 'success': True, 'cmd': '_return', 'fun': 'test.ping', 'id': 'ms-1'}}
這個事件流可以容易得使用JavaScript解析處理:
var source = new EventSource('/events');
source.onopen = function() { console.info('Listening ...') };
source.onerror = function(err) { console.error(err) };
source.onmessage = function(message) {
var saltEvent = JSON.parse(message.data);
console.log(saltEvent.tag, saltEvent.data);
};
請注意,SSE流是快速且完全異步的,而Salt是非常快的。如果使用常規POST請求創建了作業,則在POST請求的響應到達之前,作業返回將在SSE流上可用。在設計應用程序時,必須考慮到異步性。以下是一些一般準則。
- 在創建任何事件前就訂閱SSE流。
- 在SSE事件到達時直接對其進行處理,而無需等待任何其他過程首先“完成”(例如ajax請求)。
- 如果必須將事件流用於同步查找,請保留事件的緩衝區。
- 將Salt的事件流直接寫到DOM時要謹慎。它非常忙,可以迅速使分配給瀏覽器選項卡的內存不堪重負。
該文件旁邊提供了一個完整的有效概念驗證目的的JavaScript應用程序。可以通過將瀏覽器指向正在運行的rest_cherrypy
實例中的/app
端點來查看它。
或使用CORS:
var source = new EventSource('/events?token=ecd589e4e01912cf3c4035afad73426dbb8dba75', {withCredentials: true});
也可以通過shell消費流。
記錄由空白行分隔; 在嘗試反序列化JSON之前,需要手動刪除data:
和tag:
前綴。
curl的 -N
標識關閉了輸入緩存功能,因爲我們需要能增量的處理流。
這是打印每個事件的一個基本示例:
curl -NsS localhost:8000/events |\
while IFS= read -r line ; do
echo $line
done
下面是使用 awk 基於 tag 過濾事件的例子:
curl -NsS localhost:8000/events |\
awk '
BEGIN { RS=""; FS="\\n" }
$1 ~ /^tag: salt\/job\/[0-9]+\/new$/ { print $0 }
'
tag: salt/job/20140112010149808995/new
data: {"tag": "salt/job/20140112010149808995/new", "data": {"tgt_type": "glob", "jid": "20140112010149808995", "tgt": "jerry", "_stamp": "2014-01-12_01:01:49.809617", "user": "shouse", "arg": [], "fun": "test.ping", "minions": ["jerry"]}}
tag: 20140112010149808995
data: {"tag": "20140112010149808995", "data": {"fun_args": [], "jid": "20140112010149808995", "return": true, "retcode": 0, "success": true, "cmd": "_return", "_stamp": "2014-01-12_01:01:49.819316", "fun": "test.ping", "id": "jerry"}}
/hook
class salt.netapi.rest_cherrypy.app.Webhook
一個通用的Web hook入口點,可在Salt的事件總線上觸發事件。
外部服務可以將數據發佈到此URL,以觸發Salt中的相應事件。例如,Amazon SNS、Jenkins-CI或Travis-CI或GitHub Web hooks。
注意安全性
Salt的Reactor可以運行任何代碼。響應鉤子事件的Reactor SLS負責驗證該事件來自受信任的源幷包含有效數據。
這是一個通用接口,如何確保安全由您決定!
此URL需要身份驗證,但是並非所有外部服務都可以配置爲進行身份驗證。因此,可以有選擇地禁用此URL的身份驗證。建議遵循最佳做法-始終使用SSL、傳遞密鑰、將防火牆配置爲僅允許來自已知來源的流量等。
事件數據取自請求的正文。Content-Type header適用於有效負載。
事件標記的前綴是`salt/netapi/hook`,URL路徑附加在末尾。例如,發送到`/hook/mycompany/myapp/mydata`的`POST`請求將產生一個帶有`Salt/netapi/hook/mycompany/myapp/mydata`標籤的Salt事件。
以下是一個示例`.travis.yml`文件,用於將成功運行測試的通知發送給Salt:
language: python
script: python -m unittest tests
after_success:
- |
curl -sSk https://saltapi-url.example.com:8000/hook/travis/build/success -d branch="${TRAVIS_BRANCH}" -d commit="${TRAVIS_COMMIT}"
See also:Events & Reactor, reactor
- POST(*args, **kwargs)
使用自定義的標籤和數據,在Salt中觸發一個事件。
POST /hook
- Status Codes
- 200 – success
- 401 – authentication required
- 406 – requested Content-Type not available
- 413 – request body is too large
request請求使用示例:
curl -sS localhost:8000/hook \
-H 'Content-type: application/json' \
-d '{"foo": "Foo!", "bar": "Bar!"}'
POST /hook HTTP/1.1
Host: localhost:8000
Content-Length: 16
Content-Type: application/json
{"foo": "Foo!", "bar": "Bar!"}
response響應示例:
HTTP/1.1 200 OK
Content-Length: 14
Content-Type: application/json
{"success": true}
作爲一個實際可以運行的示例,內部的持續集成構建服務器可以將HTTP POST請求發送到URL https://localhost:8000/hook/mycompany/build/success,其中包含構建結果和該版本的SHA被構建爲JSON。 然後,這將在Salt中產生以下事件,該事件可用於通過Salt的Reactor繼續啓動下一個步驟的應用部署:
Event fired at Fri Feb 14 17:40:11 2014
*************************
Tag: salt/netapi/hook/mycompany/build/success
Data:
{'_stamp': '2014-02-14_17:40:11.440996',
'headers': {
'X-My-Secret-Key': 'F0fAgoQjIT@W',
'Content-Length': '37',
'Content-Type': 'application/json',
'Host': 'localhost:8000',
'Remote-Addr': '127.0.0.1'},
'post': {'revision': 'aa22a3c4b2e7', 'result': True}}
Salt 的 Reactor 響應器將會監控這類事件:
reactor:
- 'salt/netapi/hook/mycompany/build/*':
- /srv/reactor/react_ci_builds.sls
並最終完成應用程序的部署工作:
{% set secret_key = data.get('headers', {}).get('X-My-Secret-Key') %}
{% set build = data.get('post', {}) %}
{% if secret_key == 'F0fAgoQjIT@W' and build.result == True %}
deploy_my_app:
cmd.state.sls:
- tgt: 'application*'
- arg:
- myapp.deploy
- kwarg:
pillar:
revision: {{ revision }}
{% endif %}
/keys
class salt.netapi.rest_cherrypy.app.Keys
用於管理minion keys的便捷URLs。
New in version 2014.7.0.
這些URL包含了 key wheel module 功能提供的功能。
- GET(mid=None)
顯示minion keys列表或特定key的詳細信息。
*New in version 2014.7.0.*
GET /keys/(mid)
- Request Headers
- X-Auth-Token – a session token from Login.
- Accept – the desired response format.
- Status Codes
- 200 – success
- 401 – authentication required
- 406 – requested Content-Type not available
request請求使用示例:
curl -i localhost:8000/keys
GET /keys HTTP/1.1
Host: localhost:8000
Accept: application/x-yaml
response響應示例:
HTTP/1.1 200 OK
Content-Length: 165
Content-Type: application/x-yaml
return:
local:
- master.pem
- master.pub
minions:
- jerry
minions_pre: []
minions_rejected: []
request請求使用示例:
curl -i localhost:8000/keys/jerry
GET /keys/jerry HTTP/1.1
Host: localhost:8000
Accept: application/x-yaml
response響應示例:
HTTP/1.1 200 OK
Content-Length: 73
Content-Type: application/x-yaml
return:
minions:
jerry: 51:93:b3:d0:9f:3a:6d:e5:28:67:c2:4b:27:d6:cd:2b
- POST(**kwargs)
可以方便的爲minion生成密鑰並自動接受新密鑰。
接受與key.gen_accept相同的所有參數。
注意:關於
curl
的使用請避免-i
標誌,否則將會也寫入HTTP header數據,以致於生成無效的tar文件。
下面是在kickstart腳本中用來引導和配置新的minion的示例:
%post
mkdir -p /etc/salt/pki/minion
curl -sSk https://localhost:8000/keys \
-d mid=jerry \
-d username=kickstart \
-d password=kickstart \
-d eauth=pam \
| tar -C /etc/salt/pki/minion -xf -
mkdir -p /etc/salt/minion.d
printf 'master: 10.0.0.5\nid: jerry' > /etc/salt/minion.d/id.conf
%end
POST /keys
生成公鑰和私鑰,並打包爲一個tar壓縮包文件返回。
身份驗證憑據必須在請求中傳遞。
- Status Codes
- 200 – success
- 401 – authentication required
- 406 – requested Content-Type not available
request請求使用示例:
curl -sSk https://localhost:8000/keys \
-d mid=jerry \
-d username=kickstart \
-d password=kickstart \
-d eauth=pam \
-o jerry-salt-keys.tar
POST /keys HTTP/1.1
Host: localhost:8000
response響應示例:
HTTP/1.1 200 OK
Content-Length: 10240
Content-Disposition: attachment; filename="saltkeys-jerry.tar"
Content-Type: application/x-tar
jerry.pub0000644000000000000000000000070300000000000010730 0ustar 00000000000000
/ws
class salt.netapi.rest_cherrypy.app.WebsocketEndpoint
打開一個與Salt的事件總線的WebSocket連接。
Salt master主機上的事件總線公開了各種各樣的東西,特別是在master主機上開始執行時,以及在minions最終返回其結果時。 該URL提供了運行中的Salt基礎結構的實時令牌窗口。 使用websocket作爲傳輸機制。
See also:Events & Reactor
- GET(token=None, **kwargs)
返回一個與Salt的事件總線的WebSocket連接。
GET /ws/(token)
-
Query format_events
如果請求中包含
format_events
的URL參數,則事件流將進行服務器端進行內容格式化。 這對於需要避免在客戶端進行格式化時很有用:curl -NsS <...snip...> localhost:8000/ws?format_events
-
Reqheader X-Auth-Token
一個在Login步驟中獲取的身份認證token。 -
Status 101
切換至websockets協議。 -
Status 401
需要通過身份驗證。 -
Status 406
request請求中的Content-Type無效。
request請求的使用示例:
curl -NsSk \
-H 'X-Auth-Token: ffedf49d' \
-H 'Host: localhost:8000' \
-H 'Connection: Upgrade' \
-H 'Upgrade: websocket' \
-H 'Origin: https://localhost:8000' \
-H 'Sec-WebSocket-Version: 13' \
-H 'Sec-WebSocket-Key: '"$(echo -n $RANDOM | base64)" \
localhost:8000/ws
GET /ws HTTP/1.1
Connection: Upgrade
Upgrade: websocket
Host: localhost:8000
Origin: https://localhost:8000
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: s65VsgHigh7v/Jcf4nXHnA==
X-Auth-Token: ffedf49d
response響應的示例:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: mWZjBV9FCglzn1rIKJAxrTFlnJE=
Sec-WebSocket-Version: 13
對於無法配置爲發送的請求攜帶身份驗證header或cookie的瀏覽器客戶端,可以選擇性地將身份驗證令牌作爲URL的一部分傳遞: curl -NsS <...snip...> localhost:8000/ws/ffedf49d
可以很容易地使用JavaScript解析處理事件流數據:
// Note, you must be authenticated!
var source = new Websocket('ws://localhost:8000/ws/d0ce6c1a');
source.onerror = function(e) { console.debug('error!', e); };
source.onmessage = function(e) { console.debug(e.data); };
source.send('websocket client ready')
source.close();
或者使用Python。例如,使用 Python 模塊 websocket-client 。
# Note, you must be authenticated!
from websocket import create_connection
ws = create_connection('ws://localhost:8000/ws/d0ce6c1a')
ws.send('websocket client ready')
# Look at https://pypi.python.org/pypi/websocket-client/ for more
# examples.
while listening_to_events:
print ws.recv()
ws.close()
上面的示例顯示瞭如何建立與Salt的websocket連接以及如何通過向websocket客戶端發送信號通知激活Salt的事件流的實時更新。
/stats
class salt.netapi.rest_cherrypy.app.Stats
對外暴露 CherryPy server 的運行統計數據。
- GET()
返回從CherryPy服務器收集的統計信息的轉儲。
GET /stats
- Request Headers
- X-Auth-Token – a session token from Login.
- Accept – the desired response format.
- Response Headers
- Content-Type – the format of the response body; depends on the Accept request header.
- Status Codes
- 200 – success
- 401 – authentication required
- 406 – requested Content-Type not available