def _to_volumes(self, element): # ステータスチェック(保留) # try: # state = self.NODE_STATE_MAP[ # findattr(element=element, xpath="instanceState/name", # namespace=NAMESPACE) # ] # except KeyError: # state = NodeState.UNKNOWN tags = dict( ( findtext(element=item, xpath="key", namespace=NAMESPACE), findtext(element=item, xpath="value", namespace=NAMESPACE), ) for item in findall(element=element, xpath="tagSet/item", namespace=NAMESPACE) ) attachment = [] for rs in findall(element=element, xpath="attachmentSet/item", namespace=NAMESPACE): attachmentset = self._to_attachmentSet(rs) attachmentset.setDeleteOnTermination( findattr(element=element, xpath="deleteOnTermination", namespace=NAMESPACE) ) attachment.append(attachmentset) v = self._to_volume(element, attachment, tags) return v
def _to_balancer(self, el): name = findtext(element=el, xpath='LoadBalancerName', namespace=NS) id = findtext(element=el, xpath='LoadBalancerArn', namespace=NS) dns_name = findtext(el, xpath='DNSName', namespace=NS) balancer = LoadBalancer( id=id, name=name, state=State.UNKNOWN, ip=dns_name, port=None, driver=self.connection.driver ) extra = { 'listeners': self._ex_get_balancer_listeners(balancer), 'target_groups': self._ex_get_balancer_target_groups(balancer), 'tags': self._ex_get_balancer_tags(balancer) } balancer.extra = extra if len(extra['listeners']) > 0: balancer.port = extra['listeners'][0]['port'] else: balancer.port = None balancer._members = self._ex_get_balancer_memebers(balancer) return balancer
def ex_describe_all_addresses(self, only_allocated=False): """ Return all the Elastic IP addresses for this account optionally, return only the allocated addresses @param only_allocated: If true, return only those addresses that are associated with an instance @type only_allocated: C{str} @return: list list of elastic ips for this particular account. @rtype: C{list} of C{str} """ params = {'Action': 'DescribeAddresses'} result = self.connection.request(self.path, params=params.copy()).object # the list which we return elastic_ip_addresses = [] for element in findall(element=result, xpath='addressesSet/item', namespace=NAMESPACE): instance_id = findtext(element=element, xpath='instanceId', namespace=NAMESPACE) # if only allocated addresses are requested if only_allocated and not instance_id: continue ip_address = findtext(element=element, xpath='publicIp', namespace=NAMESPACE) elastic_ip_addresses.append(ip_address) return elastic_ip_addresses
def _to_rule(self, el): def __to_bool__(val): return val.lower() in ("yes", "true", "t", "1") id = findtext(element=el, xpath='RuleArn', namespace=NS) is_default = findtext(element=el, xpath='IsDefault', namespace=NS) priority = findtext(element=el, xpath='Priority', namespace=NS) target_group = findtext( element=el, xpath='Actions/member/TargetGroupArn', namespace=NS ) conditions = {} cond_members = findall( element=el, xpath='Conditions/member', namespace=NS ) for cond_member in cond_members: field = findtext(element=cond_member, xpath='Field', namespace=NS) conditions[field] = [] value_members = findall( element=cond_member, xpath='Values/member', namespace=NS ) for value_member in value_members: conditions[field].append(value_member.text) rule = { 'id': id, 'is_default': __to_bool__(is_default), 'priority': priority, 'target_group': target_group, 'conditions': conditions } return rule
def _get_resource_tags(self, element): """ Parse tags from the provided element and return a dictionary with key/value pairs. :rtype: ``dict`` """ tags = {} # Get our tag set by parsing the element tag_set = findall(element=element, xpath='tagSet/item', namespace=NS) for tag in tag_set: key = findtext(element=tag, xpath='key', namespace=NS) value = findtext(element=tag, xpath='value', namespace=NS) tags[key] = value return tags
def ex_import_keypair(self, name, keyfile): """ imports a new public key @note: This is a non-standard extension API, and only works for EC2. @param name: The name of the public key to import. This must be unique, otherwise an InvalidKeyPair.Duplicate exception is raised. @type name: C{str} @param keyfile: The filename with path of the public key to import. @type keyfile: C{str} @rtype: C{dict} """ with open(os.path.expanduser(keyfile)) as fh: content = fh.read() base64key = base64.b64encode(content) params = { 'Action': 'ImportKeyPair', 'KeyName': name, 'PublicKeyMaterial': base64key } response = self.connection.request(self.path, params=params).object key_name = findtext(element=response, xpath='keyName', namespace=NAMESPACE) key_fingerprint = findtext(element=response, xpath='keyFingerprint', namespace=NAMESPACE) return { 'keyName': key_name, 'keyFingerprint': key_fingerprint, }
def _to_balancer(self, element): ipaddress = findtext(element, 'listenerIpAddress', TYPES_URN) name = findtext(element, 'name', TYPES_URN) port = findtext(element, 'port', TYPES_URN) extra = {} pool_element = element.find(fixxpath( 'pool', TYPES_URN)) if pool_element is None: extra['pool_id'] = None else: extra['pool_id'] = pool_element.get('id') extra['network_domain_id'] = findtext(element, 'networkDomainId', TYPES_URN) balancer = LoadBalancer( id=element.get('id'), name=name, state=self._VALUE_TO_STATE_MAP.get( findtext(element, 'state', TYPES_URN), State.UNKNOWN), ip=ipaddress, port=port, driver=self.connection.driver, extra=extra ) return balancer
def _to_base_image(self, element, locations): # Eventually we will probably need multiple _to_image() functions # that parse <ServerImage> differently than <DeployedImage>. # DeployedImages are customer snapshot images, and ServerImages are # 'base' images provided by DimensionData location_id = element.get('location') location = list(filter(lambda x: x.id == location_id, locations))[0] extra = { 'description': findtext(element, 'description', SERVER_NS), 'OS_type': findtext(element, 'operatingSystem/type', SERVER_NS), 'OS_displayName': findtext(element, 'operatingSystem/displayName', SERVER_NS), 'cpuCount': findtext(element, 'cpuCount', SERVER_NS), 'resourcePath': findtext(element, 'resourcePath', SERVER_NS), 'memory': findtext(element, 'memory', SERVER_NS), 'osStorage': findtext(element, 'osStorage', SERVER_NS), 'additionalStorage': findtext(element, 'additionalStorage', SERVER_NS), 'created': findtext(element, 'created', SERVER_NS), 'location': location, } return NodeImage(id=element.get('id'), name=str(findtext(element, 'name', SERVER_NS)), extra=extra, driver=self.connection.driver)
def _get_data(self, rtype, last_key, **kwargs): params = {} if last_key: params['name'] = last_key path = API_ROOT + 'hostedzone' if rtype == 'zones': response = self.connection.request(path, params=params) transform_func = self._to_zones elif rtype == 'records': zone = kwargs['zone'] path += '/%s/rrset' % (zone.id) self.connection.set_context({'zone_id': zone.id}) response = self.connection.request(path, params=params) transform_func = self._to_records if response.status == httplib.OK: is_truncated = findtext(element=response.object, xpath='IsTruncated', namespace=NAMESPACE) exhausted = is_truncated != 'true' last_key = findtext(element=response.object, xpath='NextRecordName', namespace=NAMESPACE) items = transform_func(data=response.object, **kwargs) return items, last_key, exhausted else: return [], None, True
def _to_record(self, elem, zone, index=0): name = findtext(element=elem, xpath='Name', namespace=NAMESPACE) name = name[:-len(zone.domain) - 1] type = self._string_to_record_type(findtext(element=elem, xpath='Type', namespace=NAMESPACE)) ttl = int(findtext(element=elem, xpath='TTL', namespace=NAMESPACE)) value_elem = elem.findall( fixxpath(xpath='ResourceRecords/ResourceRecord', namespace=NAMESPACE))[index] data = findtext(element=(value_elem), xpath='Value', namespace=NAMESPACE) extra = {'ttl': ttl} if type == 'MX': split = data.split() priority, data = split extra['priority'] = int(priority) elif type == 'SRV': split = data.split() priority, weight, port, data = split extra['priority'] = int(priority) extra['weight'] = int(weight) extra['port'] = int(port) id = ':'.join((self.RECORD_TYPE_MAP[type], name)) record = Record(id=id, name=name, type=type, data=data, zone=zone, driver=self, extra=extra) return record
def ex_describe_tags(self, resource): """ Return a dictionary of tags for a resource (Node or StorageVolume). @param resource: resource which should be used @type resource: L{Node} or L{StorageVolume} @return: dict Node tags @rtype: C{dict} """ params = {'Action': 'DescribeTags', 'Filter.0.Name': 'resource-id', 'Filter.0.Value.0': resource.id, 'Filter.1.Name': 'resource-type', 'Filter.1.Value.0': 'instance', } result = self.connection.request(self.path, params=params.copy()).object tags = {} for element in findall(element=result, xpath='tagSet/item', namespace=NAMESPACE): key = findtext(element=element, xpath='key', namespace=NAMESPACE) value = findtext(element=element, xpath='value', namespace=NAMESPACE) tags[key] = value return tags
def _to_target_group_member(self, el): id = findtext(element=el, xpath='Target/Id', namespace=NS) port = findtext(element=el, xpath='Target/Port', namespace=NS) health = findtext( element=el, xpath='TargetHealth/State', namespace=NS ) return {'id': id, 'port': port, 'health': health}
def _to_target_group(self, el): target_group_arn = findtext( element=el, xpath='TargetGroupArn', namespace=NS ) name = findtext(element=el, xpath='TargetGroupName', namespace=NS) members = self._ex_get_target_group_members(target_group_arn) return {'id': target_group_arn, 'name': name, 'members': members}
def _to_volume(self, element, name): volId = findtext(element=element, xpath='volumeId', namespace=NAMESPACE) size = findtext(element=element, xpath='size', namespace=NAMESPACE) return StorageVolume(id=volId, name=name, size=int(size), driver=self)
def _to_nat_rule(self, element, network_domain): status = self._to_status(element.find(fixxpath('state', TYPES_URN))) return DimensionDataNatRule( id=element.get('id'), network_domain=network_domain, internal_ip=findtext(element, 'internalIp', TYPES_URN), external_ip=findtext(element, 'externalIp', TYPES_URN), status=status)
def _to_listener(self, el): listener_arn = findtext(element=el, xpath='ListenerArn', namespace=NS) listener = { 'id': listener_arn, 'protocol': findtext(element=el, xpath='Protocol', namespace=NS), 'port': findtext(element=el, xpath='Port', namespace=NS), 'rules': self._ex_get_rules_for_listener(listener_arn) } return listener
def _to_health_monitor(self, element): return DimensionDataDefaultHealthMonitor( id=element.get('id'), name=findtext(element, 'name', TYPES_URN), node_compatible=bool( findtext(element, 'nodeCompatible', TYPES_URN) == "true"), pool_compatible=bool( findtext(element, 'poolCompatible', TYPES_URN) == "true"), )
def _recv_wait_set(self): params = {'Action': 'DescribeSpotInstanceRequests'} object = self.conn.connection.request(self.conn.path, params=params).object wait_ids = [] for elem in object.findall(fixxpath(xpath='spotInstanceRequestSet/item', namespace=NAMESPACE)): inst_id = findtext(element=elem, xpath='spotInstanceRequestId',namespace=NAMESPACE) status = findtext(element=elem, xpath='status/code',namespace=NAMESPACE) if status == 'pending-evaluation' or status == 'pending-fulfillment': wait_ids.append(inst_id) return wait_ids
def _to_record(self, elem, zone): id = findtext(element=elem, xpath='id') name = findtext(element=elem, xpath='hostname') type = findtext(element=elem, xpath='host-type') type = self._string_to_record_type(type) data = findtext(element=elem, xpath='data') notes = findtext(element=elem, xpath='notes', no_text_value=None) state = findtext(element=elem, xpath='state', no_text_value=None) fqdn = findtext(element=elem, xpath='fqdn', no_text_value=None) priority = findtext(element=elem, xpath='priority', no_text_value=None) ttl = findtext(element=elem, xpath='ttl', no_text_value=None) if not name: name = None if ttl: ttl = int(ttl) extra = {'notes': notes, 'state': state, 'fqdn': fqdn, 'priority': priority, 'ttl': ttl} record = Record(id=id, name=name, type=type, data=data, zone=zone, driver=self, extra=extra) return record
def _to_image(self, element): n = NodeImage( id=findtext(element=element, xpath="imageId", namespace=NAMESPACE), name=findtext(element=element, xpath="imageLocation", namespace=NAMESPACE), driver=self.connection.driver, extra={ "rootDeviceType": findattr(element=element, xpath="rootDeviceType", namespace=NAMESPACE), "platform": findattr(element=element, xpath="platform", namespace=NAMESPACE), }, ) return n
def _parse_error_details(self, element): """ Parse code and message from the provided error element. :return: ``tuple`` with two elements: (code, message) :rtype: ``tuple`` """ code = findtext(element=element, xpath="Code", namespace=self.namespace) message = findtext(element=element, xpath="Message", namespace=self.namespace) return code, message
def _to_client(self, element, target): client_id = element.get('id') return DimensionDataBackupClient( id=client_id, type=self._to_client_type(element), status=element.get('status'), schedule_policy=findtext(element, 'schedulePolicyName', BACKUP_NS), storage_policy=findtext(element, 'storagePolicyName', BACKUP_NS), download_url=findtext(element, 'downloadUrl', BACKUP_NS), running_job=self._to_backup_job(element, target, client_id), alert=self._to_alert(element) )
def _to_node(self, element): if findtext(element, 'started', TYPES_URN) == 'true': state = NodeState.RUNNING else: state = NodeState.TERMINATED status = self._to_status(element.find(fixxpath('progress', TYPES_URN))) has_network_info \ = element.find(fixxpath('networkInfo', TYPES_URN)) is not None extra = { 'description': findtext(element, 'description', TYPES_URN), 'sourceImageId': findtext(element, 'sourceImageId', TYPES_URN), 'networkId': findtext(element, 'networkId', TYPES_URN), 'networkDomainId': element.find(fixxpath('networkInfo', TYPES_URN)) .get('networkDomainId') if has_network_info else None, 'datacenterId': element.get('datacenterId'), 'deployedTime': findtext(element, 'createTime', TYPES_URN), 'cpuCount': int(findtext( element, 'cpuCount', TYPES_URN)), 'memoryMb': int(findtext( element, 'memoryGb', TYPES_URN)) * 1024, 'OS_id': element.find(fixxpath( 'operatingSystem', TYPES_URN)).get('id'), 'OS_type': element.find(fixxpath( 'operatingSystem', TYPES_URN)).get('family'), 'OS_displayName': element.find(fixxpath( 'operatingSystem', TYPES_URN)).get('displayName'), 'status': status } public_ip = findtext(element, 'publicIpAddress', TYPES_URN) private_ip = element.find( fixxpath('networkInfo/primaryNic', TYPES_URN)) \ .get('privateIpv4') \ if has_network_info else \ element.find(fixxpath('nic', TYPES_URN)).get('privateIpv4') n = Node(id=element.get('id'), name=findtext(element, 'name', TYPES_URN), state=state, public_ips=[public_ip] if public_ip is not None else [], private_ips=[private_ip] if private_ip is not None else [], driver=self.connection.driver, extra=extra) return n
def _to_tags(self, data): """ return tags dict """ tags = {} xpath = 'DescribeTagsResult/TagDescriptions/member/Tags/member' for el in findall(element=data, xpath=xpath, namespace=NS): key = findtext(element=el, xpath='Key', namespace=NS) value = findtext(element=el, xpath='Value', namespace=NS) if key: tags[key] = value return tags
def _to_container(self, element): extra = { 'creation_date': findtext(element=element, xpath='CreationDate', namespace=self.namespace) } container = Container(name=findtext(element=element, xpath='Name', namespace=self.namespace), extra=extra, driver=self ) return container
def _to_status(self, element): if element is None: return DimensionDataStatus() s = DimensionDataStatus(action=findtext(element, 'action', SERVER_NS), request_time=findtext( element, 'requestTime', SERVER_NS), user_name=findtext( element, 'userName', SERVER_NS), number_of_steps=findtext( element, 'numberOfSteps', SERVER_NS), step_name=findtext( element, 'step/name', SERVER_NS), step_number=findtext( element, 'step_number', SERVER_NS), step_percent_complete=findtext( element, 'step/percentComplete', SERVER_NS), failure_reason=findtext( element, 'failureReason', SERVER_NS)) return s
def parse_error(self): """ Parse error responses from Aliyun. """ body = super(AliyunXmlResponse, self).parse_error() code, message = self._parse_error_details(element=body) request_id = findtext(element=body, xpath='RequestId', namespace=self.namespace) host_id = findtext(element=body, xpath='HostId', namespace=self.namespace) error = {'code': code, 'message': message, 'request_id': request_id, 'host_id': host_id} return u(error)
def ex_destroy_pool_member(self, member, destroy_node=False): """ Destroy a specific member of a pool :param pool: The instance of a pool member :type pool: ``DimensionDataPoolMember`` :param destroy_node: Also destroy the associated node :type destroy_node: ``bool`` :return: ``True`` for success, ``False`` for failure :rtype: ``bool`` """ # remove the pool member destroy_request = ET.Element('removePoolMember', {'xmlns': TYPES_URN, 'id': member.id}) result = self.connection.request_with_orgId_api_2( action='networkDomainVip/removePoolMember', method='POST', data=ET.tostring(destroy_request)).object if member.node_id is not None and destroy_node is True: return self.ex_destroy_node(member.node_id) else: response_code = findtext(result, 'responseCode', TYPES_URN) return response_code in ['IN_PROGRESS', 'OK']
def parse_error(self): if self.status == httplib.UNAUTHORIZED: raise InvalidCredsError(self.body) elif self.status == httplib.FORBIDDEN: raise InvalidCredsError(self.body) body = self.parse_body() if self.status == httplib.BAD_REQUEST: code = findtext(body, 'resultCode', SERVER_NS) message = findtext(body, 'resultDetail', SERVER_NS) raise OpsourceAPIException(code, message, driver=OpsourceNodeDriver) return self.body
def create_balancer(self, name, port, protocol, algorithm, members, ex_members_availability_zones=None): if ex_members_availability_zones is None: ex_members_availability_zones = ['a'] params = { 'Action': 'CreateLoadBalancer', 'LoadBalancerName': name, 'Listeners.member.1.InstancePort': str(port), 'Listeners.member.1.InstanceProtocol': protocol.upper(), 'Listeners.member.1.LoadBalancerPort': str(port), 'Listeners.member.1.Protocol': protocol.upper(), } for i, z in enumerate(ex_members_availability_zones): zone = ''.join((self.region, z)) params['AvailabilityZones.member.%d' % (i + 1)] = zone data = self.connection.request(ROOT, params=params).object balancer = LoadBalancer( id=name, name=name, state=State.PENDING, ip=findtext(element=data, xpath='DNSName', namespace=NS), port=port, driver=self.connection.driver ) balancer._members = [] return balancer
def ex_start_node(self, node): """ Powers on an existing deployed server """ body = self.connection.request_with_orgId('server/%s?start' % node.id).object result = findtext(body, 'result', GENERAL_NS) return result == 'SUCCESS'
def _to_client_type(self, element): description = element.get('description') if description is None: description = findtext(element, 'description', BACKUP_NS) return DimensionDataBackupClientType( type=element.get('type'), description=description, is_file_system=bool(element.get('isFileSystem') == 'true'))
def ex_destroy_nic(self, nic_id): request = ET.Element('removeNic', {'xmlns': TYPES_URN, 'id': nic_id}) response = self.connection.request_with_orgId_api_2( 'server/removeNic', method='POST', data=ET.tostring(request)).object response_code = findtext(response, 'responseCode', TYPES_URN) return response_code in ['IN_PROGRESS', 'OK']
def _to_network_domain(self, element, locations): status = self._to_status(element.find(fixxpath('state', TYPES_URN))) location_id = element.get('datacenterId') location = list(filter(lambda x: x.id == location_id, locations))[0] plan = findtext(element, 'type', TYPES_URN) if plan is 'ESSENTIALS': plan_type = NetworkDomainServicePlan.ESSENTIALS else: plan_type = NetworkDomainServicePlan.ADVANCED return DimensionDataNetworkDomain( id=element.get('id'), name=findtext(element, 'name', TYPES_URN), description=findtext(element, 'description', TYPES_URN), plan=plan_type, location=location, status=status)
def ex_list_availability_zones(self, only_available=True): """ Return a list of L{ExEC2AvailabilityZone} objects for the current region. Note: This is an extension method and is only available for EC2 driver. @keyword only_available: If true, return only availability zones with state 'available' @type only_available: C{str} @rtype: C{list} of L{ExEC2AvailabilityZone} """ params = {'Action': 'DescribeAvailabilityZones'} if only_available: params.update({'Filter.0.Name': 'state'}) params.update({'Filter.0.Value.0': 'available'}) params.update({'Filter.1.Name': 'region-name'}) params.update({'Filter.1.Value.0': self.region_name}) result = self.connection.request(self.path, params=params.copy()).object availability_zones = [] for element in findall(element=result, xpath='availabilityZoneInfo/item', namespace=NAMESPACE): name = findtext(element=element, xpath='zoneName', namespace=NAMESPACE) zone_state = findtext(element=element, xpath='zoneState', namespace=NAMESPACE) region_name = findtext(element=element, xpath='regionName', namespace=NAMESPACE) availability_zone = ExEC2AvailabilityZone( name=name, zone_state=zone_state, region_name=region_name ) availability_zones.append(availability_zone) return availability_zones
def reboot_node(self, node): request_elm = ET.Element('rebootServer', {'xmlns': TYPES_URN, 'id': node.id}) body = self.connection.request_with_orgId_api_2( 'server/rebootServer', method='POST', data=ET.tostring(request_elm)).object result = findtext(body, 'responseCode', TYPES_URN) return result == 'IN_PROGRESS'
def _to_client_type(self, element): description = element.get("description") if description is None: description = findtext(element, "description", BACKUP_NS) return DimensionDataBackupClientType( type=element.get("type"), description=description, is_file_system=bool(element.get("isFileSystem") == "true"), )
def ex_delete_vlan(self, vlan): delete_node = ET.Element('deleteVlan', {'xmlns': TYPES_URN}) delete_node.set('id', vlan.id) result = self.connection.request_with_orgId_api_2( 'network/deleteVlan', method='POST', data=ET.tostring(delete_node)).object response_code = findtext(result, 'responseCode', TYPES_URN) return response_code in ['IN_PROGRESS', 'OK']
def parse_error(self): """ Parse error responses from Aliyun. """ body = super(AliyunXmlResponse, self).parse_error() code, message = self._parse_error_details(element=body) request_id = findtext(element=body, xpath="RequestId", namespace=self.namespace) host_id = findtext(element=body, xpath="HostId", namespace=self.namespace) error = { "code": code, "message": message, "request_id": request_id, "host_id": host_id, } return u(error)
def _to_image(self, element): n = NodeImage(id=findtext(element=element, xpath='imageId', namespace=NAMESPACE), name=findtext(element=element, xpath='imageLocation', namespace=NAMESPACE), driver=self.connection.driver, extra={ 'rootDeviceType': findattr(element=element, xpath="rootDeviceType", namespace=NAMESPACE), 'platform': findattr(element=element, xpath="platform", namespace=NAMESPACE), }) return n
def _get_orgId(self): """ Send the /myaccount API request to opsource cloud and parse the 'orgId' from the XML response object. We need the orgId to use most of the other API functions """ if self._orgId is None: body = self.request('myaccount').object self._orgId = findtext(body, 'orgId', DIRECTORY_NS) return self._orgId
def ex_delete_nat_rule(self, rule): update_node = ET.Element('deleteNatRule', {'xmlns': TYPES_URN}) update_node.set('id', rule.id) result = self.connection.request_with_orgId_api_2( 'network/deleteNatRule', method='POST', data=ET.tostring(update_node)).object response_code = findtext(result, 'responseCode', TYPES_URN) return response_code in ['IN_PROGRESS', 'OK']
def ex_delete_public_ip_block(self, block): delete_node = ET.Element('removePublicIpBlock', {'xmlns': TYPES_URN}) delete_node.set('id', block.id) result = self.connection.request_with_orgId_api_2( 'network/removePublicIpBlock', method='POST', data=ET.tostring(delete_node)).object response_code = findtext(result, 'responseCode', TYPES_URN) return response_code in ['IN_PROGRESS', 'OK']
def ex_attach_node_to_vlan(self, node, vlan): request = ET.Element('addNic', {'xmlns': TYPES_URN}) ET.SubElement(request, 'serverId').text = node.id nic = ET.SubElement(request, 'nic') ET.SubElement(nic, 'vlanId').text = vlan.id response = self.connection.request_with_orgId_api_2( 'server/addNic', method='POST', data=ET.tostring(request)).object response_code = findtext(response, 'responseCode', TYPES_URN) return response_code in ['IN_PROGRESS', 'OK']
def parse_error(self): """ Parse error responses from Aliyun. """ body = super(AliyunXmlResponse, self).parse_error() code, message = self._parse_error_details(element=body) request_id = findtext(element=body, xpath='RequestId', namespace=self.namespace) host_id = findtext(element=body, xpath='HostId', namespace=self.namespace) error = { 'code': code, 'message': message, 'request_id': request_id, 'host_id': host_id } return u(error)
def _to_container(self, element): extra = { 'creation_date': findtext(element=element, xpath='CreationDate', namespace=self.namespace), 'location': findtext(element=element, xpath='Location', namespace=self.namespace) } container = Container(name=findtext(element=element, xpath='Name', namespace=self.namespace), extra=extra, driver=self) return container
def _to_target(self, element): backup = findall(element, 'backup', TYPES_URN) if len(backup) == 0: return extra = { 'description': findtext(element, 'description', TYPES_URN), 'sourceImageId': findtext(element, 'sourceImageId', TYPES_URN), 'datacenterId': element.get('datacenterId'), 'deployedTime': findtext(element, 'createTime', TYPES_URN), 'servicePlan': backup[0].get('servicePlan') } n = BackupTarget(id=backup[0].get('assetId'), name=findtext(element, 'name', TYPES_URN), address=element.get('id'), driver=self.connection.driver, type=BackupTargetType.VIRTUAL, extra=extra) return n
def _to_member(self, element): port = findtext(element, 'port', TYPES_URN) if port is not None: port = int(port) pool_member = DimensionDataPoolMember( id=element.get('id'), name=element.find(fixxpath( 'node', TYPES_URN)).get('name'), status=findtext(element, 'state', TYPES_URN), node_id=element.find(fixxpath( 'node', TYPES_URN)).get('id'), ip=element.find(fixxpath( 'node', TYPES_URN)).get('ipAddress'), port=port ) return pool_member
def ex_describe_addresses(self, nodes): """ Return Elastic IP addresses for all the nodes in the provided list. @type nodes: C{list} @param nodes: List of C{Node} instances @return dict Dictionary where a key is a node ID and the value is a list with the Elastic IP addresses associated with this node. """ if not nodes: return {} params = {'Action': 'DescribeAddresses'} if len(nodes) == 1: self._add_instance_filter(params, nodes[0]) result = self.connection.request(self.path, params=params.copy()).object node_instance_ids = [node.id for node in nodes] nodes_elastic_ip_mappings = {} for node_id in node_instance_ids: nodes_elastic_ip_mappings.setdefault(node_id, []) for element in findall(element=result, xpath='addressesSet/item', namespace=NAMESPACE): instance_id = findtext(element=element, xpath='instanceId', namespace=NAMESPACE) ip_address = findtext(element=element, xpath='publicIp', namespace=NAMESPACE) if instance_id not in node_instance_ids: continue nodes_elastic_ip_mappings[instance_id].append(ip_address) return nodes_elastic_ip_mappings
def ex_power_off(self, node): """ This function will abruptly power-off a server. Unlike ex_shutdown_graceful, success ensures the node will stop but some OS and application configurations may be adversely affected by the equivalent of pulling the power plug out of the machine. """ body = self.connection.request_with_orgId('server/%s?poweroff' % node.id).object result = findtext(body, 'result', GENERAL_NS) return result == 'SUCCESS'
def ex_shutdown_graceful(self, node): """ This function will attempt to "gracefully" stop a server by initiating a shutdown sequence within the guest operating system. A successful response on this function means the system has successfully passed the request into the operating system. """ body = self.connection.request_with_orgId('server/%s?shutdown' % (node.id)).object result = findtext(body, 'result', GENERAL_NS) return result == 'SUCCESS'
def destroy_node(self, node): request_elm = ET.Element('deleteServer', { 'xmlns': TYPES_URN, 'id': node.id }) body = self.connection.request_with_orgId_api_2( 'server/deleteServer', method='POST', data=ET.tostring(request_elm)).object response_code = findtext(body, 'responseCode', TYPES_URN) return response_code in ['IN_PROGRESS', 'OK']
def _to_firewall_rule(self, element, locations, network_domain): status = self._to_status(element.find(fixxpath('state', TYPES_URN))) location_id = element.get('datacenterId') location = list(filter(lambda x: x.id == location_id, locations))[0] return DimensionDataFirewallRule( id=element.get('id'), network_domain=network_domain, name=findtext(element, 'name', TYPES_URN), action=findtext(element, 'action', TYPES_URN), ip_version=findtext(element, 'ipVersion', TYPES_URN), protocol=findtext(element, 'protocol', TYPES_URN), enabled=findtext(element, 'enabled', TYPES_URN), source=self._to_firewall_address( element.find(fixxpath('source', TYPES_URN))), destination=self._to_firewall_address( element.find(fixxpath('destination', TYPES_URN))), location=location, status=status)
def _to_record(self, elem, zone, index=0): name = findtext(element=elem, xpath="Name", namespace=NAMESPACE) name = name[: -len(zone.domain) - 1] type = self._string_to_record_type( findtext(element=elem, xpath="Type", namespace=NAMESPACE) ) ttl = findtext(element=elem, xpath="TTL", namespace=NAMESPACE) if ttl is not None: ttl = int(ttl) value_elem = elem.findall( fixxpath(xpath="ResourceRecords/ResourceRecord", namespace=NAMESPACE) )[index] data = findtext(element=(value_elem), xpath="Value", namespace=NAMESPACE) extra = {"ttl": ttl} if type == "MX": split = data.split() priority, data = split extra["priority"] = int(priority) elif type == "SRV": split = data.split() priority, weight, port, data = split extra["priority"] = int(priority) extra["weight"] = int(weight) extra["port"] = int(port) id = ":".join((self.RECORD_TYPE_MAP[type], name)) record = Record( id=id, name=name, type=type, data=data, zone=zone, driver=self, ttl=extra.get("ttl", None), extra=extra, ) return record
def _to_target(self, element): backup = findall(element, "backup", TYPES_URN) if len(backup) == 0: return extra = { "description": findtext(element, "description", TYPES_URN), "sourceImageId": findtext(element, "sourceImageId", TYPES_URN), "datacenterId": element.get("datacenterId"), "deployedTime": findtext(element, "createTime", TYPES_URN), "servicePlan": backup[0].get("servicePlan"), } n = BackupTarget( id=backup[0].get("assetId"), name=findtext(element, "name", TYPES_URN), address=element.get("id"), driver=self.connection.driver, type=BackupTargetType.VIRTUAL, extra=extra, ) return n
def _to_balancer(self, el): name = findtext(element=el, xpath='LoadBalancerName', namespace=NS) dns_name = findtext(el, xpath='DNSName', namespace=NS) port = findtext(el, xpath='LoadBalancerPort', namespace=NS) balancer = LoadBalancer(id=name, name=name, state=State.UNKNOWN, ip=dns_name, port=port, driver=self.connection.driver) xpath = 'Instances/member/InstanceId' members = findall(element=el, xpath=xpath, namespace=NS) balancer._members = [] for m in members: balancer._members.append( Member(m.text, None, None, balancer=balancer)) return balancer
def _to_container(self, element): extra = { "creation_date": findtext(element=element, xpath="CreationDate", namespace=self.namespace), "location": findtext(element=element, xpath="Location", namespace=self.namespace), } container = Container( name=findtext(element=element, xpath="Name", namespace=self.namespace), extra=extra, driver=self, ) return container
def _to_balancer(self, element): ipaddress = findtext(element, 'listenerIpAddress', TYPES_URN) name = findtext(element, 'name', TYPES_URN) port = findtext(element, 'port', TYPES_URN) extra = {} extra['pool_id'] = element.find(fixxpath('pool', TYPES_URN)).get('id') extra['network_domain_id'] = findtext(element, 'networkDomainId', TYPES_URN) balancer = LoadBalancer(id=element.get('id'), name=name, state=self._VALUE_TO_STATE_MAP.get( findtext(element, 'state', TYPES_URN), State.UNKNOWN), ip=ipaddress, port=port, driver=self.connection.driver, extra=extra) return balancer
def _to_obj(self, element, container): owner_id = findtext(element=element, xpath='Owner/ID', namespace=self.namespace) owner_display_name = findtext(element=element, xpath='Owner/DisplayName', namespace=self.namespace) meta_data = { 'owner': { 'id': owner_id, 'display_name': owner_display_name } } last_modified = findtext(element=element, xpath='LastModified', namespace=self.namespace) extra = {'last_modified': last_modified} obj = Object(name=findtext(element=element, xpath='Key', namespace=self.namespace), size=int( findtext(element=element, xpath='Size', namespace=self.namespace)), hash=findtext(element=element, xpath='ETag', namespace=self.namespace).replace('"', ''), extra=extra, meta_data=meta_data, container=container, driver=self) return obj