You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by to...@apache.org on 2011/10/23 20:35:26 UTC
svn commit: r1187946 - /libcloud/trunk/libcloud/compute/drivers/opennebula.py
Author: tomaz
Date: Sun Oct 23 18:35:26 2011
New Revision: 1187946
URL: http://svn.apache.org/viewvc?rev=1187946&view=rev
Log:
Add OpenNebulaNetwork class and ex_list_networks() method to the OpenNebula
driver. Also be consistent and make node states constants uppercase and clean up
the style (double quotes to single quotes, etc.).
Contributed by Hutson Betts <hut606 at gmail dot com> and part of LIBCLOUD-121.
Modified:
libcloud/trunk/libcloud/compute/drivers/opennebula.py
Modified: libcloud/trunk/libcloud/compute/drivers/opennebula.py
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/compute/drivers/opennebula.py?rev=1187946&r1=1187945&r2=1187946&view=diff
==============================================================================
--- libcloud/trunk/libcloud/compute/drivers/opennebula.py (original)
+++ libcloud/trunk/libcloud/compute/drivers/opennebula.py Sun Oct 23 18:35:26 2011
@@ -15,6 +15,9 @@
# 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.
+"""
+OpenNebula Driver
+"""
try:
import simplejson as json
@@ -24,7 +27,7 @@ except ImportError:
from xml.etree import ElementTree as ET
from base64 import b64encode
import hashlib
-import sys
+import httplib
from libcloud.compute.base import NodeState, NodeDriver, Node, NodeLocation
from libcloud.common.base import ConnectionUserAndKey, Response
@@ -40,6 +43,9 @@ DEFAULT_API_VERSION = '3.0'
class OpenNebulaResponse(Response):
+ """
+ Response class for the OpenNebula driver.
+ """
def success(self):
i = int(self.status)
@@ -51,14 +57,14 @@ class OpenNebulaResponse(Response):
return ET.XML(self.body)
def parse_error(self):
- if int(self.status) == 401:
+ if int(self.status) == httplib.UNAUTHORIZED:
raise InvalidCredsError(self.body)
return self.body
class OpenNebulaConnection(ConnectionUserAndKey):
"""
- Connection class for the OpenNebula driver
+ Connection class for the OpenNebula driver.
"""
host = API_HOST
@@ -68,7 +74,7 @@ class OpenNebulaConnection(ConnectionUse
def add_default_headers(self, headers):
pass_sha1 = hashlib.sha1(self.key).hexdigest()
- headers['Authorization'] = ("Basic %s" % b64encode("%s:%s" %
+ headers['Authorization'] = ('Basic %s' % b64encode('%s:%s' %
(self.user_id, pass_sha1)))
return headers
@@ -91,27 +97,49 @@ class OpenNebulaNodeSize(NodeSize):
self.price, self.driver.name, self.cpu))
+class OpenNebulaNetwork(object):
+ """
+ A virtual network.
+
+ NodeNetwork objects are analogous to physical switches connecting 2
+ or more physical nodes together.
+
+ Apart from name and id, there is no further standard information;
+ other parameters are stored in a driver specific "extra" variable
+ """
+
+ def __init__(self, id, name, driver, extra=None):
+ self.id = str(id)
+ self.name = name
+ self.driver = driver
+ self.extra = extra or {}
+
+ def __repr__(self):
+ return (('<OpenNebulaNetwork: id=%s, name=%s, driver=%s ...>')
+ % (self.id, self.name, self.driver.name))
+
+
class OpenNebulaNodeDriver(NodeDriver):
"""
- OpenNebula node driver
+ OpenNebula node driver.
"""
connectionCls = OpenNebulaConnection
- type = Provider.OPENNEBULA
name = 'OpenNebula'
+ type = Provider.OPENNEBULA
NODE_STATE_MAP = {
- 'pending': NodeState.PENDING,
- 'hold': NodeState.PENDING,
- 'prolog': NodeState.PENDING,
- 'running': NodeState.RUNNING,
- 'migrate': NodeState.PENDING,
- 'epilog': NodeState.TERMINATED,
- 'stopped': NodeState.TERMINATED,
- 'suspended': NodeState.PENDING,
- 'failed': NodeState.TERMINATED,
- 'unknown': NodeState.UNKNOWN,
- 'done': NodeState.TERMINATED,
+ 'PENDING': NodeState.PENDING,
+ 'HOLD': NodeState.PENDING,
+ 'PROLOG': NodeState.PENDING,
+ 'RUNNING': NodeState.RUNNING,
+ 'MIGRATE': NodeState.PENDING,
+ 'EPILOG': NodeState.TERMINATED,
+ 'STOPPED': NodeState.TERMINATED,
+ 'SUSPENDED': NodeState.PENDING,
+ 'FAILED': NodeState.TERMINATED,
+ 'UNKNOWN': NodeState.UNKNOWN,
+ 'DONE': NodeState.TERMINATED
}
def __new__(cls, key, secret=None, api_version=DEFAULT_API_VERSION,
@@ -124,8 +152,7 @@ class OpenNebulaNodeDriver(NodeDriver):
else:
raise NotImplementedError(
"No OpenNebulaNodeDriver found for API version %s" %
- (api_version)
- )
+ (api_version))
return super(OpenNebulaNodeDriver, cls).__new__(cls)
def list_sizes(self, location=None):
@@ -204,28 +231,52 @@ class OpenNebulaNodeDriver(NodeDriver):
return self._to_node(node)
+ def ex_list_networks(self, location=None):
+ """
+ List virtual networks on a provider
+ @return: C{list} of L{OpenNebulaNetwork} objects
+ """
+ return self._to_networks(self.connection.request('/network').object)
+
def _to_images(self, object):
images = []
- for element in object.findall("DISK"):
- image_id = element.attrib["href"].partition("/storage/")[2]
- image = self.connection.request(("/storage/%s" % (
+ for element in object.findall('DISK'):
+ image_id = element.attrib['href'].partition('/storage/')[2]
+ image = self.connection.request(('/storage/%s' % (
image_id))).object
images.append(self._to_image(image))
return images
def _to_image(self, image):
- return NodeImage(id=image.findtext("ID"),
- name=image.findtext("NAME"),
+ return NodeImage(id=image.findtext('ID'),
+ name=image.findtext('NAME'),
driver=self.connection.driver,
- extra={"size": image.findtext("SIZE"),
- "url": image.findtext("URL")})
+ extra={'size': image.findtext('SIZE'),
+ 'url': image.findtext('URL')})
+
+ def _to_networks(self, object):
+ networks = []
+ for element in object.findall('NETWORK'):
+ network_id = element.attrib['href'].partition('/network/')[2]
+ network_element = self.connection.request(('/network/%s' % (
+ network_id))).object
+ networks.append(self._to_network(network_element))
+
+ return networks
+
+ def _to_network(self, element):
+ return OpenNebulaNetwork(id=element.findtext('ID'),
+ name=element.findtext('NAME'),
+ driver=self.connection.driver,
+ extra={'address': element.findtext('ADDRESS'),
+ 'size': element.findtext('SIZE')})
def _to_nodes(self, object):
computes = []
- for element in object.findall("COMPUTE"):
- compute_id = element.attrib["href"].partition("/compute/")[2]
- compute = self.connection.request(("/compute/%s" % (
+ for element in object.findall('COMPUTE'):
+ compute_id = element.attrib['href'].partition('/compute/')[2]
+ compute = self.connection.request(('/compute/%s' % (
compute_id))).object
computes.append(self._to_node(compute))
@@ -234,24 +285,26 @@ class OpenNebulaNodeDriver(NodeDriver):
def _extract_networks(self, compute):
networks = []
- for element in compute.findall("NIC"):
- ip = element.element.attrib.get('ip', None)
-
- if ip is not None:
- networks.append(ip)
+ network_list = compute.find('NETWORK')
+ for element in network_list.findall('NIC'):
+ networks.append(
+ OpenNebulaNetwork(id=element.attrib.get('network', None),
+ name=None,
+ driver=self.connection.driver,
+ extra={'ip': element.attrib.get('ip', None)}))
return networks
def _to_node(self, compute):
try:
- state = self.NODE_STATE_MAP[compute.findtext("STATE")]
+ state = self.NODE_STATE_MAP[compute.findtext('STATE').upper()]
except KeyError:
state = NodeState.UNKNOWN
networks = self._extract_networks(compute)
- return Node(id=compute.findtext("ID"),
- name=compute.findtext("NAME"),
+ return Node(id=compute.findtext('ID'),
+ name=compute.findtext('NAME'),
state=state,
public_ip=networks,
private_ip=[],
@@ -334,9 +387,16 @@ class OpenNebula_3_0_NodeDriver(OpenNebu
driver=self),
]
+ def ex_list_networks(self, location=None):
+ """
+ List virtual networks on a provider
+ @return: C{list} of L{OpenNebulaNetwork} objects
+ """
+ return self._to_networks(self.connection.request('/network').object)
+
def _to_images(self, object):
images = []
- for element in object.findall("STORAGE"):
+ for element in object.findall('STORAGE'):
image_id = element.attrib["href"].partition("/storage/")[2]
image = self.connection.request(("/storage/%s" %
(image_id))).object
@@ -345,18 +405,31 @@ class OpenNebula_3_0_NodeDriver(OpenNebu
return images
def _to_image(self, image):
- return NodeImage(id=image.findtext("ID"),
- name=image.findtext("NAME"),
+ return NodeImage(id=image.findtext('ID'),
+ name=image.findtext('NAME'),
driver=self.connection.driver,
- extra={"description": image.findtext("DESCRIPTION"),
- "TYPE": image.findtext("TYPE"),
- "size": image.findtext("SIZE"),
- "fstype": image.findtext("FSTYPE", None)})
+ extra={'description': image.findtext('DESCRIPTION'),
+ 'TYPE': image.findtext('TYPE'),
+ 'size': image.findtext('SIZE'),
+ 'fstype': image.findtext('FSTYPE', None)})
def _extract_networks(self, compute):
networks = []
- for element in compute.findall("NIC"):
- for ip in element.findall("IP"):
- networks.append(ip)
+
+ for element in compute.findall('NIC'):
+ network = element.find('NETWORK')
+ network_id = network.attrib['href'].partition('/network/')[2]
+
+ ips = []
+ for ip in element.findall('IP'):
+ ips.append(ip)
+
+ networks.append(
+ OpenNebulaNetwork(id=network_id,
+ name=network.attrib['name'],
+ driver=self.connection.driver,
+ extra={'ip': ips,
+ 'mac': element.findtext('MAC'),
+ }))
return networks