SaltStack netapi模塊REST API——rest_tornado

原文鏈接:https://docs.saltstack.com/en/latest/ref/netapi/all/salt.netapi.rest_tornado.html

rest_tornado是基於python tornado框架實現的一個Salt REST API技術方案。

您也可以參考在Github上維護的這一份技術資料:rest_tornado

A non-blocking REST API for Salt

依賴於

  • tornado Python module

配置方法

所有身份驗證均通過Salt的 external auth 外部身份驗證系統完成,該系統需要此處未介紹的一些其他配置支持。

爲了用salt-master運行rest_tornado,需要將以下內容添加到Salt master配置文件中。

rest_tornado:
    # can be any port
    port: 8000
    # address to bind to (defaults to 0.0.0.0)
    address: 0.0.0.0
    # socket backlog
    backlog: 128
    ssl_crt: /etc/pki/api/certs/server.crt
    # no need to specify ssl_key if cert and key
    # are in one single file
    ssl_key: /etc/pki/api/certs/server.key
    debug: False
    disable_ssl: False
    webhook_disable_auth: False
    cors_origin: null

Authentication - 身份認證

通過在發送訪問請求時傳遞一個session token來執行認證。 令牌是通過SaltAuthHandler URL生成的。

令牌可以通過以下兩種方式之一發送:

  • 包含一個名爲 X-Auth-Token 的自定義header。
  • 通過Cookie發送。 對於自動處理cookie支持的HTTP客戶端(例如瀏覽器),此選項很方便。

See also:您可以通過RunSaltAPIHandler URL繞過會話處理。

CORS - 跨站點請求

rest_tornado支持開箱即用的跨站點HTTP請求。 默認情況下,它是由cors_origin配置鍵禁用和控制的。

通過將cors_origin設置爲*,可以允許所有源的訪問請求。

使用下面這個配置,您只能允許一個來源:

rest_tornado:
    cors_origin: http://salt.yourcompany.com

您還可以更具體一些,並使用列表僅選擇一些允許的來源。 例如:

rest_tornado:
    cors_origin:
        - http://salt.yourcompany.com
        - http://salt-preprod.yourcampany.com

來源的格式爲完整URL,如果不是標準格式,則包含scheme和端口。

在這種情況下,rest_tornado將在允許的情況下檢查Origin報頭是否在允許的列表中。 否則,它將不返回任何內容,從而有效地阻止了源發送的請求。

作爲參考,CORS是瀏覽器使用的一種機制,用於允許(或禁止)來自瀏覽器的請求來自與salt-api不同的來源。 僅當您計劃使用作爲Javascript瀏覽器應用程序開發的Salt客戶端時,它纔是Authentication的補充和強制性要求。

Usage - 使用方法

將HTTP請求發送到下面介紹的URLs,命令通過該模塊被髮送到正在運行的Salt master。

內容協商

這個REST 接口可以靈活接受各種數據格式以及返回的格式(例如JSON、YAML、x-www-form-urlencoded)。

  • 通過包含Content-Type header頭來指定請求正文中的數據格式。
  • 使用Accept header頭爲響應主體指定所需的數據格式。

POSTPUT請求中發送的數據必須採用lowstate詞典列表的格式。這允許在單個HTTP請求中執行多個命令。

lowstate

一個包含各種鍵的字典,這些鍵指示Salt運行哪個命令,該命令所在的位置,該命令的任何參數,任何身份驗證憑據,要使用的returner返回者等。

Salt在許多地方內部使用lowstate數據格式在函數之間傳遞命令數據。 Salt還對 LocalClient() Python API接口使用lowstate。

以下示例(JSON格式)使用Salt執行兩個命令:

[{
    "client": "local",
    "tgt": "*",
    "fun": "test.fib",
    "arg": ["10"]
},
{
    "client": "runner",
    "fun": "jobs.lookup_jid",
    "jid": "20130603122505459265"
}]

Salt API請求中的多個命令將串行執行,並且不保證所有命令都將運行。 這意味着,如果test.fib(來自上面的示例)發生異常,則API仍將執行“ jobs.lookup_jid”

對這些lowstate狀態的響應是包含返回數據的字典的有序列表,yaml響應可能類似於:

- ms-1: true
  ms-2: true
- ms-1: foo
  ms-2: bar

如果在執行命令時發生異常,則該lowstate狀態的返回將是一個字符串,例如,如果沒有minions與第一個lowstate狀態匹配,我們將得到如下返回:

- No minions matched the target. No command was sent, no jid was assigned.
- ms-1: true
  ms-2: true

x-www-form-urlencoded

在請求正文中發送JSON或YAML是簡單且最靈活的,此外還支持以urlencode格式發送數據(有幾個事項需要注意)。 它是HTML表單、許多JavaScript庫和curl命令的默認格式。

例如,運行salt'*'test.ping的管理命令相當於在HTTP請求正文中發送fun=test.ping&arg&client=local&tgt=*的效果。

注意事項:

  • 每個HTTP請求只能發送一個命令。
  • 重複使用arg參數時將導致這些參數組合到一個列表中。

注意,一些流行的框架和語言(特別是jQuery,PHP和Ruby on Rails)會自動將空括號附加到重複的參數上。 例如,arg=onearg=two將作爲arg[]=one, arg[]=two發送。 這種使用方法是不支持的,請使用JSON或YAML。

A Websockets add-on to saltnado

依賴於

  • tornado Python module

爲了啓用 saltnado_websockets 功能,你需要在 saltnado的配置段落中,增加 websockets: True的配置。

rest_tornado:
    # can be any port
    port: 8000
    ssl_crt: /etc/pki/api/certs/server.crt
    # no need to specify ssl_key if cert and key
    # are in one single file
    ssl_key: /etc/pki/api/certs/server.key
    debug: False
    disable_ssl: False
    websockets: True

all_events

可以使用一個websocket連接將Salt的事件總線上的所有“實時”事件對外暴露出來。 應該注意的是,這裏的“實時”是指一旦有任何與Salt有關的動作發生(更改minions,新的jobs等),這些事件對服務器就是可用的了。 不過,這是在假定客戶端能夠容忍任何與網絡傳輸相關的延遲的前提之下。 該端點提供的功能類似於/events端點。

Salt master主機上的事件總線公開了各種各樣的東西,特別是在master主機上開始執行管理命令時以及在minions最終返回其結果時。 該URL提供了運行中的Salt基礎結構的實時窗口。 使用websocket作爲傳輸機制。

對外暴露一個GET方法以返回websocket連接。 所有請求都應包含一個身份驗證令牌。 下面顯示了一種獲取身份驗證令牌的方法。

% curl -si localhost:8000/login \
    -H "Accept: application/json" \
    -d username='salt' \
    -d password='salt' \
    -d eauth='pam'

響應結果:

{
    "return": [{
        "perms": [".*", "@runner", "@wheel"],
        "start": 1400556492.277421,
        "token": "d0ce6c1a37e99dcc0374392f272fe19c0090cca7",
        "expire": 1400599692.277422,
        "user": "salt",
        "eauth": "pam"
    }]
}

在此示例中,返回的令牌爲d0ce6c1a37e99dcc0374392f272fe19c0090cca7,這可以包含在後續的websocket請求中(作爲URL的一部分)。

可通過JavaScript輕鬆地使用事件流:

// Note, you must be authenticated!

// Get the Websocket connection to Salt

var source = new Websocket('wss://localhost:8000/all_events/d0ce6c1a37e99dcc0374392f272fe19c0090cca7');

// Get Salt's "real time" event stream.
source.onopen = function() { source.send('websocket client ready'); };

// Other handlers
source.onerror = function(e) { console.debug('error!', e); };

// e.data represents Salt's "real time" event data as serialized JSON.
source.onmessage = function(e) { console.debug(e.data); };

// Terminates websocket connection and Salt's "real time" event stream on the server.
source.close();

或者使用Python, 例如使用 Python module websocket-client 。 或者是使用 tornado client

# Note, you must be authenticated!

from websocket import create_connection

# Get the Websocket connection to Salt
ws = create_connection('wss://localhost:8000/all_events/d0ce6c1a37e99dcc0374392f272fe19c0090cca7')

# Get Salt's "real time" event stream.
ws.send('websocket client ready')


# Simple listener to print results of Salt's "real time" event stream.
# Look at https://pypi.python.org/pypi/websocket-client/ for more examples.
while listening_to_events:
    print ws.recv()       #  Salt's "real time" event data as serialized JSON.

# Terminates websocket connection and Salt's "real time" event stream on the server.
ws.close()

# Please refer to https://github.com/liris/websocket-client/issues/81 when using a self signed cert

上面的示例顯示瞭如何建立與Salt的websocket連接以及如何通過向websocket客戶端發送信號websocket client ready通知激活Salt的事件流的實時更新。

formatted_events

通過Websocket連接從Salt的事件總線中暴露格式化的 formatted “real-time”事件。 應該注意的是,這裏的“實時”是指一旦發生任何與Salt有關的動作(更改minions,新jobs等),這些事件就可用於服務器了。 但是,這假定客戶端能夠容忍任何與網絡傳輸相關的延遲。 該端點提供的功能類似於/events端點。

Salt master主機上的事件總線公開了各種各樣的東西,特別是在master主機上開始執行管理命令時以及在minions最終返回其結果時。 該URL提供了運行中的Salt基礎結構的實時窗口。 使用websocket作爲傳輸機制。

格式化的事件解析原始的“實時”事件流,並維護以下各項的當前視圖:

  • minions
  • jobs

處理minions的更改(例如添加、刪除鍵或斷開連接)或處理jobs作業並更新客戶端。 由於我們使用salt的狀態事件來跟蹤minions,因此請啓用present_events並在salt master配置文件中爲loop_interval設置一個較小的值。

暴露了一個GET方法以返回websocket連接。 所有請求都應包含一個身份驗證令牌。 下面顯示了一種獲取身份驗證令牌的方法。

% curl -si localhost:8000/login \
    -H "Accept: application/json" \
    -d username='salt' \
    -d password='salt' \
    -d eauth='pam'

響應結果:

{
    "return": [{
        "perms": [".*", "@runner", "@wheel"],
        "start": 1400556492.277421,
        "token": "d0ce6c1a37e99dcc0374392f272fe19c0090cca7",
        "expire": 1400599692.277422,
        "user": "salt",
        "eauth": "pam"
    }]
}

在此示例中,返回的令牌爲d0ce6c1a37e99dcc0374392f272fe19c0090cca7,並且可以包含在後續的websocket請求中(作爲URL的一部分)。

可通過JavaScript輕鬆使用事件流:

// Note, you must be authenticated!

// Get the Websocket connection to Salt
var source = new Websocket('wss://localhost:8000/formatted_events/d0ce6c1a37e99dcc0374392f272fe19c0090cca7');

// Get Salt's "real time" event stream.
source.onopen = function() { source.send('websocket client ready'); };

// Other handlers
source.onerror = function(e) { console.debug('error!', e); };

// e.data represents Salt's "real time" event data as serialized JSON.
source.onmessage = function(e) { console.debug(e.data); };

// Terminates websocket connection and Salt's "real time" event stream on the server.
source.close();

或者是使用 Python, 例如使用 Python module websocket-client ,或者使用 tornado client

# Note, you must be authenticated!

from websocket import create_connection

# Get the Websocket connection to Salt
ws = create_connection('wss://localhost:8000/formatted_events/d0ce6c1a37e99dcc0374392f272fe19c0090cca7')

# Get Salt's "real time" event stream.
ws.send('websocket client ready')


# Simple listener to print results of Salt's "real time" event stream.
# Look at https://pypi.python.org/pypi/websocket-client/ for more examples.
while listening_to_events:
    print ws.recv()       #  Salt's "real time" event data as serialized JSON.

# Terminates websocket connection and Salt's "real time" event stream on the server.
ws.close()

# Please refer to https://github.com/liris/websocket-client/issues/81 when using a self signed cert

上面的示例顯示瞭如何建立與Salt的websocket連接以及如何通過向websocket客戶端發送信號通知激活Salt的事件流的實時更新。

Example responses

Minion信息是由每個相連的minion的ID(mid)作爲關鍵字的字典,還包括每個minion的grains信息。

在響應結果中會隨着以下minion事件發送Minion的信息:

  • connection drops
    • 需要每間隔loop_interval秒定期運行一次manage.present
  • minion addition
  • minon removal
# Not all grains are shown
data: {
    "minions": {
        "minion1": {
            "id": "minion1",
            "grains": {
                "kernel": "Darwin",
                "domain": "local",
                "zmqversion": "4.0.3",
                "kernelrelease": "13.2.0"
            }
        }
    }
}

Job information 也會被跟蹤和發送。

作業信息也是字典,其中每個作業的信息都以salt的jid作爲關鍵字。

data: {
    "jobs": {
        "20140609153646699137": {
            "tgt_type": "glob",
            "jid": "20140609153646699137",
            "tgt": "*",
            "start_time": "2014-06-09T15:36:46.700315",
            "state": "complete",
            "fun": "test.ping",
            "minions": {
                "minion1": {
                    "return": true,
                    "retcode": 0,
                    "success": true
                }
            }
        }
    }
}

REST URI Reference

/

salt.netapi.rest_tornado.saltnado.SaltAPIHandler

內置別名。

/login

salt.netapi.rest_tornado.saltnado.SaltAuthHandler

內置別名。

/minions

salt.netapi.rest_tornado.saltnado.MinionSaltAPIHandler

內置別名。

/jobs

salt.netapi.rest_tornado.saltnado.JobsSaltAPIHandler

內置別名。

/run

salt.netapi.rest_tornado.saltnado.RunSaltAPIHandler

內置別名。

/events

salt.netapi.rest_tornado.saltnado.EventsSaltAPIHandler

內置別名。

/hook

salt.netapi.rest_tornado.saltnado.WebhookSaltAPIHandler

內置別名。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章