http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/voxel.py ---------------------------------------------------------------------- diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/voxel.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/voxel.py deleted file mode 100644 index 9865027..0000000 --- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/voxel.py +++ /dev/null @@ -1,307 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -Voxel VoxCloud driver -""" -import datetime -import hashlib - -from libcloud.utils.py3 import b - -from libcloud.common.base import XmlResponse, ConnectionUserAndKey -from libcloud.common.types import InvalidCredsError -from libcloud.compute.providers import Provider -from libcloud.compute.types import NodeState -from libcloud.compute.base import Node, NodeDriver -from libcloud.compute.base import NodeSize, NodeImage, NodeLocation - -VOXEL_API_HOST = "api.voxel.net" - - -class VoxelResponse(XmlResponse): - def __init__(self, response, connection): - self.parsed = None - super(VoxelResponse, self).__init__(response=response, - connection=connection) - - def parse_body(self): - if not self.body: - return None - if not self.parsed: - self.parsed = super(VoxelResponse, self).parse_body() - return self.parsed - - def parse_error(self): - err_list = [] - if not self.body: - return None - if not self.parsed: - self.parsed = super(VoxelResponse, self).parse_body() - for err in self.parsed.findall('err'): - code = err.get('code') - err_list.append("(%s) %s" % (code, err.get('msg'))) - # From voxel docs: - # 1: Invalid login or password - # 9: Permission denied: user lacks access rights for this method - if code == "1" or code == "9": - # sucks, but only way to detect - # bad authentication tokens so far - raise InvalidCredsError(err_list[-1]) - return "\n".join(err_list) - - def success(self): - if not self.parsed: - self.parsed = super(VoxelResponse, self).parse_body() - stat = self.parsed.get('stat') - if stat != "ok": - return False - return True - - -class VoxelConnection(ConnectionUserAndKey): - """ - Connection class for the Voxel driver - """ - - host = VOXEL_API_HOST - responseCls = VoxelResponse - - def add_default_params(self, params): - params = dict([(k, v) for k, v in list(params.items()) - if v is not None]) - params["key"] = self.user_id - params["timestamp"] = datetime.datetime.utcnow().isoformat() + "+0000" - - keys = list(params.keys()) - keys.sort() - - md5 = hashlib.md5() - md5.update(b(self.key)) - for key in keys: - if params[key]: - if not params[key] is None: - md5.update(b("%s%s" % (key, params[key]))) - else: - md5.update(b(key)) - params['api_sig'] = md5.hexdigest() - return params - -VOXEL_INSTANCE_TYPES = {} -RAM_PER_CPU = 2048 - -NODE_STATE_MAP = { - 'IN_PROGRESS': NodeState.PENDING, - 'QUEUED': NodeState.PENDING, - 'SUCCEEDED': NodeState.RUNNING, - 'shutting-down': NodeState.TERMINATED, - 'terminated': NodeState.TERMINATED, - 'unknown': NodeState.UNKNOWN, -} - - -class VoxelNodeDriver(NodeDriver): - """ - Voxel VoxCLOUD node driver - """ - - connectionCls = VoxelConnection - type = Provider.VOXEL - name = 'Voxel VoxCLOUD' - website = 'http://www.voxel.net/' - - def _initialize_instance_types(): - for cpus in range(1, 14): - if cpus == 1: - name = "Single CPU" - else: - name = "%d CPUs" % cpus - id = "%dcpu" % cpus - ram = cpus * RAM_PER_CPU - - VOXEL_INSTANCE_TYPES[id] = { - 'id': id, - 'name': name, - 'ram': ram, - 'disk': None, - 'bandwidth': None, - 'price': None} - - features = {"create_node": [], - "list_sizes": ["variable_disk"]} - - _initialize_instance_types() - - def list_nodes(self): - params = {"method": "voxel.devices.list"} - result = self.connection.request('/', params=params).object - return self._to_nodes(result) - - def list_sizes(self, location=None): - return [NodeSize(driver=self.connection.driver, **i) - for i in list(VOXEL_INSTANCE_TYPES.values())] - - def list_images(self, location=None): - params = {"method": "voxel.images.list"} - result = self.connection.request('/', params=params).object - return self._to_images(result) - - def create_node(self, **kwargs): - """Create Voxel Node - - :keyword name: the name to assign the node (mandatory) - :type name: ``str`` - - :keyword image: distribution to deploy - :type image: :class:`NodeImage` - - :keyword size: the plan size to create (mandatory) - Requires size.disk (GB) to be set manually - :type size: :class:`NodeSize` - - :keyword location: which datacenter to create the node in - :type location: :class:`NodeLocation` - - :keyword ex_privateip: Backend IP address to assign to node; - must be chosen from the customer's - private VLAN assignment. - :type ex_privateip: ``str`` - - :keyword ex_publicip: Public-facing IP address to assign to node; - must be chosen from the customer's - public VLAN assignment. - :type ex_publicip: ``str`` - - :keyword ex_rootpass: Password for root access; generated if unset. - :type ex_rootpass: ``str`` - - :keyword ex_consolepass: Password for remote console; - generated if unset. - :type ex_consolepass: ``str`` - - :keyword ex_sshuser: Username for SSH access - :type ex_sshuser: ``str`` - - :keyword ex_sshpass: Password for SSH access; generated if unset. - :type ex_sshpass: ``str`` - - :keyword ex_voxel_access: Allow access Voxel administrative access. - Defaults to False. - :type ex_voxel_access: ``bool`` - - :rtype: :class:`Node` or ``None`` - """ - - # assert that disk > 0 - if not kwargs["size"].disk: - raise ValueError("size.disk must be non-zero") - - # convert voxel_access to string boolean if needed - voxel_access = kwargs.get("ex_voxel_access", None) - if voxel_access is not None: - voxel_access = "true" if voxel_access else "false" - - params = { - 'method': 'voxel.voxcloud.create', - 'hostname': kwargs["name"], - 'disk_size': int(kwargs["size"].disk), - 'facility': kwargs["location"].id, - 'image_id': kwargs["image"].id, - 'processing_cores': kwargs["size"].ram / RAM_PER_CPU, - 'backend_ip': kwargs.get("ex_privateip", None), - 'frontend_ip': kwargs.get("ex_publicip", None), - 'admin_password': kwargs.get("ex_rootpass", None), - 'console_password': kwargs.get("ex_consolepass", None), - 'ssh_username': kwargs.get("ex_sshuser", None), - 'ssh_password': kwargs.get("ex_sshpass", None), - 'voxel_access': voxel_access, - } - - object = self.connection.request('/', params=params).object - - if self._getstatus(object): - return Node( - id=object.findtext("device/id"), - name=kwargs["name"], - state=NODE_STATE_MAP[object.findtext("device/status")], - public_ips=kwargs.get("publicip", None), - private_ips=kwargs.get("privateip", None), - driver=self.connection.driver - ) - else: - return None - - def reboot_node(self, node): - params = {'method': 'voxel.devices.power', - 'device_id': node.id, - 'power_action': 'reboot'} - return self._getstatus( - self.connection.request('/', params=params).object) - - def destroy_node(self, node): - params = {'method': 'voxel.voxcloud.delete', - 'device_id': node.id} - return self._getstatus( - self.connection.request('/', params=params).object) - - def list_locations(self): - params = {"method": "voxel.voxcloud.facilities.list"} - result = self.connection.request('/', params=params).object - nodes = self._to_locations(result) - return nodes - - def _getstatus(self, element): - status = element.attrib["stat"] - return status == "ok" - - def _to_locations(self, object): - return [NodeLocation(element.attrib["label"], - element.findtext("description"), - element.findtext("description"), - self) - for element in object.findall('facilities/facility')] - - def _to_nodes(self, object): - nodes = [] - for element in object.findall('devices/device'): - if element.findtext("type") == "Virtual Server": - try: - state = self.NODE_STATE_MAP[element.attrib['status']] - except KeyError: - state = NodeState.UNKNOWN - - public_ip = private_ip = None - ipassignments = element.findall("ipassignments/ipassignment") - for ip in ipassignments: - if ip.attrib["type"] == "frontend": - public_ip = ip.text - elif ip.attrib["type"] == "backend": - private_ip = ip.text - - nodes.append(Node(id=element.attrib['id'], - name=element.attrib['label'], - state=state, - public_ips=public_ip, - private_ips=private_ip, - driver=self.connection.driver)) - return nodes - - def _to_images(self, object): - images = [] - for element in object.findall("images/image"): - images.append(NodeImage(id=element.attrib["id"], - name=element.attrib["summary"], - driver=self.connection.driver)) - return images
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/vpsnet.py ---------------------------------------------------------------------- diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/vpsnet.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/vpsnet.py deleted file mode 100644 index 8d026a8..0000000 --- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/vpsnet.py +++ /dev/null @@ -1,193 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -""" -VPS.net driver -""" -import base64 - -try: - import simplejson as json -except ImportError: - import json - -from libcloud.utils.py3 import b - -from libcloud.common.base import ConnectionUserAndKey, JsonResponse -from libcloud.common.types import InvalidCredsError, MalformedResponseError -from libcloud.compute.providers import Provider -from libcloud.compute.types import NodeState -from libcloud.compute.base import Node, NodeDriver -from libcloud.compute.base import NodeSize, NodeImage, NodeLocation - -API_HOST = 'api.vps.net' -API_VERSION = 'api10json' - -RAM_PER_NODE = 256 -DISK_PER_NODE = 10 -BANDWIDTH_PER_NODE = 250 - - -class VPSNetResponse(JsonResponse): - def parse_body(self): - try: - return super(VPSNetResponse, self).parse_body() - except MalformedResponseError: - return self.body - - def success(self): - # vps.net wrongly uses 406 for invalid auth creds - if self.status == 406 or self.status == 403: - raise InvalidCredsError() - return True - - def parse_error(self): - try: - errors = super(VPSNetResponse, self).parse_body()['errors'][0] - except MalformedResponseError: - return self.body - else: - return "\n".join(errors) - - -class VPSNetConnection(ConnectionUserAndKey): - """ - Connection class for the VPS.net driver - """ - - host = API_HOST - responseCls = VPSNetResponse - - allow_insecure = False - - def add_default_headers(self, headers): - user_b64 = base64.b64encode(b('%s:%s' % (self.user_id, self.key))) - headers['Authorization'] = 'Basic %s' % (user_b64.decode('utf-8')) - return headers - - -class VPSNetNodeDriver(NodeDriver): - """ - VPS.net node driver - """ - - type = Provider.VPSNET - api_name = 'vps_net' - name = "vps.net" - website = 'http://vps.net/' - connectionCls = VPSNetConnection - - def _to_node(self, vm): - if vm['running']: - state = NodeState.RUNNING - else: - state = NodeState.PENDING - - n = Node(id=vm['id'], - name=vm['label'], - state=state, - public_ips=[vm.get('primary_ip_address', None)], - private_ips=[], - extra={'slices_count': vm['slices_count']}, - # Number of nodes consumed by VM - driver=self.connection.driver) - return n - - def _to_image(self, image, cloud): - image = NodeImage(id=image['id'], - name="%s: %s" % (cloud, image['label']), - driver=self.connection.driver) - - return image - - def _to_size(self, num): - size = NodeSize(id=num, - name="%d Node" % (num,), - ram=RAM_PER_NODE * num, - disk=DISK_PER_NODE, - bandwidth=BANDWIDTH_PER_NODE * num, - price=self._get_price_per_node(num) * num, - driver=self.connection.driver) - return size - - def _get_price_per_node(self, num): - single_node_price = self._get_size_price(size_id='1') - return num * single_node_price - - def create_node(self, name, image, size, **kwargs): - """Create a new VPS.net node - - @inherits: :class:`NodeDriver.create_node` - - :keyword ex_backups_enabled: Enable automatic backups - :type ex_backups_enabled: ``bool`` - - :keyword ex_fqdn: Fully Qualified domain of the node - :type ex_fqdn: ``str`` - """ - headers = {'Content-Type': 'application/json'} - request = {'virtual_machine': - {'label': name, - 'fqdn': kwargs.get('ex_fqdn', ''), - 'system_template_id': image.id, - 'backups_enabled': kwargs.get('ex_backups_enabled', 0), - 'slices_required': size.id}} - - res = self.connection.request('/virtual_machines.%s' % (API_VERSION,), - data=json.dumps(request), - headers=headers, - method='POST') - node = self._to_node(res.object['virtual_machine']) - return node - - def reboot_node(self, node): - res = self.connection.request( - '/virtual_machines/%s/%s.%s' % (node.id, - 'reboot', - API_VERSION), - method="POST") - node = self._to_node(res.object['virtual_machine']) - return True - - def list_sizes(self, location=None): - res = self.connection.request('/nodes.%s' % (API_VERSION,)) - available_nodes = len([size for size in res.object - if size['slice']['virtual_machine_id']]) - sizes = [self._to_size(i) for i in range(1, available_nodes + 1)] - return sizes - - def destroy_node(self, node): - res = self.connection.request('/virtual_machines/%s.%s' - % (node.id, API_VERSION), - method='DELETE') - return res.status == 200 - - def list_nodes(self): - res = self.connection.request('/virtual_machines.%s' % (API_VERSION,)) - return [self._to_node(i['virtual_machine']) for i in res.object] - - def list_images(self, location=None): - res = self.connection.request('/available_clouds.%s' % (API_VERSION,)) - - images = [] - for cloud in res.object: - label = cloud['cloud']['label'] - templates = cloud['cloud']['system_templates'] - images.extend([self._to_image(image, label) - for image in templates]) - - return images - - def list_locations(self): - return [NodeLocation(0, "VPS.net Western US", 'US', self)] http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/vsphere.py ---------------------------------------------------------------------- diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/vsphere.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/vsphere.py deleted file mode 100644 index 7a79c26..0000000 --- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/vsphere.py +++ /dev/null @@ -1,552 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -VMware vSphere driver supporting vSphere v5.5. - -Note: This driver requires pysphere package -(https://pypi.python.org/pypi/pysphere) which can be installed using pip. For -more information, please refer to the official documentation. -""" - -import os -import sys -import atexit - -try: - import pysphere - pysphere -except ImportError: - raise ImportError('Missing "pysphere" dependency. You can install it ' - 'using pip - pip install pysphere') - -from pysphere import VIServer -from pysphere.vi_task import VITask -from pysphere.vi_mor import VIMor, MORTypes -from pysphere.resources import VimService_services as VI -from pysphere.vi_virtual_machine import VIVirtualMachine - -from libcloud.utils.decorators import wrap_non_libcloud_exceptions -from libcloud.common.base import ConnectionUserAndKey -from libcloud.common.types import LibcloudError -from libcloud.common.types import InvalidCredsError -from libcloud.compute.base import NodeDriver -from libcloud.compute.base import NodeLocation -from libcloud.compute.base import NodeImage -from libcloud.compute.base import Node -from libcloud.compute.types import NodeState, Provider -from libcloud.utils.networking import is_public_subnet - -__all__ = [ - 'VSphereNodeDriver', - 'VSphere_5_5_NodeDriver' -] - -DEFAULT_API_VERSION = '5.5' -DEFAULT_CONNECTION_TIMEOUT = 5 # default connection timeout in seconds - - -class VSphereConnection(ConnectionUserAndKey): - def __init__(self, user_id, key, secure=True, - host=None, port=None, url=None, timeout=None): - if host and url: - raise ValueError('host and url arguments are mutually exclusive') - - if host: - host_or_url = host - elif url: - host_or_url = url - else: - raise ValueError('Either "host" or "url" argument must be ' - 'provided') - - self.host_or_url = host_or_url - self.client = None - super(VSphereConnection, self).__init__(user_id=user_id, - key=key, secure=secure, - host=host, port=port, - url=url, timeout=timeout) - - def connect(self): - self.client = VIServer() - - trace_file = os.environ.get('LIBCLOUD_DEBUG', None) - - try: - self.client.connect(host=self.host_or_url, user=self.user_id, - password=self.key, - sock_timeout=DEFAULT_CONNECTION_TIMEOUT, - trace_file=trace_file) - except Exception: - e = sys.exc_info()[1] - message = e.message - fault = getattr(e, 'fault', None) - - if fault == 'InvalidLoginFault': - raise InvalidCredsError(message) - - raise LibcloudError(value=message, driver=self.driver) - - atexit.register(self.disconnect) - - def disconnect(self): - if not self.client: - return - - try: - self.client.disconnect() - except Exception: - # Ignore all the disconnect errors - pass - - def run_client_method(self, method_name, **method_kwargs): - method = getattr(self.client, method_name, None) - return method(**method_kwargs) - - -class VSphereNodeDriver(NodeDriver): - name = 'VMware vSphere' - website = 'http://www.vmware.com/products/vsphere/' - type = Provider.VSPHERE - connectionCls = VSphereConnection - - NODE_STATE_MAP = { - 'POWERED ON': NodeState.RUNNING, - 'POWERED OFF': NodeState.STOPPED, - 'SUSPENDED': NodeState.SUSPENDED, - 'POWERING ON': NodeState.PENDING, - 'POWERING OFF': NodeState.PENDING, - 'SUSPENDING': NodeState.PENDING, - 'RESETTING': NodeState.PENDING, - 'BLOCKED ON MSG': NodeState.ERROR, - 'REVERTING TO SNAPSHOT': NodeState.PENDING - } - - def __new__(cls, username, password, secure=True, host=None, port=None, - url=None, api_version=DEFAULT_API_VERSION, **kwargs): - if cls is VSphereNodeDriver: - if api_version == '5.5': - cls = VSphere_5_5_NodeDriver - else: - raise NotImplementedError('Unsupported API version: %s' % - (api_version)) - return super(VSphereNodeDriver, cls).__new__(cls) - - def __init__(self, username, password, secure=True, - host=None, port=None, url=None, timeout=None): - self.url = url - super(VSphereNodeDriver, self).__init__(key=username, secret=password, - secure=secure, host=host, - port=port, url=url) - - @wrap_non_libcloud_exceptions - def list_locations(self): - """ - List available locations. - - In vSphere case, a location represents a datacenter. - """ - datacenters = self.connection.client.get_datacenters() - - locations = [] - for id, name in datacenters.items(): - location = NodeLocation(id=id, name=name, country=None, - driver=self) - locations.append(location) - - return locations - - @wrap_non_libcloud_exceptions - def list_images(self): - """ - List available images (templates). - """ - server = self.connection.client - - names = ['name', 'config.uuid', 'config.template'] - properties = server._retrieve_properties_traversal( - property_names=names, - from_node=None, - obj_type=MORTypes.VirtualMachine) - - images = [] - for prop in properties: - id = None - name = None - is_template = False - - for item in prop.PropSet: - if item.Name == 'config.uuid': - id = item.Val - if item.Name == 'name': - name = item.Val - elif item.Name == 'config.template': - is_template = item.Val - - if is_template: - image = NodeImage(id=id, name=name, driver=self) - images.append(image) - - return images - - @wrap_non_libcloud_exceptions - def list_nodes(self): - vm_paths = self.connection.client.get_registered_vms() - nodes = self._to_nodes(vm_paths=vm_paths) - - return nodes - - @wrap_non_libcloud_exceptions - @wrap_non_libcloud_exceptions - def ex_clone_node(self, node, name, power_on=True, template=False): - """ - Clone the provided node. - - :param node: Node to clone. - :type node: :class:`libcloud.compute.base.Node` - - :param name: Name of the new node. - :type name: ``str`` - - :param power_on: Power the new node on after being created. - :type power_on: ``bool`` - - :param template: Specifies whether or not the new virtual machine - should be marked as a template. - :type template: ``bool`` - - :return: New node. - :rtype: :class:`libcloud.compute.base.Node` - """ - vm = self._get_vm_for_node(node=node) - new_vm = vm.clone(name=name, power_on=power_on, template=template) - new_node = self._to_node(vm=new_vm) - - return new_node - - @wrap_non_libcloud_exceptions - def ex_migrate_node(self, node, resource_pool=None, host=None, - priority='default'): - """ - Migrate provided node to a new host or resource pool. - - :param node: Node to clone. - :type node: :class:`libcloud.compute.base.Node` - - :param resource_pool: ID of the target resource pool to migrate the - node into. - :type resource_pool: ``str`` - - :param host: Target host to migrate the host to. - :type host: ``str`` - - :param priority: Migration task priority. Possible values: default, - high, low. - :type priority: ``str`` - - :return: True on success. - :rtype: ``bool`` - """ - vm = self._get_vm_for_node(node=node) - vm.migrate(priority=priority, resource_pool=resource_pool, host=host) - - return True - - @wrap_non_libcloud_exceptions - def reboot_node(self, node): - vm = self._get_vm_for_node(node=node) - vm.reset() - - return True - - @wrap_non_libcloud_exceptions - def destroy_node(self, node, ex_remove_files=True): - """ - :param ex_remove_files: Remove all the files from the datastore. - :type ex_remove_files: ``bool`` - """ - ex_remove_files = False - vm = self._get_vm_for_node(node=node) - - server = self.connection.client - - # Based on code from - # https://pypi.python.org/pypi/pyxenter - if ex_remove_files: - request = VI.Destroy_TaskRequestMsg() - - _this = request.new__this(vm._mor) - _this.set_attribute_type(vm._mor.get_attribute_type()) - request.set_element__this(_this) - ret = server._proxy.Destroy_Task(request)._returnval - task = VITask(ret, server) - - # Wait for the task to finish - status = task.wait_for_state([task.STATE_SUCCESS, - task.STATE_ERROR]) - - if status == task.STATE_ERROR: - raise LibcloudError('Error destroying node: %s' % - (task.get_error_message())) - else: - request = VI.UnregisterVMRequestMsg() - - _this = request.new__this(vm._mor) - _this.set_attribute_type(vm._mor.get_attribute_type()) - request.set_element__this(_this) - ret = server._proxy.UnregisterVM(request) - task = VITask(ret, server) - - return True - - @wrap_non_libcloud_exceptions - def ex_stop_node(self, node): - vm = self._get_vm_for_node(node=node) - vm.power_off() - - return True - - @wrap_non_libcloud_exceptions - def ex_start_node(self, node): - vm = self._get_vm_for_node(node=node) - vm.power_on() - - return True - - @wrap_non_libcloud_exceptions - def ex_suspend_node(self, node): - vm = self._get_vm_for_node(node=node) - vm.suspend() - - return True - - @wrap_non_libcloud_exceptions - def ex_get_resource_pools(self): - """ - Return all the available resource pools. - - :rtype: ``dict`` - """ - result = self.connection.client.get_resource_pools() - return result - - @wrap_non_libcloud_exceptions - def ex_get_resource_pool_name(self, node): - """ - Retrieve resource pool name for the provided node. - - :rtype: ``str`` - """ - vm = self._get_vm_for_node(node=node) - return vm.get_resource_pool_name() - - @wrap_non_libcloud_exceptions - def ex_get_hosts(self): - """ - Return all the available hosts. - - :rtype: ``dict`` - """ - result = self.connection.client.get_hosts() - return result - - @wrap_non_libcloud_exceptions - def ex_get_datastores(self): - """ - Return all the available datastores. - - :rtype: ``dict`` - """ - result = self.connection.client.get_datastores() - return result - - @wrap_non_libcloud_exceptions - def ex_get_node_by_path(self, path): - """ - Retrieve Node object for a VM with a provided path. - - :type path: ``str`` - :rtype: :class:`libcloud.compute.base.Node` - """ - vm = self.connection.client.get_vm_by_path(path) - node = self._to_node(vm=vm) - return node - - def ex_get_node_by_uuid(self, uuid): - """ - Retrieve Node object for a VM with a provided uuid. - - :type uuid: ``str`` - """ - vm = self._get_vm_for_uuid(uuid=uuid) - node = self._to_node(vm=vm) - return node - - @wrap_non_libcloud_exceptions - def ex_get_server_type(self): - """ - Return VMware installation type. - - :rtype: ``str`` - """ - return self.connection.client.get_server_type() - - @wrap_non_libcloud_exceptions - def ex_get_api_version(self): - """ - Return API version of the vmware provider. - - :rtype: ``str`` - """ - return self.connection.client.get_api_version() - - def _get_vm_for_uuid(self, uuid, datacenter=None): - """ - Retrieve VM for the provided UUID. - - :type uuid: ``str`` - """ - server = self.connection.client - - dc_list = [] - if datacenter and VIMor.is_mor(datacenter): - dc_list.append(datacenter) - else: - dc = server.get_datacenters() - if datacenter: - dc_list = [k for k, v in dc.iteritems() if v == datacenter] - else: - dc_list = list(dc.iterkeys()) - - for mor_dc in dc_list: - request = VI.FindByUuidRequestMsg() - search_index = server._do_service_content.SearchIndex - mor_search_index = request.new__this(search_index) - mor_search_index.set_attribute_type(MORTypes.SearchIndex) - request.set_element__this(mor_search_index) - - mor_datacenter = request.new_datacenter(mor_dc) - mor_datacenter.set_attribute_type(MORTypes.Datacenter) - request.set_element_datacenter(mor_datacenter) - - request.set_element_vmSearch(True) - request.set_element_uuid(uuid) - - try: - vm = server._proxy.FindByUuid(request)._returnval - except VI.ZSI.FaultException: - pass - else: - if vm: - return VIVirtualMachine(server, vm) - - return None - - def _to_nodes(self, vm_paths): - nodes = [] - for vm_path in vm_paths: - vm = self.connection.client.get_vm_by_path(vm_path) - node = self._to_node(vm=vm) - nodes.append(node) - - return nodes - - def _to_node(self, vm): - assert(isinstance(vm, VIVirtualMachine)) - - properties = vm.get_properties() - status = vm.get_status() - - uuid = vm.properties.config.uuid - instance_uuid = vm.properties.config.instanceUuid - - id = uuid - name = properties['name'] - public_ips = [] - private_ips = [] - - state = self.NODE_STATE_MAP.get(status, NodeState.UNKNOWN) - ip_address = properties.get('ip_address', None) - net = properties.get('net', []) - resource_pool_id = str(vm.properties.resourcePool._obj) - - try: - operating_system = vm.properties.summary.guest.guestFullName, - except Exception: - operating_system = 'unknown' - - extra = { - 'uuid': uuid, - 'instance_uuid': instance_uuid, - 'path': properties['path'], - 'resource_pool_id': resource_pool_id, - 'hostname': properties.get('hostname', None), - 'guest_id': properties['guest_id'], - 'devices': properties.get('devices', {}), - 'disks': properties.get('disks', []), - 'net': net, - - 'overall_status': vm.properties.overallStatus, - 'operating_system': operating_system, - - 'cpus': vm.properties.config.hardware.numCPU, - 'memory_mb': vm.properties.config.hardware.memoryMB - } - - # Add primary IP - if ip_address: - if is_public_subnet(ip_address): - public_ips.append(ip_address) - else: - private_ips.append(ip_address) - - # Add other IP addresses - for nic in net: - ip_addresses = nic['ip_addresses'] - for ip_address in ip_addresses: - try: - is_public = is_public_subnet(ip_address) - except Exception: - # TODO: Better support for IPv6 - is_public = False - - if is_public: - public_ips.append(ip_address) - else: - private_ips.append(ip_address) - - # Remove duplicate IPs - public_ips = list(set(public_ips)) - private_ips = list(set(private_ips)) - - node = Node(id=id, name=name, state=state, public_ips=public_ips, - private_ips=private_ips, driver=self, extra=extra) - return node - - def _get_vm_for_node(self, node): - uuid = node.id - vm = self._get_vm_for_uuid(uuid=uuid) - return vm - - def _ex_connection_class_kwargs(self): - kwargs = { - 'url': self.url - } - - return kwargs - - -class VSphere_5_5_NodeDriver(VSphereNodeDriver): - name = 'VMware vSphere v5.5' http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/vultr.py ---------------------------------------------------------------------- diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/vultr.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/vultr.py deleted file mode 100644 index 3823119..0000000 --- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/vultr.py +++ /dev/null @@ -1,210 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -""" -Vultr Driver -""" - -import time - -from libcloud.utils.py3 import httplib -from libcloud.utils.py3 import urlencode - -from libcloud.common.base import ConnectionKey, JsonResponse -from libcloud.compute.types import Provider, NodeState -from libcloud.common.types import LibcloudError, InvalidCredsError -from libcloud.compute.base import NodeDriver -from libcloud.compute.base import Node, NodeImage, NodeSize, NodeLocation - - -class VultrResponse(JsonResponse): - def parse_error(self): - if self.status == httplib.OK: - body = self.parse_body() - return body - elif self.status == httplib.FORBIDDEN: - raise InvalidCredsError(self.body) - else: - raise LibcloudError(self.body) - - -class SSHKey(object): - def __init__(self, id, name, pub_key): - self.id = id - self.name = name - self.pub_key = pub_key - - def __repr__(self): - return (('<SSHKey: id=%s, name=%s, pub_key=%s>') % - (self.id, self.name, self.pub_key)) - - -class VultrConnection(ConnectionKey): - """ - Connection class for the Vultr driver. - """ - - host = 'api.vultr.com' - responseCls = VultrResponse - - def add_default_params(self, params): - """ - Add parameters that are necessary for every request - - This method add ``api_key`` to - the request. - """ - params['api_key'] = self.key - return params - - def encode_data(self, data): - return urlencode(data) - - def get(self, url): - return self.request(url) - - def post(self, url, data): - headers = {'Content-Type': 'application/x-www-form-urlencoded'} - return self.request(url, data=data, headers=headers, method='POST') - - -class VultrNodeDriver(NodeDriver): - """ - VultrNode node driver. - """ - - connectionCls = VultrConnection - - type = Provider.VULTR - name = 'Vultr' - website = 'https://www.vultr.com' - - NODE_STATE_MAP = {'pending': NodeState.PENDING, - 'active': NodeState.RUNNING} - - def list_nodes(self): - return self._list_resources('/v1/server/list', self._to_node) - - def list_key_pairs(self): - """ - List all the available SSH keys. - :return: Available SSH keys. - :rtype: ``list`` of :class:`SSHKey` - """ - return self._list_resources('/v1/sshkey/list', self._to_ssh_key) - - def list_locations(self): - return self._list_resources('/v1/regions/list', self._to_location) - - def list_sizes(self): - return self._list_resources('/v1/plans/list', self._to_size) - - def list_images(self): - return self._list_resources('/v1/os/list', self._to_image) - - def create_node(self, name, size, image, location, ex_ssh_key_ids=None): - params = {'DCID': location.id, 'VPSPLANID': size.id, - 'OSID': image.id, 'label': name} - - if ex_ssh_key_ids is not None: - params['SSHKEYID'] = ','.join(ex_ssh_key_ids) - - result = self.connection.post('/v1/server/create', params) - if result.status != httplib.OK: - return False - - subid = result.object['SUBID'] - - retry_count = 3 - created_node = None - - for i in range(retry_count): - try: - nodes = self.list_nodes() - created_node = [n for n in nodes if n.id == subid][0] - except IndexError: - time.sleep(1) - pass - else: - break - - return created_node - - def reboot_node(self, node): - params = {'SUBID': node.id} - res = self.connection.post('/v1/server/reboot', params) - - return res.status == httplib.OK - - def destroy_node(self, node): - params = {'SUBID': node.id} - res = self.connection.post('/v1/server/destroy', params) - - return res.status == httplib.OK - - def _list_resources(self, url, tranform_func): - data = self.connection.get(url).object - sorted_key = sorted(data) - return [tranform_func(data[key]) for key in sorted_key] - - def _to_node(self, data): - if 'status' in data: - state = self.NODE_STATE_MAP.get(data['status'], NodeState.UNKNOWN) - if state == NodeState.RUNNING and \ - data['power_status'] != 'running': - state = NodeState.STOPPED - else: - state = NodeState.UNKNOWN - - if 'main_ip' in data and data['main_ip'] is not None: - public_ips = [data['main_ip']] - else: - public_ips = [] - - extra_keys = [] - extra = {} - for key in extra_keys: - if key in data: - extra[key] = data[key] - - node = Node(id=data['SUBID'], name=data['label'], state=state, - public_ips=public_ips, private_ips=None, extra=extra, - driver=self) - - return node - - def _to_location(self, data): - return NodeLocation(id=data['DCID'], name=data['name'], - country=data['country'], driver=self) - - def _to_size(self, data): - extra = {'vcpu_count': int(data['vcpu_count'])} - ram = int(data['ram']) - disk = int(data['disk']) - bandwidth = float(data['bandwidth']) - price = float(data['price_per_month']) - - return NodeSize(id=data['VPSPLANID'], name=data['name'], - ram=ram, disk=disk, - bandwidth=bandwidth, price=price, - extra=extra, driver=self) - - def _to_image(self, data): - extra = {'arch': data['arch'], 'family': data['family']} - return NodeImage(id=data['OSID'], name=data['name'], extra=extra, - driver=self) - - def _to_ssh_key(self, data): - return SSHKey(id=data['SSHKEYID'], name=data['name'], - pub_key=data['ssh_key']) http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/providers.py ---------------------------------------------------------------------- diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/providers.py b/apache-libcloud-1.0.0rc2/libcloud/compute/providers.py deleted file mode 100644 index 6bf4814..0000000 --- a/apache-libcloud-1.0.0rc2/libcloud/compute/providers.py +++ /dev/null @@ -1,158 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -""" -Provider related utilities -""" - -from libcloud.compute.types import Provider -from libcloud.common.providers import get_driver as _get_provider_driver -from libcloud.common.providers import set_driver as _set_provider_driver -from libcloud.compute.types import OLD_CONSTANT_TO_NEW_MAPPING -from libcloud.compute.deprecated import DEPRECATED_DRIVERS - -__all__ = [ - "Provider", - "DRIVERS", - "get_driver"] - -DRIVERS = { - Provider.AZURE: - ('libcloud.compute.drivers.azure', 'AzureNodeDriver'), - Provider.AZURE_ARM: - ('libcloud.compute.drivers.azure_arm', 'AzureNodeDriver'), - Provider.DUMMY: - ('libcloud.compute.drivers.dummy', 'DummyNodeDriver'), - Provider.EC2: - ('libcloud.compute.drivers.ec2', 'EC2NodeDriver'), - Provider.ECP: - ('libcloud.compute.drivers.ecp', 'ECPNodeDriver'), - Provider.ELASTICHOSTS: - ('libcloud.compute.drivers.elastichosts', 'ElasticHostsNodeDriver'), - Provider.SKALICLOUD: - ('libcloud.compute.drivers.skalicloud', 'SkaliCloudNodeDriver'), - Provider.SERVERLOVE: - ('libcloud.compute.drivers.serverlove', 'ServerLoveNodeDriver'), - Provider.CLOUDSIGMA: - ('libcloud.compute.drivers.cloudsigma', 'CloudSigmaNodeDriver'), - Provider.GCE: - ('libcloud.compute.drivers.gce', 'GCENodeDriver'), - Provider.GOGRID: - ('libcloud.compute.drivers.gogrid', 'GoGridNodeDriver'), - Provider.RACKSPACE: - ('libcloud.compute.drivers.rackspace', 'RackspaceNodeDriver'), - Provider.RACKSPACE_FIRST_GEN: - ('libcloud.compute.drivers.rackspace', 'RackspaceFirstGenNodeDriver'), - Provider.KILI: - ('libcloud.compute.drivers.kili', 'KiliCloudNodeDriver'), - Provider.VPSNET: - ('libcloud.compute.drivers.vpsnet', 'VPSNetNodeDriver'), - Provider.LINODE: - ('libcloud.compute.drivers.linode', 'LinodeNodeDriver'), - Provider.RIMUHOSTING: - ('libcloud.compute.drivers.rimuhosting', 'RimuHostingNodeDriver'), - Provider.VOXEL: - ('libcloud.compute.drivers.voxel', 'VoxelNodeDriver'), - Provider.SOFTLAYER: - ('libcloud.compute.drivers.softlayer', 'SoftLayerNodeDriver'), - Provider.EUCALYPTUS: - ('libcloud.compute.drivers.ec2', 'EucNodeDriver'), - Provider.OPENNEBULA: - ('libcloud.compute.drivers.opennebula', 'OpenNebulaNodeDriver'), - Provider.BRIGHTBOX: - ('libcloud.compute.drivers.brightbox', 'BrightboxNodeDriver'), - Provider.NIMBUS: - ('libcloud.compute.drivers.ec2', 'NimbusNodeDriver'), - Provider.BLUEBOX: - ('libcloud.compute.drivers.bluebox', 'BlueboxNodeDriver'), - Provider.GANDI: - ('libcloud.compute.drivers.gandi', 'GandiNodeDriver'), - Provider.DIMENSIONDATA: - ('libcloud.compute.drivers.dimensiondata', 'DimensionDataNodeDriver'), - Provider.OPENSTACK: - ('libcloud.compute.drivers.openstack', 'OpenStackNodeDriver'), - Provider.VCLOUD: - ('libcloud.compute.drivers.vcloud', 'VCloudNodeDriver'), - Provider.TERREMARK: - ('libcloud.compute.drivers.vcloud', 'TerremarkDriver'), - Provider.CLOUDSTACK: - ('libcloud.compute.drivers.cloudstack', 'CloudStackNodeDriver'), - Provider.LIBVIRT: - ('libcloud.compute.drivers.libvirt_driver', 'LibvirtNodeDriver'), - Provider.JOYENT: - ('libcloud.compute.drivers.joyent', 'JoyentNodeDriver'), - Provider.VCL: - ('libcloud.compute.drivers.vcl', 'VCLNodeDriver'), - Provider.KTUCLOUD: - ('libcloud.compute.drivers.ktucloud', 'KTUCloudNodeDriver'), - Provider.HOSTVIRTUAL: - ('libcloud.compute.drivers.hostvirtual', 'HostVirtualNodeDriver'), - Provider.ABIQUO: - ('libcloud.compute.drivers.abiquo', 'AbiquoNodeDriver'), - Provider.DIGITAL_OCEAN: - ('libcloud.compute.drivers.digitalocean', 'DigitalOceanNodeDriver'), - Provider.NEPHOSCALE: - ('libcloud.compute.drivers.nephoscale', 'NephoscaleNodeDriver'), - Provider.EXOSCALE: - ('libcloud.compute.drivers.exoscale', 'ExoscaleNodeDriver'), - Provider.IKOULA: - ('libcloud.compute.drivers.ikoula', 'IkoulaNodeDriver'), - Provider.OUTSCALE_SAS: - ('libcloud.compute.drivers.ec2', 'OutscaleSASNodeDriver'), - Provider.OUTSCALE_INC: - ('libcloud.compute.drivers.ec2', 'OutscaleINCNodeDriver'), - Provider.VSPHERE: - ('libcloud.compute.drivers.vsphere', 'VSphereNodeDriver'), - Provider.PROFIT_BRICKS: - ('libcloud.compute.drivers.profitbricks', 'ProfitBricksNodeDriver'), - Provider.VULTR: - ('libcloud.compute.drivers.vultr', 'VultrNodeDriver'), - Provider.AURORACOMPUTE: - ('libcloud.compute.drivers.auroracompute', 'AuroraComputeNodeDriver'), - Provider.CLOUDWATT: - ('libcloud.compute.drivers.cloudwatt', 'CloudwattNodeDriver'), - Provider.PACKET: - ('libcloud.compute.drivers.packet', 'PacketNodeDriver'), - Provider.ONAPP: - ('libcloud.compute.drivers.onapp', 'OnAppNodeDriver'), - Provider.RUNABOVE: - ('libcloud.compute.drivers.runabove', 'RunAboveNodeDriver'), - Provider.INTERNETSOLUTIONS: - ('libcloud.compute.drivers.internetsolutions', - 'InternetSolutionsNodeDriver'), - Provider.INDOSAT: - ('libcloud.compute.drivers.indosat', 'IndosatNodeDriver'), - Provider.MEDONE: - ('libcloud.compute.drivers.medone', 'MedOneNodeDriver'), - Provider.BSNL: - ('libcloud.compute.drivers.bsnl', 'BSNLNodeDriver'), - Provider.CISCOCCS: - ('libcloud.compute.drivers.ciscoccs', 'CiscoCCSNodeDriver'), - Provider.NTTA: - ('libcloud.compute.drivers.ntta', 'NTTAmericaNodeDriver'), - Provider.ALIYUN_ECS: - ('libcloud.compute.drivers.ecs', 'ECSDriver'), -} - - -def get_driver(provider): - deprecated_constants = OLD_CONSTANT_TO_NEW_MAPPING - return _get_provider_driver(drivers=DRIVERS, provider=provider, - deprecated_providers=DEPRECATED_DRIVERS, - deprecated_constants=deprecated_constants) - - -def set_driver(provider, module, klass): - return _set_provider_driver(drivers=DRIVERS, provider=provider, - module=module, klass=klass) http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/ssh.py ---------------------------------------------------------------------- diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/ssh.py b/apache-libcloud-1.0.0rc2/libcloud/compute/ssh.py deleted file mode 100644 index c65aab2..0000000 --- a/apache-libcloud-1.0.0rc2/libcloud/compute/ssh.py +++ /dev/null @@ -1,568 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -Wraps multiple ways to communicate over SSH. -""" - -have_paramiko = False - -try: - import paramiko - have_paramiko = True -except ImportError: - pass - -# Depending on your version of Paramiko, it may cause a deprecation -# warning on Python 2.6. -# Ref: https://bugs.launchpad.net/paramiko/+bug/392973 - -import os -import time -import subprocess -import logging -import warnings - -from os.path import split as psplit -from os.path import join as pjoin - -from libcloud.utils.logging import ExtraLogFormatter -from libcloud.utils.py3 import StringIO -from libcloud.utils.py3 import b - -__all__ = [ - 'BaseSSHClient', - 'ParamikoSSHClient', - 'ShellOutSSHClient', - - 'SSHCommandTimeoutError' -] - - -class SSHCommandTimeoutError(Exception): - """ - Exception which is raised when an SSH command times out. - """ - def __init__(self, cmd, timeout): - self.cmd = cmd - self.timeout = timeout - message = 'Command didn\'t finish in %s seconds' % (timeout) - super(SSHCommandTimeoutError, self).__init__(message) - - def __repr__(self): - return ('<SSHCommandTimeoutError: cmd="%s",timeout=%s)>' % - (self.cmd, self.timeout)) - - def __str__(self): - return self.message - - -class BaseSSHClient(object): - """ - Base class representing a connection over SSH/SCP to a remote node. - """ - - def __init__(self, hostname, port=22, username='root', password=None, - key=None, key_files=None, timeout=None): - """ - :type hostname: ``str`` - :keyword hostname: Hostname or IP address to connect to. - - :type port: ``int`` - :keyword port: TCP port to communicate on, defaults to 22. - - :type username: ``str`` - :keyword username: Username to use, defaults to root. - - :type password: ``str`` - :keyword password: Password to authenticate with or a password used - to unlock a private key if a password protected key - is used. - - :param key: Deprecated in favor of ``key_files`` argument. - - :type key_files: ``str`` or ``list`` - :keyword key_files: A list of paths to the private key files to use. - """ - if key is not None: - message = ('You are using deprecated "key" argument which has ' - 'been replaced with "key_files" argument') - warnings.warn(message, DeprecationWarning) - - # key_files has precedent - key_files = key if not key_files else key_files - - self.hostname = hostname - self.port = port - self.username = username - self.password = password - self.key_files = key_files - self.timeout = timeout - - def connect(self): - """ - Connect to the remote node over SSH. - - :return: True if the connection has been successfully established, - False otherwise. - :rtype: ``bool`` - """ - raise NotImplementedError( - 'connect not implemented for this ssh client') - - def put(self, path, contents=None, chmod=None, mode='w'): - """ - Upload a file to the remote node. - - :type path: ``str`` - :keyword path: File path on the remote node. - - :type contents: ``str`` - :keyword contents: File Contents. - - :type chmod: ``int`` - :keyword chmod: chmod file to this after creation. - - :type mode: ``str`` - :keyword mode: Mode in which the file is opened. - - :return: Full path to the location where a file has been saved. - :rtype: ``str`` - """ - raise NotImplementedError( - 'put not implemented for this ssh client') - - def delete(self, path): - """ - Delete/Unlink a file on the remote node. - - :type path: ``str`` - :keyword path: File path on the remote node. - - :return: True if the file has been successfully deleted, False - otherwise. - :rtype: ``bool`` - """ - raise NotImplementedError( - 'delete not implemented for this ssh client') - - def run(self, cmd): - """ - Run a command on a remote node. - - :type cmd: ``str`` - :keyword cmd: Command to run. - - :return ``list`` of [stdout, stderr, exit_status] - """ - raise NotImplementedError( - 'run not implemented for this ssh client') - - def close(self): - """ - Shutdown connection to the remote node. - - :return: True if the connection has been successfully closed, False - otherwise. - :rtype: ``bool`` - """ - raise NotImplementedError( - 'close not implemented for this ssh client') - - def _get_and_setup_logger(self): - logger = logging.getLogger('libcloud.compute.ssh') - path = os.getenv('LIBCLOUD_DEBUG') - - if path: - handler = logging.FileHandler(path) - handler.setFormatter(ExtraLogFormatter()) - logger.addHandler(handler) - logger.setLevel(logging.DEBUG) - - return logger - - -class ParamikoSSHClient(BaseSSHClient): - """ - A SSH Client powered by Paramiko. - """ - - # Maximum number of bytes to read at once from a socket - CHUNK_SIZE = 4096 - - # How long to sleep while waiting for command to finish - SLEEP_DELAY = 1.5 - - def __init__(self, hostname, port=22, username='root', password=None, - key=None, key_files=None, key_material=None, timeout=None): - """ - Authentication is always attempted in the following order: - - - The key passed in (if key is provided) - - Any key we can find through an SSH agent (only if no password and - key is provided) - - Any "id_rsa" or "id_dsa" key discoverable in ~/.ssh/ (only if no - password and key is provided) - - Plain username/password auth, if a password was given (if password is - provided) - """ - if key_files and key_material: - raise ValueError(('key_files and key_material arguments are ' - 'mutually exclusive')) - - super(ParamikoSSHClient, self).__init__(hostname=hostname, port=port, - username=username, - password=password, - key=key, - key_files=key_files, - timeout=timeout) - - self.key_material = key_material - - self.client = paramiko.SSHClient() - self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) - self.logger = self._get_and_setup_logger() - - def connect(self): - conninfo = {'hostname': self.hostname, - 'port': self.port, - 'username': self.username, - 'allow_agent': False, - 'look_for_keys': False} - - if self.password: - conninfo['password'] = self.password - - if self.key_files: - conninfo['key_filename'] = self.key_files - - if self.key_material: - conninfo['pkey'] = self._get_pkey_object(key=self.key_material) - - if not self.password and not (self.key_files or self.key_material): - conninfo['allow_agent'] = True - conninfo['look_for_keys'] = True - - if self.timeout: - conninfo['timeout'] = self.timeout - - extra = {'_hostname': self.hostname, '_port': self.port, - '_username': self.username, '_timeout': self.timeout} - self.logger.debug('Connecting to server', extra=extra) - - self.client.connect(**conninfo) - return True - - def put(self, path, contents=None, chmod=None, mode='w'): - extra = {'_path': path, '_mode': mode, '_chmod': chmod} - self.logger.debug('Uploading file', extra=extra) - - sftp = self.client.open_sftp() - # less than ideal, but we need to mkdir stuff otherwise file() fails - head, tail = psplit(path) - - if path[0] == "/": - sftp.chdir("/") - else: - # Relative path - start from a home directory (~) - sftp.chdir('.') - - for part in head.split("/"): - if part != "": - try: - sftp.mkdir(part) - except IOError: - # so, there doesn't seem to be a way to - # catch EEXIST consistently *sigh* - pass - sftp.chdir(part) - - cwd = sftp.getcwd() - - ak = sftp.file(tail, mode=mode) - ak.write(contents) - if chmod is not None: - ak.chmod(chmod) - ak.close() - sftp.close() - - if path[0] == '/': - file_path = path - else: - file_path = pjoin(cwd, path) - - return file_path - - def delete(self, path): - extra = {'_path': path} - self.logger.debug('Deleting file', extra=extra) - - sftp = self.client.open_sftp() - sftp.unlink(path) - sftp.close() - return True - - def run(self, cmd, timeout=None): - """ - Note: This function is based on paramiko's exec_command() - method. - - :param timeout: How long to wait (in seconds) for the command to - finish (optional). - :type timeout: ``float`` - """ - extra = {'_cmd': cmd} - self.logger.debug('Executing command', extra=extra) - - # Use the system default buffer size - bufsize = -1 - - transport = self.client.get_transport() - chan = transport.open_session() - - start_time = time.time() - chan.exec_command(cmd) - - stdout = StringIO() - stderr = StringIO() - - # Create a stdin file and immediately close it to prevent any - # interactive script from hanging the process. - stdin = chan.makefile('wb', bufsize) - stdin.close() - - # Receive all the output - # Note #1: This is used instead of chan.makefile approach to prevent - # buffering issues and hanging if the executed command produces a lot - # of output. - # - # Note #2: If you are going to remove "ready" checks inside the loop - # you are going to have a bad time. Trying to consume from a channel - # which is not ready will block for indefinitely. - exit_status_ready = chan.exit_status_ready() - - if exit_status_ready: - # It's possible that some data is already available when exit - # status is ready - stdout.write(self._consume_stdout(chan).getvalue()) - stderr.write(self._consume_stderr(chan).getvalue()) - - while not exit_status_ready: - current_time = time.time() - elapsed_time = (current_time - start_time) - - if timeout and (elapsed_time > timeout): - # TODO: Is this the right way to clean up? - chan.close() - - raise SSHCommandTimeoutError(cmd=cmd, timeout=timeout) - - stdout.write(self._consume_stdout(chan).getvalue()) - stderr.write(self._consume_stderr(chan).getvalue()) - - # We need to check the exist status here, because the command could - # print some output and exit during this sleep below. - exit_status_ready = chan.exit_status_ready() - - if exit_status_ready: - break - - # Short sleep to prevent busy waiting - time.sleep(self.SLEEP_DELAY) - - # Receive the exit status code of the command we ran. - status = chan.recv_exit_status() - - stdout = stdout.getvalue() - stderr = stderr.getvalue() - - extra = {'_status': status, '_stdout': stdout, '_stderr': stderr} - self.logger.debug('Command finished', extra=extra) - - return [stdout, stderr, status] - - def close(self): - self.logger.debug('Closing server connection') - - self.client.close() - return True - - def _consume_stdout(self, chan): - """ - Try to consume stdout data from chan if it's receive ready. - """ - stdout = self._consume_data_from_channel( - chan=chan, - recv_method=chan.recv, - recv_ready_method=chan.recv_ready) - return stdout - - def _consume_stderr(self, chan): - """ - Try to consume stderr data from chan if it's receive ready. - """ - stderr = self._consume_data_from_channel( - chan=chan, - recv_method=chan.recv_stderr, - recv_ready_method=chan.recv_stderr_ready) - return stderr - - def _consume_data_from_channel(self, chan, recv_method, recv_ready_method): - """ - Try to consume data from the provided channel. - - Keep in mind that data is only consumed if the channel is receive - ready. - """ - result = StringIO() - result_bytes = bytearray() - - if recv_ready_method(): - data = recv_method(self.CHUNK_SIZE) - result_bytes += b(data) - - while data: - ready = recv_ready_method() - - if not ready: - break - - data = recv_method(self.CHUNK_SIZE) - result_bytes += b(data) - - # We only decode data at the end because a single chunk could contain - # a part of multi byte UTF-8 character (whole multi bytes character - # could be split over two chunks) - result.write(result_bytes.decode('utf-8')) - return result - - def _get_pkey_object(self, key): - """ - Try to detect private key type and return paramiko.PKey object. - """ - - for cls in [paramiko.RSAKey, paramiko.DSSKey, paramiko.ECDSAKey]: - try: - key = cls.from_private_key(StringIO(key)) - except paramiko.ssh_exception.SSHException: - # Invalid key, try other key type - pass - else: - return key - - msg = ('Invalid or unsupported key type (only RSA, DSS and ECDSA keys' - ' are supported)') - raise paramiko.ssh_exception.SSHException(msg) - - -class ShellOutSSHClient(BaseSSHClient): - """ - This client shells out to "ssh" binary to run commands on the remote - server. - - Note: This client should not be used in production. - """ - - def __init__(self, hostname, port=22, username='root', password=None, - key=None, key_files=None, timeout=None): - super(ShellOutSSHClient, self).__init__(hostname=hostname, - port=port, username=username, - password=password, - key=key, - key_files=key_files, - timeout=timeout) - if self.password: - raise ValueError('ShellOutSSHClient only supports key auth') - - child = subprocess.Popen(['ssh'], stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - child.communicate() - - if child.returncode == 127: - raise ValueError('ssh client is not available') - - self.logger = self._get_and_setup_logger() - - def connect(self): - """ - This client doesn't support persistent connections establish a new - connection every time "run" method is called. - """ - return True - - def run(self, cmd): - return self._run_remote_shell_command([cmd]) - - def put(self, path, contents=None, chmod=None, mode='w'): - if mode == 'w': - redirect = '>' - elif mode == 'a': - redirect = '>>' - else: - raise ValueError('Invalid mode: ' + mode) - - cmd = ['echo "%s" %s %s' % (contents, redirect, path)] - self._run_remote_shell_command(cmd) - return path - - def delete(self, path): - cmd = ['rm', '-rf', path] - self._run_remote_shell_command(cmd) - return True - - def close(self): - return True - - def _get_base_ssh_command(self): - cmd = ['ssh'] - - if self.key_files: - cmd += ['-i', self.key_files] - - if self.timeout: - cmd += ['-oConnectTimeout=%s' % (self.timeout)] - - cmd += ['%s@%s' % (self.username, self.hostname)] - - return cmd - - def _run_remote_shell_command(self, cmd): - """ - Run a command on a remote server. - - :param cmd: Command to run. - :type cmd: ``list`` of ``str`` - - :return: Command stdout, stderr and status code. - :rtype: ``tuple`` - """ - base_cmd = self._get_base_ssh_command() - full_cmd = base_cmd + [' '.join(cmd)] - - self.logger.debug('Executing command: "%s"' % (' '.join(full_cmd))) - - child = subprocess.Popen(full_cmd, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - stdout, stderr = child.communicate() - return (stdout, stderr, child.returncode) - - -class MockSSHClient(BaseSSHClient): - pass - - -SSHClient = ParamikoSSHClient -if not have_paramiko: - SSHClient = MockSSHClient http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/types.py ---------------------------------------------------------------------- diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/types.py b/apache-libcloud-1.0.0rc2/libcloud/compute/types.py deleted file mode 100644 index 9e96575..0000000 --- a/apache-libcloud-1.0.0rc2/libcloud/compute/types.py +++ /dev/null @@ -1,358 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -""" -Base types used by other parts of libcloud -""" - -from libcloud.common.types import LibcloudError, MalformedResponseError -from libcloud.common.types import InvalidCredsError, InvalidCredsException - -__all__ = [ - "Provider", - "NodeState", - "DeploymentError", - "DeploymentException", - - # @@TR: should the unused imports below be exported? - "LibcloudError", - "MalformedResponseError", - "InvalidCredsError", - "InvalidCredsException", - - "OLD_CONSTANT_TO_NEW_MAPPING" -] - - -class Type(object): - @classmethod - def tostring(cls, value): - """Return the string representation of the state object attribute - :param str value: the state object to turn into string - :return: the uppercase string that represents the state object - :rtype: str - """ - return value.upper() - - @classmethod - def fromstring(cls, value): - """Return the state object attribute that matches the string - :param str value: the string to look up - :return: the state object attribute that matches the string - :rtype: str - """ - return getattr(cls, value.upper(), None) - - -class Provider(Type): - """ - Defines for each of the supported providers - - :cvar DUMMY: Example provider - :cvar EC2_US_EAST: Amazon AWS US N. Virgina - :cvar EC2_US_WEST: Amazon AWS US N. California - :cvar EC2_EU_WEST: Amazon AWS EU Ireland - :cvar RACKSPACE: Rackspace next-gen OpenStack based Cloud Servers - :cvar RACKSPACE_FIRST_GEN: Rackspace First Gen Cloud Servers - :cvar GCE: Google Compute Engine - :cvar GOGRID: GoGrid - :cvar VPSNET: VPS.net - :cvar LINODE: Linode.com - :cvar VCLOUD: vmware vCloud - :cvar RIMUHOSTING: RimuHosting.com - :cvar ECP: Enomaly - :cvar IBM: IBM Developer Cloud - :cvar OPENNEBULA: OpenNebula.org - :cvar ELASTICHOSTS: ElasticHosts.com - :cvar CLOUDSIGMA: CloudSigma - :cvar NIMBUS: Nimbus - :cvar BLUEBOX: Bluebox - :cvar OPSOURCE: Opsource Cloud - :cvar DIMENSIONDATA: Dimension Data Cloud - :cvar NINEFOLD: Ninefold - :cvar TERREMARK: Terremark - :cvar EC2_US_WEST_OREGON: Amazon AWS US West 2 (Oregon) - :cvar CLOUDSTACK: CloudStack - :cvar CLOUDSIGMA_US: CloudSigma US Las Vegas - :cvar LIBVIRT: Libvirt driver - :cvar JOYENT: Joyent driver - :cvar VCL: VCL driver - :cvar KTUCLOUD: kt ucloud driver - :cvar GRIDSPOT: Gridspot driver - :cvar ABIQUO: Abiquo driver - :cvar NEPHOSCALE: NephoScale driver - :cvar EXOSCALE: Exoscale driver. - :cvar IKOULA: Ikoula driver. - :cvar OUTSCALE_SAS: Outscale SAS driver. - :cvar OUTSCALE_INC: Outscale INC driver. - :cvar PROFIT_BRICKS: ProfitBricks driver. - :cvar VULTR: vultr driver. - :cvar AZURE: Azure Service Manager (classic) driver. - :cvar AZURE_ARM: Azure Resource Manager (modern) driver. - :cvar AURORACOMPUTE: Aurora Compute driver. - :cvar ALIYUN_ECS: Aliyun ECS driver. - """ - AZURE = 'azure' - AZURE_ARM = 'azure_arm' - DUMMY = 'dummy' - EC2 = 'ec2' - RACKSPACE = 'rackspace' - GCE = 'gce' - GOGRID = 'gogrid' - VPSNET = 'vpsnet' - LINODE = 'linode' - VCLOUD = 'vcloud' - RIMUHOSTING = 'rimuhosting' - VOXEL = 'voxel' - SOFTLAYER = 'softlayer' - EUCALYPTUS = 'eucalyptus' - ECP = 'ecp' - IBM = 'ibm' - OPENNEBULA = 'opennebula' - ELASTICHOSTS = 'elastichosts' - BRIGHTBOX = 'brightbox' - CLOUDSIGMA = 'cloudsigma' - NIMBUS = 'nimbus' - BLUEBOX = 'bluebox' - GANDI = 'gandi' - OPSOURCE = 'opsource' - DIMENSIONDATA = 'dimensiondata' - OPENSTACK = 'openstack' - SKALICLOUD = 'skalicloud' - SERVERLOVE = 'serverlove' - NINEFOLD = 'ninefold' - TERREMARK = 'terremark' - CLOUDSTACK = 'cloudstack' - LIBVIRT = 'libvirt' - JOYENT = 'joyent' - VCL = 'vcl' - KTUCLOUD = 'ktucloud' - GRIDSPOT = 'gridspot' - RACKSPACE_FIRST_GEN = 'rackspace_first_gen' - HOSTVIRTUAL = 'hostvirtual' - ABIQUO = 'abiquo' - DIGITAL_OCEAN = 'digitalocean' - NEPHOSCALE = 'nephoscale' - CLOUDFRAMES = 'cloudframes' - EXOSCALE = 'exoscale' - IKOULA = 'ikoula' - OUTSCALE_SAS = 'outscale_sas' - OUTSCALE_INC = 'outscale_inc' - VSPHERE = 'vsphere' - PROFIT_BRICKS = 'profitbricks' - VULTR = 'vultr' - AURORACOMPUTE = 'aurora_compute' - CLOUDWATT = 'cloudwatt' - PACKET = 'packet' - RUNABOVE = 'runabove' - INTERNETSOLUTIONS = 'internetsolutions' - INDOSAT = 'indosat' - BSNL = 'bsnl' - NTTA = 'ntta' - MEDONE = 'medone' - CISCOCCS = 'ciscoccs' - ALIYUN_ECS = 'aliyun_ecs' - - # OpenStack based providers - HPCLOUD = 'hpcloud' - CLOUDWATT = 'cloudwatt' - KILI = 'kili' - ONAPP = 'onapp' - - # Deprecated constants which aren't supported anymore - RACKSPACE_UK = 'rackspace_uk' - RACKSPACE_NOVA_BETA = 'rackspace_nova_beta' - RACKSPACE_NOVA_DFW = 'rackspace_nova_dfw' - RACKSPACE_NOVA_LON = 'rackspace_nova_lon' - RACKSPACE_NOVA_ORD = 'rackspace_nova_ord' - - EC2_US_EAST = 'ec2_us_east' - EC2_EU = 'ec2_eu_west' # deprecated name - EC2_EU_WEST = 'ec2_eu_west' - EC2_US_WEST = 'ec2_us_west' - EC2_AP_SOUTHEAST = 'ec2_ap_southeast' - EC2_AP_NORTHEAST = 'ec2_ap_northeast' - EC2_AP_NORTHEAST1 = 'ec2_ap_northeast_1' - EC2_AP_NORTHEAST2 = 'ec2_ap_northeast_2' - EC2_US_WEST_OREGON = 'ec2_us_west_oregon' - EC2_SA_EAST = 'ec2_sa_east' - EC2_AP_SOUTHEAST2 = 'ec2_ap_southeast_2' - - ELASTICHOSTS_UK1 = 'elastichosts_uk1' - ELASTICHOSTS_UK2 = 'elastichosts_uk2' - ELASTICHOSTS_US1 = 'elastichosts_us1' - ELASTICHOSTS_US2 = 'elastichosts_us2' - ELASTICHOSTS_US3 = 'elastichosts_us3' - ELASTICHOSTS_CA1 = 'elastichosts_ca1' - ELASTICHOSTS_AU1 = 'elastichosts_au1' - ELASTICHOSTS_CN1 = 'elastichosts_cn1' - - CLOUDSIGMA_US = 'cloudsigma_us' - - # Removed - # SLICEHOST = 'slicehost' - - -DEPRECATED_RACKSPACE_PROVIDERS = [Provider.RACKSPACE_UK, - Provider.RACKSPACE_NOVA_BETA, - Provider.RACKSPACE_NOVA_DFW, - Provider.RACKSPACE_NOVA_LON, - Provider.RACKSPACE_NOVA_ORD] -OLD_CONSTANT_TO_NEW_MAPPING = { - # Rackspace - Provider.RACKSPACE_UK: Provider.RACKSPACE_FIRST_GEN, - - Provider.RACKSPACE_NOVA_BETA: Provider.RACKSPACE, - Provider.RACKSPACE_NOVA_DFW: Provider.RACKSPACE, - Provider.RACKSPACE_NOVA_LON: Provider.RACKSPACE, - Provider.RACKSPACE_NOVA_ORD: Provider.RACKSPACE, - - # AWS - Provider.EC2_US_EAST: Provider.EC2, - Provider.EC2_EU: Provider.EC2, - Provider.EC2_EU_WEST: Provider.EC2, - Provider.EC2_US_WEST: Provider.EC2, - Provider.EC2_AP_SOUTHEAST: Provider.EC2, - Provider.EC2_AP_SOUTHEAST2: Provider.EC2, - Provider.EC2_AP_NORTHEAST: Provider.EC2, - Provider.EC2_AP_NORTHEAST1: Provider.EC2, - Provider.EC2_AP_NORTHEAST2: Provider.EC2, - Provider.EC2_US_WEST_OREGON: Provider.EC2, - Provider.EC2_SA_EAST: Provider.EC2, - Provider.EC2_AP_SOUTHEAST: Provider.EC2, - - # ElasticHosts - Provider.ELASTICHOSTS_UK1: Provider.ELASTICHOSTS, - Provider.ELASTICHOSTS_UK2: Provider.ELASTICHOSTS, - Provider.ELASTICHOSTS_US1: Provider.ELASTICHOSTS, - Provider.ELASTICHOSTS_US2: Provider.ELASTICHOSTS, - Provider.ELASTICHOSTS_US3: Provider.ELASTICHOSTS, - Provider.ELASTICHOSTS_CA1: Provider.ELASTICHOSTS, - Provider.ELASTICHOSTS_AU1: Provider.ELASTICHOSTS, - Provider.ELASTICHOSTS_CN1: Provider.ELASTICHOSTS, -} - - -class NodeState(Type): - """ - Standard states for a node - - :cvar RUNNING: Node is running. - :cvar STARTING: Node is starting up. - :cvar REBOOTING: Node is rebooting. - :cvar TERMINATED: Node is terminated. This node can't be started later on. - :cvar STOPPING: Node is currently trying to stop. - :cvar STOPPED: Node is stopped. This node can be started later on. - :cvar PENDING: Node is pending. - :cvar SUSPENDED: Node is suspended. - :cvar ERROR: Node is an error state. Usually no operations can be performed - on the node once it ends up in the error state. - :cvar PAUSED: Node is paused. - :cvar RECONFIGURING: Node is being reconfigured. - :cvar UNKNOWN: Node state is unknown. - """ - RUNNING = 'running' - STARTING = 'starting' - REBOOTING = 'rebooting' - TERMINATED = 'terminated' - PENDING = 'pending' - UNKNOWN = 'unknown' - STOPPING = 'stopping' - STOPPED = 'stopped' - SUSPENDED = 'suspended' - ERROR = 'error' - PAUSED = 'paused' - RECONFIGURING = 'reconfiguring' - - -class StorageVolumeState(Type): - """ - Standard states of a StorageVolume - """ - AVAILABLE = 'available' - ERROR = 'error' - INUSE = 'inuse' - CREATING = 'creating' - DELETING = 'deleting' - DELETED = 'deleted' - BACKUP = 'backup' - ATTACHING = 'attaching' - UNKNOWN = 'unknown' - - -class VolumeSnapshotState(Type): - """ - Standard states of VolumeSnapshots - """ - AVAILABLE = 'available' - ERROR = 'error' - CREATING = 'creating' - DELETING = 'deleting' - RESTORING = 'restoring' - UNKNOWN = 'unknown' - - -class Architecture(object): - """ - Image and size architectures. - - :cvar I386: i386 (32 bt) - :cvar X86_64: x86_64 (64 bit) - """ - I386 = 0 - X86_X64 = 1 - - -class DeploymentError(LibcloudError): - """ - Exception used when a Deployment Task failed. - - :ivar node: :class:`Node` on which this exception happened, you might want - to call :func:`Node.destroy` - """ - def __init__(self, node, original_exception=None, driver=None): - self.node = node - self.value = original_exception - self.driver = driver - - def __str__(self): - return self.__repr__() - - def __repr__(self): - return (('<DeploymentError: node=%s, error=%s, driver=%s>' - % (self.node.id, str(self.value), str(self.driver)))) - - -class KeyPairError(LibcloudError): - error_type = 'KeyPairError' - - def __init__(self, name, driver): - self.name = name - self.value = 'Key pair with name %s does not exist' % (name) - super(KeyPairError, self).__init__(value=self.value, driver=driver) - - def __str__(self): - return self.__repr__() - - def __repr__(self): - return ('<%s name=%s, value=%s, driver=%s>' % - (self.error_type, self.name, self.value, self.driver.name)) - - -class KeyPairDoesNotExistError(KeyPairError): - error_type = 'KeyPairDoesNotExistError' - - -"""Deprecated alias of :class:`DeploymentException`""" -DeploymentException = DeploymentError http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/container/__init__.py ---------------------------------------------------------------------- diff --git a/apache-libcloud-1.0.0rc2/libcloud/container/__init__.py b/apache-libcloud-1.0.0rc2/libcloud/container/__init__.py deleted file mode 100644 index e69de29..0000000
