ecs.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. # coding:utf-8
  2. import json
  3. import logging
  4. import time
  5. from aliyunsdkcore import client
  6. from aliyunsdkecs.request.v20140526.DescribeInstancesRequest import DescribeInstancesRequest
  7. from aliyunsdkecs.request.v20140526.RunInstancesRequest import RunInstancesRequest
  8. from aliyunsdkecs.request.v20140526.DeleteInstanceRequest import DeleteInstanceRequest
  9. class EcsClient(object):
  10. def __init__(self, config):
  11. # 区域设置
  12. self.region_id = config.get("region_id", "cn-beijing")
  13. self.ak_id = config.get("ak_id")
  14. self.ak_secret = config.get("ak_secret")
  15. self.config = config
  16. self.clt = client.AcsClient(self.ak_id, self.ak_secret, self.region_id)
  17. # pass
  18. # 创建请求
  19. @staticmethod
  20. def build_request(config):
  21. request = RunInstancesRequest()
  22. # 实例所属的地域区
  23. request.set_ZoneId(config.get("zone_id")) if config.get("zone_id") else None
  24. # 交换机ID
  25. request.set_VSwitchId(config.get("vswitch_id")) if config.get("vswitch_id") else None
  26. # 镜像ID
  27. request.set_ImageId(config.get("image_id")) if config.get("image_id") else None
  28. # 安全组ID
  29. request.set_SecurityGroupId(config.get("security_group_id")) if config.get("security_group_id") else None
  30. # 实例规格
  31. request.set_InstanceType(config.get("instance_type")) if config.get("instance_type") else None
  32. # 优化本地盘
  33. request.set_IoOptimized(config.get("io_optimized")) if config.get("io_optimized") else None
  34. # 高效云盘
  35. request.set_SystemDiskCategory(config.get("system_disk_category")) if config.get(
  36. "system_disk_category") else None
  37. # 默认40G
  38. request.set_SystemDiskSize(config.get("system_disk_size")) if config.get("system_disk_size") else None
  39. request.set_SpotStrategy("SpotAsPriceGo") # 竞价模式自动出价
  40. request.set_PasswordInherit(True) # 使用镜像用户名密码
  41. # 实例名称
  42. request.set_InstanceName(config.get("instance_name")) if config.get("instance_name") else "auto_create_instance"
  43. # 保护期
  44. request.set_SpotDuration(config.get("spot_duration")) if config.get("spot_duration") else 0
  45. return request
  46. # 创建实例并启动
  47. def create_multiple_instances(self, amount):
  48. '''
  49. 创建实例
  50. :param amount: 创建数量
  51. :param config: 实例配置见 build_request
  52. :return:
  53. '''
  54. request = self.build_request(self.config)
  55. request.set_Amount(amount)
  56. return self._execute_request(request, amount)
  57. # 发送API请求
  58. def _send_request(self, request):
  59. request.set_accept_format('json')
  60. try:
  61. response_str = self.clt.do_action_with_exception(request)
  62. logging.info(response_str)
  63. response_detail = json.loads(response_str)
  64. return response_detail
  65. except Exception as e:
  66. logging.error(e)
  67. return None
  68. def _execute_request(self, request, amount):
  69. response = self._send_request(request)
  70. if response.get('Code') is None:
  71. instance_ids = response.get('InstanceIdSets').get('InstanceIdSet')
  72. instances = []
  73. while len(instances) < amount:
  74. time.sleep(10)
  75. instances = self.check_instance_running(instance_ids)
  76. return instances
  77. # 检查实例的运行状态
  78. def check_instance_running(self, instance_ids):
  79. request = DescribeInstancesRequest()
  80. request.set_InstanceIds(json.dumps(instance_ids))
  81. response = self._send_request(request)
  82. if response.get('Code') is None:
  83. instances_list = response.get('Instances').get('Instance')
  84. instances = []
  85. for instance_detail in instances_list:
  86. if instance_detail.get('Status') == "Running":
  87. vpc_attributes = instance_detail.get('VpcAttributes', {}).get('PrivateIpAddress', {}).get(
  88. 'IpAddress',[])
  89. intranet_ip = vpc_attributes[0] if len(vpc_attributes) > 0 else None
  90. instances.append((instance_detail.get('InstanceId'), intranet_ip))
  91. return instances
  92. def release_instance(self, instance_id, force=False):
  93. """
  94. 根据实例id删除实例
  95. :param instance_id: 实例id
  96. :param force: 当值为True时,运行的中实例也会被释放
  97. :return:
  98. """
  99. request = DeleteInstanceRequest()
  100. request.set_InstanceId(instance_id)
  101. request.set_Force(force)
  102. return self._send_request(request)
  103. # 检查实例的运行状态
  104. def check_instance_status(self, instance_ids):
  105. instances = []
  106. request = DescribeInstancesRequest()
  107. request.set_InstanceIds(json.dumps(instance_ids))
  108. response = self._send_request(request)
  109. if response.get('Code') is None:
  110. instances_list = response.get('Instances').get('Instance')
  111. for instance_detail in instances_list:
  112. vpc_attributes = instance_detail.get('VpcAttributes', {}).get('PrivateIpAddress', {}).get('IpAddress',
  113. [])
  114. intranet_ip = vpc_attributes[0] if len(vpc_attributes) > 0 else None
  115. instances.append((instance_detail.get('InstanceId'), intranet_ip))
  116. return instances
  117. else:
  118. return None
  119. def add_instance(self, num):
  120. for i in range(5):
  121. try:
  122. instance_ids = self.create_multiple_instances(num)
  123. if instance_ids:
  124. return instance_ids
  125. except Exception as e:
  126. print(e)
  127. time.sleep(5)
  128. def delete_instance(self, instance_ids):
  129. delete_false = []
  130. for instance_id in instance_ids:
  131. try:
  132. result = self.release_instance(instance_id, force=True)
  133. if not result:
  134. delete_false.append(instance_id)
  135. except Exception as e:
  136. print(e)
  137. time.sleep(2)
  138. delete_false.append(instance_id)
  139. return delete_false
  140. def instance_status(self, instance_ids):
  141. for r in range(5):
  142. try:
  143. result = self.check_instance_status(instance_ids)
  144. if result:
  145. return result
  146. except Exception as e:
  147. print(e)
  148. time.sleep(2)
  149. if __name__ == '__main__':
  150. config = {
  151. "ak_id": "LTAI4G5x9aoZx8dDamQ7vfZi",
  152. "region_id": "cn-beijing",
  153. "ak_secret": "Bk98FsbPYXcJe72n1bG3Ssf73acuNh",
  154. "image_id": "m-2zeihn2b3vxj7s5z1zxp",
  155. "instance_type": "ecs.g5.xlarge",
  156. "security_group_id": "sg-2ze6zhxrqy9vueae27xy",
  157. "vswitch_id": "vsw-2ze1n1k3mo3fv2irsfdps"
  158. }
  159. ecs = EcsClient(config)
  160. # result=ecs.create_multiple_instances(1)
  161. # print(result)
  162. # result = ecs.check_instance_status(["i-2ze4j0syekh1oq9017ok"])
  163. # print(result)
  164. # result = ecs.release_instance("i-2ze4j0syekh1oq9017ok", force=True)
  165. # print(result)