全部產品
Search
文件中心

:ECS 執行個體續費

更新時間:Aug 23, 2018

除了通過 ECS控制台售賣頁 進行雲端服務器續費外,阿里雲還支援直接通過 API 進行續費查詢和續費管理。

本文主要涉及如下關鍵功能:

  • 按照過期時間查詢雲端服務器
  • 續費執行個體
  • 查詢雲端服務器自動續費時間
  • 設定雲端服務器自動續費時間

對於訂用帳戶的雲端服務器,生命週期非常重要。如果雲端服務器資源不能按時續費,將可能導致伺服器被鎖定甚至被釋放,從而影響業務持久性。API 幫助您及時瞭解和檢查資源的到期時間,並完成續費儲值功能。

本篇需關注如下 API:

查詢指定範圍內到期的雲端服務器

查詢執行個體列表的 API,通過過濾參數,您可以查詢一定時間範圍內到期的執行個體資訊。通過設定過濾參數 ExpiredStartTimeExpiredEndTime(時間參數 按照 ISO8601 標準表示,並需要使用 UTC 時間。 格式為:yyyy-MM-ddTHH:mmZ。) ,可以方便地查詢該時間範圍內到期的執行個體列表。如果需要通過安全性群組進行過濾,只需加上安全性群組 ID 即可。

  1. INSTANCE_EXPIRED_START_TIME_IN_UTC_STRING = '2017-01-22T00:00Z'
  2. INSTANCE_EXPIRE_END_TIME_IN_UTC_STRING = '2017-01-28T00:00Z'
  3. def describe_need_renew_instance(page_size=100, page_number=1, instance_id=None,
  4. check_need_renew=True, security_group_id=None):
  5. request = DescribeInstancesRequest()
  6. if check_need_renew is True:
  7. request.set_Filter3Key("ExpiredStartTime")
  8. request.set_Filter3Value(INSTANCE_EXPIRED_START_TIME_IN_UTC_STRING)
  9. request.set_Filter4Key("ExpiredEndTime")
  10. request.set_Filter4Value(INSTANCE_EXPIRE_END_TIME_IN_UTC_STRING)
  11. if instance_id is not None:
  12. request.set_InstanceIds(json.dumps([instance_id]))
  13. if security_group_id:
  14. request.set_SecurityGroupId(security_group_id)
  15. request.set_PageNumber(page_number)
  16. request.set_PageSize(page_size)
  17. return _send_request(request)

續費雲端服務器

續費執行個體只支援訂用帳戶的伺服器類型,不支援隨用隨付的伺服器,同時要求使用者必須支援帳號的餘額支付或信用支付。執行 API 的時候將執行同步的扣費和訂單生成。因此,執行 API 的時候必須保證您的帳號有足夠的資金支援自動扣費。

  1. def _renew_instance_action(instance_id, period='1'):
  2. request = RenewInstanceRequest()
  3. request.set_Period(period)
  4. request.set_InstanceId(instance_id)
  5. response = _send_request(request)
  6. logging.info('renew %s ready, output is %s ', instance_id, response)

續費執行個體將會自動完成扣費。在完成續費後,您可以根據InstanceId查詢執行個體的資源到期時間。由於 API 為非同步任務,查詢資源到期時間可能需要延遲 10 秒才會變化。

開啟雲端服務器自動續費

為了減少您的資源到期維護成本,針對訂用帳戶的 ECS 執行個體,阿里雲還推出了自動續費功能。 自動續費扣款日為伺服器到期前第 7 天的 08:00:00。如果前一日執行自動扣費失敗,將會繼續下一日定時執行,直到完成扣費或者 7 天后到期資源鎖定。您只需要保證自己的帳號餘額或者信用額度充足即可。

查詢自動續費設定

您可以通過 OpenAPI 來查詢和設定自動續費。該 API 僅支援訂用帳戶的執行個體,隨用隨付的執行個體執行將會報錯。查詢執行個體的自動續費狀態支援一次最多查詢 100 個訂用帳戶的執行個體,多個執行個體 ID 以逗號連接。

DescribeInstanceAutoRenewAttribut 的入參為執行個體 ID:

InstanceId:支援最多查詢 100 個訂用帳戶的執行個體,多個執行個體 ID 以逗號連接。

  1. # check the instances is renew or not
  2. def describe_auto_renew(instance_ids, expected_auto_renew=True):
  3. describe_request = DescribeInstanceAutoRenewAttributeRequest()
  4. describe_request.set_InstanceId(instance_ids)
  5. response_detail = _send_request(request=describe_request)
  6. failed_instance_ids = ''
  7. if response_detail is not None:
  8. attributes = response_detail.get('InstanceRenewAttributes').get('InstanceRenewAttribute')
  9. if attributes:
  10. for item in attributes:
  11. auto_renew_status = item.get('AutoRenewEnabled')
  12. if auto_renew_status != expected_auto_renew:
  13. failed_instance_ids += item.get('InstanceId') + ','
  14. describe_auto_renew('i-1111,i-2222')

返回內容如下:

  1. {"InstanceRenewAttributes":{"InstanceRenewAttribute":[{"Duration":0,"InstanceId":"i-1111","AutoRenewEnabled":false},{"Duration":0,"InstanceId":"i-2222","AutoRenewEnabled":false}]},"RequestId":"71FBB7A5-C793-4A0D-B17E-D6B426EA746A"}

如果設定自動續費,則返回的屬性AutoRenewEnabled為 true,否則返回 false。

設定和取消雲端服務器的自動續費

設定自動續費有三個入參:

  • InstanceId: 支援最多查詢100個訂用帳戶的執行個體,多個執行個體 ID 以逗號連接。
  • Duration:支援 1、2、3、6、12,單位為月。
  • AutoRenew:true/false, true為開啟自動續費,false為取消自動續費。
  1. def setting_instance_auto_renew(instance_ids, auto_renew = True):
  2. logging.info('execute enable auto renew ' + instance_ids)
  3. request = ModifyInstanceAutoRenewAttributeRequest();
  4. request.set_Duration(1);
  5. request.set_AutoRenew(auto_renew);
  6. request.set_InstanceId(instance_ids)
  7. _send_request(request)

執行成功返回 Response 如下:

  1. {"RequestId":"7DAC9984-AAB4-43EF-8FC7-7D74C57BE46D"}

續費成功後,您可以再執行一次查詢。如果續費成功將返回續費時長以及是否開啟自動續費。

  1. {"InstanceRenewAttributes":{"InstanceRenewAttribute":[{"Duration":1,"InstanceId":"i-1111","AutoRenewEnabled":true},{"Duration":1,"InstanceId":"i-2222","AutoRenewEnabled":true}]},"RequestId":"7F4D14B0-D0D2-48C7-B310-B1DF713D4331"}

完整的代碼如下:

  1. # coding=utf-8
  2. # if the python sdk is not install using 'sudo pip install aliyun-python-sdk-ecs'
  3. # if the python sdk is install using 'sudo pip install --upgrade aliyun-python-sdk-ecs'
  4. # make sure the sdk version is 2.1.2, you can use command 'pip show aliyun-python-sdk-ecs' to check
  5. import json
  6. import logging
  7. from aliyunsdkcore import client
  8. from aliyunsdkecs.request.v20140526.DescribeInstanceAutoRenewAttributeRequest import \
  9. DescribeInstanceAutoRenewAttributeRequest
  10. from aliyunsdkecs.request.v20140526.DescribeInstancesRequest import DescribeInstancesRequest
  11. from aliyunsdkecs.request.v20140526.ModifyInstanceAutoRenewAttributeRequest import \
  12. ModifyInstanceAutoRenewAttributeRequest
  13. from aliyunsdkecs.request.v20140526.RenewInstanceRequest import RenewInstanceRequest
  14. logging.basicConfig(level=logging.INFO,
  15. format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
  16. datefmt='%a, %d %b %Y %H:%M:%S')
  17. clt = client.AcsClient('Your Access Key Id', 'Your Access Key Secrect', 'cn-beijing')
  18. # data format in UTC, only support passed the value for minute, seconds is not support.
  19. INSTANCE_EXPIRED_START_TIME_IN_UTC_STRING = '2017-01-22T00:00Z'
  20. INSTANCE_EXPIRE_END_TIME_IN_UTC_STRING = '2017-01-28T00:00Z'
  21. def renew_job(page_size=100, page_number=1, check_need_renew=True, security_group_id=None):
  22. response = describe_need_renew_instance(page_size=page_size, page_number=page_number,
  23. check_need_renew=check_need_renew,
  24. security_group_id=security_group_id)
  25. response_list = response.get('Instances').get('Instance')
  26. logging.info("%s instances need to renew", str(response.get('TotalCount')))
  27. if response_list > 0:
  28. instance_ids = ''
  29. for item in response_list:
  30. instance_id = item.get('InstanceId')
  31. instance_ids += instance_id + ','
  32. renew_instance(instance_id=instance_id)
  33. logging.info("%s execute renew action ready", instance_ids)
  34. def describe_need_renew_instance(page_size=100, page_number=1, instance_id=None,
  35. check_need_renew=True, security_group_id=None):
  36. request = DescribeInstancesRequest()
  37. if check_need_renew is True:
  38. request.set_Filter3Key("ExpiredStartTime")
  39. request.set_Filter3Value(INSTANCE_EXPIRED_START_TIME_IN_UTC_STRING)
  40. request.set_Filter4Key("ExpiredEndTime")
  41. request.set_Filter4Value(INSTANCE_EXPIRE_END_TIME_IN_UTC_STRING)
  42. if instance_id is not None:
  43. request.set_InstanceIds(json.dumps([instance_id]))
  44. if security_group_id:
  45. request.set_SecurityGroupId(security_group_id)
  46. request.set_PageNumber(page_number)
  47. request.set_PageSize(page_size)
  48. return _send_request(request)
  49. # check the instances is renew or not
  50. def describe_instance_auto_renew_setting(instance_ids, expected_auto_renew=True):
  51. describe_request = DescribeInstanceAutoRenewAttributeRequest()
  52. describe_request.set_InstanceId(instance_ids)
  53. response_detail = _send_request(request=describe_request)
  54. failed_instance_ids = ''
  55. if response_detail is not None:
  56. attributes = response_detail.get('InstanceRenewAttributes').get('InstanceRenewAttribute')
  57. if attributes:
  58. for item in attributes:
  59. auto_renew_status = item.get('AutoRenewEnabled')
  60. if auto_renew_status != expected_auto_renew:
  61. failed_instance_ids += item.get('InstanceId') + ','
  62. if len(failed_instance_ids) > 0:
  63. logging.error("instance %s auto renew not match expect %s.", failed_instance_ids,
  64. expected_auto_renew)
  65. def setting_instance_auto_renew(instance_ids, auto_renew=True):
  66. logging.info('execute enable auto renew ' + instance_ids)
  67. request = ModifyInstanceAutoRenewAttributeRequest();
  68. request.set_Duration(1);
  69. request.set_AutoRenew(auto_renew);
  70. request.set_InstanceId(instance_ids)
  71. _send_request(request)
  72. describe_instance_auto_renew_setting(instance_ids, auto_renew)
  73. # if using the instance id can be found means the instance is not renew successfully.
  74. def check_instance_need_renew(instance_id):
  75. response = describe_need_renew_instance(instance_id=instance_id)
  76. if response is not None:
  77. return response.get('TotalCount') == 1
  78. return False
  79. # 續費一個執行個體一個月
  80. def renew_instance(instance_id, period='1'):
  81. need_renew = check_instance_need_renew(instance_id)
  82. if need_renew:
  83. _renew_instance_action(instance_id=instance_id, period=period)
  84. # describe_need_renew_instance(instance_id=instance_id, check_need_renew=False)
  85. def _renew_instance_action(instance_id, period='1'):
  86. request = RenewInstanceRequest()
  87. request.set_Period(period)
  88. request.set_InstanceId(instance_id)
  89. response = _send_request(request)
  90. logging.info('renew %s ready, output is %s ', instance_id, response)
  91. def _send_request(request):
  92. request.set_accept_format('json')
  93. try:
  94. response_str = clt.do_action(request)
  95. logging.info(response_str)
  96. response_detail = json.loads(response_str)
  97. return response_detail
  98. except Exception as e:
  99. logging.error(e)
  100. if __name__ == '__main__':
  101. logging.info("Renew ECS Instance by OpenApi!")
  102. # 查詢在指定的時間範圍內是否有需要續費的執行個體。
  103. describe_need_renew_instance()
  104. # 續費一個執行個體, 直接執行扣費
  105. renew_instance('i-1111')
  106. # 查詢執行個體自動續費的狀態
  107. # describe_instance_auto_renew_setting('i-1111,i-2222')
  108. # 設定執行個體自動續費
  109. # setting_instance_auto_renew('i-1111,i-2222')

如您想瞭解 ECS 中 API 的其它操作,請參考 ECS中的API操作