diff options
| author | Jenkins <jenkins@review.openstack.org> | 2011-12-09 17:31:34 +0000 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2011-12-09 17:31:34 +0000 |
| commit | 2aadaba580f0253d64a69a5cf4127e50346a34fb (patch) | |
| tree | 10b7434fdf5a221720e79f70ff3811a723634cf9 /nova/api | |
| parent | 8920181a0d8cfb4f78af0fa0b868e864d8971744 (diff) | |
| parent | f7df18f22715e958510805db42df818ac0f0d243 (diff) | |
| download | nova-2aadaba580f0253d64a69a5cf4127e50346a34fb.tar.gz nova-2aadaba580f0253d64a69a5cf4127e50346a34fb.tar.xz nova-2aadaba580f0253d64a69a5cf4127e50346a34fb.zip | |
Merge "Add templates for selected resource extensions."
Diffstat (limited to 'nova/api')
| -rw-r--r-- | nova/api/openstack/v2/contrib/security_groups.py | 100 | ||||
| -rw-r--r-- | nova/api/openstack/v2/contrib/simple_tenant_usage.py | 51 | ||||
| -rw-r--r-- | nova/api/openstack/v2/contrib/virtual_interfaces.py | 31 | ||||
| -rw-r--r-- | nova/api/openstack/v2/contrib/volumes.py | 130 | ||||
| -rw-r--r-- | nova/api/openstack/v2/contrib/volumetypes.py | 81 |
5 files changed, 343 insertions, 50 deletions
diff --git a/nova/api/openstack/v2/contrib/security_groups.py b/nova/api/openstack/v2/contrib/security_groups.py index 50f129bd6..3c4f0e473 100644 --- a/nova/api/openstack/v2/contrib/security_groups.py +++ b/nova/api/openstack/v2/contrib/security_groups.py @@ -24,6 +24,7 @@ import webob from nova.api.openstack import common from nova.api.openstack.v2 import extensions from nova.api.openstack import wsgi +from nova.api.openstack import xmlutil from nova import compute from nova import db from nova import exception @@ -355,6 +356,85 @@ class SecurityGroupRulesController(SecurityGroupController): return webob.Response(status_int=202) +def make_rule(elem): + elem.set('id') + elem.set('parent_group_id') + + proto = xmlutil.SubTemplateElement(elem, 'ip_protocol') + proto.text = 'ip_protocol' + + from_port = xmlutil.SubTemplateElement(elem, 'from_port') + from_port.text = 'from_port' + + to_port = xmlutil.SubTemplateElement(elem, 'to_port') + to_port.text = 'to_port' + + group = xmlutil.SubTemplateElement(elem, 'group', selector='group') + name = xmlutil.SubTemplateElement(group, 'name') + name.text = 'name' + tenant_id = xmlutil.SubTemplateElement(group, 'tenant_id') + tenant_id.text = 'tenant_id' + + ip_range = xmlutil.SubTemplateElement(elem, 'ip_range', + selector='ip_range') + cidr = xmlutil.SubTemplateElement(ip_range, 'cidr') + cidr.text = 'cidr' + + +def make_sg(elem): + elem.set('id') + elem.set('tenant_id') + elem.set('name') + + desc = xmlutil.SubTemplateElement(elem, 'description') + desc.text = 'description' + + rules = xmlutil.SubTemplateElement(elem, 'rules') + rule = xmlutil.SubTemplateElement(rules, 'rule', selector='rules') + make_rule(rule) + + +sg_nsmap = {None: wsgi.XMLNS_V11} + + +class SecurityGroupRuleTemplate(xmlutil.TemplateBuilder): + def construct(self): + root = xmlutil.TemplateElement('security_group_rule', + selector='security_group_rule') + make_rule(root) + return xmlutil.MasterTemplate(root, 1, nsmap=sg_nsmap) + + +class SecurityGroupTemplate(xmlutil.TemplateBuilder): + def construct(self): + root = xmlutil.TemplateElement('security_group', + selector='security_group') + make_sg(root) + return xmlutil.MasterTemplate(root, 1, nsmap=sg_nsmap) + + +class SecurityGroupsTemplate(xmlutil.TemplateBuilder): + def construct(self): + root = xmlutil.TemplateElement('security_groups') + elem = xmlutil.SubTemplateElement(root, 'security_group', + selector='security_groups') + make_sg(elem) + return xmlutil.MasterTemplate(root, 1, nsmap=sg_nsmap) + + +class SecurityGroupXMLSerializer(xmlutil.XMLTemplateSerializer): + def index(self): + return SecurityGroupsTemplate() + + def default(self): + return SecurityGroupTemplate() + + +class SecurityGroupRulesXMLSerializer(xmlutil.XMLTemplateSerializer): + def default(self): + return SecurityGroupRuleTemplate() + + class Security_groups(extensions.ExtensionDescriptor): """Security group support""" @@ -439,10 +519,8 @@ class Security_groups(extensions.ExtensionDescriptor): def get_resources(self): resources = [] - metadata = _get_metadata() body_serializers = { - 'application/xml': wsgi.XMLDictSerializer(metadata=metadata, - xmlns=wsgi.XMLNS_V11), + 'application/xml': SecurityGroupXMLSerializer(), } serializer = wsgi.ResponseSerializer(body_serializers, None) @@ -458,6 +536,11 @@ class Security_groups(extensions.ExtensionDescriptor): resources.append(res) + body_serializers = { + 'application/xml': SecurityGroupRulesXMLSerializer(), + } + serializer = wsgi.ResponseSerializer(body_serializers, None) + body_deserializers = { 'application/xml': SecurityGroupRulesXMLDeserializer(), } @@ -538,14 +621,3 @@ class SecurityGroupRulesXMLDeserializer(wsgi.MetadataXMLDeserializer): sg_rule['cidr'] = self.extract_text(cidr_node) return sg_rule - - -def _get_metadata(): - metadata = { - "attributes": { - "security_group": ["id", "tenant_id", "name"], - "rule": ["id", "parent_group_id"], - "security_group_rule": ["id", "parent_group_id"], - } - } - return metadata diff --git a/nova/api/openstack/v2/contrib/simple_tenant_usage.py b/nova/api/openstack/v2/contrib/simple_tenant_usage.py index e896371ed..4204c53bf 100644 --- a/nova/api/openstack/v2/contrib/simple_tenant_usage.py +++ b/nova/api/openstack/v2/contrib/simple_tenant_usage.py @@ -23,6 +23,8 @@ from webob import exc from nova.api.openstack.v2 import extensions from nova.api.openstack.v2 import views +from nova.api.openstack import wsgi +from nova.api.openstack import xmlutil from nova.compute import api from nova.db.sqlalchemy.session import get_session from nova import exception @@ -211,6 +213,47 @@ class SimpleTenantUsageController(object): return {'tenant_usage': usage} +def make_usage(elem): + for subelem_tag in ('tenant_id', 'total_local_gb_usage', + 'total_vcpus_usage', 'total_memory_mb_usage', + 'total_hours', 'start', 'stop'): + subelem = xmlutil.SubTemplateElement(elem, subelem_tag) + subelem.text = subelem_tag + + server_usages = xmlutil.SubTemplateElement(elem, 'server_usages') + server_usage = xmlutil.SubTemplateElement(server_usages, 'server_usage', + selector='server_usages') + for subelem_tag in ('name', 'hours', 'memory_mb', 'local_gb', 'vcpus', + 'tenant_id', 'flavor', 'started_at', 'ended_at', + 'state', 'uptime'): + subelem = xmlutil.SubTemplateElement(server_usage, subelem_tag) + subelem.text = subelem_tag + + +class SimpleTenantUsageTemplate(xmlutil.TemplateBuilder): + def construct(self): + root = xmlutil.TemplateElement('tenant_usage', selector='tenant_usage') + make_usage(root) + return xmlutil.MasterTemplate(root, 1) + + +class SimpleTenantUsagesTemplate(xmlutil.TemplateBuilder): + def construct(self): + root = xmlutil.TemplateElement('tenant_usages') + elem = xmlutil.SubTemplateElement(root, 'tenant_usage', + selector='tenant_usages') + make_usage(elem) + return xmlutil.MasterTemplate(root, 1) + + +class SimpleTenantUsageSerializer(xmlutil.XMLTemplateSerializer): + def index(self): + return SimpleTenantUsagesTemplate() + + def show(self): + return SimpleTenantUsageTemplate() + + class Simple_tenant_usage(extensions.ExtensionDescriptor): """Simple tenant usage extension""" @@ -222,8 +265,14 @@ class Simple_tenant_usage(extensions.ExtensionDescriptor): def get_resources(self): resources = [] + body_serializers = { + 'application/xml': SimpleTenantUsageSerializer(), + } + serializer = wsgi.ResponseSerializer(body_serializers) + res = extensions.ResourceExtension('os-simple-tenant-usage', - SimpleTenantUsageController()) + SimpleTenantUsageController(), + serializer=serializer) resources.append(res) return resources diff --git a/nova/api/openstack/v2/contrib/virtual_interfaces.py b/nova/api/openstack/v2/contrib/virtual_interfaces.py index 1975a8dc0..211b8c9be 100644 --- a/nova/api/openstack/v2/contrib/virtual_interfaces.py +++ b/nova/api/openstack/v2/contrib/virtual_interfaces.py @@ -18,6 +18,7 @@ from nova.api.openstack import common from nova.api.openstack.v2 import extensions from nova.api.openstack import wsgi +from nova.api.openstack import xmlutil from nova import log as logging from nova import network @@ -33,13 +34,6 @@ def _translate_vif_summary_view(_context, vif): return d -def _get_metadata(): - metadata = { - "attributes": { - 'virtual_interface': ["id", "mac_address"]}} - return metadata - - class ServerVirtualInterfaceController(object): """The instance VIF API controller for the Openstack API. """ @@ -63,6 +57,24 @@ class ServerVirtualInterfaceController(object): entity_maker=_translate_vif_summary_view) +vif_nsmap = {None: wsgi.XMLNS_V11} + + +class VirtualInterfaceTemplate(xmlutil.TemplateBuilder): + def construct(self): + root = xmlutil.TemplateElement('virtual_interfaces') + elem = xmlutil.SubTemplateElement(root, 'virtual_interface', + selector='virtual_interfaces') + elem.set('id') + elem.set('mac_address') + return xmlutil.MasterTemplate(root, 1, nsmap=vif_nsmap) + + +class VirtualInterfaceSerializer(xmlutil.XMLTemplateSerializer): + def default(self): + return VirtualInterfaceTemplate() + + class Virtual_interfaces(extensions.ExtensionDescriptor): """Virtual interface support""" @@ -74,10 +86,9 @@ class Virtual_interfaces(extensions.ExtensionDescriptor): def get_resources(self): resources = [] - metadata = _get_metadata() body_serializers = { - 'application/xml': wsgi.XMLDictSerializer(metadata=metadata, - xmlns=wsgi.XMLNS_V11)} + 'application/xml': VirtualInterfaceSerializer() + } serializer = wsgi.ResponseSerializer(body_serializers, None) res = extensions.ResourceExtension( 'os-virtual-interfaces', diff --git a/nova/api/openstack/v2/contrib/volumes.py b/nova/api/openstack/v2/contrib/volumes.py index 5d86282f2..75d8af803 100644 --- a/nova/api/openstack/v2/contrib/volumes.py +++ b/nova/api/openstack/v2/contrib/volumes.py @@ -21,6 +21,8 @@ import webob from nova.api.openstack import common from nova.api.openstack.v2 import extensions from nova.api.openstack.v2 import servers +from nova.api.openstack import wsgi +from nova.api.openstack import xmlutil from nova import compute from nova import db from nova import exception @@ -86,21 +88,6 @@ def _translate_volume_summary_view(context, vol): class VolumeController(object): """The Volumes API controller for the OpenStack API.""" - _serialization_metadata = { - 'application/xml': { - "attributes": { - "volume": [ - "id", - "status", - "size", - "availabilityZone", - "createdAt", - "displayName", - "displayDescription", - "volumeType", - "metadata", - ]}}} - def __init__(self): self.volume_api = volume.API() super(VolumeController, self).__init__() @@ -180,6 +167,51 @@ class VolumeController(object): return {'volume': retval} +def make_volume(elem): + elem.set('id') + elem.set('status') + elem.set('size') + elem.set('availabilityZone') + elem.set('createdAt') + elem.set('displayName') + elem.set('displayDescription') + elem.set('volumeType') + + attachments = xmlutil.SubTemplateElement(elem, 'attachments') + attachment = xmlutil.SubTemplateElement(attachments, 'attachment', + selector='attachments') + make_attachment(attachment) + + metadata = xmlutil.make_flat_dict('metadata') + elem.append(metadata) + + +class VolumeTemplate(xmlutil.TemplateBuilder): + def construct(self): + root = xmlutil.TemplateElement('volume', selector='volume') + make_volume(root) + return xmlutil.MasterTemplate(root, 1) + + +class VolumesTemplate(xmlutil.TemplateBuilder): + def construct(self): + root = xmlutil.TemplateElement('volumes') + elem = xmlutil.SubTemplateElement(root, 'volume', selector='volumes') + make_volume(elem) + return xmlutil.MasterTemplate(root, 1) + + +class VolumeSerializer(xmlutil.XMLTemplateSerializer): + def default(self): + return VolumeTemplate() + + def index(self): + return VolumesTemplate() + + def detail(self): + return VolumesTemplate() + + def _translate_attachment_detail_view(_context, vol): """Maps keys for attachment details view.""" @@ -216,14 +248,6 @@ class VolumeAttachmentController(object): """ - _serialization_metadata = { - 'application/xml': { - 'attributes': { - 'volumeAttachment': ['id', - 'serverId', - 'volumeId', - 'device']}}} - def __init__(self): self.compute_api = compute.API() self.volume_api = volume.API() @@ -331,6 +355,38 @@ class VolumeAttachmentController(object): return {'volumeAttachments': res} +def make_attachment(elem): + elem.set('id') + elem.set('serverId') + elem.set('volumeId') + elem.set('device') + + +class VolumeAttachmentTemplate(xmlutil.TemplateBuilder): + def construct(self): + root = xmlutil.TemplateElement('volumeAttachment', + selector='volumeAttachment') + make_attachment(root) + return xmlutil.MasterTemplate(root, 1) + + +class VolumeAttachmentsTemplate(xmlutil.TemplateBuilder): + def construct(self): + root = xmlutil.TemplateElement('volumeAttachments') + elem = xmlutil.SubTemplateElement(root, 'volumeAttachment', + selector='volumeAttachments') + make_attachment(elem) + return xmlutil.MasterTemplate(root, 1) + + +class VolumeAttachmentSerializer(xmlutil.XMLTemplateSerializer): + def default(self): + return VolumeAttachmentTemplate() + + def index(self): + return VolumeAttachmentsTemplate() + + class BootFromVolumeController(servers.Controller): """The boot from volume API controller for the Openstack API.""" @@ -349,22 +405,48 @@ class Volumes(extensions.ExtensionDescriptor): def get_resources(self): resources = [] + body_serializers = { + 'application/xml': VolumeSerializer(), + } + serializer = wsgi.ResponseSerializer(body_serializers) + # NOTE(justinsb): No way to provide singular name ('volume') # Does this matter? res = extensions.ResourceExtension('os-volumes', VolumeController(), + serializer=serializer, collection_actions={'detail': 'GET'}) resources.append(res) + body_serializers = { + 'application/xml': VolumeAttachmentSerializer(), + } + serializer = wsgi.ResponseSerializer(body_serializers) + res = extensions.ResourceExtension('os-volume_attachments', VolumeAttachmentController(), + serializer=serializer, parent=dict( member_name='server', collection_name='servers')) resources.append(res) + headers_serializer = servers.HeadersSerializer() + body_serializers = { + 'application/xml': servers.ServerXMLSerializer(), + } + serializer = wsgi.ResponseSerializer(body_serializers, + headers_serializer) + + body_deserializers = { + 'application/xml': servers.ServerXMLDeserializer(), + } + deserializer = wsgi.RequestDeserializer(body_deserializers) + res = extensions.ResourceExtension('os-volumes_boot', - BootFromVolumeController()) + BootFromVolumeController(), + serializer=serializer, + deserializer=deserializer) resources.append(res) return resources diff --git a/nova/api/openstack/v2/contrib/volumetypes.py b/nova/api/openstack/v2/contrib/volumetypes.py index ca3866c99..24ac87d01 100644 --- a/nova/api/openstack/v2/contrib/volumetypes.py +++ b/nova/api/openstack/v2/contrib/volumetypes.py @@ -21,6 +21,7 @@ from webob import exc from nova.api.openstack.v2 import extensions from nova.api.openstack import wsgi +from nova.api.openstack import xmlutil from nova import db from nova import exception from nova.volume import volume_types @@ -89,6 +90,37 @@ class VolumeTypesController(object): raise error +def make_voltype(elem): + elem.set('id') + elem.set('name') + extra_specs = xmlutil.make_flat_dict('extra_specs', selector='extra_specs') + elem.append(extra_specs) + + +class VolumeTypeTemplate(xmlutil.TemplateBuilder): + def construct(self): + root = xmlutil.TemplateElement('volume_type', selector='volume_type') + make_voltype(root) + return xmlutil.MasterTemplate(root, 1) + + +class VolumeTypesTemplate(xmlutil.TemplateBuilder): + def construct(self): + root = xmlutil.TemplateElement('volume_types') + sel = lambda obj, do_raise=False: obj.values() + elem = xmlutil.SubTemplateElement(root, 'volume_type', selector=sel) + make_voltype(elem) + return xmlutil.MasterTemplate(root, 1) + + +class VolumeTypesSerializer(xmlutil.XMLTemplateSerializer): + def index(self): + return VolumeTypesTemplate() + + def default(self): + return VolumeTypeTemplate() + + class VolumeTypeExtraSpecsController(object): """ The volume type extra specs API controller for the Openstack API """ @@ -160,6 +192,40 @@ class VolumeTypeExtraSpecsController(object): raise error +class VolumeTypeExtraSpecsTemplate(xmlutil.TemplateBuilder): + def construct(self): + root = xmlutil.make_flat_dict('extra_specs', selector='extra_specs') + return xmlutil.MasterTemplate(root, 1) + + +class VolumeTypeExtraSpecTemplate(xmlutil.TemplateBuilder): + def construct(self): + tagname = xmlutil.Selector('key') + + def extraspec_sel(obj, do_raise=False): + # Have to extract the key and value for later use... + key, value = obj.items()[0] + return dict(key=key, value=value) + + root = xmlutil.TemplateElement(tagname, selector=extraspec_sel) + root.text = 'value' + return xmlutil.MasterTemplate(root, 1) + + +class VolumeTypeExtraSpecsSerializer(xmlutil.XMLTemplateSerializer): + def index(self): + return VolumeTypeExtraSpecsTemplate() + + def create(self): + return VolumeTypeExtraSpecsTemplate() + + def update(self): + return VolumeTypeExtraSpecTemplate() + + def show(self): + return VolumeTypeExtraSpecTemplate() + + class Volumetypes(extensions.ExtensionDescriptor): """Volume types support""" @@ -170,13 +236,26 @@ class Volumetypes(extensions.ExtensionDescriptor): def get_resources(self): resources = [] + + body_serializers = { + 'application/xml': VolumeTypesSerializer(), + } + serializer = wsgi.ResponseSerializer(body_serializers) + res = extensions.ResourceExtension( 'os-volume-types', - VolumeTypesController()) + VolumeTypesController(), + serializer=serializer) resources.append(res) + body_serializers = { + 'application/xml': VolumeTypeExtraSpecsSerializer(), + } + serializer = wsgi.ResponseSerializer(body_serializers) + res = extensions.ResourceExtension('extra_specs', VolumeTypeExtraSpecsController(), + serializer=serializer, parent=dict( member_name='vol_type', collection_name='os-volume-types')) |
