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 2013/01/25 06:48:37 UTC
svn commit: r1438331 [1/2] - in /libcloud/trunk: ./ libcloud/common/
libcloud/compute/ libcloud/compute/drivers/ libcloud/test/compute/
libcloud/test/compute/fixtures/abiquo/
Author: tomaz
Date: Fri Jan 25 05:48:36 2013
New Revision: 1438331
URL: http://svn.apache.org/viewvc?rev=1438331&view=rev
Log:
Add new compute driver for Abiquo provider (http://www.abiquo.com/).
Contributed by Jaume Devesa, part of LIBCLOUD-250.
Added:
libcloud/trunk/libcloud/common/abiquo.py
libcloud/trunk/libcloud/compute/drivers/abiquo.py
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/dcs.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/ent_1.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/ent_1_dcrep_2.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/ent_1_dcrep_2_template_11.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/ent_1_dcrep_2_templates.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/ent_1_dcreps.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/login.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/not_found_error.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/privilege_errors.html
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/unauthorized_user.html
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_5.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_5_needs_sync.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_5_vm_3_not_allocated.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_5_vms.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_6.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_6_undeploy.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_6_undeploy_task.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_6_undeploy_task_failed.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_6_vm_3.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_6_vm_3_allocated.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_6_vm_3_deploy.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_6_vm_3_deploy_task.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_6_vm_3_deploy_task_failed.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_6_vm_3_deployed.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_6_vm_3_nics.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_6_vm_3_reset.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_6_vm_3_reset_task.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_6_vm_3_undeploy.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_6_vm_3_undeploy_task.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_6_vm_3_undeploy_task_failed.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_6_vm_creation_ok.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_6_vms.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_6_vms_allocated.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_creation_ok.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapps.xml
libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdcs.xml
libcloud/trunk/libcloud/test/compute/test_abiquo.py
Modified:
libcloud/trunk/CHANGES
libcloud/trunk/libcloud/compute/drivers/__init__.py
libcloud/trunk/libcloud/compute/providers.py
libcloud/trunk/libcloud/compute/types.py
Modified: libcloud/trunk/CHANGES
URL: http://svn.apache.org/viewvc/libcloud/trunk/CHANGES?rev=1438331&r1=1438330&r2=1438331&view=diff
==============================================================================
--- libcloud/trunk/CHANGES (original)
+++ libcloud/trunk/CHANGES Fri Jan 25 05:48:36 2013
@@ -100,6 +100,9 @@ Changes with Apache Libcloud in developm
(cr1.8xlarge).
[Tomaz Muraus]
+ - Add new driver for Abiquo provider - http://www.abiquo.com (LIBCLOUD-250).
+ [Jaume Devesa]
+
*) Storage
- Add a new local storage driver.
Added: libcloud/trunk/libcloud/common/abiquo.py
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/common/abiquo.py?rev=1438331&view=auto
==============================================================================
--- libcloud/trunk/libcloud/common/abiquo.py (added)
+++ libcloud/trunk/libcloud/common/abiquo.py Fri Jan 25 05:48:36 2013
@@ -0,0 +1,245 @@
+# 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.
+"""
+Abiquo Utilities Module for the Abiquo Driver.
+
+Common utilities needed by the L{AbiquoNodeDriver}.
+"""
+import base64
+
+from libcloud.common.base import ConnectionUserAndKey, PollingConnection
+from libcloud.common.base import XmlResponse
+from libcloud.common.types import InvalidCredsError, LibcloudError
+from libcloud.utils.py3 import httplib
+from libcloud.utils.py3 import urlparse
+from libcloud.utils.py3 import b
+from libcloud.compute.base import NodeState
+
+
+def get_href(element, rel):
+ """
+ Search a RESTLink element in the L{AbiquoResponse}.
+
+ Abiquo, as a REST API, it offers self-discovering functionality.
+ That means that you could walk through the whole API only
+ navigating from the links offered by the entities.
+
+ This is a basic method to find the 'relations' of an entity searching into
+ its links.
+
+ For instance, a Rack entity serialized as XML as the following::
+
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+ <rack>
+ <link href="http://host/api/admin/datacenters/1"
+ type="application/vnd.abiquo.datacenter+xml" rel="datacenter"/>
+ <link href="http://host/api/admin/datacenters/1/racks/1"
+ type="application/vnd.abiquo.rack+xml" rel="edit"/>
+ <link href="http://host/api/admin/datacenters/1/racks/1/machines"
+ type="application/vnd.abiquo.machines+xml" rel="machines"/>
+ <haEnabled>false</haEnabled>
+ <id>1</id>
+ <longDescription></longDescription>
+ <name>racacaca</name>
+ <nrsq>10</nrsq>
+ <shortDescription></shortDescription>
+ <vlanIdMax>4094</vlanIdMax>
+ <vlanIdMin>2</vlanIdMin>
+ <vlanPerVdcReserved>1</vlanPerVdcReserved>
+ <vlansIdAvoided></vlansIdAvoided>
+ </rack>
+
+ offers link to datacenters (rel='datacenter'), to itself (rel='edit') and
+ to the machines defined in it (rel='machines')
+
+ A call to this method with the 'rack' element using 'datacenter' as 'rel'
+ will return:
+
+ 'http://10.60.12.7:80/api/admin/datacenters/1'
+
+ @type element: C{xml.etree.ElementTree}
+ @param element: Xml Entity returned by Abiquo API (required)
+ @type rel: C{string}
+ @param rel: relation link name
+ @rtype: C{string}
+ @return: the 'href' value according to the 'rel' input parameter
+ """
+ links = element.findall('link')
+ for link in links:
+ if link.attrib['rel'] == rel:
+ href = link.attrib['href']
+ # href is something like:
+ #
+ # 'http://localhost:80/api/admin/enterprises'
+ #
+ # we are only interested in '/admin/enterprises/' part
+ return urlparse.urlparse(href).path[len(b('/api')):]
+
+
+class AbiquoResponse(XmlResponse):
+ """
+ Abiquo XML Response.
+
+ Wraps the response in XML bodies or extract the error data in
+ case of error.
+ """
+
+ # Map between abiquo state and Libcloud State
+ NODE_STATE_MAP = {
+ 'NOT_ALLOCATED': NodeState.TERMINATED,
+ 'ALLOCATED': NodeState.PENDING,
+ 'CONFIGURED': NodeState.PENDING,
+ 'ON': NodeState.RUNNING,
+ 'PAUSED': NodeState.PENDING,
+ 'OFF': NodeState.PENDING,
+ 'LOCKED': NodeState.PENDING,
+ 'UNKNOWN': NodeState.UNKNOWN
+ }
+
+ def parse_error(self):
+ """
+ Parse the error messages.
+
+ Response body can easily be handled by this class parent
+ L{XmlResponse}, but there are use cases which Abiquo API
+ does not respond an XML but an HTML. So we need to
+ handle these special cases.
+ """
+ if self.status == httplib.UNAUTHORIZED:
+ raise InvalidCredsError(driver=self.connection.driver)
+ elif self.status == httplib.FORBIDDEN:
+ raise ForbiddenError(self.connection.driver)
+ else:
+ errors = self.parse_body().findall('error')
+ # Most of the exceptions only have one error
+ raise LibcloudError(errors[0].findtext('message'))
+
+ def success(self):
+ """
+ Determine if the request was successful.
+
+ Any of the 2XX HTTP response codes are accepted as successfull requests
+
+ @rtype: C{bool}
+ @return: successful request or not.
+ """
+ return self.status in [httplib.OK, httplib.CREATED, httplib.NO_CONTENT,
+ httplib.ACCEPTED]
+
+ def async_success(self):
+ """
+ Determinate if async request was successful.
+
+ An async_request retrieves for a task object that can be successfully
+ retrieved (self.status == OK), but the asyncronous task (the body of
+ the HTTP response) which we are asking for has finished with an error.
+ So this method checks if the status code is 'OK' and if the task
+ has finished successfully.
+
+ @rtype: C{bool}
+ @return: successful asynchronous request or not
+ """
+ if self.success():
+ # So we have a 'task' object in the body
+ task = self.parse_body()
+ return task.findtext('state') == 'FINISHED_SUCCESSFULLY'
+ else:
+ return False
+
+
+class AbiquoConnection(ConnectionUserAndKey, PollingConnection):
+ """
+ A Connection to Abiquo API.
+
+ Basic L{ConnectionUserAndKey} connection with L{PollingConnection} features
+ for asynchronous tasks.
+ """
+
+ responseCls = AbiquoResponse
+
+ def add_default_headers(self, headers):
+ """
+ Add Basic Authentication header to all the requests.
+
+ It injects the 'Authorization: Basic Base64String===' header
+ in each request
+
+ @type headers: C{dict}
+ @param headers: Default input headers
+ @rtype C{dict}
+ @return: Default input headers with the 'Authorization'
+ header
+ """
+ b64string = b('%s:%s' % (self.user_id, self.key))
+ encoded = base64.b64encode(b64string).decode('utf-8')
+
+ authorization = 'Basic ' + encoded
+
+ headers['Authorization'] = authorization
+ return headers
+
+ def get_poll_request_kwargs(self, response, context, request_kwargs):
+ """
+ Manage polling request arguments.
+
+ Return keyword arguments which are passed to the L{NodeDriver.request}
+ method when polling for the job status. The Abiquo Asynchronous
+ Response returns and 'acceptedrequest' XmlElement as the following::
+
+ <acceptedrequest>
+ <link href="http://uri/to/task" rel="status"/>
+ <message>You can follow the progress in the link</message>
+ </acceptedrequest>
+
+ We need to extract the href URI to poll.
+
+ @type response: C{xml.etree.ElementTree}
+ @keyword response: Object returned by poll request.
+ @type request_kwargs: C{dict}
+ @keyword request_kwargs: Default request arguments and headers
+ @rtype: C{dict}
+ @return: Modified keyword arguments
+ """
+ accepted_request_obj = response.object
+ link_poll = get_href(accepted_request_obj, 'status')
+
+ # Override just the 'action' and 'method' keys of the previous dict
+ request_kwargs['action'] = link_poll
+ request_kwargs['method'] = 'GET'
+ return request_kwargs
+
+ def has_completed(self, response):
+ """
+ Decide if the asynchronous job has ended.
+
+ @type response: C{xml.etree.ElementTree}
+ @param response: Response object returned by poll request
+ @rtype: C{bool}
+ @return: Whether the job has completed
+ """
+ task = response.object
+ task_state = task.findtext('state')
+ return task_state in ['FINISHED_SUCCESSFULLY', 'ABORTED',
+ 'FINISHED_UNSUCCESSFULLY']
+
+
+class ForbiddenError(LibcloudError):
+ """
+ Exception used when credentials are ok but user has not permissions.
+ """
+
+ def __init__(self, driver):
+ message = 'User has not permission to perform this task.'
+ super(LibcloudError, self).__init__(message, driver)
Modified: libcloud/trunk/libcloud/compute/drivers/__init__.py
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/compute/drivers/__init__.py?rev=1438331&r1=1438330&r2=1438331&view=diff
==============================================================================
--- libcloud/trunk/libcloud/compute/drivers/__init__.py (original)
+++ libcloud/trunk/libcloud/compute/drivers/__init__.py Fri Jan 25 05:48:36 2013
@@ -18,6 +18,7 @@ Drivers for working with different provi
"""
__all__ = [
+ 'abiquo',
'brightbox',
'bluebox',
'dummy',
Added: libcloud/trunk/libcloud/compute/drivers/abiquo.py
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/compute/drivers/abiquo.py?rev=1438331&view=auto
==============================================================================
--- libcloud/trunk/libcloud/compute/drivers/abiquo.py (added)
+++ libcloud/trunk/libcloud/compute/drivers/abiquo.py Fri Jan 25 05:48:36 2013
@@ -0,0 +1,760 @@
+# 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.
+"""
+Abiquo Compute Driver
+
+The driver implements the compute Abiquo functionality for the Abiquo API.
+This version is compatible with the following versions of Abiquo:
+
+ * Abiquo 2.0 (http://wiki.abiquo.com/display/ABI20/The+Abiquo+API)
+ * Abiquo 2.2 (http://wiki.abiquo.com/display/ABI22/The+Abiquo+API)
+"""
+import xml.etree.ElementTree as ET
+
+from libcloud.compute.base import NodeDriver, NodeSize
+from libcloud.compute.types import Provider, LibcloudError
+from libcloud.common.abiquo import (AbiquoConnection, get_href,
+ AbiquoResponse)
+from libcloud.compute.base import NodeLocation, NodeImage, Node
+from libcloud.utils.py3 import tostring
+
+
+class AbiquoNodeDriver(NodeDriver):
+ """
+ Implements the L{NodeDriver}'s for the Abiquo Compute Provider
+ """
+
+ type = Provider.ABIQUO
+ name = 'Abiquo'
+ website = 'http://www.abiquo.com/'
+ connectionCls = AbiquoConnection
+ features = {'create_node': ['password']}
+ timeout = 2000 # some images take a lot of time!
+
+ # Media Types
+ NODES_MIME_TYPE = 'application/vnd.abiquo.virtualmachineswithnode+xml'
+ NODE_MIME_TYPE = 'application/vnd.abiquo.virtualmachinewithnode+xml'
+ VAPP_MIME_TYPE = 'application/vnd.abiquo.virtualappliance+xml'
+ VM_TASK_MIME_TYPE = 'application/vnd.abiquo.virtualmachinetask+xml'
+
+ # Others constants
+ GIGABYTE = 1073741824
+
+ def __init__(self, user_id, secret, endpoint, **kwargs):
+ """
+ Initializes Abiquo Driver
+
+ Initializes the L{NodeDriver} object. After that, it generates the
+ context
+
+ @param user_id: identifier of Abiquo user (required)
+ @type user_id: C{str}
+ @param secret: password of the Abiquo user (required)
+ @type secret: C{str}
+ @param endpoint: Abiquo API endpoint (required)
+ @type endpoint: C{str} that can be parsed as URL
+ """
+ self.endpoint = endpoint
+ super(AbiquoNodeDriver, self).__init__(key=user_id, secret=secret,
+ secure=False, host=None,
+ port=None, **kwargs)
+ self.ex_set_context()
+
+ def create_node(self, **kwargs):
+ """
+ Create a new node instance in Abiquo
+
+ All the L{Node}s need to be defined inside a VirtualAppliance
+ (called L{NodeGroup} here). If there is no group name defined,
+ 'libcloud' name will be used instead.
+
+ This method wraps these Abiquo actions:
+
+ 1. Create a group if it does not exist.
+ 2. Register a new node in the group.
+ 3. Deploy the node and boot it.
+ 4. Retrieves it again to get schedule-time attributes (such as ips
+ and vnc ports).
+
+ The rest of the driver methods has been created in a way that, if any
+ of these actions fail, the user can not reach an inconsistent state
+
+ @keyword name: The name for this new node (required)
+ @type name: C{str}
+
+ @keyword size: The size of resources allocated to this node.
+ @type size: L{NodeSize}
+
+ @keyword image: OS Image to boot on node. (required)
+ @type image: L{NodeImage}
+
+ @keyword location: Which data center to create a node in. If empty,
+ undefined behavoir will be selected. (optional)
+ @type location: L{NodeLocation}
+
+ @keyword auth: Initial authentication information for the node
+ (optional)
+ @type auth: L{NodeAuthPassword}
+
+ @keyword group_name: Which group this node belongs to. If empty,
+ it will be created into 'libcloud' group. If
+ it does not found any group in the target
+ location (random location if you have not set
+ the parameter), then it will create a new
+ group with this name.
+ @type group_name: c{str}
+
+ @return: The newly created node.
+ @rtype: L{Node}
+ """
+ # Define the location
+ # To be clear:
+ # 'xml_loc' is the xml element we navigate into (we need links)
+ # 'loc' is the L{NodeLocation} entity
+ xml_loc, loc = self._define_create_node_location(**kwargs)
+
+ # Define the Group
+ group = self._define_create_node_group(xml_loc, loc, **kwargs)
+
+ # Register the Node
+ vm = self._define_create_node_node(group, **kwargs)
+
+ # Execute the 'create' in hypervisor action
+ self._deploy_remote(vm)
+
+ # Retrieve it again, to get some schedule-time defined values
+ edit_vm = get_href(vm, 'edit')
+ headers = {'Accept': self.NODE_MIME_TYPE}
+ vm = self.connection.request(edit_vm, headers=headers).object
+ return self._to_node(vm, self)
+
+ def destroy_node(self, node):
+ """
+ Destroy a node
+
+ Depending on the provider, this may destroy all data associated with
+ the node, including backups.
+
+ @param node: The node to be destroyed
+ @type node: L{Node}
+
+ @return: True if the destroy was successful, otherwise False
+ @rtype: C{bool}
+ """
+
+ # Refresh node state
+ e_vm = self.connection.request(node.extra['uri_id']).object
+ state = e_vm.findtext('state')
+
+ if state in ['ALLOCATED', 'CONFIGURED', 'LOCKED', 'UNKNOWN']:
+ raise LibcloudError('Invalid Node state', self)
+
+ if state != 'NOT_ALLOCATED':
+ # prepare the element that forces the undeploy
+ vm_task = ET.Element('virtualmachinetask')
+ force_undeploy = ET.SubElement(vm_task, 'forceUndeploy')
+ force_undeploy.text = 'True'
+ # Set the URI
+ destroy_uri = node.extra['uri_id'] + '/action/undeploy'
+ # Prepare the headers
+ headers = {'Content-type': self.VM_TASK_MIME_TYPE}
+ res = self.connection.async_request(action=destroy_uri,
+ method='POST',
+ data=tostring(vm_task),
+ headers=headers)
+
+ if state == 'NOT_ALLOCATED' or res.async_success():
+ self.connection.request(action=node.extra['uri_id'],
+ method='DELETE')
+ return True
+ else:
+ return False
+
+ def ex_run_node(self, node):
+ """
+ Runs a node
+
+ Here there is a bit difference between Abiquo states and libcloud
+ states, so this method is created to have better compatibility. In
+ libcloud, if the node is not running, then it does not exist (avoiding
+ UNKNOWN and temporal states). In Abiquo, you can define a node, and
+ then deploy it.
+
+ If the node is in L{NodeState.TERMINATED} libcloud's state and in
+ 'NOT_DEPLOYED' Abiquo state, there is a way to run and recover it
+ for libcloud using this method. There is no way to reach this state
+ if you are using only libcloud, but you may have used another Abiquo
+ client and now you want to recover your node to be used by libcloud.
+
+ @param node: The node to run
+ @type node: L{Node}
+
+ @return: The node itself, but with the new state
+ @rtype: L{Node}
+ """
+ # Refresh node state
+ e_vm = self.connection.request(node.extra['uri_id']).object
+ state = e_vm.findtext('state')
+
+ if state != 'NOT_ALLOCATED':
+ raise LibcloudError('Invalid Node state', self)
+
+ # --------------------------------------------------------
+ # Deploy the Node
+ # --------------------------------------------------------
+ self._deploy_remote(e_vm)
+
+ # --------------------------------------------------------
+ # Retrieve it again, to get some schedule-defined
+ # values.
+ # --------------------------------------------------------
+ edit_vm = get_href(e_vm, 'edit')
+ headers = {'Accept': self.NODE_MIME_TYPE}
+ e_vm = self.connection.request(edit_vm, headers=headers).object
+ return self._to_node(e_vm, self)
+
+ def ex_set_context(self):
+ """
+ Generates the context
+
+ For each connection, it is good to store some objects that will be
+ useful for further requests, such as the 'user' and the 'enterprise'
+ objects.
+
+ Executes the 'login' resource after setting the connection parameters
+ and, if the execution is successful, it sets the 'user' object into
+ context. After that, it also requests for the 'enterprise' and
+ 'locations' data.
+
+ List of locations should remain the same for a single libcloud
+ connection. However, this method is public and you are able to
+ refresh the list of locations any time.
+ """
+ user = self.connection.request('/login').object
+ self.connection.context['user'] = user
+ e_ent = get_href(self.connection.context['user'],
+ 'enterprise')
+ ent = self.connection.request(e_ent).object
+ self.connection.context['enterprise'] = ent
+
+ uri_vdcs = '/cloud/virtualdatacenters'
+ e_vdcs = self.connection.request(uri_vdcs).object
+
+ # Set a dict for the datacenter and its href for a further search
+ params = {"idEnterprise": self._get_enterprise_id()}
+ e_dcs = self.connection.request('/admin/datacenters',
+ params=params).object
+ dc_dict = {}
+ for dc in e_dcs.findall('datacenter'):
+ key = get_href(dc, 'edit')
+ dc_dict[key] = dc
+
+ # Set the context for the locations
+ self.connection.context['locations'] = {}
+ for e_vdc in e_vdcs.findall('virtualDatacenter'):
+ dc_link = get_href(e_vdc, 'datacenter')
+ loc = self._to_location(e_vdc, dc_dict[dc_link], self)
+
+ # Save into context the link to the itself because we will need
+ # it in the future, but we save here to don't extend the class
+ # L{NodeLocation}.
+ # So here we have the dict: L{NodeLocation} -> link_datacenter
+ self.connection.context['locations'][loc] = get_href(e_vdc, 'edit')
+
+ def ex_create_group(self, name, location=None):
+ """
+ Create an empty group.
+
+ You can specify the location as well.
+
+ @param name: name of the group (required)
+ @type name: C{str}
+
+ @param location: location were to create the group
+ @type location: L{NodeLocation}
+
+ @returns: the created group
+ @rtype: L{NodeGroup}
+ """
+ # prepare the element
+ vapp = ET.Element('virtualAppliance')
+ vapp_name = ET.SubElement(vapp, 'name')
+ vapp_name.text = name
+
+ if location is None:
+ location = self.list_locations()[0]
+ elif not location in self.list_locations():
+ raise LibcloudError('Location does not exist')
+
+ link_vdc = self.connection.context['locations'][location]
+ e_vdc = self.connection.request(link_vdc).object
+
+ creation_link = get_href(e_vdc, 'virtualappliances')
+ headers = {'Content-type': self.VAPP_MIME_TYPE}
+ vapp = self.connection.request(creation_link, data=tostring(vapp),
+ headers=headers, method='POST').object
+
+ uri_vapp = get_href(vapp, 'edit')
+
+ return NodeGroup(self, vapp.findtext('name'),
+ uri=uri_vapp)
+
+ def ex_destroy_group(self, group):
+ """
+ Destroy a group.
+
+ Be careful! Destroying a group means destroying all the L{Node}s there
+ and the group itself!
+
+ If there is currently any action over any L{Node} of the L{NodeGroup},
+ then the method will raise an exception.
+
+ @param name: The group (required)
+ @type name: L{NodeGroup}
+
+ @return: If the group was destroyed successfully
+ @rtype: C{bool}
+ """
+ # Refresh group state
+ e_group = self.connection.request(group.uri).object
+ state = e_group.findtext('state')
+
+ if state not in ['NOT_DEPLOYED', 'DEPLOYED']:
+ error = 'Can not destroy group because of current state'
+ raise LibcloudError(error, self)
+
+ if state == 'DEPLOYED':
+ # prepare the element that forces the undeploy
+ vm_task = ET.Element('virtualmachinetask')
+ force_undeploy = ET.SubElement(vm_task, 'forceUndeploy')
+ force_undeploy.text = 'True'
+
+ # Set the URI
+ undeploy_uri = group.uri + '/action/undeploy'
+
+ # Prepare the headers
+ headers = {'Content-type': self.VM_TASK_MIME_TYPE}
+ res = self.connection.async_request(action=undeploy_uri,
+ method='POST',
+ data=tostring(vm_task),
+ headers=headers)
+
+ if state == 'NOT_DEPLOYED' or res.async_success():
+ # The node is no longer deployed. Unregister it.
+ self.connection.request(action=group.uri,
+ method='DELETE')
+ return True
+ else:
+ return False
+
+ def ex_list_groups(self, location=None):
+ """
+ List all groups.
+
+ @param location: filter the groups by location (optional)
+ @type location: a L{NodeLocation} instance.
+
+ @return: the list of L{NodeGroup}
+ """
+ groups = []
+ for vdc in self._get_locations(location):
+ link_vdc = self.connection.context['locations'][vdc]
+ e_vdc = self.connection.request(link_vdc).object
+ apps_link = get_href(e_vdc, 'virtualappliances')
+ vapps = self.connection.request(apps_link).object
+ for vapp in vapps.findall('virtualAppliance'):
+ nodes = []
+ vms_link = get_href(vapp, 'virtualmachines')
+ headers = {'Accept': self.NODES_MIME_TYPE}
+ vms = self.connection.request(vms_link, headers=headers).object
+ for vm in vms.findall('virtualmachinewithnode'):
+ nodes.append(self._to_node(vm, self))
+
+ group = NodeGroup(self, vapp.findtext('name'),
+ nodes, get_href(vapp, 'edit'))
+ groups.append(group)
+
+ return groups
+
+ def list_images(self, location=None):
+ """
+ List images on Abiquo Repositories
+
+ @keyword location: The location to list images for.
+ @type location: L{NodeLocation}
+
+ @return: list of node image objects
+ @rtype: C{list} of L{NodeImage}
+ """
+ enterprise_id = self._get_enterprise_id()
+ uri = '/admin/enterprises/%s/datacenterrepositories/' % (enterprise_id)
+ repos = self.connection.request(uri).object
+
+ images = []
+ for repo in repos.findall('datacenterRepository'):
+ # filter by location. Skips when the name of the location
+ # is different from the 'datacenterRepository' element
+ for vdc in self._get_locations(location):
+ # Check if the virtual datacenter belongs to this repo
+ link_vdc = self.connection.context['locations'][vdc]
+ e_vdc = self.connection.request(link_vdc).object
+ dc_link_vdc = get_href(e_vdc, 'datacenter')
+ dc_link_repo = get_href(repo, 'datacenter')
+
+ if dc_link_vdc == dc_link_repo:
+ # Filter the template in case we don't have it yet
+ url_templates = get_href(repo, 'virtualmachinetemplates')
+ hypervisor_type = e_vdc.findtext('hypervisorType')
+ params = {'hypervisorTypeName': hypervisor_type}
+ templates = self.connection.request(url_templates,
+ params).object
+ for templ in templates.findall('virtualMachineTemplate'):
+ # Avoid duplicated templates
+ id_template = templ.findtext('id')
+ ids = [image.id for image in images]
+ if id_template not in ids:
+ images.append(self._to_nodeimage(templ, self,
+ get_href(repo,
+ 'edit')))
+
+ return images
+
+ def list_locations(self):
+ """
+ Return list of locations where the user has access to.
+
+ @return: the list of L{NodeLocation} available for the current user
+ @rtype: C{list} of L{NodeLocation}
+ """
+ return list(self.connection.context['locations'].keys())
+
+ def list_nodes(self, location=None):
+ """
+ List all nodes.
+
+ @param location: Filter the groups by location (optional)
+ @type location: a L{NodeLocation} instance.
+
+ @return: List of node objects
+ @rtype: C{list} of L{Node}
+ """
+ nodes = []
+
+ for group in self.ex_list_groups(location):
+ nodes.extend(group.nodes)
+
+ return nodes
+
+ def list_sizes(self, location=None):
+ """
+ List sizes on a provider.
+
+ Abiquo does not work with sizes. However, this method
+ returns a list of predefined ones (copied from L{DummyNodeDriver} but
+ without price neither bandwidth) to help the users to create their own.
+
+ If you call the method L{AbiquoNodeDriver.create_node} with the size
+ informed, it will just override the 'ram' value of the 'image'
+ template. So it is no too much usefull work with sizes...
+
+ @return: The list of sizes
+ @rtype: C{list} of L{NodeSizes}
+ """
+ return [
+ NodeSize(id=1,
+ name='Small',
+ ram=128,
+ disk=4,
+ bandwidth=None,
+ price=None,
+ driver=self),
+ NodeSize(id=2,
+ name='Medium',
+ ram=512,
+ disk=16,
+ bandwidth=None,
+ price=None,
+ driver=self),
+ NodeSize(id=3,
+ name='Big',
+ ram=4096,
+ disk=32,
+ bandwidth=None,
+ price=None,
+ driver=self),
+ NodeSize(id=4,
+ name="XXL Big",
+ ram=4096 * 2,
+ disk=32 * 4,
+ bandwidth=None,
+ price=None,
+ driver=self)
+ ]
+
+ def reboot_node(self, node):
+ """
+ Reboot a node.
+
+ @param node: The node to be rebooted
+ @type node: L{Node}
+
+ @return: True if the reboot was successful, otherwise False
+ @rtype: C{bool}
+ """
+ reboot_uri = node.extra['uri_id'] + '/action/reset'
+ res = self.connection.async_request(action=reboot_uri, method='POST')
+ return res.async_success()
+
+ # -------------------------
+ # Extenstion methods
+ # -------------------------
+
+ def _ex_connection_class_kwargs(self):
+ """
+ Set the endpoint as an extra L{AbiquoConnection} argument.
+
+ According to Connection code, the "url" argument should be
+ parsed properly to connection.
+
+ @return: C{dict} of L{AbiquoConnection} input arguments
+ """
+
+ return {'url': self.endpoint}
+
+ def _deploy_remote(self, e_vm):
+ """
+ Asynchronous call to create the node.
+ """
+ # --------------------------------------------------------
+ # Deploy the Node
+ # --------------------------------------------------------
+ # prepare the element that forces the deploy
+ vm_task = ET.Element('virtualmachinetask')
+ force_deploy = ET.SubElement(vm_task, 'forceEnterpriseSoftLimits')
+ force_deploy.text = 'True'
+
+ # Prepare the headers
+ headers = {'Content-type': self.VM_TASK_MIME_TYPE}
+ link_deploy = get_href(e_vm, 'deploy')
+ res = self.connection.async_request(action=link_deploy, method='POST',
+ data=tostring(vm_task),
+ headers=headers)
+ if not res.async_success():
+ raise LibcloudError('Could not run the node', self)
+
+ def _to_location(self, vdc, dc, driver):
+ """
+ Generates the L{NodeLocation} class.
+ """
+ identifier = vdc.findtext('id')
+ name = vdc.findtext('name')
+ country = dc.findtext('name')
+ return NodeLocation(identifier, name, country, driver)
+
+ def _to_node(self, vm, driver):
+ """
+ Generates the L{Node} class.
+ """
+ identifier = vm.findtext('id')
+ name = vm.findtext('nodeName')
+ state = AbiquoResponse.NODE_STATE_MAP[vm.findtext('state')]
+
+ link_image = get_href(vm, 'virtualmachinetemplate')
+ image_element = self.connection.request(link_image).object
+ repo_link = get_href(image_element, 'datacenterrepository')
+ image = self._to_nodeimage(image_element, self, repo_link)
+
+ ## Fill the 'ips' data
+ private_ips = []
+ public_ips = []
+ nics_element = self.connection.request(get_href(vm, 'nics')).object
+ for nic in nics_element.findall('nic'):
+ ip = nic.findtext('ip')
+ for link in nic.findall('link'):
+ rel = link.attrib['rel']
+ if rel == 'privatenetwork':
+ private_ips.append(ip)
+ elif rel in ['publicnetwork', 'externalnetwork',
+ 'unmanagednetwork']:
+ public_ips.append(ip)
+
+ extra = {'uri_id': get_href(vm, 'edit')}
+
+ if vm.find('vdrpIp') is not None:
+ extra['vdrp_ip'] = vm.findtext('vdrpIP')
+ extra['vdrp_port'] = vm.findtext('vdrpPort')
+
+ return Node(identifier, name, state, public_ips, private_ips,
+ driver, image=image, extra=extra)
+
+ def _to_nodeimage(self, template, driver, repo):
+ """
+ Generates the L{NodeImage} class.
+ """
+ identifier = template.findtext('id')
+ name = template.findtext('name')
+ url = get_href(template, 'edit')
+ extra = {'repo': repo, 'url': url}
+ return NodeImage(identifier, name, driver, extra)
+
+ def _get_locations(self, location=None):
+ """
+ Returns the locations as a generator.
+ """
+ if location is not None:
+ yield location
+ else:
+ for loc in self.list_locations():
+ yield loc
+
+ def _get_enterprise_id(self):
+ """
+ Returns the identifier of the logged user's enterprise.
+ """
+ return self.connection.context['enterprise'].findtext('id')
+
+ def _define_create_node_location(self, **kwargs):
+ """
+ Search for a location where to create the node.
+
+ Based on 'create_node' **kwargs argument, decide in which
+ location will be created.
+ """
+ # First, get image location
+ if not 'image' in kwargs:
+ error = "'image' parameter is mandatory"
+ raise LibcloudError(error, self)
+
+ image = kwargs['image']
+
+ # Get the location argument
+ location = None
+ if 'location' in kwargs:
+ location = kwargs['location']
+ if not location in self.list_locations():
+ raise LibcloudError('Location does not exist')
+
+ # Check if the image is compatible with any of the locations or
+ # the input location
+ loc = None
+ target_loc = None
+ for candidate_loc in self._get_locations(location):
+ link_vdc = self.connection.context['locations'][candidate_loc]
+ e_vdc = self.connection.request(link_vdc).object
+ # url_location = get_href(e_vdc, 'datacenter')
+ for img in self.list_images(candidate_loc):
+ if img.id == image.id:
+ loc = e_vdc
+ target_loc = candidate_loc
+ break
+
+ if loc is None:
+ error = 'The image can not be used in any location'
+ raise LibcloudError(error, self)
+
+ return loc, target_loc
+
+ def _define_create_node_group(self, xml_loc, loc, **kwargs):
+ """
+ Search for a group where to create the node.
+
+ If we can not find any group, create it into argument 'location'
+ """
+ if not 'group_name' in kwargs:
+ group_name = NodeGroup.DEFAULT_GROUP_NAME
+ else:
+ group_name = kwargs['group_name']
+
+ # We search if the group is already defined into the location
+ groups_link = get_href(xml_loc, 'virtualappliances')
+ vapps_element = self.connection.request(groups_link).object
+ target_group = None
+ for vapp in vapps_element.findall('virtualAppliance'):
+ if vapp.findtext('name') == group_name:
+ uri_vapp = get_href(vapp, 'edit')
+ return NodeGroup(self, vapp.findtext('name'), uri=uri_vapp)
+
+ # target group not found: create it. Since it is an extension of
+ # the basic 'libcloud' functionality, we try to be as flexible as
+ # possible.
+ if target_group is None:
+ return self.ex_create_group(group_name, loc)
+
+ def _define_create_node_node(self, group, **kwargs):
+ """
+ Defines the node before to create.
+
+ In Abiquo, you first need to 'register' or 'define' the node in
+ the API before to create it into the target hypervisor.
+ """
+ vm = ET.Element('virtualmachinewithnode')
+ if 'name' in kwargs:
+ vmname = ET.SubElement(vm, 'nodeName')
+ vmname.text = kwargs['name']
+ attrib = {'type': 'application/vnd.abiquo/virtualmachinetemplate+xml',
+ 'rel': 'virtualmachinetemplate',
+ 'href': kwargs['image'].extra['url']}
+ ET.SubElement(vm, 'link', attrib=attrib)
+ headers = {'Content-type': self.NODE_MIME_TYPE}
+
+ if 'size' in kwargs:
+ # Override the 'NodeSize' data
+ ram = ET.SubElement(vm, 'ram')
+ ram.text = str(kwargs['size'].ram)
+ hd = ET.SubElement(vm, 'hdInBytes')
+ hd.text = str(int(kwargs['size'].disk) * self.GIGABYTE)
+
+ # Create the virtual machine
+ nodes_link = group.uri + '/virtualmachines'
+ vm = self.connection.request(nodes_link, data=tostring(vm),
+ headers=headers, method='POST').object
+ edit_vm = get_href(vm, 'edit')
+ headers = {'Accept': self.NODE_MIME_TYPE}
+
+ return self.connection.request(edit_vm, headers=headers).object
+
+
+class NodeGroup(object):
+ """
+ Group of virtual machines that can be managed together
+
+ All L{Node}s in Abiquo must be defined inside a Virtual Appliance.
+ We offer a way to handle virtual appliances (called NodeGroup to
+ maintain some kind of name conventions here) inside the L{AbiquoNodeDriver}
+ without breaking compatibility of the rest of libcloud API.
+
+ If the user does not want to handle groups, all the virtual machines
+ will be created inside a group named 'libcloud'
+ """
+ DEFAULT_GROUP_NAME = 'libcloud'
+
+ def __init__(self, driver, name=DEFAULT_GROUP_NAME, nodes=[], uri=''):
+ """
+ Initialize a new group object.
+ """
+ self.driver = driver
+ self.name = name
+ self.nodes = nodes
+ self.uri = uri
+
+ def __repr__(self):
+ return (('<NodeGroup: name=%s, nodes=[%s] >')
+ % (self.name, ",".join(map(str, self.nodes))))
+
+ def destroy(self):
+ """
+ Destroys the group delegating the execution to L{AbiquoNodeDriver}.
+ """
+ return self.driver.ex_destroy_group(self)
Modified: libcloud/trunk/libcloud/compute/providers.py
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/compute/providers.py?rev=1438331&r1=1438330&r2=1438331&view=diff
==============================================================================
--- libcloud/trunk/libcloud/compute/providers.py (original)
+++ libcloud/trunk/libcloud/compute/providers.py Fri Jan 25 05:48:36 2013
@@ -120,7 +120,9 @@ DRIVERS = {
Provider.KTUCLOUD:
('libcloud.compute.drivers.ktucloud', 'KTUCloudNodeDriver'),
Provider.HOSTVIRTUAL:
- ('libcloud.compute.drivers.hostvirtual', 'HostVirtualNodeDriver')
+ ('libcloud.compute.drivers.hostvirtual', 'HostVirtualNodeDriver'),
+ Provider.ABIQUO:
+ ('libcloud.compute.drivers.abiquo', 'AbiquoNodeDriver')
}
Modified: libcloud/trunk/libcloud/compute/types.py
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/compute/types.py?rev=1438331&r1=1438330&r2=1438331&view=diff
==============================================================================
--- libcloud/trunk/libcloud/compute/types.py (original)
+++ libcloud/trunk/libcloud/compute/types.py Fri Jan 25 05:48:36 2013
@@ -69,6 +69,7 @@ class Provider(object):
@cvar VCL: VCL driver
@cvar KTUCLOUD: kt ucloud driver
@cvar GRIDSPOT: Gridspot driver
+ @cvar ABIQUO: Abiquo driver
"""
DUMMY = 'dummy'
EC2 = 'ec2'
@@ -112,6 +113,7 @@ class Provider(object):
GRIDSPOT = 'gridspot'
RACKSPACE_FIRST_GEN = 'rackspace_first_gen'
HOSTVIRTUAL = 'hostvirtual'
+ ABIQUO = 'abiquo'
# Deprecated constants which are still supported
EC2_US_EAST = 'ec2_us_east'
Added: libcloud/trunk/libcloud/test/compute/fixtures/abiquo/dcs.xml
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/abiquo/dcs.xml?rev=1438331&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/abiquo/dcs.xml (added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/abiquo/dcs.xml Fri Jan 25 05:48:36 2013
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<datacenters>
+ <datacenter>
+ <link href="http://10.60.12.7:80/api/admin/datacenters/2" type="application/vnd.abiquo.datacenter+xml" rel="edit"/>
+ <link href="http://10.60.12.7:80/api/admin/datacenters/2/action/getlimits" type="application/vnd.abiquo.limit+xml" rel="getLimits"/>
+ <link href="http://10.60.12.7:80/api/admin/datacenters/2/racks" type="application/vnd.abiquo.racks+xml" rel="racks"/>
+ <link href="http://10.60.12.7:80/api/admin/datacenters/2/remoteservices" type="application/vnd.abiquo.remoteservices+xml" rel="remoteservices"/>
+ <link href="http://10.60.12.7:80/api/admin/datacenters/2/storage/tiers" type="application/vnd.abiquo.tiers+xml" rel="tiers"/>
+ <id>2</id>
+ <location>barcelona</location>
+ <name>barcelona</name>
+ <remoteServices>
+ <remoteService>
+ <link href="http://10.60.12.7:80/api/admin/datacenters/2" type="application/vnd.abiquo.datacenter+xml" rel="datacenter"/>
+ <link href="http://10.60.12.7:80/api/admin/datacenters/2/remoteservices/virtualfactory/action/check" rel="check"/>
+ <link href="http://10.60.12.7:80/api/admin/datacenters/2/remoteservices/virtualfactory" type="application/vnd.abiquo.remoteservice+xml" rel="edit"/>
+ <id>3</id>
+ <status>1</status>
+ <type>VIRTUAL_FACTORY</type>
+ <uri>http://10.60.12.7:80/virtualfactory</uri>
+ </remoteService>
+ <remoteService>
+ <link href="http://10.60.12.7:80/api/admin/datacenters/2" type="application/vnd.abiquo.datacenter+xml" rel="datacenter"/>
+ <link href="http://10.60.12.7:80/api/admin/datacenters/2/remoteservices/virtualsystemmonitor/action/check" rel="check"/>
+ <link href="http://10.60.12.7:80/api/admin/datacenters/2/remoteservices/virtualsystemmonitor" type="application/vnd.abiquo.remoteservice+xml" rel="edit"/>
+ <id>4</id>
+ <status>1</status>
+ <type>VIRTUAL_SYSTEM_MONITOR</type>
+ <uri>http://10.60.12.7:80/vsm</uri>
+ </remoteService>
+ <remoteService>
+ <link href="http://10.60.12.7:80/api/admin/datacenters/2" type="application/vnd.abiquo.datacenter+xml" rel="datacenter"/>
+ <link href="http://10.60.12.7:80/api/admin/datacenters/2/remoteservices/appliancemanager/action/check" rel="check"/>
+ <link href="http://10.60.12.7:80/api/admin/datacenters/2/remoteservices/appliancemanager" type="application/vnd.abiquo.remoteservice+xml" rel="edit"/>
+ <id>5</id>
+ <status>1</status>
+ <type>APPLIANCE_MANAGER</type>
+ <uri>http://10.60.12.7:80/am</uri>
+ </remoteService>
+ <remoteService>
+ <link href="http://10.60.12.7:80/api/admin/datacenters/2" type="application/vnd.abiquo.datacenter+xml" rel="datacenter"/>
+ <link href="http://10.60.12.7:80/api/admin/datacenters/2/remoteservices/nodecollector/action/check" rel="check"/>
+ <link href="http://10.60.12.7:80/api/admin/datacenters/2/remoteservices/nodecollector" type="application/vnd.abiquo.remoteservice+xml" rel="edit"/>
+ <id>6</id>
+ <status>1</status>
+ <type>NODE_COLLECTOR</type>
+ <uri>http://10.60.12.7:80/nodecollector</uri>
+ </remoteService>
+ <remoteService>
+ <link href="http://10.60.12.7:80/api/admin/datacenters/2" type="application/vnd.abiquo.datacenter+xml" rel="datacenter"/>
+ <link href="http://10.60.12.7:80/api/admin/datacenters/2/remoteservices/storagesystemmonitor/action/check" rel="check"/>
+ <link href="http://10.60.12.7:80/api/admin/datacenters/2/remoteservices/storagesystemmonitor" type="application/vnd.abiquo.remoteservice+xml" rel="edit"/>
+ <id>7</id>
+ <status>1</status>
+ <type>STORAGE_SYSTEM_MONITOR</type>
+ <uri>http://10.60.12.7:80/ssm</uri>
+ </remoteService>
+ <remoteService>
+ <link href="http://10.60.12.7:80/api/admin/datacenters/2" type="application/vnd.abiquo.datacenter+xml" rel="datacenter"/>
+ <link href="http://10.60.12.7:80/api/admin/datacenters/2/remoteservices/dhcpservice" type="application/vnd.abiquo.remoteservice+xml" rel="edit"/>
+ <id>8</id>
+ <status>1</status>
+ <type>DHCP_SERVICE</type>
+ <uri>omapi://10.60.12.7:7911</uri>
+ </remoteService>
+ <remoteService>
+ <link href="http://10.60.12.7:80/api/admin/datacenters/2" type="application/vnd.abiquo.datacenter+xml" rel="datacenter"/>
+ <link href="http://10.60.12.7:80/api/admin/datacenters/2/remoteservices/bpmservice/action/check" rel="check"/>
+ <link href="http://10.60.12.7:80/api/admin/datacenters/2/remoteservices/bpmservice" type="application/vnd.abiquo.remoteservice+xml" rel="edit"/>
+ <id>9</id>
+ <status>1</status>
+ <type>BPM_SERVICE</type>
+ <uri>http://10.60.12.7:80/bpm-async</uri>
+ </remoteService>
+ </remoteServices>
+ <uuid>Abiquo</uuid>
+ </datacenter>
+</datacenters>
Added: libcloud/trunk/libcloud/test/compute/fixtures/abiquo/ent_1.xml
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/abiquo/ent_1.xml?rev=1438331&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/abiquo/ent_1.xml (added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/abiquo/ent_1.xml Fri Jan 25 05:48:36 2013
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<enterprise>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1/appslib/templateDefinitionLists" type="application/vnd.abiquo.templatedefinitionlists+xml" rel="appslib/templateDefinitionLists"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1/appslib/templateDefinitions" type="application/vnd.abiquo.templatedefinitions+xml" rel="appslib/templateDefinitions"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1/action/virtualdatacenters" type="application/vnd.abiquo.virtualdatacenters+xml" rel="cloud/virtualdatacenters"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1" type="application/vnd.abiquo.enterprise+xml" rel="edit"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1/action/externalnetworks" type="application/vnd.abiquo.vlans+xml" rel="externalnetworks"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1/action/ips" rel="ips" title="ips"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1/limits" type="application/vnd.abiquo.limits+xml" rel="limits"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1/reservedmachines" type="application/vnd.abiquo.machines+xml" rel="reservedmachines"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1/users" type="application/vnd.abiquo.users+xml" rel="users"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1/action/virtualappliances" type="application/vnd.abiquo.virtualappliances+xml; version=2.0" rel="virtualappliances"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1/action/virtualappliances" rel="virtualappliances" title="virtualappliances"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1/action/virtualmachines" type="application/vnd.abiquo.virtualmachines+xml" rel="virtualmachines"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1/action/volumes" type="application/vnd.abiquo.iscsivolumes+xml" rel="volumes"/>
+ <cpuHard>0</cpuHard>
+ <cpuSoft>0</cpuSoft>
+ <hdHard>0</hdHard>
+ <hdSoft>0</hdSoft>
+ <publicIpsHard>0</publicIpsHard>
+ <publicIpsSoft>0</publicIpsSoft>
+ <ramHard>0</ramHard>
+ <ramSoft>0</ramSoft>
+ <storageHard>0</storageHard>
+ <storageSoft>0</storageSoft>
+ <vlansHard>0</vlansHard>
+ <vlansSoft>0</vlansSoft>
+ <id>1</id>
+ <isReservationRestricted>false</isReservationRestricted>
+ <name>Abiquo</name>
+ <repositoryHard>0</repositoryHard>
+ <repositorySoft>0</repositorySoft>
+</enterprise>
Added: libcloud/trunk/libcloud/test/compute/fixtures/abiquo/ent_1_dcrep_2.xml
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/abiquo/ent_1_dcrep_2.xml?rev=1438331&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/abiquo/ent_1_dcrep_2.xml (added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/abiquo/ent_1_dcrep_2.xml Fri Jan 25 05:48:36 2013
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<datacenterRepository>
+ <link href="http://10.60.12.7:80/am/erepos/1" rel="applianceManagerRepositoryUri"/><link href="http://10.60.12.7:80/api/admin/datacenters/2" type="application/vnd.abiquo.datacenter+xml" rel="datacenter" title="barcelona"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1/datacenterrepositories/2" type="application/vnd.abiquo.datacenterrepository+xml" rel="edit"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1" type="application/vnd.abiquo.enterprise+xml" rel="enterprise"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1/datacenterrepositories/2/actions/refresh" rel="refresh"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1/datacenterrepositories/2/virtualmachinetemplates" type="application/vnd.abiquo.virtualmachinetemplates+xml" rel="virtualmachinetemplates"/>
+<id>2</id><name>virtual image repo</name><repositoryCapacityMb>0</repositoryCapacityMb><repositoryLocation>10.60.1.72:/opt/vm_repository</repositoryLocation><repositoryRemainingMb>0</repositoryRemainingMb></datacenterRepository>
Added: libcloud/trunk/libcloud/test/compute/fixtures/abiquo/ent_1_dcrep_2_template_11.xml
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/abiquo/ent_1_dcrep_2_template_11.xml?rev=1438331&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/abiquo/ent_1_dcrep_2_template_11.xml (added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/abiquo/ent_1_dcrep_2_template_11.xml Fri Jan 25 05:48:36 2013
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<virtualMachineTemplate>
+ <link href="http://10.60.12.7:80/api/config/categories/1" type="application/vnd.abiquo.category+xml" rel="category" title="Others"/>
+ <link href="http://10.60.12.7:80/api/admin/datacenters/2" type="application/vnd.abiquo.datacenter+xml" rel="datacenter"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1/datacenterrepositories/2" type="application/vnd.abiquo.datacenterrepository+xml" rel="datacenterrepository"/>
+ <link href="http://10.60.12.7:80/am/erepos/1/templates/rs%3A9000/ovf/269/desc.ovf?format=diskFile" rel="diskfile"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1/datacenterrepositories/2/virtualmachinetemplates/11" type="application/vnd.abiquo.virtualmachinetemplate+xml" rel="edit" title="m0n0wall-vhd"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1" type="application/vnd.abiquo.enterprise+xml" rel="enterprise"/>
+ <link href="http://10.60.12.7:80/am/erepos/1/templates/rs%3A9000/ovf/269/desc.ovf?format=envelope" rel="ovfdocument"/>
+ <link href="http://10.60.12.7:80/am/erepos/1/templates/rs%3A9000/ovf/269/desc.ovf" rel="template"/>
+ <link href="http://rs:9000/ovf/269/desc.ovf" rel="templatedefinition"/>
+ <link href="http://10.60.12.7:80/am/erepos/1/templates/rs%3A9000/ovf/269/desc.ovf?format=status" rel="templatestatus"/>
+ <id>11</id>
+ <name>m0n0wall-vhd</name>
+ <description>m0n0wall image in VHD format ready for XenServer and HyperV</description>
+ <path>1/rs/abiport9000/ovf/269/m0n0wall-1.3b18-i386-flat.vmdk-VHD_SPARSE.vhd</path>
+ <diskFormatType>VHD_SPARSE</diskFormatType>
+ <diskFileSize>10490880</diskFileSize>
+ <cpuRequired>1</cpuRequired>
+ <ramRequired>128</ramRequired>
+ <hdRequired>27262976</hdRequired>
+ <shared>false</shared>
+ <costCode>0</costCode>
+ <creationDate>2013-01-10T20:25:12-05:00</creationDate>
+ <creationUser>SYSTEM</creationUser>
+ <chefEnabled>false</chefEnabled>
+ <iconUrl>http://icons.abiquo.com/monowall.jpg</iconUrl>
+</virtualMachineTemplate>
Added: libcloud/trunk/libcloud/test/compute/fixtures/abiquo/ent_1_dcrep_2_templates.xml
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/abiquo/ent_1_dcrep_2_templates.xml?rev=1438331&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/abiquo/ent_1_dcrep_2_templates.xml (added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/abiquo/ent_1_dcrep_2_templates.xml Fri Jan 25 05:48:36 2013
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<virtualMachineTemplates>
+ <virtualMachineTemplate>
+ <link href="http://10.60.12.7:80/api/config/categories/1" type="application/vnd.abiquo.category+xml" rel="category" title="Others"/><link href="http://10.60.12.7:80/api/admin/datacenters/2" type="application/vnd.abiquo.datacenter+xml" rel="datacenter"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1/datacenterrepositories/2" type="application/vnd.abiquo.datacenterrepository+xml" rel="datacenterrepository"/>
+ <link href="http://10.60.12.7:80/am/erepos/1/templates/rs%3A9000/ovf/269/desc.ovf?format=diskFile" rel="diskfile"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1/datacenterrepositories/2/virtualmachinetemplates/11" type="application/vnd.abiquo.virtualmachinetemplate+xml" rel="edit" title="m0n0wall-vhd"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1" type="application/vnd.abiquo.enterprise+xml" rel="enterprise"/>
+ <link href="http://10.60.12.7:80/am/erepos/1/templates/rs%3A9000/ovf/269/desc.ovf?format=envelope" rel="ovfdocument"/>
+ <link href="http://10.60.12.7:80/am/erepos/1/templates/rs%3A9000/ovf/269/desc.ovf" rel="template"/>
+ <link href="http://rs:9000/ovf/269/desc.ovf" rel="templatedefinition"/>
+ <link href="http://10.60.12.7:80/am/erepos/1/templates/rs%3A9000/ovf/269/desc.ovf?format=status" rel="templatestatus"/>
+ <id>11</id><name>m0n0wall-vhd</name><description>m0n0wall image in VHD format ready for XenServer and HyperV</description><path>1/rs/abiport9000/ovf/269/m0n0wall-1.3b18-i386-flat.vmdk-VHD_SPARSE.vhd</path><diskFormatType>VHD_SPARSE</diskFormatType><diskFileSize>10490880</diskFileSize><cpuRequired>1</cpuRequired><ramRequired>128</ramRequired><hdRequired>27262976</hdRequired><shared>false</shared><costCode>0</costCode><creationDate>2013-01-10T20:25:12-05:00</creationDate><creationUser>SYSTEM</creationUser><chefEnabled>false</chefEnabled><iconUrl>http://icons.abiquo.com/monowall.jpg</iconUrl></virtualMachineTemplate>
+ <virtualMachineTemplate>
+ <link href="http://10.60.12.7:80/api/config/categories/1" type="application/vnd.abiquo.category+xml" rel="category" title="Others"/>
+ <link href="http://10.60.12.7:80/api/admin/datacenters/2" type="application/vnd.abiquo.datacenter+xml" rel="datacenter"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1/datacenterrepositories/2" type="application/vnd.abiquo.datacenterrepository+xml" rel="datacenterrepository"/>
+ <link href="http://10.60.12.7:80/am/erepos/1/templates/rs%3A9000/ovf/73/desc.ovf?format=diskFile" rel="diskfile"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1/datacenterrepositories/2/virtualmachinetemplates/19" type="application/vnd.abiquo.virtualmachinetemplate+xml" rel="edit" title="RHEL6 Build Bot"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1" type="application/vnd.abiquo.enterprise+xml" rel="enterprise"/>
+ <link href="http://10.60.12.7:80/am/erepos/1/templates/rs%3A9000/ovf/73/desc.ovf?format=envelope" rel="ovfdocument"/>
+ <link href="http://10.60.12.7:80/am/erepos/1/templates/rs%3A9000/ovf/73/desc.ovf" rel="template"/>
+ <link href="http://rs:9000/ovf/73/desc.ovf" rel="templatedefinition"/>
+ <link href="http://10.60.12.7:80/am/erepos/1/templates/rs%3A9000/ovf/73/desc.ovf?format=status" rel="templatestatus"/>
+ <id>19</id>
+ <name>RHEL6 Build Bot</name>
+ <description>RHEL6 Build Bot</description>
+ <path>1/rs/abiport9000/ovf/73/build-bot-rhel6-disk1.vmdk</path>
+ <diskFormatType>VMDK_STREAM_OPTIMIZED</diskFormatType>
+ <diskFileSize>351064576</diskFileSize>
+ <cpuRequired>1</cpuRequired>
+ <ramRequired>1024</ramRequired>
+ <hdRequired>4294967296</hdRequired>
+ <shared>false</shared>
+ <costCode>0</costCode>
+ <creationDate>2013-01-10T20:25:12-05:00</creationDate>
+ <creationUser>SYSTEM</creationUser>
+ <chefEnabled>false</chefEnabled>
+ <iconUrl>http://rs.bcn.abiquo.com:9000/public/icons/q.png</iconUrl>
+ </virtualMachineTemplate>
+</virtualMachineTemplates>
Added: libcloud/trunk/libcloud/test/compute/fixtures/abiquo/ent_1_dcreps.xml
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/abiquo/ent_1_dcreps.xml?rev=1438331&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/abiquo/ent_1_dcreps.xml (added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/abiquo/ent_1_dcreps.xml Fri Jan 25 05:48:36 2013
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<datacenterRepositories>
+ <datacenterRepository>
+ <link href="http://10.60.12.7:80/am/erepos/1" rel="applianceManagerRepositoryUri"/><link href="http://10.60.12.7:80/api/admin/datacenters/2" type="application/vnd.abiquo.datacenter+xml" rel="datacenter" title="barcelona"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1/datacenterrepositories/2" type="application/vnd.abiquo.datacenterrepository+xml" rel="edit"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1" type="application/vnd.abiquo.enterprise+xml" rel="enterprise"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1/datacenterrepositories/2/actions/refresh" rel="refresh"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1/datacenterrepositories/2/virtualmachinetemplates" type="application/vnd.abiquo.virtualmachinetemplates+xml" rel="virtualmachinetemplates"/>
+ <id>2</id><name>virtual image repo</name><repositoryCapacityMb>0</repositoryCapacityMb><repositoryLocation>10.60.1.72:/opt/vm_repository</repositoryLocation><repositoryRemainingMb>0</repositoryRemainingMb></datacenterRepository>
+</datacenterRepositories>
Added: libcloud/trunk/libcloud/test/compute/fixtures/abiquo/login.xml
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/abiquo/login.xml?rev=1438331&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/abiquo/login.xml (added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/abiquo/login.xml Fri Jan 25 05:48:36 2013
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<user>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1/users/2" type="application/vnd.abiquo.user+xml" rel="edit"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1" type="application/vnd.abiquo.enterprise+xml" rel="enterprise"/>
+ <link href="http://10.60.12.7:80/api/admin/roles/2" type="application/vnd.abiquo.role+xml" rel="role"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1/users/2/action/virtualmachines" type="application/vnd.abiquo.virtualmachines+xml" rel="virtualmachines"/>
+ <active>true</active>
+ <authType>ABIQUO</authType>
+ <description>Standard user</description>
+ <email></email>
+ <id>2</id>
+ <locale>en_US</locale>
+ <name>Standard</name>
+ <nick>user</nick>
+ <password>c69a39bd64ffb77ea7ee3369dce742f3</password>
+ <surname>User</surname>
+</user>
Added: libcloud/trunk/libcloud/test/compute/fixtures/abiquo/not_found_error.xml
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/abiquo/not_found_error.xml?rev=1438331&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/abiquo/not_found_error.xml (added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/abiquo/not_found_error.xml Fri Jan 25 05:48:36 2013
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<errors>
+ <error>
+ <code>DC-0</code>
+ <message>The requested datacenter does not exist</message>
+ </error>
+</errors>
Added: libcloud/trunk/libcloud/test/compute/fixtures/abiquo/privilege_errors.html
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/abiquo/privilege_errors.html?rev=1438331&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/abiquo/privilege_errors.html (added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/abiquo/privilege_errors.html Fri Jan 25 05:48:36 2013
@@ -0,0 +1,23 @@
+<html>
+ <head>
+ <title>Apache Tomcat/6.0.35 - Error report</title>
+ <style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style>
+ </head>
+ <body>
+ <h1>HTTP Status 403 - Access is denied</h1>
+ <HR size="1" noshade="noshade">
+ <p>
+ <b>type</b>
+ Status report</p>
+ <p>
+ <b>message</b>
+ <u>Access is denied</u>
+ </p>
+ <p>
+ <b>description</b>
+ <u>Access to the specified resource (Access is denied) has been forbidden.</u>
+ </p>
+ <HR size="1" noshade="noshade">
+ <h3>Apache Tomcat/6.0.35</h3>
+ </body>
+ </html>
Added: libcloud/trunk/libcloud/test/compute/fixtures/abiquo/unauthorized_user.html
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/abiquo/unauthorized_user.html?rev=1438331&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/abiquo/unauthorized_user.html (added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/abiquo/unauthorized_user.html Fri Jan 25 05:48:36 2013
@@ -0,0 +1,23 @@
+<html>
+ <head>
+ <title>Apache Tomcat/6.0.35 - Error report</title>
+ <style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style>
+ </head>
+ <body>
+ <h1>HTTP Status 401 - Bad credentials</h1>
+ <HR size="1" noshade="noshade">
+ <p>
+ <b>type</b>
+ Status report</p>
+ <p>
+ <b>message</b>
+ <u>Bad credentials</u>
+ </p>
+ <p>
+ <b>description</b>
+ <u>This request requires HTTP authentication (Bad credentials).</u>
+ </p>
+ <HR size="1" noshade="noshade">
+ <h3>Apache Tomcat/6.0.35</h3>
+ </body>
+ </html>
Added: libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4.xml
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4.xml?rev=1438331&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4.xml (added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4.xml Fri Jan 25 05:48:36 2013
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<virtualDatacenter>
+ <link href="http://10.60.12.7:80/api/admin/datacenters/2" type="application/vnd.abiquo.datacenter+xml" rel="datacenter"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/privatenetworks/2" type="application/vnd.abiquo.vlan+xml" rel="defaultnetwork"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/action/dhcpinfo" type="text/plain" rel="dhcpinfo"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/disks" type="application/vnd.abiquo.harddisks+xml" rel="disks"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4" type="application/vnd.abiquo.virtualdatacenter+xml" rel="edit"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1" type="application/vnd.abiquo.enterprise+xml" rel="enterprise"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/action/ips" type="application/vnd.abiquo.ip+xml" rel="ips"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/privatenetworks" type="application/vnd.abiquo.vlans+xml" rel="privatenetworks"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/publicips/purchased" type="application/vnd.abiquo.ips+xml" rel="purchased"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/volumes/action/statefulcandidates" type="application/vnd.abiquo.iscsivolumes+xml" rel="statefulcandidates"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/tiers" type="application/vnd.abiquo.tiers+xml" rel="tiers"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/publicips/topurchase" type="application/vnd.abiquo.ips+xml" rel="topurchase"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances" type="application/vnd.abiquo.virtualappliances+xml" rel="virtualappliances"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/volumes" type="application/vnd.abiquo.iscsivolumes+xml" rel="volumes"/>
+ <cpuHard>0</cpuHard>
+ <cpuSoft>0</cpuSoft>
+ <hdHard>0</hdHard>
+ <hdSoft>0</hdSoft>
+ <publicIpsHard>0</publicIpsHard>
+ <publicIpsSoft>0</publicIpsSoft>
+ <ramHard>0</ramHard>
+ <ramSoft>0</ramSoft>
+ <storageHard>0</storageHard>
+ <storageSoft>0</storageSoft>
+ <vlansHard>0</vlansHard>
+ <vlansSoft>0</vlansSoft>
+ <hypervisorType>KVM</hypervisorType>
+ <id>4</id>
+ <name>vdc_kvm</name>
+ <network>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4" type="application/vnd.abiquo.virtualdatacenter+xml" rel="virtualdatacenter"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/privatenetworks/2" type="application/vnd.abiquo.vlan+xml" rel="edit"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/privatenetworks/2/ips" type="application/vnd.abiquo.ip+xml" rel="ips"/>
+ <address>192.168.0.0</address>
+ <dhcpOptions/>
+ <gateway>192.168.0.1</gateway>
+ <id>2</id>
+ <mask>24</mask>
+ <name>default_private_network</name>
+ <primaryDNS></primaryDNS>
+ <secondaryDNS></secondaryDNS>
+ <sufixDNS></sufixDNS>
+ <type>INTERNAL</type>
+ </network>
+</virtualDatacenter>
Added: libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_5.xml
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_5.xml?rev=1438331&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_5.xml (added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_5.xml Fri Jan 25 05:48:36 2013
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<virtualAppliance>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/5/action/deploy" type="application/vnd.abiquo.acceptedrequest+xml" rel="deploy"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/5" type="application/vnd.abiquo.virtualappliance+xml" rel="edit"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1" type="application/vnd.abiquo.enterprise+xml" rel="enterprise"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/5/action/ips" type="application/vnd.abiquo.ip+xml" rel="ips"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/5/action/price" type="text/plain" rel="price"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/5/state" type="application/vnd.abiquo.virtualappliancestate+xml" rel="state"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/5/action/undeploy" type="application/vnd.abiquo.acceptedrequest+xml" rel="undeploy"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4" type="application/vnd.abiquo.virtualdatacenter+xml" rel="virtualdatacenter"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/5/virtualmachines" type="application/vnd.abiquo.virtualmachines+xml" rel="virtualmachines"/>
+ <error>0</error>
+ <highDisponibility>0</highDisponibility>
+ <id>5</id>
+ <name>libcloud_test_group</name>
+ <publicApp>0</publicApp>
+ <state>NOT_DEPLOYED</state>
+</virtualAppliance>
Added: libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_5_needs_sync.xml
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_5_needs_sync.xml?rev=1438331&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_5_needs_sync.xml (added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_5_needs_sync.xml Fri Jan 25 05:48:36 2013
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<virtualAppliance>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/5/action/deploy" type="application/vnd.abiquo.acceptedrequest+xml" rel="deploy"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/5" type="application/vnd.abiquo.virtualappliance+xml" rel="edit"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1" type="application/vnd.abiquo.enterprise+xml" rel="enterprise"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/5/action/ips" type="application/vnd.abiquo.ip+xml" rel="ips"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/5/action/price" type="text/plain" rel="price"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/5/state" type="application/vnd.abiquo.virtualappliancestate+xml" rel="state"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/5/action/undeploy" type="application/vnd.abiquo.acceptedrequest+xml" rel="undeploy"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4" type="application/vnd.abiquo.virtualdatacenter+xml" rel="virtualdatacenter"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/5/virtualmachines" type="application/vnd.abiquo.virtualmachines+xml" rel="virtualmachines"/>
+ <error>0</error>
+ <highDisponibility>0</highDisponibility>
+ <id>5</id>
+ <name>libcloud_test_group</name>
+ <publicApp>0</publicApp>
+ <state>NEEDS_SYNC</state>
+</virtualAppliance>
Added: libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_5_vm_3_not_allocated.xml
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_5_vm_3_not_allocated.xml?rev=1438331&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_5_vm_3_not_allocated.xml (added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_5_vm_3_not_allocated.xml Fri Jan 25 05:48:36 2013
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<virtualmachinewithnode>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/6/virtualmachines/3/network/configurations" type="application/vnd.abiquo.virtualmachinenetworkconfigurations+xml" rel="configurations"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/6/virtualmachines/3/action/deploy" type="application/vnd.abiquo.acceptedrequest+xml" rel="deploy"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/6/virtualmachines/3/storage/disks" type="application/vnd.abiquo.harddisks+xml" rel="disks"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/6/virtualmachines/3" type="application/vnd.abiquo.virtualmachine+xml" rel="edit"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1" type="application/vnd.abiquo.enterprise+xml" rel="enterprise"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/6/virtualmachines/3/action/instance" type="application/vnd.abiquo.acceptedrequest+xml" rel="instance"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/6/virtualmachines/3/network/configurations/2" type="application/vnd.abiquo.virtualmachinenetworkconfiguration+xml" rel="network_configuration"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/6/virtualmachines/3/network/nics" type="application/vnd.abiquo.nics+xml" rel="nics"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/privatenetworks/2/ips/64" type="application/vnd.abiquo.ip+xml" rel="privateip"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/6/virtualmachines/3/action/reset" type="application/vnd.abiquo.acceptedrequest+xml" rel="reset"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/6/virtualmachines/3/state" type="application/vnd.abiquo.virtualmachinestate+xml" rel="state"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/6/virtualmachines/3/tasks" type="application/vnd.abiquo.tasks+xml" rel="tasks"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/6/virtualmachines/3/tasks" rel="tasks"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/6/virtualmachines/3/action/undeploy" type="application/vnd.abiquo.acceptedrequest+xml" rel="undeploy"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1/users/2" type="application/vnd.abiquo.user+xml" rel="user"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/6" type="application/vnd.abiquo.virtualappliance+xml; version=2.0" rel="virtualappliance"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4" type="application/vnd.abiquo.virtualdatacenter+xml" rel="virtualdatacenter" title="KVM"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/6/virtualmachines/3" type="application/vnd.abiquo.virtualmachine+xml" rel="virtualmachine"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1/datacenterrepositories/2/virtualmachinetemplates/11" type="application/vnd.abiquo.virtualmachinetemplate+xml" rel="virtualmachinetemplate"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/6/virtualmachines/3/storage/volumes" type="application/vnd.abiquo.iscsivolumes+xml" rel="volumes"/>
+ <cpu>1</cpu>
+ <hdInBytes>27262976</hdInBytes>
+ <highDisponibility>0</highDisponibility>
+ <id>3</id>
+ <idState>1</idState>
+ <idType>1</idType>
+ <name>ABQ_914f8125-33d3-4fe3-a162-5d6f5bf32614</name>
+ <ram>128</ram>
+ <state>NOT_ALLOCATED</state>
+ <uuid>914f8125-33d3-4fe3-a162-5d6f5bf32614</uuid>
+ <vdrpPort>0</vdrpPort>
+ <nodeId>3</nodeId>
+ <nodeName>node-name</nodeName>
+ <x>0</x>
+ <y>0</y>
+</virtualmachinewithnode>
Added: libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_5_vms.xml
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_5_vms.xml?rev=1438331&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_5_vms.xml (added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/abiquo/vdc_4_vapp_5_vms.xml Fri Jan 25 05:48:36 2013
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<virtualmachineswithnode>
+ <virtualmachinewithnode>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/6/virtualmachines/3/network/configurations" type="application/vnd.abiquo.virtualmachinenetworkconfigurations+xml" rel="configurations"/><link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/6/virtualmachines/3/action/deploy" type="application/vnd.abiquo.acceptedrequest+xml" rel="deploy"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/6/virtualmachines/3/storage/disks" type="application/vnd.abiquo.harddisks+xml" rel="disks"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/6/virtualmachines/3" type="application/vnd.abiquo.virtualmachine+xml" rel="edit"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1" type="application/vnd.abiquo.enterprise+xml" rel="enterprise"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/6/virtualmachines/3/action/instance" type="application/vnd.abiquo.acceptedrequest+xml" rel="instance"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/6/virtualmachines/3/network/configurations/2" type="application/vnd.abiquo.virtualmachinenetworkconfiguration+xml" rel="network_configuration"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/6/virtualmachines/3/network/nics" type="application/vnd.abiquo.nics+xml" rel="nics"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/6/virtualmachines/3/action/reset" type="application/vnd.abiquo.acceptedrequest+xml" rel="reset"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/6/virtualmachines/3/state" type="application/vnd.abiquo.virtualmachinestate+xml" rel="state"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/6/virtualmachines/3/tasks" type="application/vnd.abiquo.tasks+xml" rel="tasks"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/6/virtualmachines/3/tasks" rel="tasks"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/6/virtualmachines/3/action/undeploy" type="application/vnd.abiquo.acceptedrequest+xml" rel="undeploy"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1/users/2" type="application/vnd.abiquo.user+xml" rel="user"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/6" type="application/vnd.abiquo.virtualappliance+xml; version=2.0" rel="virtualappliance"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4" type="application/vnd.abiquo.virtualdatacenter+xml" rel="virtualdatacenter" title="KVM"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/6/virtualmachines/3" type="application/vnd.abiquo.virtualmachine+xml" rel="virtualmachine"/>
+ <link href="http://10.60.12.7:80/api/admin/enterprises/1/datacenterrepositories/2/virtualmachinetemplates/11" type="application/vnd.abiquo.virtualmachinetemplate+xml" rel="virtualmachinetemplate"/>
+ <link href="http://10.60.12.7:80/api/cloud/virtualdatacenters/4/virtualappliances/6/virtualmachines/3/storage/volumes" type="application/vnd.abiquo.iscsivolumes+xml" rel="volumes"/>
+ <cpu>1</cpu><hdInBytes>27262976</hdInBytes><highDisponibility>0</highDisponibility><id>3</id><idState>1</idState><idType>1</idType><name>ABQ_914f8125-33d3-4fe3-a162-5d6f5bf32614</name><ram>128</ram><state>NOT_ALLOCATED</state><uuid>914f8125-33d3-4fe3-a162-5d6f5bf32614</uuid><vdrpPort>0</vdrpPort><nodeId>3</nodeId><nodeName>node-name</nodeName><x>0</x><y>0</y></virtualmachinewithnode>
+</virtualmachineswithnode>