# coding: utf-8"""This module be able to manage ecs instances on the aliyun cloud. We choosesome helper functions from salt.cloud.clouds.aliyun since DRY principle.Full documentations about the Aliyun APIs are located at"https://help.aliyun.com/document_detail/25484.html"."""import sysimport timeimport uuidimport hmacimport base64import json #隐藏部分内部调用库 import logging log = logging.getLogger(__name__) from hashlib import sha1 import requestsimport salt.utils try: from salt.ext.six.moves.urllib.parse import quote as _quoteexcept: pass DEFAULT_ALIYUN_API_VERSION = ‘2014-05-26‘ def get_params(integration_info): utils.logger.info(‘{}‘.format(integration_info)) access_key_id = None secret_key = None if not isinstance(integration_info,dict): integration_info=json.loads(integration_info) for k, v in integration_info.items(): if k == ‘access_key_id‘: access_key_id = v elif k == ‘secret_key‘: secret_key = v return access_key_id, secret_key class HTTPError(Exception): def __init__(self, response): self.has_data = False self.status_code = response.status_code utils.logger.debug(self.status_code) self.content = response.content utils.logger.debug(self.content) if ‘application/json‘ in response.headers[‘Content-Type‘].lower(): self.has_data = True self.data = json.loads( self.content, object_hook=salt.utils.decode_dict) def _compute_signature(parameters, secret_key): ‘‘‘ Generate aliyun request signature ‘‘‘ def percent_encode(line): if not isinstance(line, str): return line s = line utils.logger.debug(sys.stdin.encoding) utils.logger.debug(sys.getdefaultencoding()) utils.logger.debug(sys.getfilesystemencoding()) if sys.stdin.encoding is None and sys.getfilesystemencoding() is None: s = line.decode().encode(‘utf8‘) elif sys.stdin.encoding is None and sys.getfilesystemencoding(): s = line.decode(sys.getfilesystemencoding()).encode(‘utf8‘) else: s = line.decode(sys.stdin.encoding).encode(‘utf8‘) res = _quote(s, ‘‘) res = res.replace(‘+‘, ‘%20‘) res = res.replace(‘*‘, ‘%2A‘) res = res.replace(‘%7E‘, ‘~‘) return res sortedParameters = sorted(list(parameters.items()), key=lambda items: items[0]) canonicalizedQueryString = ‘‘ for k, v in sortedParameters: canonicalizedQueryString += ‘&‘ + percent_encode(k) \ + ‘=‘ + percent_encode(v) # All aliyun API only support GET method stringToSign = ‘GET&%2F&‘ + percent_encode(canonicalizedQueryString[1:]) h = hmac.new(secret_key + "&", stringToSign, sha1) signature = base64.encodestring(h.digest()).strip() return signature def query(access_key_id, secret_key, params, jid=None, outputParam=[], **kwargs): ‘‘‘ Make a web call to aliyun ECS REST API ‘‘‘ path = ‘https://ecs.aliyuncs.com/‘ timestamp = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()) # public interface parameters parameters = { ‘Format‘: ‘JSON‘, ‘Version‘: DEFAULT_ALIYUN_API_VERSION, ‘AccessKeyId‘: access_key_id, ‘SignatureVersion‘: ‘1.0‘, ‘SignatureMethod‘: ‘HMAC-SHA1‘, ‘SignatureNonce‘: str(uuid.uuid1()), ‘TimeStamp‘: timestamp, } # include action or function parameters if params: parameters.update(params) # Calculate the string for Signature signature = _compute_signature(parameters, secret_key) parameters[‘Signature‘] = signature utils.logger.debug(parameters) utils.logger.debug(path) utils.logger.debug(parameters) request = requests.get(path, params=parameters, verify=True) utils.logger.debug(‘request url:{}‘.format(path)) utils.logger.debug(‘parameters:{}‘.format(parameters)) if request.status_code != 200: raise HTTPError(request) log.debug(request.url) utils.logger.debug(request.url) utils.logger.debug(request.status_code) content = request.text utils.logger.debug(content) result = json.loads(content, object_hook=salt.utils.decode_dict) if ‘Code‘ in result: raise HTTPError(request) return result def http_error_code_result(http_error): if http_error.has_data and ‘Code‘ in http_error.data: return {"success": False, "message": u‘error code:{0}‘.format(http_error.data[‘Code‘])} else: log.error(‘{}‘.format(http_error.content)) utils.logger.error(‘{}‘.format(http_error.content)) return {"success": False, "message": u‘unknown error‘} def byteify(input_str): if isinstance(input_str, dict): return {byteify(key): byteify(value) for key, value in input_str.iteritems()} elif isinstance(input_str, list): return [byteify(element) for element in input_str] elif isinstance(input_str, unicode): return input_str.encode(‘utf-8‘) else: return input_str def create(integration_info=None, vm_conf=None, jid=None, outputParam=[], **kwargs): params = { ‘Action‘: ‘CreateInstance‘, } try: ret, param = utils_errors.check_inputs(locals()) if not ret: return {‘success‘: False, ‘message‘: ‘input params error,please check input params:{}‘.format(param)} access_key_id, secret_key = get_params(integration_info) if vm_conf in ({}, None, ‘‘): return {"success": False, "message": u‘create ECS instance fail,please check the config params‘} else: params.update(vm_conf) params = byteify(params) access_key_id = byteify(access_key_id) secret_key = byteify(secret_key) result = query(access_key_id, secret_key, params) utils.logger.info(‘result:{}‘.format(result)) instanceId = result.get(‘InstanceId‘, None) out = {‘instance_id‘: instanceId} utils.logger.info(‘{} {}‘.format(out, outputParam)) outs = utils_params.get_output(out, outputParam) except HTTPError as e: return http_error_code_result(e) return {"success": True, "message": u‘create ECS instance success,instance ID:{0}‘.format(instanceId), ‘outputParam‘: outs} def edit(integration_info=None, opts=None, access_key_id=None, secret_key=None, instance_id=None, instanceName=None, Description=None, Password=None, HostName=None, jid=None, outputParam=[], **kwargs): access_key_id, secret_key = get_params(integration_info) params = { ‘Action‘: ‘ModifyInstanceAttribute‘, ‘InstanceId‘: instance_id, ‘InstanceName‘: instanceName, ‘Description‘: Description, ‘Password‘: Password, ‘HostName‘: HostName, } for k, v in params.items(): if not v: del params[k] try: ret, param = utils_errors.check_inputs(locals()) if not ret: return {‘success‘: False, ‘message‘: ‘input params error,please check input params:{}‘.format(param)} params = byteify(params) access_key_id = byteify(access_key_id) secret_key = byteify(secret_key) result = query(access_key_id, secret_key, params) utils.logger.info(‘{}‘.format(result)) instanceId = result.get(‘RequestId‘, None) out = {‘instance_id‘: instanceId} outs = utils_params.get_output(out, outputParam) utils.logger.info(‘{}‘.format(outs)) except HTTPError as e: return http_error_code_result(e) else: return {‘success‘: True, ‘message‘: u‘edit ECS instance success,instance ID:{0}‘.format( instanceId), ‘outputParam‘: outs} def _query_status(integration_info, region_id=None, instance_id=None, **kwargs): access_key_id, secret_key = get_params(integration_info) params = { ‘Action‘: ‘DescribeInstanceStatus‘, } try: params = byteify(params) access_key_id = byteify(access_key_id) secret_key = byteify(secret_key) regions = _query_region(integration_info) status = None for i in regions: params[‘RegionId‘] = i result = query(access_key_id, secret_key, params) for i in result[‘InstanceStatuses‘][‘InstanceStatus‘]: if i[‘InstanceId‘] == instance_id: status = i[‘Status‘] break if status: # Running|Stopped return True, status if not status: return False, ‘the instance not exists‘ except HTTPError as e: return http_error_code_result(e) def start(integration_info=None, opts=None, access_key_id=None, secret_key=None, instance_id=None, jid=None, outputParam=[], **kwargs): access_key_id, secret_key = get_params(integration_info) params = { ‘Action‘: ‘StartInstance‘, ‘InstanceId‘: instance_id, } try: ret, param = utils_errors.check_inputs(locals()) if not ret: return {‘success‘: False, ‘message‘: ‘input params error,please check input params:{}‘.format(param)} params = byteify(params) access_key_id = byteify(access_key_id) secret_key = byteify(secret_key) result = query(access_key_id, secret_key, params) except HTTPError as e: return http_error_code_result(e) else: return {‘success‘: True, ‘message‘: u‘instance start success‘} def _query_zone(integration_info=None, region_id=None): params = { ‘Action‘: ‘DescribeZones‘, ‘RegionId‘: region_id, } access_key_id, secret_key = get_params(integration_info) params = byteify(params) access_key_id = byteify(access_key_id) secret_key = byteify(secret_key) result = query(access_key_id, secret_key, params) return result.get(‘ZoneId‘) def _query_region(integration_info=None): params = { ‘Action‘: ‘DescribeRegions‘, } access_key_id, secret_key = get_params(integration_info) params = byteify(params) access_key_id = byteify(access_key_id) secret_key = byteify(secret_key) result = query(access_key_id, secret_key, params) result = result[‘Regions‘][‘Region‘] results = [i[‘RegionId‘] for i in result] return results def query_ecs(integration_info=None, opts=None, region_id=None, instance_id=‘Instances‘, jid=None, outputParam=[], **kwargs): params = { ‘Action‘: ‘DescribeInstances‘, ‘RegionId‘: region_id, } try: ret, param = utils_errors.check_inputs(locals()) if not ret: return {‘success‘: False, ‘message‘: ‘input params error,please check input params:{}‘.format(param)} access_key_id, secret_key = get_params(integration_info) params = byteify(params) access_key_id = byteify(access_key_id) secret_key = byteify(secret_key) result = query(access_key_id, secret_key, params)[‘Instances‘][‘Instance‘] out = {} for i in result: if i[‘InstanceId‘] == instance_id: out[‘PrivateIpAddresses‘] = ‘,‘.join( i[‘VpcAttributes‘][‘PrivateIpAddress‘][‘IpAddress‘]) out[‘InnerIpAddresses‘] = ‘,‘.join(i[‘InnerIpAddress‘][‘IpAddress‘]) out[‘PublicIpAddresses‘] = ‘,‘.join(i[‘PublicIpAddress‘][‘IpAddress‘]) out[‘InstanceName‘] = ‘,‘.join(i[‘InstanceName‘]) out[‘Memory‘] = ‘,‘.join(i[‘Memory‘]) out[‘CPU‘] = ‘,‘.join(i[‘Cpu‘]) out[‘HostName‘] = ‘,‘.join(i[‘HostName‘]) out[‘Status‘] = ‘,‘.join(i[‘Status‘]) out[‘CreationTime‘] = ‘,‘.join(i[‘CreationTime‘]) out[‘ExpiredTime‘] = ‘,‘.join(i[‘ExpiredTime‘]) out[‘InstanceNetworkType‘] = ‘,‘.join(i[‘InstanceNetworkType‘]) outs = utils_params.get_output(out, outputParam) except HTTPError as e: return http_error_code_result(e) else: return {‘success‘: True, ‘message‘: ‘query success‘, ‘outputParam‘: outs} def query_zone(integration_info=None, region_id=None, **kwargs): params = { ‘Action‘: ‘DescribeZones‘, ‘RegionId‘: region_id } try: ret, param = utils_errors.check_inputs(locals()) if not ret: return {‘success‘: False, ‘message‘: ‘input params error,please check input params:{}‘.format(param)} access_key_id, secret_key = get_params(integration_info) params = byteify(params) access_key_id = byteify(access_key_id) secret_key = byteify(secret_key) result = query(access_key_id, secret_key, params) except HTTPError as e: return http_error_code_result(e) else: return {‘success‘: True, ‘message‘: ‘query result:\n{}‘.format(utils_params.format_json(result))} def reboot(integration_info=None, opts=None, access_key_id=None, secret_key=None, instance_id=None, jid=None, outputParam=[], **kwargs): params = { ‘Action‘: ‘RebootInstance‘, ‘InstanceId‘: instance_id, } try: ret, param = utils_errors.check_inputs(locals()) if not ret: return {‘success‘: False, ‘message‘: ‘input params error,please check input params:{}‘.format(param)} access_key_id, secret_key = get_params(integration_info) params = byteify(params) access_key_id = byteify(access_key_id) secret_key = byteify(secret_key) result = query(access_key_id, secret_key, params) except HTTPError as e: return http_error_code_result(e) else: return {‘success‘: True, ‘message‘: u‘instance restart success‘} def stop(integration_info=None, instance_id=None, **kwargs): params = { ‘Action‘: ‘StopInstance‘, ‘InstanceId‘: instance_id, } try: ret, param = utils_errors.check_inputs(locals()) if not ret: return {‘success‘: False, ‘message‘: ‘input params error,please check input params:{}‘.format(param)} access_key_id, secret_key = get_params(integration_info) params = byteify(params) access_key_id = byteify(access_key_id) secret_key = byteify(secret_key) result = query(access_key_id, secret_key, params) start_time = time.time() while True: status, res = _query_status(integration_info, instance_id=instance_id) if status and res == ‘Stopped‘: return {‘success‘: True, ‘message‘: u‘instance stop success‘} end_time = time.time() if end_time - start_time >= 10000: return {‘success‘: False, ‘message‘: u‘time is out‘} except HTTPError as e: return http_error_code_result(e) def delete(integration_info=None, opts=None, instance_id=None, access_key_id=None, secret_key=None, jid=None, outputParam=[], **kwargs): params = { ‘Action‘: ‘DeleteInstance‘, ‘InstanceId‘: instance_id, } try: ret, param = utils_errors.check_inputs(locals()) if not ret: return {‘success‘: False, ‘message‘: ‘input params error,please check input params:{}‘.format(param)} access_key_id, secret_key = get_params(integration_info) params = byteify(params) access_key_id = byteify(access_key_id) secret_key = byteify(secret_key) result = query(access_key_id, secret_key, params) except HTTPError as e: return http_error_code_result(e) else: return {‘success‘: True, ‘message‘: u‘instance delete success‘} def create_image(integration_info=None, opts=None, image=None, jid=None, access_key_id=None, secret_key=None, outputParam=[], **kwargs): params = { ‘Action‘: ‘CreateImage‘, } try: ret, param = utils_errors.check_inputs(locals()) if not ret: return {‘success‘: False, ‘message‘: ‘input params error,please check input params:{}‘.format(param)} access_key_id, secret_key = get_params(integration_info) params.update(image) params = byteify(params) access_key_id = byteify(access_key_id) secret_key = byteify(secret_key) result = query(access_key_id, secret_key, params) utils.logger.debug(‘create_image‘) except HTTPError as e: return http_error_code_result(e) else: return {‘success‘: True, ‘message‘: u‘create image success,image ID:{0}‘.format(result[‘ImageId‘])}
原文地址:https://www.cnblogs.com/slqt/p/10947959.html
时间: 2024-10-11 16:17:12