http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/azure_arm.py ---------------------------------------------------------------------- diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/azure_arm.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/azure_arm.py deleted file mode 100644 index c7d0441..0000000 --- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/azure_arm.py +++ /dev/null @@ -1,1281 +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. - -""" -Driver for Microsoft Azure Resource Manager (ARM) Virtual Machines provider. - -http://azure.microsoft.com/en-us/services/virtual-machines/ -""" - -import base64 -import binascii -import os -import time - -from libcloud.common.azure_arm import AzureResourceManagementConnection -from libcloud.compute.providers import Provider -from libcloud.compute.base import Node, NodeDriver, NodeLocation, NodeSize -from libcloud.compute.base import NodeImage, NodeAuthSSHKey -from libcloud.compute.base import NodeAuthPassword -from libcloud.compute.types import NodeState -from libcloud.common.types import LibcloudError -from libcloud.storage.types import ObjectDoesNotExistError -from libcloud.common.exceptions import BaseHTTPError -from libcloud.storage.drivers.azure_blobs import AzureBlobsStorageDriver -from libcloud.utils.py3 import basestring - - -class AzureImage(NodeImage): - """Represents a Marketplace node image that an Azure VM can boot from.""" - - def __init__(self, version, sku, offer, publisher, location, driver): - self.publisher = publisher - self.offer = offer - self.sku = sku - self.version = version - self.location = location - urn = "%s:%s:%s:%s" % (self.publisher, self.offer, - self.sku, self.version) - name = "%s %s %s %s" % (self.publisher, self.offer, - self.sku, self.version) - super(AzureImage, self).__init__(urn, name, driver) - - def __repr__(self): - return (('<AzureImage: id=%s, name=%s, location=%s>') - % (self.id, self.name, self.location)) - - -class AzureVhdImage(NodeImage): - """Represents a VHD node image that an Azure VM can boot from.""" - - def __init__(self, storage_account, blob_container, name, driver): - urn = "https://%s.blob.core.windows.net/%s/%s" % (storage_account, - blob_container, - name) - super(AzureVhdImage, self).__init__(urn, name, driver) - - def __repr__(self): - return (('<AzureVhdImage: id=%s, name=%s, location=%s>') - % (self.id, self.name, self.location)) - - -class AzureNetwork(object): - """Represent an Azure virtual network.""" - - def __init__(self, id, name, location, extra): - self.id = id - self.name = name - self.location = location - self.extra = extra - - def __repr__(self): - return (('<AzureNetwork: id=%s, name=%s, location=%s ...>') - % (self.id, self.name, self.location)) - - -class AzureSubnet(object): - """Represents a subnet of an Azure virtual network.""" - - def __init__(self, id, name, extra): - self.id = id - self.name = name - self.extra = extra - - def __repr__(self): - return (('<AzureSubnet: id=%s, name=%s ...>') - % (self.id, self.name)) - - -class AzureNic(object): - """Represents an Azure virtual network interface controller (NIC).""" - - def __init__(self, id, name, location, extra): - self.id = id - self.name = name - self.location = location - self.extra = extra - - def __repr__(self): - return (('<AzureNic: id=%s, name=%s ...>') - % (self.id, self.name)) - - -class AzureIPAddress(object): - """Represents an Azure public IP address resource.""" - - def __init__(self, id, name, extra): - self.id = id - self.name = name - self.extra = extra - - def __repr__(self): - return (('<AzureIPAddress: id=%s, name=%s ...>') - % (self.id, self.name)) - - -class AzureNodeDriver(NodeDriver): - """Compute node driver for Azure Resource Manager.""" - - connectionCls = AzureResourceManagementConnection - name = 'Azure Virtual machines' - website = 'http://azure.microsoft.com/en-us/services/virtual-machines/' - type = Provider.AZURE_ARM - features = {'create_node': ['ssh_key', 'password']} - - # The API doesn't provide state or country information, so fill it in. - # Information from https://azure.microsoft.com/en-us/regions/ - _location_to_country = { - "centralus": "Iowa, USA", - "eastus": "Virginia, USA", - "eastus2": "Virginia, USA", - "usgoviowa": "Iowa, USA", - "usgovvirginia": "Virginia, USA", - "northcentralus": "Illinois, USA", - "southcentralus": "Texas, USA", - "westus": "California, USA", - "northeurope": "Ireland", - "westeurope": "Netherlands", - "eastasia": "Hong Kong", - "southeastasia": "Singapore", - "japaneast": "Tokyo, Japan", - "japanwest": "Osaka, Japan", - "brazilsouth": "Sao Paulo State, Brazil", - "australiaeast": "New South Wales, Australia", - "australiasoutheast": "Victoria, Australia" - } - - def __init__(self, tenant_id, subscription_id, key, secret, - secure=True, host=None, port=None, - api_version=None, region=None, **kwargs): - self.tenant_id = tenant_id - self.subscription_id = subscription_id - super(AzureNodeDriver, self).__init__(key=key, secret=secret, - secure=secure, - host=host, port=port, - api_version=api_version, - region=region, **kwargs) - if self.region is not None: - loc_id = self.region.lower().replace(" ", "") - country = self._location_to_country.get(loc_id) - self.default_location = NodeLocation(loc_id, - self.region, - country, - self) - else: - self.default_location = None - - def list_locations(self): - """ - List data centers available with the current subscription. - - :return: list of node location objects - :rtype: ``list`` of :class:`.NodeLocation` - """ - - action = "/subscriptions/%s/providers/Microsoft.Compute" % ( - self.subscription_id) - r = self.connection.request(action, - params={"api-version": "2015-01-01"}) - - for rt in r.object["resourceTypes"]: - if rt["resourceType"] == "virtualMachines": - return [self._to_location(l) for l in rt["locations"]] - - return [] - - def list_sizes(self, location=None): - """ - List available VM sizes. - - :param location: The location at which to list sizes - (if None, use default location specified as 'region' in __init__) - :type location: :class:`.NodeLocation` - - :return: list of node size objects - :rtype: ``list`` of :class:`.NodeSize` - """ - - if location is None: - if self.default_location: - location = self.default_location - else: - raise ValueError("location is required.") - action = \ - "/subscriptions/%s/providers/Microsoft" \ - ".Compute/locations/%s/vmSizes" \ - % (self.subscription_id, location.id) - r = self.connection.request(action, - params={"api-version": "2015-06-15"}) - return [self._to_node_size(d) for d in r.object["value"]] - - def list_images(self, location=None, ex_publisher=None, ex_offer=None, - ex_sku=None, ex_version=None): - """ - List available VM images to boot from. - - :param location: The location at which to list images - (if None, use default location specified as 'region' in __init__) - :type location: :class:`.NodeLocation` - - :param ex_publisher: Filter by publisher, or None to list - all publishers. - :type ex_publisher: ``str`` - - :param ex_offer: Filter by offer, or None to list all offers. - :type ex_offer: ``str`` - - :param ex_sku: Filter by sku, or None to list all skus. - :type ex_sku: ``str`` - - :param ex_version: Filter by version, or None to list all versions. - :type ex_version: ``str`` - - :return: list of node image objects. - :rtype: ``list`` of :class:`.AzureImage` - """ - - images = [] - - if location is None: - locations = [self.default_location] - else: - locations = [location] - - for loc in locations: - if not ex_publisher: - publishers = self.ex_list_publishers(loc) - else: - publishers = [( - "/subscriptions/%s/providers/Microsoft" - ".Compute/locations/%s/publishers/%s" % - (self.subscription_id, loc.id, ex_publisher), - ex_publisher)] - - for pub in publishers: - if not ex_offer: - offers = self.ex_list_offers(pub[0]) - else: - offers = [("%s/artifacttypes/vmimage/offers/%s" % ( - pub[0], ex_offer), ex_offer)] - - for off in offers: - if not ex_sku: - skus = self.ex_list_skus(off[0]) - else: - skus = [("%s/skus/%s" % (off[0], ex_sku), ex_sku)] - - for sku in skus: - if not ex_version: - versions = self.ex_list_image_versions(sku[0]) - else: - versions = [("%s/versions/%s" % ( - sku[0], ex_version), ex_version)] - - for v in versions: - images.append(AzureImage(v[1], sku[1], - off[1], pub[1], - loc.id, - self.connection.driver)) - return images - - def get_image(self, image_id, location=None): - """Returns a single node image from a provider. - - :param image_id: Either an image urn in the form - `Publisher:Offer:Sku:Version` or a Azure blob store URI in the form - `http://storageaccount.blob.core.windows.net/container/image.vhd` - pointing to a VHD file. - :type image_id: ``str`` - - :param location: The location at which to search for the image - (if None, use default location specified as 'region' in __init__) - :type location: :class:`.NodeLocation` - - :rtype :class:`.AzureImage`: or :class:`.AzureVhdImage`: - :return: AzureImage or AzureVhdImage instance on success. - - """ - - if image_id.startswith("http"): - (storageAccount, blobContainer, blob) = _split_blob_uri(image_id) - return AzureVhdImage(storageAccount, blobContainer, blob, self) - else: - (ex_publisher, ex_offer, ex_sku, ex_version) = image_id.split(":") - i = self.list_images(location, ex_publisher, - ex_offer, ex_sku, ex_version) - return i[0] if i else None - - def list_nodes(self, ex_resource_group=None, ex_fetch_nic=True): - """ - List all nodes. - - :param ex_resource_group: List nodes in a specific resource group. - :type ex_urn: ``str`` - - :param ex_fetch_nic: Fetch NIC resources in order to get - IP address information for nodes (requires extra API calls). - :type ex_urn: ``bool`` - - :return: list of node objects - :rtype: ``list`` of :class:`.Node` - """ - - if ex_resource_group: - action = "/subscriptions/%s/resourceGroups/%s/" \ - "providers/Microsoft.Compute/virtualMachines" \ - % (self.subscription_id, ex_resource_group) - else: - action = "/subscriptions/%s/providers/Microsoft.Compute/" \ - "virtualMachines" \ - % (self.subscription_id) - r = self.connection.request(action, - params={"api-version": "2015-06-15"}) - return [self._to_node(n, fetch_nic=ex_fetch_nic) - for n in r.object["value"]] - - def create_node(self, - name, - size, - image, - auth, - ex_resource_group, - ex_storage_account, - ex_blob_container="vhds", - location=None, - ex_user_name="azureuser", - ex_network=None, - ex_subnet=None, - ex_nic=None, - ex_tags={}, - ex_customdata=""): - """Create a new node instance. This instance will be started - automatically. - - This driver supports the ``ssh_key`` feature flag for ``created_node`` - so you can upload a public key into the new instance:: - - >>> from libcloud.compute.drivers.azure_arm import AzureNodeDriver - >>> driver = AzureNodeDriver(...) - >>> auth = NodeAuthSSHKey('pubkey data here') - >>> node = driver.create_node("test_node", auth=auth) - - This driver also supports the ``password`` feature flag for - ``create_node`` - so you can set a password:: - - >>> driver = AzureNodeDriver(...) - >>> auth = NodeAuthPassword('mysecretpassword') - >>> node = driver.create_node("test_node", auth=auth, ...) - - If you don't provide the ``auth`` argument libcloud will assign - a password:: - - >>> driver = AzureNodeDriver(...) - >>> node = driver.create_node("test_node", ...) - >>> password = node.extra["properties"] \ - ["osProfile"]["adminPassword"] - - :param name: String with a name for this new node (required) - :type name: ``str`` - - :param size: The size of resources allocated to this node. - (required) - :type size: :class:`.NodeSize` - - :param image: OS Image to boot on node. (required) - :type image: :class:`.AzureImage` - - :param location: Which data center to create a node in. - (if None, use default location specified as 'region' in __init__) - :type location: :class:`.NodeLocation` - - :param auth: Initial authentication information for the node - (optional) - :type auth: :class:`.NodeAuthSSHKey` or :class:`NodeAuthPassword` - - :param ex_resource_group: The resource group in which to create the - node - :type ex_resource_group: ``str`` - - :param ex_storage_account: The storage account id in which to store - the node's disk image. - Note: when booting from a user image (AzureVhdImage) - the source image and the node image must use the same storage account. - :type ex_storage_account: ``str`` - - :param ex_blob_container: The name of the blob container on the - storage account in which to store the node's disk image (optional, - default "vhds") - :type ex_blob_container: ``str`` - - :param ex_user_name: User name for the initial admin user - (optional, default "azureuser") - :type ex_user_name: ``str`` - - :param ex_network: The virtual network the node will be attached to. - Must provide either `ex_network` (to create a default NIC for the - node on the given network) or `ex_nic` (to supply the NIC explicitly). - :type ex_network: ``str`` - - :param ex_subnet: If ex_network is provided, the subnet of the - virtual network the node will be attached to. Optional, default - is the "default" subnet. - :type ex_subnet: ``str`` - - :param ex_nic: A virtual NIC to attach to this Node, from - `ex_create_network_interface` or `ex_get_nic`. - Must provide either `ex_nic` (to supply the NIC explicitly) or - ex_network (to create a default NIC for the node on the - given network). - :type ex_nic: :class:`AzureNic` - - :param ex_tags: Optional tags to associate with this node. - :type ex_tags: ``dict`` - - :param ex_customdata: Custom data that will - be placed in the file /var/lib/waagent/CustomData - https://azure.microsoft.com/en-us/documentation/ \ - articles/virtual-machines-how-to-inject-custom-data/ - :type ex_customdata: ``str`` - - :return: The newly created node. - :rtype: :class:`.Node` - - """ - - if location is None: - location = self.default_location - if ex_nic is None: - if ex_network is None: - raise ValueError("Must provide either ex_network or ex_nic") - if ex_subnet is None: - ex_subnet = "default" - - subnet_id = "/subscriptions/%s/resourceGroups/%s/providers" \ - "/Microsoft.Network/virtualnetworks/%s/subnets/%s" % \ - (self.subscription_id, ex_resource_group, - ex_network, ex_subnet) - subnet = AzureSubnet(subnet_id, ex_subnet, {}) - ex_nic = self.ex_create_network_interface(name + "-nic", - subnet, - ex_resource_group, - location) - - auth = self._get_and_check_auth(auth) - - target = "/subscriptions/%s/resourceGroups/%s/providers" \ - "/Microsoft.Compute/virtualMachines/%s" % \ - (self.subscription_id, ex_resource_group, name) - - n = 0 - while True: - try: - instance_vhd = "https://%s.blob.core.windows.net" \ - "/%s/%s-os_%i.vhd" \ - % (ex_storage_account, - ex_blob_container, - name, - n) - self._ex_delete_old_vhd(ex_resource_group, instance_vhd) - break - except LibcloudError: - n += 1 - - if isinstance(image, AzureVhdImage): - storageProfile = { - "osDisk": { - "name": "virtualmachine-osDisk", - "osType": "linux", - "caching": "ReadWrite", - "createOption": "FromImage", - "image": { - "uri": image.id - }, - "vhd": { - "uri": instance_vhd - } - } - } - elif isinstance(image, AzureImage): - storageProfile = { - "imageReference": { - "publisher": image.publisher, - "offer": image.offer, - "sku": image.sku, - "version": image.version - }, - "osDisk": { - "name": "virtualmachine-osDisk", - "vhd": { - "uri": instance_vhd - }, - "caching": "ReadWrite", - "createOption": "FromImage" - } - } - else: - raise LibcloudError( - "Unknown image type %s," - "expected one of AzureImage, AzureVhdImage", - type(image)) - - data = { - "id": target, - "name": name, - "type": "Microsoft.Compute/virtualMachines", - "location": location.id, - "tags": ex_tags, - "properties": { - "hardwareProfile": { - "vmSize": size.id - }, - "storageProfile": storageProfile, - "osProfile": { - "computerName": name - }, - "networkProfile": { - "networkInterfaces": [ - { - "id": ex_nic.id - } - ] - } - } - } - - if ex_customdata: - data["properties"]["osProfile"]["customData"] = \ - base64.b64encode(ex_customdata) - - data["properties"]["osProfile"]["adminUsername"] = ex_user_name - - if isinstance(auth, NodeAuthSSHKey): - data["properties"]["osProfile"]["adminPassword"] = \ - binascii.hexlify(os.urandom(20)) - data["properties"]["osProfile"]["linuxConfiguration"] = { - "disablePasswordAuthentication": "true", - "ssh": { - "publicKeys": [ - { - "path": '/home/%s/.ssh/authorized_keys' % ( - ex_user_name), - "keyData": auth.pubkey - } - ] - } - } - elif isinstance(auth, NodeAuthPassword): - data["properties"]["osProfile"]["linuxConfiguration"] = { - "disablePasswordAuthentication": "false" - } - data["properties"]["osProfile"]["adminPassword"] = auth.password - else: - raise ValueError( - "Must provide NodeAuthSSHKey or NodeAuthPassword in auth") - - r = self.connection.request(target, - params={"api-version": "2015-06-15"}, - data=data, - method="PUT") - - node = self._to_node(r.object) - node.size = size - node.image = image - return node - - def reboot_node(self, node): - """ - Reboot a node. - - :param node: The node to be rebooted - :type node: :class:`.Node` - - :return: True if the reboot was successful, otherwise False - :rtype: ``bool`` - """ - - target = "%s/restart" % node.id - try: - self.connection.request(target, - params={"api-version": "2015-06-15"}, - method='POST') - return True - except BaseHTTPError as h: - if h.code == 202: - return True - else: - return False - - def destroy_node(self, node, ex_destroy_nic=True, ex_destroy_vhd=True): - """ - Destroy a node. - - :param node: The node to be destroyed - :type node: :class:`.Node` - - :param ex_destroy_nic: Destroy the NICs associated with - this node (default True). - :type node: ``bool`` - - :param ex_destroy_vhd: Destroy the OS disk blob associated with - this node (default True). - :type node: ``bool`` - - :return: True if the destroy was successful, False otherwise. - :rtype: ``bool`` - """ - - # This returns a 202 (Accepted) which means that the delete happens - # asynchronously. - try: - self.connection.request(node.id, - params={"api-version": "2015-06-15"}, - method='DELETE') - except BaseHTTPError as h: - if h.code == 202: - pass - else: - return False - - # Need to poll until the node actually goes away. - while True: - try: - time.sleep(10) - self.connection.request( - node.id, - params={"api-version": "2015-06-15"}) - except BaseHTTPError as h: - if h.code == 404: - break - else: - return False - - # Optionally clean up the network - # interfaces that were attached to this node. - interfaces = \ - node.extra["properties"]["networkProfile"]["networkInterfaces"] - if ex_destroy_nic: - for nic in interfaces: - while True: - try: - self.connection.request(nic["id"], - params={ - "api-version": - "2015-06-15"}, - method='DELETE') - break - except BaseHTTPError as h: - if h.code == 202: - break - inuse = h.message.startswith("[NicInUse]") - if h.code == 400 and inuse: - time.sleep(10) - else: - return False - - # Optionally clean up OS disk VHD. - vhd_uri = \ - node.extra["properties"]["storageProfile"]["osDisk"]["vhd"]["uri"] - if ex_destroy_vhd: - while True: - try: - resourceGroup = node.id.split("/")[4] - self._ex_delete_old_vhd( - resourceGroup, - vhd_uri) - break - except LibcloudError as e: - if "LeaseIdMissing" in str(e): - # Unfortunately lease errors - # (which occur if the vhd blob - # hasn't yet been released by the VM being destroyed) - # get raised as plain - # LibcloudError. Wait a bit and try again. - time.sleep(10) - else: - raise - - return True - - def ex_list_publishers(self, location=None): - """ - List node image publishers. - - :param location: The location at which to list publishers - (if None, use default location specified as 'region' in __init__) - :type location: :class:`.NodeLocation` - - :return: A list of tuples in the form - ("publisher id", "publisher name") - :rtype: ``list`` - """ - - if location is None and self.default_location: - location = self.default_location - else: - raise ValueError("location is required.") - - action = "/subscriptions/%s/providers/Microsoft.Compute/" \ - "locations/%s/publishers" \ - % (self.subscription_id, location.id) - r = self.connection.request(action, - params={"api-version": "2015-06-15"}) - return [(p["id"], p["name"]) for p in r.object] - - def ex_list_offers(self, publisher): - """ - List node image offers from a publisher. - - :param publisher: The complete resource path to a publisher - (as returned by `ex_list_publishers`) - :type publisher: ``str`` - - :return: A list of tuples in the form - ("offer id", "offer name") - :rtype: ``list`` - """ - - action = "%s/artifacttypes/vmimage/offers" % (publisher) - r = self.connection.request(action, - params={"api-version": "2015-06-15"}) - return [(p["id"], p["name"]) for p in r.object] - - def ex_list_skus(self, offer): - """ - List node image skus in an offer. - - :param offer: The complete resource path to an offer (as returned by - `ex_list_offers`) - :type publisher: ``str`` - - :return: A list of tuples in the form - ("sku id", "sku name") - :rtype: ``list`` - """ - - action = "%s/skus" % (offer) - r = self.connection.request(action, - params={"api-version": "2015-06-15"}) - return [(sku["id"], sku["name"]) for sku in r.object] - - def ex_list_image_versions(self, sku): - """ - List node image versions in a sku. - - :param sku: The complete resource path to a sku (as returned by - `ex_list_skus`) - :type publisher: ``str`` - - :return: A list of tuples in the form - ("version id", "version name") - :rtype: ``list`` - """ - - action = "%s/versions" % (sku) - r = self.connection.request(action, - params={"api-version": "2015-06-15"}) - return [(img["id"], img["name"]) for img in r.object] - - def ex_list_networks(self): - """ - List virtual networks. - - :return: A list of virtual networks. - :rtype: ``list`` of :class:`.AzureNetwork` - """ - - action = "/subscriptions/%s/providers/" \ - "Microsoft.Network/virtualnetworks" \ - % (self.subscription_id) - r = self.connection.request(action, - params={"api-version": "2015-06-15"}) - return [AzureNetwork(net["id"], net["name"], net["location"], - net["properties"]) for net in r.object["value"]] - - def ex_list_subnets(self, network): - """ - List subnets of a virtual network. - - :param network: The virtual network containing the subnets. - :type network: :class:`.AzureNetwork` - - :return: A list of subnets. - :rtype: ``list`` of :class:`.AzureSubnet` - """ - - action = "%s/subnets" % (network.id) - r = self.connection.request(action, - params={"api-version": "2015-06-15"}) - return [AzureSubnet(net["id"], net["name"], net["properties"]) - for net in r.object["value"]] - - def ex_list_nics(self, resource_group): - """ - List available virtual network interface controllers - in a resource group - - :param resource_group: List NICS in a specific resource group - containing the NICs. - :type resource_group: ``str`` - - :return: A list of NICs. - :rtype: ``list`` of :class:`.AzureNic` - """ - - action = "/subscriptions/%s/providers/Microsoft.Network" \ - "/networkInterfaces" % \ - (self.subscription_id, resource_group) - r = self.connection.request(action, - params={"api-version": "2015-06-15"}) - return [self._to_nic(net) for net in r.object["value"]] - - def ex_get_nic(self, id): - """ - Fetch information about a NIC. - - :param id: The complete resource path to the NIC resource. - :type id: ``str`` - - :return: The NIC object - :rtype: :class:`.AzureNic` - """ - - r = self.connection.request(id, params={"api-version": "2015-06-15"}) - return self._to_nic(r.object) - - def ex_get_public_ip(self, id): - """ - Fetch information about a public IP resource. - - :param id: The complete resource path to the public IP resource. - :type id: ``str` - - :return: The public ip object - :rtype: :class:`.AzureIPAddress` - """ - - r = self.connection.request(id, params={"api-version": "2015-06-15"}) - return self._to_ip_address(r.object) - - def ex_list_public_ips(self, resource_group): - """ - List public IP resources. - - :param resource_group: List public IPs in a specific resource group. - :type resource_group: ``str`` - - :return: List of public ip objects - :rtype: ``list`` of :class:`.AzureIPAddress` - """ - - action = "/subscriptions/%s/providers/Microsoft.Network" \ - "/publicIPAddresses" % (self.subscription_id, resource_group) - r = self.connection.request(action, - params={"api-version": "2015-06-15"}) - return [self._to_ip_address(net) for net in r.object["value"]] - - def ex_create_public_ip(self, name, resource_group, location=None): - """ - Create a public IP resources. - - :param name: Name of the public IP resource - :type name: ``str`` - - :param resource_group: The resource group to create the public IP - :type resource_group: ``str`` - - :param location: The location at which to create the public IP - (if None, use default location specified as 'region' in __init__) - :type location: :class:`.NodeLocation` - - :return: The newly created public ip object - :rtype: :class:`.AzureIPAddress` - """ - - if location is None and self.default_location: - location = self.default_location - else: - raise ValueError("location is required.") - - target = "/subscriptions/%s/resourceGroups/%s/" \ - "providers/Microsoft.Network/publicIPAddresses/%s" \ - % (self.subscription_id, resource_group, name) - data = { - "location": location.id, - "tags": {}, - "properties": { - "publicIPAllocationMethod": "Dynamic" - } - } - r = self.connection.request(target, - params={"api-version": "2015-06-15"}, - data=data, - method='PUT' - ) - return self._to_ip_address(r.object) - - def ex_create_network_interface(self, name, subnet, resource_group, - location=None, public_ip=None): - """ - Create a virtual network interface (NIC). - - :param name: Name of the NIC resource - :type name: ``str`` - - :param subnet: The subnet to attach the NIC - :type subnet: :class:`.AzureSubnet` - - :param resource_group: The resource group to create the NIC - :type resource_group: ``str`` - - :param location: The location at which to create the NIC - (if None, use default location specified as 'region' in __init__) - :type location: :class:`.NodeLocation` - - :param public_ip: Associate a public IP resource with this NIC - (optional). - :type public_ip: :class:`.AzureIPAddress` - - :return: The newly created NIC - :rtype: :class:`.AzureNic` - """ - - if location is None: - if self.default_location: - location = self.default_location - else: - raise ValueError("location is required.") - - target = "/subscriptions/%s/resourceGroups/%s/providers" \ - "/Microsoft.Network/networkInterfaces/%s" \ - % (self.subscription_id, resource_group, name) - - data = { - "location": location.id, - "tags": {}, - "properties": { - "ipConfigurations": [{ - "name": "myip1", - "properties": { - "subnet": { - "id": subnet.id - }, - "privateIPAllocationMethod": "Dynamic" - } - }] - } - } - - if public_ip: - data["properties"]["ipConfigurations"][0]["publicIPAddress"] = { - "id": public_ip.id - } - - r = self.connection.request(target, - params={"api-version": "2015-06-15"}, - data=data, - method='PUT' - ) - return AzureNic(r.object["id"], r.object["name"], r.object["location"], - r.object["properties"]) - - def ex_create_tags(self, resource, tags, replace=False): - """ - Update tags on any resource supporting tags. - - :param resource: The resource to update. - :type resource: ``str`` or Azure object with an ``id`` attribute. - - :param tags: The tags to set. - :type tags: ``dict`` - - :param replace: If true, replace all tags with the new tags. - If false (default) add or update tags. - :type replace: ``bool`` - """ - - if not isinstance(resource, basestring): - resource = resource.id - r = self.connection.request( - resource, - params={"api-version": "2015-06-15"}) - if replace: - r.object["tags"] = tags - else: - r.object["tags"].update(tags) - r = self.connection.request(resource, data={"tags": r.object["tags"]}, - params={"api-version": "2015-06-15"}, - method="PATCH") - - def ex_start_node(self, node): - """ - Start a stopped node. - - :param node: The node to be started - :type node: :class:`.Node` - """ - - target = "%s/start" % node.id - r = self.connection.request(target, - params={"api-version": "2015-06-15"}, - method='POST') - return r.object - - def ex_stop_node(self, node, deallocate=True): - """ - Stop a running node. - - :param node: The node to be stopped - :type node: :class:`.Node` - - :param deallocate: If True (default) stop and then deallocate the node - (release the hardware allocated to run the node). If False, stop the - node but maintain the hardware allocation. If the node is not - deallocated, the subscription will continue to be billed as if it - were running. - :type deallocate: ``bool`` - """ - - if deallocate: - target = "%s/deallocate" % node.id - else: - target = "%s/stop" % node.id - r = self.connection.request(target, - params={"api-version": "2015-06-15"}, - method='POST') - return r.object - - def ex_get_storage_account_keys(self, resource_group, storage_account): - """ - Get account keys required to access to a storage account - (using AzureBlobsStorageDriver). - - :param resource_group: The resource group - containing the storage account - :type resource_group: ``str`` - - :param storage_account: Storage account to access - :type storage_account: ``str`` - - :return: The account keys, in the form `{"key1": "XXX", "key2": "YYY"}` - :rtype: ``.dict`` - """ - - action = "/subscriptions/%s/resourceGroups/%s/" \ - "providers/Microsoft.Storage/storageAccounts/%s/listKeys" \ - % (self.subscription_id, - resource_group, - storage_account) - - r = self.connection.request(action, - params={ - "api-version": "2015-05-01-preview"}, - method="POST") - return r.object - - def ex_run_command(self, node, - command, - filerefs=[], - timestamp=0, - storage_account_name=None, - storage_account_key=None, - location=None): - """ - Run a command on the node as root. - - Does not require ssh to log in, - uses Windows Azure Agent (waagent) running - on the node. - - :param node: The node on which to run the command. - :type node: :class:``.Node`` - - :param command: The actual command to run. Note this is parsed - into separate arguments according to shell quoting rules but is - executed directly as a subprocess, not a shell command. - :type command: ``str`` - - :param filerefs: Optional files to fetch by URI from Azure blob store - (must provide storage_account_name and storage_account_key), - or regular HTTP. - :type command: ``list`` of ``str`` - - :param location: The location of the virtual machine - (if None, use default location specified as 'region' in __init__) - :type location: :class:`.NodeLocation` - - :param storage_account_name: The storage account - from which to fetch files in `filerefs` - :type storage_account_name: ``str`` - - :param storage_account_key: The storage key to - authorize to the blob store. - :type storage_account_key: ``str`` - - :type: ``list`` of :class:`.NodeLocation` - - """ - - if location is None: - if self.default_location: - location = self.default_location - else: - raise ValueError("location is required.") - - name = "init" - - target = node.id + "/extensions/" + name - - data = { - "location": location.id, - "name": name, - "properties": { - "publisher": "Microsoft.OSTCExtensions", - "type": "CustomScriptForLinux", - "typeHandlerVersion": "1.3", - "settings": { - "fileUris": filerefs, - "commandToExecute": command, - "timestamp": timestamp - } - } - } - - if storage_account_name and storage_account_key: - data["properties"]["protectedSettings"] = { - "storageAccountName": storage_account_name, - "storageAccountKey": storage_account_key} - - r = self.connection.request(target, - params={"api-version": "2015-06-15"}, - data=data, - method='PUT') - return r.object - - def _ex_delete_old_vhd(self, resource_group, uri): - try: - (storageAccount, blobContainer, blob) = _split_blob_uri(uri) - keys = self.ex_get_storage_account_keys(resource_group, - storageAccount) - blobdriver = AzureBlobsStorageDriver(storageAccount, - keys["key1"]) - blobdriver.delete_object(blobdriver.get_object(blobContainer, - blob)) - return True - except ObjectDoesNotExistError: - return True - - def _ex_connection_class_kwargs(self): - kwargs = super(AzureNodeDriver, self)._ex_connection_class_kwargs() - kwargs['tenant_id'] = self.tenant_id - kwargs['subscription_id'] = self.subscription_id - return kwargs - - def _to_node(self, data, fetch_nic=True): - private_ips = [] - public_ips = [] - nics = data["properties"]["networkProfile"]["networkInterfaces"] - if fetch_nic: - for nic in nics: - try: - n = self.ex_get_nic(nic["id"]) - priv = n.extra["ipConfigurations"][0]["properties"] \ - .get("privateIPAddress") - if priv: - private_ips.append(priv) - pub = n.extra["ipConfigurations"][0]["properties"].get( - "publicIPAddress") - if pub: - pub_addr = self.ex_get_public_ip(pub["id"]) - addr = pub_addr.extra.get("ipAddress") - if addr: - public_ips.append(addr) - except BaseHTTPError: - pass - - state = NodeState.UNKNOWN - try: - action = "%s/InstanceView" % (data["id"]) - r = self.connection.request(action, - params={"api-version": "2015-06-15"}) - for status in r.object["statuses"]: - if status["code"] == "ProvisioningState/creating": - state = NodeState.PENDING - break - elif status["code"] == "ProvisioningState/deleting": - state = NodeState.TERMINATED - break - elif status["code"].startswith("ProvisioningState/failed"): - state = NodeState.ERROR - break - elif status["code"] == "ProvisioningState/succeeded": - pass - - if status["code"] == "PowerState/deallocated": - state = NodeState.STOPPED - break - elif status["code"] == "PowerState/deallocating": - state = NodeState.PENDING - break - elif status["code"] == "PowerState/running": - state = NodeState.RUNNING - except BaseHTTPError: - pass - - node = Node(data["id"], - data["name"], - state, - public_ips, - private_ips, - driver=self.connection.driver, - extra=data) - - return node - - def _to_node_size(self, data): - return NodeSize(id=data["name"], - name=data["name"], - ram=data["memoryInMB"], - # convert to disk from MB to GB - disk=data["resourceDiskSizeInMB"] / 1024, - bandwidth=0, - price=0, - driver=self.connection.driver, - extra={"numberOfCores": data["numberOfCores"], - "osDiskSizeInMB": data["osDiskSizeInMB"], - "maxDataDiskCount": data["maxDataDiskCount"]}) - - def _to_nic(self, data): - return AzureNic(data["id"], data["name"], data["location"], - data["properties"]) - - def _to_ip_address(self, data): - return AzureIPAddress(data["id"], data["name"], data["properties"]) - - def _to_location(self, loc): - # XXX for some reason the API returns location names like - # "East US" instead of "eastus" which is what is actually needed - # for other API calls, so do a name->id fixup. - loc_id = loc.lower().replace(" ", "") - return NodeLocation(loc_id, loc, self._location_to_country.get(loc_id), - self.connection.driver) - - -def _split_blob_uri(uri): - uri = uri.split("/") - storageAccount = uri[2].split(".")[0] - blobContainer = uri[3] - blob = '/'.join(uri[4:]) - return (storageAccount, blobContainer, blob)
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/bluebox.py ---------------------------------------------------------------------- diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/bluebox.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/bluebox.py deleted file mode 100644 index 204e0de..0000000 --- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/bluebox.py +++ /dev/null @@ -1,235 +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. - -""" -libcloud driver for the Blue Box Blocks API - -This driver implements all libcloud functionality for the Blue Box Blocks API. - -Blue Box home page http://bluebox.net -Blue Box API documentation https://boxpanel.bluebox -.net/public/the_vault/index.php/Blocks_API -""" - -import copy -import base64 - -from libcloud.utils.py3 import urlencode -from libcloud.utils.py3 import b - -from libcloud.common.base import JsonResponse, ConnectionUserAndKey -from libcloud.compute.providers import Provider -from libcloud.compute.types import NodeState, InvalidCredsError -from libcloud.compute.base import Node, NodeDriver -from libcloud.compute.base import NodeSize, NodeImage, NodeLocation -from libcloud.compute.base import NodeAuthPassword, NodeAuthSSHKey - -# Current end point for Blue Box API. -BLUEBOX_API_HOST = "boxpanel.bluebox.net" - -# The API doesn't currently expose all of the required values for libcloud, -# so we simply list what's available right now, along with all of the various -# attributes that are needed by libcloud. -BLUEBOX_INSTANCE_TYPES = { - '1gb': { - 'id': '94fd37a7-2606-47f7-84d5-9000deda52ae', - 'name': 'Block 1GB Virtual Server', - 'ram': 1024, - 'disk': 20, - 'cpu': 0.5 - }, - '2gb': { - 'id': 'b412f354-5056-4bf0-a42f-6ddd998aa092', - 'name': 'Block 2GB Virtual Server', - 'ram': 2048, - 'disk': 25, - 'cpu': 1 - }, - '4gb': { - 'id': '0cd183d3-0287-4b1a-8288-b3ea8302ed58', - 'name': 'Block 4GB Virtual Server', - 'ram': 4096, - 'disk': 50, - 'cpu': 2 - }, - '8gb': { - 'id': 'b9b87a5b-2885-4a2e-b434-44a163ca6251', - 'name': 'Block 8GB Virtual Server', - 'ram': 8192, - 'disk': 100, - 'cpu': 4 - } -} - -RAM_PER_CPU = 2048 - -NODE_STATE_MAP = {'queued': NodeState.PENDING, - 'building': NodeState.PENDING, - 'running': NodeState.RUNNING, - 'error': NodeState.TERMINATED, - 'unknown': NodeState.UNKNOWN} - - -class BlueboxResponse(JsonResponse): - def parse_error(self): - if int(self.status) == 401: - if not self.body: - raise InvalidCredsError(str(self.status) + ': ' + self.error) - else: - raise InvalidCredsError(self.body) - return self.body - - -class BlueboxNodeSize(NodeSize): - def __init__(self, id, name, cpu, ram, disk, price, driver): - self.id = id - self.name = name - self.cpu = cpu - self.ram = ram - self.disk = disk - self.price = price - self.driver = driver - - def __repr__(self): - return (( - '<NodeSize: id=%s, name=%s, cpu=%s, ram=%s, disk=%s, ' - 'price=%s, driver=%s ...>') - % (self.id, self.name, self.cpu, self.ram, self.disk, - self.price, self.driver.name)) - - -class BlueboxConnection(ConnectionUserAndKey): - """ - Connection class for the Bluebox driver - """ - - host = BLUEBOX_API_HOST - secure = True - responseCls = BlueboxResponse - - 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) - return headers - - -class BlueboxNodeDriver(NodeDriver): - """ - Bluebox Blocks node driver - """ - - connectionCls = BlueboxConnection - type = Provider.BLUEBOX - api_name = 'bluebox' - name = 'Bluebox Blocks' - website = 'http://bluebox.net' - features = {'create_node': ['ssh_key', 'password']} - - def list_nodes(self): - result = self.connection.request('/api/blocks.json') - return [self._to_node(i) for i in result.object] - - def list_sizes(self, location=None): - sizes = [] - for key, values in list(BLUEBOX_INSTANCE_TYPES.items()): - attributes = copy.deepcopy(values) - attributes.update({'price': self._get_size_price(size_id=key)}) - sizes.append(BlueboxNodeSize(driver=self.connection.driver, - **attributes)) - - return sizes - - def list_images(self, location=None): - result = self.connection.request('/api/block_templates.json') - images = [] - for image in result.object: - images.extend([self._to_image(image)]) - - return images - - def create_node(self, **kwargs): - headers = {'Content-Type': 'application/x-www-form-urlencoded'} - size = kwargs["size"] - - name = kwargs['name'] - image = kwargs['image'] - size = kwargs['size'] - - auth = self._get_and_check_auth(kwargs.get('auth')) - - data = { - 'hostname': name, - 'product': size.id, - 'template': image.id - } - - ssh = None - password = None - - if isinstance(auth, NodeAuthSSHKey): - ssh = auth.pubkey - data.update(ssh_public_key=ssh) - elif isinstance(auth, NodeAuthPassword): - password = auth.password - data.update(password=password) - - if "ex_username" in kwargs: - data.update(username=kwargs["ex_username"]) - - if not ssh and not password: - raise Exception("SSH public key or password required.") - - params = urlencode(data) - result = self.connection.request('/api/blocks.json', headers=headers, - data=params, method='POST') - node = self._to_node(result.object) - - if getattr(auth, "generated", False): - node.extra['password'] = auth.password - - return node - - def destroy_node(self, node): - url = '/api/blocks/%s.json' % (node.id) - result = self.connection.request(url, method='DELETE') - - return result.status == 200 - - def list_locations(self): - return [NodeLocation(0, "Blue Box Seattle US", 'US', self)] - - def reboot_node(self, node): - url = '/api/blocks/%s/reboot.json' % (node.id) - result = self.connection.request(url, method="PUT") - return result.status == 200 - - def _to_node(self, vm): - state = NODE_STATE_MAP[vm.get('status', NodeState.UNKNOWN)] - n = Node(id=vm['id'], - name=vm['hostname'], - state=state, - public_ips=[ip['address'] for ip in vm['ips']], - private_ips=[], - extra={'storage': vm['storage'], 'cpu': vm['cpu']}, - driver=self.connection.driver) - return n - - def _to_image(self, image): - image = NodeImage(id=image['id'], - name=image['description'], - driver=self.connection.driver) - return image http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/brightbox.py ---------------------------------------------------------------------- diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/brightbox.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/brightbox.py deleted file mode 100644 index 8798332..0000000 --- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/brightbox.py +++ /dev/null @@ -1,306 +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. -""" -Brightbox Driver -""" - -from libcloud.utils.py3 import httplib -from libcloud.utils.py3 import b - -from libcloud.common.brightbox import BrightboxConnection -from libcloud.compute.types import Provider, NodeState -from libcloud.compute.base import NodeDriver -from libcloud.compute.base import Node, NodeImage, NodeSize, NodeLocation - -import base64 - - -API_VERSION = '1.0' - - -def _extract(d, keys): - return dict((k, d[k]) for k in keys if k in d and d[k] is not None) - - -class BrightboxNodeDriver(NodeDriver): - """ - Brightbox node driver - """ - - connectionCls = BrightboxConnection - - type = Provider.BRIGHTBOX - name = 'Brightbox' - website = 'http://www.brightbox.co.uk/' - - NODE_STATE_MAP = {'creating': NodeState.PENDING, - 'active': NodeState.RUNNING, - 'inactive': NodeState.UNKNOWN, - 'deleting': NodeState.UNKNOWN, - 'deleted': NodeState.TERMINATED, - 'failed': NodeState.UNKNOWN, - 'unavailable': NodeState.UNKNOWN} - - def __init__(self, key, secret=None, secure=True, host=None, port=None, - api_version=API_VERSION, **kwargs): - super(BrightboxNodeDriver, self).__init__(key=key, secret=secret, - secure=secure, - host=host, port=port, - api_version=api_version, - **kwargs) - - def _to_node(self, data): - extra_data = _extract(data, ['fqdn', 'user_data', 'status', - 'interfaces', 'snapshots', - 'server_groups', 'hostname', - 'started_at', 'created_at', - 'deleted_at']) - extra_data['zone'] = self._to_location(data['zone']) - - ipv6_addresses = [interface['ipv6_address'] for interface - in data['interfaces'] if 'ipv6_address' in interface] - - private_ips = [interface['ipv4_address'] - for interface in data['interfaces'] - if 'ipv4_address' in interface] - - public_ips = [cloud_ip['public_ip'] for cloud_ip in data['cloud_ips']] - public_ips += ipv6_addresses - - return Node( - id=data['id'], - name=data['name'], - state=self.NODE_STATE_MAP[data['status']], - private_ips=private_ips, - public_ips=public_ips, - driver=self.connection.driver, - size=self._to_size(data['server_type']), - image=self._to_image(data['image']), - extra=extra_data - ) - - def _to_image(self, data): - extra_data = _extract(data, ['arch', 'compatibility_mode', - 'created_at', 'description', - 'disk_size', 'min_ram', 'official', - 'owner', 'public', 'source', - 'source_type', 'status', 'username', - 'virtual_size', 'licence_name']) - - if data.get('ancestor', None): - extra_data['ancestor'] = self._to_image(data['ancestor']) - - return NodeImage( - id=data['id'], - name=data['name'], - driver=self, - extra=extra_data - ) - - def _to_size(self, data): - return NodeSize( - id=data['id'], - name=data['name'], - ram=data['ram'], - disk=data['disk_size'], - bandwidth=0, - price=0, - driver=self - ) - - def _to_location(self, data): - if data: - return NodeLocation( - id=data['id'], - name=data['handle'], - country='GB', - driver=self - ) - else: - return None - - def _post(self, path, data={}): - headers = {'Content-Type': 'application/json'} - return self.connection.request(path, data=data, headers=headers, - method='POST') - - def _put(self, path, data={}): - headers = {'Content-Type': 'application/json'} - return self.connection.request(path, data=data, headers=headers, - method='PUT') - - def create_node(self, **kwargs): - """Create a new Brightbox node - - Reference: https://api.gb1.brightbox.com/1.0/#server_create_server - - @inherits: :class:`NodeDriver.create_node` - - :keyword ex_userdata: User data - :type ex_userdata: ``str`` - - :keyword ex_servergroup: Name or list of server group ids to - add server to - :type ex_servergroup: ``str`` or ``list`` of ``str`` - """ - data = { - 'name': kwargs['name'], - 'server_type': kwargs['size'].id, - 'image': kwargs['image'].id, - } - - if 'ex_userdata' in kwargs: - data['user_data'] = base64.b64encode(b(kwargs['ex_userdata'])) \ - .decode('ascii') - - if 'location' in kwargs: - data['zone'] = kwargs['location'].id - - if 'ex_servergroup' in kwargs: - if not isinstance(kwargs['ex_servergroup'], list): - kwargs['ex_servergroup'] = [kwargs['ex_servergroup']] - data['server_groups'] = kwargs['ex_servergroup'] - - data = self._post('/%s/servers' % self.api_version, data).object - return self._to_node(data) - - def destroy_node(self, node): - response = self.connection.request( - '/%s/servers/%s' % (self.api_version, node.id), - method='DELETE') - return response.status == httplib.ACCEPTED - - def list_nodes(self): - data = self.connection.request('/%s/servers' % self.api_version).object - return list(map(self._to_node, data)) - - def list_images(self, location=None): - data = self.connection.request('/%s/images' % self.api_version).object - return list(map(self._to_image, data)) - - def list_sizes(self): - data = self.connection.request('/%s/server_types' % self.api_version) \ - .object - return list(map(self._to_size, data)) - - def list_locations(self): - data = self.connection.request('/%s/zones' % self.api_version).object - return list(map(self._to_location, data)) - - def ex_list_cloud_ips(self): - """ - List Cloud IPs - - @note: This is an API extension for use on Brightbox - - :rtype: ``list`` of ``dict`` - """ - return self.connection.request('/%s/cloud_ips' % self.api_version) \ - .object - - def ex_create_cloud_ip(self, reverse_dns=None): - """ - Requests a new cloud IP address for the account - - @note: This is an API extension for use on Brightbox - - :param reverse_dns: Reverse DNS hostname - :type reverse_dns: ``str`` - - :rtype: ``dict`` - """ - params = {} - - if reverse_dns: - params['reverse_dns'] = reverse_dns - - return self._post('/%s/cloud_ips' % self.api_version, params).object - - def ex_update_cloud_ip(self, cloud_ip_id, reverse_dns): - """ - Update some details of the cloud IP address - - @note: This is an API extension for use on Brightbox - - :param cloud_ip_id: The id of the cloud ip. - :type cloud_ip_id: ``str`` - - :param reverse_dns: Reverse DNS hostname - :type reverse_dns: ``str`` - - :rtype: ``dict`` - """ - response = self._put('/%s/cloud_ips/%s' % (self.api_version, - cloud_ip_id), - {'reverse_dns': reverse_dns}) - return response.status == httplib.OK - - def ex_map_cloud_ip(self, cloud_ip_id, interface_id): - """ - Maps (or points) a cloud IP address at a server's interface - or a load balancer to allow them to respond to public requests - - @note: This is an API extension for use on Brightbox - - :param cloud_ip_id: The id of the cloud ip. - :type cloud_ip_id: ``str`` - - :param interface_id: The Interface ID or LoadBalancer ID to - which this Cloud IP should be mapped to - :type interface_id: ``str`` - - :return: True if the mapping was successful. - :rtype: ``bool`` - """ - response = self._post('/%s/cloud_ips/%s/map' % (self.api_version, - cloud_ip_id), - {'destination': interface_id}) - return response.status == httplib.ACCEPTED - - def ex_unmap_cloud_ip(self, cloud_ip_id): - """ - Unmaps a cloud IP address from its current destination making - it available to remap. This remains in the account's pool - of addresses - - @note: This is an API extension for use on Brightbox - - :param cloud_ip_id: The id of the cloud ip. - :type cloud_ip_id: ``str`` - - :return: True if the unmap was successful. - :rtype: ``bool`` - """ - response = self._post('/%s/cloud_ips/%s/unmap' % (self.api_version, - cloud_ip_id)) - return response.status == httplib.ACCEPTED - - def ex_destroy_cloud_ip(self, cloud_ip_id): - """ - Release the cloud IP address from the account's ownership - - @note: This is an API extension for use on Brightbox - - :param cloud_ip_id: The id of the cloud ip. - :type cloud_ip_id: ``str`` - - :return: True if the unmap was successful. - :rtype: ``bool`` - """ - response = self.connection.request( - '/%s/cloud_ips/%s' % (self.api_version, - cloud_ip_id), - method='DELETE') - return response.status == httplib.OK http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/bsnl.py ---------------------------------------------------------------------- diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/bsnl.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/bsnl.py deleted file mode 100644 index 6353671..0000000 --- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/bsnl.py +++ /dev/null @@ -1,53 +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. - -from libcloud.compute.providers import Provider -from libcloud.common.dimensiondata import (DimensionDataConnection, - API_ENDPOINTS) -from libcloud.compute.drivers.dimensiondata import DimensionDataNodeDriver - -DEFAULT_REGION = 'bsnl-in' - - -class BSNLNodeDriver(DimensionDataNodeDriver): - """ - BSNL node driver, based on Dimension Data driver - """ - - selected_region = None - connectionCls = DimensionDataConnection - name = 'BSNL' - website = 'http://www.bsnlcloud.com/' - type = Provider.BSNL - features = {'create_node': ['password']} - api_version = 1.0 - - def __init__(self, key, secret=None, secure=True, host=None, port=None, - api_version=None, region=DEFAULT_REGION, **kwargs): - - if region not in API_ENDPOINTS: - raise ValueError('Invalid region: %s' % (region)) - - self.selected_region = API_ENDPOINTS[region] - - super(BSNLNodeDriver, self).__init__( - key=key, - secret=secret, - secure=secure, - host=host, - port=port, - api_version=api_version, - region=region, - **kwargs) http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/ciscoccs.py ---------------------------------------------------------------------- diff --git a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/ciscoccs.py b/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/ciscoccs.py deleted file mode 100644 index adc21f1..0000000 --- a/apache-libcloud-1.0.0rc2/libcloud/compute/drivers/ciscoccs.py +++ /dev/null @@ -1,56 +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. -""" -Cisco CCS Driver -""" - -from libcloud.compute.providers import Provider -from libcloud.common.dimensiondata import (DimensionDataConnection, - API_ENDPOINTS) -from libcloud.compute.drivers.dimensiondata import DimensionDataNodeDriver - -DEFAULT_REGION = 'cisco-na' - - -class CiscoCCSNodeDriver(DimensionDataNodeDriver): - """ - Cisco CCS node driver, based on Dimension Data driver - """ - - selected_region = None - connectionCls = DimensionDataConnection - name = 'CiscoCCS' - website = 'http://www.cisco.com/' - type = Provider.CISCOCCS - features = {'create_node': ['password']} - api_version = 1.0 - - def __init__(self, key, secret=None, secure=True, host=None, port=None, - api_version=None, region=DEFAULT_REGION, **kwargs): - - if region not in API_ENDPOINTS: - raise ValueError('Invalid region: %s' % (region)) - - self.selected_region = API_ENDPOINTS[region] - - super(CiscoCCSNodeDriver, self).__init__( - key=key, - secret=secret, - secure=secure, - host=host, - port=port, - api_version=api_version, - region=region, - **kwargs)
