Source code for libcloud.compute.drivers.runabove

# 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.common.runabove import API_ROOT, RunAboveConnection
from libcloud.compute.base import NodeDriver, NodeSize, Node, NodeLocation
from libcloud.compute.base import NodeImage
from libcloud.compute.types import Provider
from libcloud.compute.drivers.openstack import OpenStackNodeDriver
from libcloud.compute.drivers.openstack import OpenStackKeyPair


[docs]class RunAboveNodeDriver(NodeDriver): """ Libcloud driver for the RunAbove API Rough mapping of which is which: list_nodes linode.list reboot_node linode.reboot destroy_node linode.delete create_node linode.create, linode.update, linode.disk.createfromdistribution, linode.disk.create, linode.config.create, linode.ip.addprivate, linode.boot list_sizes avail.linodeplans list_images avail.distributions list_locations avail.datacenters list_volumes linode.disk.list destroy_volume linode.disk.delete For more information on the Linode API, be sure to read the reference: http://www.linode.com/api/ """ type = Provider.RUNABOVE name = "RunAbove" website = 'https://www.runabove.com/' connectionCls = RunAboveConnection features = {'create_node': ['ssh_key']} api_name = 'runabove' NODE_STATE_MAP = OpenStackNodeDriver.NODE_STATE_MAP def __init__(self, key, secret, ex_consumer_key=None): """ Instantiate the driver with the given API key :param key: the API key to use (required) :type key: ``str`` :rtype: ``None`` """ self.datacenter = None self.consumer_key = ex_consumer_key NodeDriver.__init__(self, key, secret, ex_consumer_key=ex_consumer_key)
[docs] def list_nodes(self, location=None): """ List all Linodes that the API key can access This call will return all Linodes that the API key in use has access to. If a node is in this list, rebooting will work; however, creation and destruction are a separate grant. :return: List of node objects that the API key can access :rtype: ``list`` of :class:`Node` """ action = API_ROOT + '/instance' data = {} if location: data['region'] = location.id response = self.connection.request(action, data=data) return self._to_nodes(response.object)
[docs] def ex_get_node(self, node_id): action = API_ROOT + '/instance/' + node_id response = self.connection.request(action, method='GET') return self._to_node(response.object)
[docs] def create_node(self, **kwargs): action = API_ROOT + '/instance' data = { 'name': kwargs["name"], 'imageId': kwargs["image"].id, 'flavorId': kwargs["size"].id, 'region': kwargs["location"].id, } if kwargs.get('ex_keyname'): data['sshKeyName'] = kwargs['ex_keyname'] response = self.connection.request(action, data=data, method='POST') return self._to_node(response.object)
[docs] def destroy_node(self, node): action = API_ROOT + '/instance/' + node.id self.connection.request(action, method='DELETE') return True
[docs] def list_sizes(self, location=None): """ List available RunAbove flavors. :keyword location: the facility to retrieve plans in :type location: :class:`NodeLocation` :rtype: ``list`` of :class:`NodeSize` """ action = API_ROOT + '/flavor' data = {} if location: data['region'] = location.id response = self.connection.request(action, data=data) return self._to_sizes(response.object)
[docs] def ex_get_size(self, size_id): action = API_ROOT + '/flavor/' + size_id response = self.connection.request(action) return self._to_size(response.object)
[docs] def list_images(self, location=None, size=None): """ List available Linux distributions Retrieve all Linux distributions that can be deployed to a Linode. :rtype: ``list`` of :class:`NodeImage` """ action = API_ROOT + '/image' data = {} if location: data['region'] = location.id if size: data['flavorId'] = size.id response = self.connection.request(action, data=data) return self._to_images(response.object)
[docs] def get_image(self, image_id): action = API_ROOT + '/image/' + image_id response = self.connection.request(action) return self._to_image(response.object)
[docs] def list_locations(self): """ List available facilities for deployment Retrieve all facilities that a Linode can be deployed in. :rtype: ``list`` of :class:`NodeLocation` """ action = API_ROOT + '/region' data = self.connection.request(action) return self._to_locations(data.object)
[docs] def list_key_pairs(self, location=None): action = API_ROOT + '/ssh' data = {} if location: data['region'] = location.id response = self.connection.request(action, data=data) return self._to_key_pairs(response.object)
[docs] def get_key_pair(self, name, location): action = API_ROOT + '/ssh/' + name data = {'region': location.id} response = self.connection.request(action, data=data) return self._to_key_pair(response.object)
[docs] def import_key_pair_from_string(self, name, key_material, location): """ Import a new public key. :param name: Key pair name. :type name: ``str`` :param key_material: Public key material. :type key_material: ``str`` :return: Imported key pair object. :rtype: :class:`.KeyPair` """ action = API_ROOT + '/ssh' data = {'name': name, 'publicKey': key_material, 'region': location.id} response = self.connection.request(action, data=data, method='POST') return self._to_key_pair(response.object)
[docs] def delete_key_pair(self, name, location): """ Delete an existing key pair. :param key_pair: Key pair object or ID. :type key_pair: :class.KeyPair` or ``int`` :return: True of False based on success of Keypair deletion :rtype: ``bool`` """ action = API_ROOT + '/ssh/' + name data = {'name': name, 'region': location.id} self.connection.request(action, data=data, method='DELETE') return True
def _to_volumes(self, objs): return [self._to_volume(obj) for obj in objs] def _to_location(self, obj): location = self.connection.LOCATIONS[obj] return NodeLocation(driver=self, **location) def _to_locations(self, objs): return [self._to_location(obj) for obj in objs] def _to_node(self, obj): extra = obj.copy() if 'flavorId' in extra: public_ips = [obj.pop('ip')] else: ip = extra.pop('ipv4') public_ips = [ip] if ip else [] del extra['instanceId'] del extra['name'] return Node(id=obj['instanceId'], name=obj['name'], state=self.NODE_STATE_MAP[obj['status']], public_ips=public_ips, private_ips=[], driver=self, extra=extra) def _to_nodes(self, objs): return [self._to_node(obj) for obj in objs] def _to_size(self, obj): extra = {'vcpus': obj['vcpus'], 'type': obj['type'], 'region': obj['region']} return NodeSize(id=obj['id'], name=obj['name'], ram=obj['ram'], disk=obj['disk'], bandwidth=None, price=None, driver=self, extra=extra) def _to_sizes(self, objs): return [self._to_size(obj) for obj in objs] def _to_image(self, obj): extra = {'region': obj['region'], 'visibility': obj['visibility'], 'deprecated': obj['deprecated']} return NodeImage(id=obj['id'], name=obj['name'], driver=self, extra=extra) def _to_images(self, objs): return [self._to_image(obj) for obj in objs] def _to_key_pair(self, obj): extra = {'region': obj['region']} return OpenStackKeyPair(name=obj['name'], public_key=obj['publicKey'], driver=self, fingerprint=obj['fingerPrint'], extra=extra) def _to_key_pairs(self, objs): return [self._to_key_pair(obj) for obj in objs] def _ex_connection_class_kwargs(self): return {'ex_consumer_key': self.consumer_key} def _add_required_headers(self, headers, method, action, data, timestamp): timestamp = self.connection.get_timestamp() signature = self.connection.make_signature(method, action, data, str(timestamp)) headers.update({ 'X-Ra-Timestamp': timestamp, 'X-Ra-Signature': signature })