summaryrefslogtreecommitdiffstats
path: root/nova/api
diff options
context:
space:
mode:
authorAlex Meade <alex.meade@rackspace.com>2011-08-25 14:58:31 -0400
committerAlex Meade <alex.meade@rackspace.com>2011-08-25 14:58:31 -0400
commit73704209a146bf51f51f445dc1ccc4410181ad6c (patch)
treeb00952926bc2922f5625a1f64c5d23526613fab0 /nova/api
parente0b64c9aa0d2617d1d9e4dc0c35dc3899e0e527a (diff)
Updated ServerXMLSerializer to use etree instead of minidom
Diffstat (limited to 'nova/api')
-rw-r--r--nova/api/openstack/schemas/v1.1/server.rng6
-rw-r--r--nova/api/openstack/servers.py215
2 files changed, 105 insertions, 116 deletions
diff --git a/nova/api/openstack/schemas/v1.1/server.rng b/nova/api/openstack/schemas/v1.1/server.rng
index dbd169a83..68f86373c 100644
--- a/nova/api/openstack/schemas/v1.1/server.rng
+++ b/nova/api/openstack/schemas/v1.1/server.rng
@@ -15,9 +15,6 @@
<optional>
<attribute name="adminPass"> <text/> </attribute>
</optional>
- <zeroOrMore>
- <externalRef href="../atom-link.rng"/>
- </zeroOrMore>
<element name="image">
<attribute name="id"> <text/> </attribute>
<externalRef href="../atom-link.rng"/>
@@ -47,4 +44,7 @@
</element>
</zeroOrMore>
</element>
+ <zeroOrMore>
+ <externalRef href="../atom-link.rng"/>
+ </zeroOrMore>
</element>
diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py
index 27c67e79e..b978dea08 100644
--- a/nova/api/openstack/servers.py
+++ b/nova/api/openstack/servers.py
@@ -17,8 +17,8 @@ import base64
import os
import traceback
+from lxml import etree
from webob import exc
-from xml.dom import minidom
import webob
from nova import compute
@@ -37,6 +37,7 @@ import nova.api.openstack.views.addresses
import nova.api.openstack.views.flavors
import nova.api.openstack.views.images
import nova.api.openstack.views.servers
+from nova.api.openstack import xmlutil
LOG = logging.getLogger('nova.api.openstack.servers')
@@ -835,123 +836,112 @@ class HeadersSerializer(wsgi.ResponseHeadersSerializer):
class ServerXMLSerializer(wsgi.XMLDictSerializer):
- xmlns = wsgi.XMLNS_V11
-
- def __init__(self):
- self.metadata_serializer = common.MetadataXMLSerializer()
- self.addresses_serializer = ips.IPXMLSerializer()
-
- def _create_basic_entity_node(self, xml_doc, id, links, name):
- basic_node = xml_doc.createElement(name)
- basic_node.setAttribute('id', str(id))
- link_nodes = self._create_link_nodes(xml_doc, links)
- for link_node in link_nodes:
- basic_node.appendChild(link_node)
- return basic_node
-
- def _create_metadata_node(self, xml_doc, metadata):
- return self.metadata_serializer.meta_list_to_xml(xml_doc, metadata)
-
- def _create_addresses_node(self, xml_doc, addresses):
- return self.addresses_serializer.networks_to_xml(xml_doc, addresses)
-
- def _add_server_attributes(self, node, server):
- node.setAttribute('id', str(server['id']))
- node.setAttribute('uuid', str(server['uuid']))
- node.setAttribute('hostId', str(server['hostId']))
- node.setAttribute('name', server['name'])
- node.setAttribute('created', str(server['created']))
- node.setAttribute('updated', str(server['updated']))
- node.setAttribute('status', server['status'])
- if 'accessIPv4' in server:
- node.setAttribute('accessIPv4', str(server['accessIPv4']))
- if 'accessIPv6' in server:
- node.setAttribute('accessIPv6', str(server['accessIPv6']))
- if 'progress' in server:
- node.setAttribute('progress', str(server['progress']))
-
- def _server_to_xml(self, xml_doc, server):
- server_node = xml_doc.createElement('server')
- server_node.setAttribute('id', str(server['id']))
- server_node.setAttribute('name', server['name'])
- link_nodes = self._create_link_nodes(xml_doc,
- server['links'])
- for link_node in link_nodes:
- server_node.appendChild(link_node)
- return server_node
-
- def _server_to_xml_detailed(self, xml_doc, server):
- server_node = xml_doc.createElement('server')
- self._add_server_attributes(server_node, server)
-
- link_nodes = self._create_link_nodes(xml_doc,
- server['links'])
- for link_node in link_nodes:
- server_node.appendChild(link_node)
-
- if 'image' in server:
- image_node = self._create_basic_entity_node(xml_doc,
- server['image']['id'],
- server['image']['links'],
- 'image')
- server_node.appendChild(image_node)
-
- if 'flavor' in server:
- flavor_node = self._create_basic_entity_node(xml_doc,
- server['flavor']['id'],
- server['flavor']['links'],
- 'flavor')
- server_node.appendChild(flavor_node)
-
- metadata = server.get('metadata', {}).items()
- if len(metadata) > 0:
- metadata_node = self._create_metadata_node(xml_doc, metadata)
- server_node.appendChild(metadata_node)
-
- addresses_node = self._create_addresses_node(xml_doc,
- server['addresses'])
- server_node.appendChild(addresses_node)
-
- return server_node
-
- def _server_list_to_xml(self, xml_doc, servers, detailed):
- container_node = xml_doc.createElement('servers')
+ NSMAP = {None: xmlutil.XMLNS_V11, 'atom': xmlutil.XMLNS_ATOM}
+
+ def _create_metadata_node(self, metadata_dict):
+ metadata_elem = etree.Element('metadata', nsmap=self.NSMAP)
+ for (key, value) in metadata_dict.items():
+ elem = etree.SubElement(metadata_elem, 'meta')
+ elem.set('key', key)
+ elem.text = value
+
+ return metadata_elem
+
+ def _create_image_node(self, image_dict):
+ image_elem = etree.Element('image', nsmap=self.NSMAP)
+ image_elem.set('id', str(image_dict['id']))
+ for link in image_dict.get('links', []):
+ elem = etree.SubElement(image_elem,
+ '{%s}link' % xmlutil.XMLNS_ATOM)
+ elem.set('rel', link['rel'])
+ elem.set('href', link['href'])
+ return image_elem
+
+ def _create_flavor_node(self, flavor_dict):
+ flavor_elem = etree.Element('flavor', nsmap=self.NSMAP)
+ flavor_elem.set('id', str(flavor_dict['id']))
+ for link in flavor_dict.get('links', []):
+ elem = etree.SubElement(flavor_elem,
+ '{%s}link' % xmlutil.XMLNS_ATOM)
+ elem.set('rel', link['rel'])
+ elem.set('href', link['href'])
+ return flavor_elem
+
+ def _create_addresses_node(self, addresses_dict):
+ addresses_elem = etree.Element('addresses', nsmap=self.NSMAP)
+ for (network_id, ip_dicts) in addresses_dict.items():
+ network_node = etree.SubElement(addresses_elem, 'network')
+ network_node.set('id', str(network_id))
+ for ip_dict in ip_dicts:
+ ip_elem = etree.SubElement(network_node, 'ip')
+ ip_elem.set('version', str(ip_dict['version']))
+ ip_elem.set('addr', ip_dict['addr'])
+ return addresses_elem
+
+ def _populate_server(self, server_elem, server_dict, detailed=False):
+ """Populate a server xml element from a dict."""
+
+ server_elem.set('name', server_dict['name'])
+ server_elem.set('id', str(server_dict['id']))
if detailed:
- server_to_xml = self._server_to_xml_detailed
- else:
- server_to_xml = self._server_to_xml
-
- for server in servers:
- item_node = server_to_xml(xml_doc, server)
- container_node.appendChild(item_node)
- return container_node
+ server_elem.set('uuid', str(server_dict['uuid']))
+ server_elem.set('updated', str(server_dict['updated']))
+ server_elem.set('created', str(server_dict['created']))
+ server_elem.set('hostId', str(server_dict['hostId']))
+ server_elem.set('accessIPv4', str(server_dict['accessIPv4']))
+ server_elem.set('accessIPv6', str(server_dict['accessIPv6']))
+ server_elem.set('status', str(server_dict['status']))
+ if 'progress' in server_dict:
+ server_elem.set('progress', str(server_dict['progress']))
+ image_elem = self._create_image_node(server_dict['image'])
+ server_elem.append(image_elem)
+
+ flavor_elem = self._create_flavor_node(server_dict['flavor'])
+ server_elem.append(flavor_elem)
+
+ meta_elem = self._create_metadata_node(
+ server_dict.get('metadata', {}))
+ server_elem.append(meta_elem)
+
+ addresses_elem = self._create_addresses_node(
+ server_dict.get('addresses', {}))
+ server_elem.append(addresses_elem)
+
+ for link in server_dict.get('links', []):
+ elem = etree.SubElement(server_elem,
+ '{%s}link' % xmlutil.XMLNS_ATOM)
+ elem.set('rel', link['rel'])
+ elem.set('href', link['href'])
+ return server_elem
+
+ def _to_xml(self, root):
+ """Convert the xml object to an xml string."""
+ return etree.tostring(root, encoding='UTF-8')
def index(self, servers_dict):
- xml_doc = minidom.Document()
- node = self._server_list_to_xml(xml_doc,
- servers_dict['servers'],
- detailed=False)
- return self.to_xml_string(node, True)
+ servers = etree.Element('servers', nsmap=self.NSMAP)
+ for server_dict in servers_dict['servers']:
+ server = etree.SubElement(servers, 'server')
+ self._populate_server(server, server_dict, False)
+ return self._to_xml(servers)
def detail(self, servers_dict):
- xml_doc = minidom.Document()
- node = self._server_list_to_xml(xml_doc,
- servers_dict['servers'],
- detailed=True)
- return self.to_xml_string(node, True)
+ servers = etree.Element('servers', nsmap=self.NSMAP)
+ for server_dict in servers_dict['servers']:
+ server = etree.SubElement(servers, 'server')
+ self._populate_server(server, server_dict, True)
+ return self._to_xml(servers)
def show(self, server_dict):
- xml_doc = minidom.Document()
- node = self._server_to_xml_detailed(xml_doc,
- server_dict['server'])
- return self.to_xml_string(node, True)
+ server = etree.Element('server', nsmap=self.NSMAP)
+ self._populate_server(server, server_dict['server'], True)
+ return self._to_xml(server)
def create(self, server_dict):
- xml_doc = minidom.Document()
- node = self._server_to_xml_detailed(xml_doc,
- server_dict['server'])
- node.setAttribute('adminPass', server_dict['server']['adminPass'])
- return self.to_xml_string(node, True)
+ server = etree.Element('server', nsmap=self.NSMAP)
+ self._populate_server(server, server_dict['server'], True)
+ server.set('adminPass', server_dict['server']['adminPass'])
+ return self._to_xml(server)
def action(self, server_dict):
#NOTE(bcwaldon): We need a way to serialize actions individually. This
@@ -959,10 +949,9 @@ class ServerXMLSerializer(wsgi.XMLDictSerializer):
return self.create(server_dict)
def update(self, server_dict):
- xml_doc = minidom.Document()
- node = self._server_to_xml_detailed(xml_doc,
- server_dict['server'])
- return self.to_xml_string(node, True)
+ server = etree.Element('server', nsmap=self.NSMAP)
+ self._populate_server(server, server_dict['server'], True)
+ return self._to_xml(server)
def create_resource(version='1.0'):