diff options
| author | Jenkins <jenkins@review.openstack.org> | 2013-02-20 06:16:33 +0000 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2013-02-20 06:16:33 +0000 |
| commit | 6d0ed8f86fbaa7c52e66a1d335dcf063232de8dd (patch) | |
| tree | 25d1bbf94abb1f9c35e2578dd128fec764f28847 /nova/api | |
| parent | 4e54c59b8888a2c5a8ab41c213d3bff2faba5570 (diff) | |
| parent | a9add7d35e27b90f0c420d2b24b1af88b978fd7b (diff) | |
| download | nova-6d0ed8f86fbaa7c52e66a1d335dcf063232de8dd.tar.gz nova-6d0ed8f86fbaa7c52e66a1d335dcf063232de8dd.tar.xz nova-6d0ed8f86fbaa7c52e66a1d335dcf063232de8dd.zip | |
Merge "Add support for network adapter hotplug."
Diffstat (limited to 'nova/api')
| -rw-r--r-- | nova/api/openstack/compute/contrib/attach_interfaces.py | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/nova/api/openstack/compute/contrib/attach_interfaces.py b/nova/api/openstack/compute/contrib/attach_interfaces.py new file mode 100644 index 000000000..a838354d0 --- /dev/null +++ b/nova/api/openstack/compute/contrib/attach_interfaces.py @@ -0,0 +1,192 @@ +# Copyright 2012 SINA Inc. +# All Rights Reserved. +# +# Licensed 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. + +"""The instance interfaces extension.""" + +import webob +from webob import exc + +from nova.api.openstack import extensions +from nova import compute +from nova import exception +from nova import network +from nova.openstack.common import log as logging + + +LOG = logging.getLogger(__name__) +authorize = extensions.extension_authorizer('compute', 'attach_interfaces') + + +def _translate_interface_attachment_view(port_info): + """Maps keys for interface attachment details view.""" + return { + 'net_id': port_info['network_id'], + 'port_id': port_info['id'], + 'mac_addr': port_info['mac_address'], + 'port_state': port_info['status'], + 'fixed_ips': port_info.get('fixed_ips', None), + } + + +class InterfaceAttachmentController(object): + """The interface attachment API controller for the OpenStack API.""" + + def __init__(self): + self.compute_api = compute.API() + self.network_api = network.API() + super(InterfaceAttachmentController, self).__init__() + + def index(self, req, server_id): + """Returns the list of interface attachments for a given instance.""" + return self._items(req, server_id, + entity_maker=_translate_interface_attachment_view) + + def show(self, req, server_id, id): + """Return data about the given interface attachment.""" + context = req.environ['nova.context'] + authorize(context) + + port_id = id + try: + instance = self.compute_api.get(context, server_id) + except exception.NotFound: + raise exc.HTTPNotFound() + + try: + port_info = self.network_api.show_port(context, port_id) + except exception.NotFound: + raise exc.HTTPNotFound() + + if port_info['port']['device_id'] != server_id: + raise exc.HTTPNotFound() + + return {'interfaceAttachment': _translate_interface_attachment_view( + port_info['port'])} + + def create(self, req, server_id, body): + """Attach an interface to an instance.""" + context = req.environ['nova.context'] + authorize(context) + + network_id = None + port_id = None + req_ip = None + if body: + attachment = body['interfaceAttachment'] + network_id = attachment.get('net_id', None) + port_id = attachment.get('port_id', None) + try: + req_ip = attachment['fixed_ips'][0]['ip_address'] + except Exception: + pass + + if network_id and port_id: + raise exc.HTTPBadRequest() + if req_ip and not network_id: + raise exc.HTTPBadRequest() + + try: + instance = self.compute_api.get(context, server_id) + LOG.audit(_("Attach interface"), instance=instance) + network_info = self.compute_api.attach_interface(context, + instance, network_id, port_id, req_ip) + except exception.NotFound, e: + LOG.exception(e) + raise exc.HTTPNotFound() + except NotImplementedError: + msg = _("Network driver does not support this function.") + raise webob.exc.HTTPNotImplemented(explanation=msg) + except exception.InterfaceAttachFailed, e: + LOG.exception(e) + msg = _("Failed to attach interface") + raise webob.exc.HTTPInternalServerError(explanation=msg) + + network, mapping = network_info + return self.show(req, server_id, mapping['vif_uuid']) + + def update(self, req, server_id, id, body): + """Update a interface attachment. We don't currently support this.""" + msg = _("Attachments update is not supported") + raise exc.HTTPNotImplemented(explanation=msg) + + def delete(self, req, server_id, id): + """Detach an interface from an instance.""" + context = req.environ['nova.context'] + authorize(context) + port_id = id + + try: + instance = self.compute_api.get(context, server_id) + LOG.audit(_("Detach interface %s"), port_id, instance=instance) + + except exception.NotFound: + raise exc.HTTPNotFound() + try: + self.compute_api.detach_interface(context, + instance, port_id=port_id) + except exception.PortNotFound: + raise exc.HTTPNotFound + except NotImplementedError: + msg = _("Network driver does not support this function.") + raise webob.exc.HTTPNotImplemented(explanation=msg) + + return webob.Response(status_int=202) + + def _items(self, req, server_id, entity_maker): + """Returns a list of attachments, transformed through entity_maker.""" + context = req.environ['nova.context'] + authorize(context) + + try: + instance = self.compute_api.get(context, server_id) + except exception.NotFound: + raise exc.HTTPNotFound() + + results = [] + search_opts = {'device_id': instance['uuid']} + + try: + data = self.network_api.list_ports(context, **search_opts) + except exception.NotFound: + raise exc.HTTPNotFound() + except NotImplementedError: + msg = _("Network driver does not support this function.") + raise webob.exc.HTTPNotImplemented(explanation=msg) + + ports = data.get('ports', []) + results = [entity_maker(port) for port in ports] + + return {'interfaceAttachments': results} + + +class Attach_interfaces(extensions.ExtensionDescriptor): + """Attach interface support.""" + + name = "AttachInterfaces" + alias = "os-attach-interfaces" + namespace = "http://docs.openstack.org/compute/ext/interfaces/api/v1.1" + updated = "2012-07-22T00:00:00+00:00" + + def get_resources(self): + resources = [] + + res = extensions.ResourceExtension('os-interface', + InterfaceAttachmentController(), + parent=dict( + member_name='server', + collection_name='servers')) + resources.append(res) + + return resources |
