class CommonDeserializer(wsgi.MetadataXMLDeserializer): """Common deserializer to handle xml-formatted volume requests. Handles standard volume attributes as well as the optional metadata attribute """ metadata_deserializer = common.MetadataXMLDeserializer() def _extract_volume(self, node): """Marshal the volume attribute of a parsed request.""" volume = {} volume_node = self.find_first_child_named(node, 'volume') attributes = ['display_name', 'display_description', 'size', 'volume_type', 'availability_zone'] for attr in attributes: if volume_node.getAttribute(attr): volume[attr] = volume_node.getAttribute(attr) metadata_node = self.find_first_child_named(volume_node, 'metadata') if metadata_node is not None: volume['metadata'] = self.extract_metadata(metadata_node) return volume
def test_metadata_deserializer(self): """Should throw a 400 error on corrupt xml.""" deserializer = common.MetadataXMLDeserializer() self.assertRaises( exception.MalformedRequestBody, deserializer.deserialize, utils.killer_xml_body())
class ServerGroupXMLDeserializer(wsgi.MetadataXMLDeserializer): """Deserializer to handle xml-formatted server group requests.""" metadata_deserializer = common.MetadataXMLDeserializer() def default(self, string): """Deserialize an xml-formatted server group create request.""" dom = xmlutil.safe_minidom_parse_string(string) server_group = self._extract_server_group(dom) return {'body': {'server_group': server_group}} def _extract_server_group(self, node): """Marshal the instance attribute of a parsed request.""" server_group = {} sg_node = self.find_first_child_named(node, 'server_group') if sg_node is not None: if sg_node.hasAttribute('name'): server_group['name'] = sg_node.getAttribute('name') if sg_node.hasAttribute('id'): server_group['id'] = sg_node.getAttribute('id') policies = self._extract_policies(sg_node) server_group['policies'] = policies or [] return server_group def _extract_policies(self, server_group_node): """Marshal the server group policies element of a parsed request.""" policies_node = self.find_first_child_named(server_group_node, 'policies') if policies_node is not None: policy_nodes = self.find_children_named(policies_node, 'policy') policies = [] if policy_nodes is not None: for node in policy_nodes: policies.append(node.firstChild.nodeValue) return policies def _extract_members(self, server_group_node): """Marshal the server group members element of a parsed request.""" members_node = self.find_first_child_named(server_group_node, 'members') if members_node is not None: member_nodes = self.find_children_named(members_node, 'member') members = [] if member_nodes is not None: for node in member_nodes: members.append(node.firstChild.nodeValue) return members
def create_resource(): headers_serializer = common.MetadataHeadersSerializer() body_deserializers = { 'application/xml': common.MetadataXMLDeserializer(), } body_serializers = { 'application/xml': common.MetadataXMLSerializer(), } serializer = wsgi.ResponseSerializer(body_serializers, headers_serializer) deserializer = wsgi.RequestDeserializer(body_deserializers) return wsgi.Resource(Controller(), deserializer, serializer)
class ServerXMLDeserializer(wsgi.XMLDeserializer): """ Deserializer to handle xml-formatted server create requests. Handles standard server attributes as well as optional metadata and personality attributes """ metadata_deserializer = common.MetadataXMLDeserializer() def create(self, string): """Deserialize an xml-formatted server create request""" dom = minidom.parseString(string) server = self._extract_server(dom) return {'body': {'server': server}} def _extract_server(self, node): """Marshal the server attribute of a parsed request""" server = {} server_node = self.find_first_child_named(node, 'server') attributes = ["name", "imageId", "flavorId", "adminPass"] for attr in attributes: if server_node.getAttribute(attr): server[attr] = server_node.getAttribute(attr) metadata_node = self.find_first_child_named(server_node, "metadata") server["metadata"] = self.metadata_deserializer.extract_metadata( metadata_node) server["personality"] = self._extract_personality(server_node) return server def _extract_personality(self, server_node): """Marshal the personality attribute of a parsed request""" node = self.find_first_child_named(server_node, "personality") personality = [] if node is not None: for file_node in self.find_children_named(node, "file"): item = {} if file_node.hasAttribute("path"): item["path"] = file_node.getAttribute("path") item["contents"] = self.extract_text(file_node) personality.append(item) return personality
class MetadataXMLDeserializationTest(test.TestCase): deserializer = common.MetadataXMLDeserializer() def test_create(self): request_body = """ <metadata xmlns="http://docs.openstack.org/compute/api/v1.1"> <meta key='123'>asdf</meta> <meta key='567'>jkl;</meta> </metadata>""" output = self.deserializer.deserialize(request_body, 'create') expected = {"body": {"metadata": {"123": "asdf", "567": "jkl;"}}} self.assertEqual(output, expected) def test_create_empty(self): request_body = """ <metadata xmlns="http://docs.openstack.org/compute/api/v1.1"/>""" output = self.deserializer.deserialize(request_body, 'create') expected = {"body": {"metadata": {}}} self.assertEqual(output, expected) def test_update_all(self): request_body = """ <metadata xmlns="http://docs.openstack.org/compute/api/v1.1"> <meta key='123'>asdf</meta> <meta key='567'>jkl;</meta> </metadata>""" output = self.deserializer.deserialize(request_body, 'update_all') expected = {"body": {"metadata": {"123": "asdf", "567": "jkl;"}}} self.assertEqual(output, expected) def test_update(self): request_body = """ <meta xmlns="http://docs.openstack.org/compute/api/v1.1" key='123'>asdf</meta>""" output = self.deserializer.deserialize(request_body, 'update') expected = {"body": {"meta": {"123": "asdf"}}} self.assertEqual(output, expected)
class CommonDeserializer(wsgi.MetadataXMLDeserializer): """ Common deserializer to handle xml-formatted server create requests. Handles standard server attributes as well as optional metadata and personality attributes """ metadata_deserializer = common.MetadataXMLDeserializer() def _extract_personality(self, server_node): """Marshal the personality attribute of a parsed request""" node = self.find_first_child_named(server_node, "personality") if node is not None: personality = [] for file_node in self.find_children_named(node, "file"): item = {} if file_node.hasAttribute("path"): item["path"] = file_node.getAttribute("path") item["contents"] = self.extract_text(file_node) personality.append(item) return personality else: return None def _extract_server(self, node): """Marshal the server attribute of a parsed request""" server = {} server_node = self.find_first_child_named(node, 'server') attributes = [ "name", "imageRef", "flavorRef", "adminPass", "accessIPv4", "accessIPv6" ] for attr in attributes: if server_node.getAttribute(attr): server[attr] = server_node.getAttribute(attr) metadata_node = self.find_first_child_named(server_node, "metadata") if metadata_node is not None: server["metadata"] = self.extract_metadata(metadata_node) personality = self._extract_personality(server_node) if personality is not None: server["personality"] = personality networks = self._extract_networks(server_node) if networks is not None: server["networks"] = networks security_groups = self._extract_security_groups(server_node) if security_groups is not None: server["security_groups"] = security_groups auto_disk_config = server_node.getAttribute('auto_disk_config') if auto_disk_config: server['auto_disk_config'] = utils.bool_from_str(auto_disk_config) return server def _extract_networks(self, server_node): """Marshal the networks attribute of a parsed request""" node = self.find_first_child_named(server_node, "networks") if node is not None: networks = [] for network_node in self.find_children_named(node, "network"): item = {} if network_node.hasAttribute("uuid"): item["uuid"] = network_node.getAttribute("uuid") if network_node.hasAttribute("fixed_ip"): item["fixed_ip"] = network_node.getAttribute("fixed_ip") networks.append(item) return networks else: return None def _extract_security_groups(self, server_node): """Marshal the security_groups attribute of a parsed request""" node = self.find_first_child_named(server_node, "security_groups") if node is not None: security_groups = [] for sg_node in self.find_children_named(node, "security_group"): item = {} name = self.find_attribute_or_element(sg_node, 'name') if name: item["name"] = name security_groups.append(item) return security_groups else: return None
class ServerXMLDeserializer(wsgi.MetadataXMLDeserializer): """ Deserializer to handle xml-formatted server create requests. Handles standard server attributes as well as optional metadata and personality attributes """ metadata_deserializer = common.MetadataXMLDeserializer() def action(self, string): dom = minidom.parseString(string) action_node = dom.childNodes[0] action_name = action_node.tagName action_deserializer = { 'createImage': self._action_create_image, 'changePassword': self._action_change_password, 'reboot': self._action_reboot, 'rebuild': self._action_rebuild, 'resize': self._action_resize, 'confirmResize': self._action_confirm_resize, 'revertResize': self._action_revert_resize, }.get(action_name, self.default) action_data = action_deserializer(action_node) return {'body': {action_name: action_data}} def _action_create_image(self, node): return self._deserialize_image_action(node, ('name',)) def _action_change_password(self, node): if not node.hasAttribute("adminPass"): raise AttributeError("No adminPass was specified in request") return {"adminPass": node.getAttribute("adminPass")} def _action_reboot(self, node): if not node.hasAttribute("type"): raise AttributeError("No reboot type was specified in request") return {"type": node.getAttribute("type")} def _action_rebuild(self, node): rebuild = {} if node.hasAttribute("name"): rebuild['name'] = node.getAttribute("name") metadata_node = self.find_first_child_named(node, "metadata") if metadata_node is not None: rebuild["metadata"] = self.extract_metadata(metadata_node) personality = self._extract_personality(node) if personality is not None: rebuild["personality"] = personality if not node.hasAttribute("imageRef"): raise AttributeError("No imageRef was specified in request") rebuild["imageRef"] = node.getAttribute("imageRef") return rebuild def _action_resize(self, node): if not node.hasAttribute("flavorRef"): raise AttributeError("No flavorRef was specified in request") return {"flavorRef": node.getAttribute("flavorRef")} def _action_confirm_resize(self, node): return None def _action_revert_resize(self, node): return None def _deserialize_image_action(self, node, allowed_attributes): data = {} for attribute in allowed_attributes: value = node.getAttribute(attribute) if value: data[attribute] = value metadata_node = self.find_first_child_named(node, 'metadata') if metadata_node is not None: metadata = self.metadata_deserializer.extract_metadata( metadata_node) data['metadata'] = metadata return data def create(self, string): """Deserialize an xml-formatted server create request""" dom = minidom.parseString(string) server = self._extract_server(dom) return {'body': {'server': server}} def _extract_server(self, node): """Marshal the server attribute of a parsed request""" server = {} server_node = self.find_first_child_named(node, 'server') attributes = ["name", "imageRef", "flavorRef", "adminPass", "accessIPv4", "accessIPv6"] for attr in attributes: if server_node.getAttribute(attr): server[attr] = server_node.getAttribute(attr) metadata_node = self.find_first_child_named(server_node, "metadata") if metadata_node is not None: server["metadata"] = self.extract_metadata(metadata_node) personality = self._extract_personality(server_node) if personality is not None: server["personality"] = personality networks = self._extract_networks(server_node) if networks is not None: server["networks"] = networks security_groups = self._extract_security_groups(server_node) if security_groups is not None: server["security_groups"] = security_groups auto_disk_config = server_node.getAttribute('auto_disk_config') if auto_disk_config: server['auto_disk_config'] = utils.bool_from_str(auto_disk_config) return server def _extract_personality(self, server_node): """Marshal the personality attribute of a parsed request""" node = self.find_first_child_named(server_node, "personality") if node is not None: personality = [] for file_node in self.find_children_named(node, "file"): item = {} if file_node.hasAttribute("path"): item["path"] = file_node.getAttribute("path") item["contents"] = self.extract_text(file_node) personality.append(item) return personality else: return None def _extract_networks(self, server_node): """Marshal the networks attribute of a parsed request""" node = self.find_first_child_named(server_node, "networks") if node is not None: networks = [] for network_node in self.find_children_named(node, "network"): item = {} if network_node.hasAttribute("uuid"): item["uuid"] = network_node.getAttribute("uuid") if network_node.hasAttribute("fixed_ip"): item["fixed_ip"] = network_node.getAttribute("fixed_ip") networks.append(item) return networks else: return None def _extract_security_groups(self, server_node): """Marshal the security_groups attribute of a parsed request""" node = self.find_first_child_named(server_node, "security_groups") if node is not None: security_groups = [] for sg_node in self.find_children_named(node, "security_group"): item = {} name_node = self.find_first_child_named(sg_node, "name") if name_node: item["name"] = self.extract_text(name_node) security_groups.append(item) return security_groups else: return None