本文介紹 阿裡雲資源編排服務(ROS)
(下面簡稱ROS)的異步通知功能。
建立、更新或删除資源棧(下面簡稱Stack)時,為了判斷操作是否完成,通常我們會起一個定時任務,輪詢Stack的狀态直至完成。這種做法比較低效,使用異步通知功能,可以避免這個問題。ROS會在資源棧的操作完成時,回調通知客戶。
使用方法
- 在建立Stack時,通過Webhook參數指定回調位址。
- 回調位址可以是一個或多個,通過逗号分隔。
- 回調目前隻支援HTTP POST。
- Stack至少包含一個輸出。
示例
搭建HTTP伺服器
申請一台擁有公網IP的ECS,并安全組入方向開放相應端口。這裡我建立一台CentOS 7.6的機器,安全組開放8081端口。登入機器執行如下指令,啟動一個Web服務。
pip install web.py
cat >website.py <<EOF
# -*- coding: utf-8 -*-
import web
import json
urls = (
'/', 'Index'
)
class Index(object):
def GET(self):
return "Hello, world!"
def POST(self):
s = web.data()
try:
print(json.dumps(json.loads(s), sort_keys=True, indent=4, separators=(',', ': ')))
except:
print(s)
return "Hello, world!"
if __name__ == "__main__":
app = web.application(urls, globals())
app.run()
EOF
python website.py 8081
建立Stack
以Python SDK為例,重點關注帶注釋部分。
# coding:utf-8
import json
import pprint
from aliyunsdkcore import client
from aliyunsdkros.request.v20150901 import CreateStacksRequest
AK = '<AK>' # Access Key
SECRET = '<SECRET>' # Access Key Secret
REGION = '<REGION>' # RegionId,比如cn-beijing
WEB_HOOK = 'http://<PUBLIC_IP>:8081' # 回調位址,使用ECS的公網IP代替PUBLIC_IP
class RequestHelper(object):
def __init__(self):
self._clt = client.AcsClient(AK, SECRET, REGION)
_instance = None
@classmethod
def instance(cls):
if not cls._instance:
cls._instance = cls()
return cls._instance
def run(self, request, body=None):
if body is not None:
request.set_content(json.dumps(body))
request.set_content_type('application/json')
status, headers, body = self._clt.get_response(request)
pprint.pprint(status)
pprint.pprint(headers)
try:
pprint.pprint(json.loads(body))
except ValueError:
pprint.pprint(body)
def main():
request = CreateStacksRequest.CreateStacksRequest()
body = {
'Name': 'test-web-hook',
'DisableRollback': False,
'TimeoutMins': 120,
'Webhook': WEB_HOOK, #通過Webhook參數指定回調位址
'Template': {
'ROSTemplateFormatVersion': '2015-09-01',
'Resources': {
'WaitConditionHandle': {
'Type': 'ALIYUN::ROS::WaitConditionHandle'
}
},
'Outputs': {
'CurlCli': {
'Value': {
'Fn::GetAtt': ['WaitConditionHandle', 'CurlCli']
}
}
}
}
}
RequestHelper.instance().run(request, body)
if __name__ == '__main__':
main()
觀察回調結果
{
"Outputs": [
{
"Description": "No description given",
"OutputKey": "CurlCli",
"OutputValue": "curl -i -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'x-acs-region-id: cn-beijing' http://100.100.100.110/waitcondition?stackname=test-web-hook\\&stackid=80bd6b6c-e888-4573-ae3b-93d29144911d\\&resource=WaitConditionHandle\\&expire=1555424388\\&signature=e014516fa8028d8a8df9c9f4c9f7dc82a49421c1"
}
],
"StackId": "80bd6b6c-e888-4573-ae3b-93d29144911d",
"StackName": "test-web-hook",
"Status": "CREATE_COMPLETE"
}