EcsDryRun(檢查請求)簡述

龍轔發表於2018-02-27

使用場景

在使用OpenAPI的過程中,經常會遇到一個不熟悉的API,為了測試這個API的使用方法,需要對這個介面進行真實的呼叫。這個過程遇到的問題是顯而易見的,如果是查詢類介面(比如DescribeInstances),直接進行測試呼叫是沒有什麼問題的,但是對於操作甚至建立類介面(如RunInstances),如果呼叫介面會對例項直接產生影響,或者會產生不必要的測試費用。

DryRun功能就是為了解決這種問題而存在的,DryRun是一個檢驗請求,帶有DryRun引數的請求只會檢查其合法性,而不會對資源產生影響。使用這種方式,可以僅僅通過呼叫來確定一個請求的引數是否合理,賬號是否有足夠的許可權呼叫這個介面。

使用方式

根據不同型別的介面,將DryRun的使用方式分為兩種,一種是查詢類介面,一種是建立類介面。

查詢相關

查詢類介面主要包括5個介面:DescribeInstances, DescribeSnapshots, DescribeSecurityGroups, DescribeImages, DescribeDisks。在不使用DryRun的情況下,如果使用(RAM)子賬號呼叫,沒有許可權的請求會以空結果的狀態的返回(並不會報錯),表示這個使用者並沒有許可權查詢所有例項。在這種情況下,介面的返回並不能完全判定沒有查詢到資源還是使用者沒有許可權呼叫。

在使用DryRun時,請求的返回裡永遠不會包含實際的查詢結果,所有的結果都會以報錯的形式返回,包括檢查通過的請求(為了與成功但是沒有資料的請求相區分)。檢查通過的請求會以特定的錯誤碼錶示檢查通過

DryRun檢查通過的特定錯誤碼
Code: DryRunOperation 
Message: Request validation has been passed with DryRun flag set.

示例程式碼如下:

# common codes, 下次不再新增
# coding=utf-8
import logging
from aliyunsdkcore import client
from aliyunsdkcore.acs_exception.exceptions import ServerException, ClientException
from aliyunsdkecs.request.v20140526.DescribeInstancesRequest import DescribeInstancesRequest

clint = client.AcsClient(`AK`, `SK`, `cn-qingdao`)  # region 按實際填寫
logging.basicConfig(level=logging.INFO,
                    format=`%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s`,
                    datefmt=`%a, %d %b %Y %H:%M:%S`)


def _get_response(request):
    try:
        ret = clint.do_action_with_exception(request)
        logging.info(ret)
    except ServerException, e:
        logging.error(e)
    except ClientException, e:
        logging.error(e)

# common codes end

def describe_instance():
    request = DescribeInstancesRequest()
    request.set_DryRun(`true`)
    _get_response(request)
if __name__ == `__main__`:
    describe_instance()
    

DryRun引數為bool型別,取值範圍為true | false,預設為false,所有介面的DryRun入參都是統一的。

在查詢介面呼叫時,DryRun引數為true時檢查的請求內容主要為是否有許可權呼叫介面,以及少數的引數基礎規則檢查(是否必填等)。

建立相關

現在支援DryRun的建立介面主要為RunInstances。在不使用DryRun的情況下,RunInstances如果需要測試建立,需要真正的建立出來一臺例項才能保證呼叫的有效。

使用DryRun引數,則可以簡單檢查請求是否合法。建立介面的DryRun檢查主要包含幾個方面:使用者是否有許可權呼叫、該地域下是否有相應資源售賣、引數之間是否衝突。需要注意的是,RunInstances在使用DryRun的時候,有一個與正常情況不同的引數:Amount,在DryRun為true時,Amount引數必須為1。也就是DryRun引數是不能用來檢測建立數量的。

建立介面的DryRun程式碼示例如下:

from aliyunsdkecs.request.v20140526.RunInstancesRequest import RunInstancesRequest

def run_instance():
    request = RunInstancesRequest()
    request.set_SecurityGroupId(`sg-id`)
    request.set_ImageId(`imageid`)
    request.set_InstanceType(`instance-type`)
    request.set_VSwitchId(`vsw-id`)
    request.set_DryRun(`true`)
    _get_response(request)
if __name__ == `__main__`:
    run_instance()

在引數完全正確的情況下,可以不通過建立例項來判斷請求的合法性,來對呼叫Ecs OpenAPI的程式碼進行除錯。

最佳實踐

從DryRun引數的設計來看,主要還是應用在呼叫預檢查以及測試階段對請求進行校驗的場景,在使用子賬號進行查詢操作時,可以預先使用DryRun引數判斷子使用者是否有許可權發起此次請求操作,同時,DryRun也可以用作子賬號的後置檢查,如果查詢介面沒有報錯但是返回了空結果,可以使用DryRun進行一次許可權校驗,來確定是否子賬號的許可權不夠。

對建立類介面來說,DryRun的使用場景比較廣泛:

  • 子賬號在建立資源前可以使用DryRun判斷是否許可權足夠
  • 在進行彈性擴充套件建立例項的程式碼除錯時,設定DryRun為true,可以不實際建立出例項就可以達到程式碼除錯的效果(唯一的cost就是DryRun的成功請求與實際成功的返回不完全一樣)
  • 建立資源前,可以進行資源的預先檢查,可以列舉出使用場景匹配的不同資源組合是否合理可建立。


相關文章