Fixing detail action for port collection
Adding PortIsDown exception Adding unit tests for detail actions and PortIsDown PEP8 FIXES
This commit is contained in:
parent
1b3d8c76e5
commit
100f47e9e6
@ -72,6 +72,8 @@ class Controller(common.QuantumController):
|
||||
return faults.Fault(faults.PortNotFound(e))
|
||||
except exception.PortInUse as e:
|
||||
return faults.Fault(faults.PortInUse(e))
|
||||
except exception.PortIsDown as e:
|
||||
return faults.Fault(faults.PortIsDown(e))
|
||||
except exception.AlreadyAttached as e:
|
||||
return faults.Fault(faults.AlreadyAttached(e))
|
||||
|
||||
|
@ -34,6 +34,7 @@ class Fault(webob.exc.HTTPException):
|
||||
430: "portNotFound",
|
||||
431: "requestedStateInvalid",
|
||||
432: "portInUse",
|
||||
433: "portIsDown",
|
||||
440: "alreadyAttached",
|
||||
470: "serviceUnavailable",
|
||||
471: "pluginFault"}
|
||||
@ -133,6 +134,19 @@ class PortInUse(webob.exc.HTTPClientError):
|
||||
explanation = ('A resource is currently attached to the logical port')
|
||||
|
||||
|
||||
class PortIsDown(webob.exc.HTTPClientError):
|
||||
"""
|
||||
subclass of :class:`~HTTPClientError`
|
||||
|
||||
This indicates that the server could not plug an attachment into a port
|
||||
as the port is administratively down
|
||||
code: 433, title: PortIsDown
|
||||
"""
|
||||
code = 433
|
||||
title = 'Port is Down'
|
||||
explanation = ('The specified logical port is administratively down')
|
||||
|
||||
|
||||
class AlreadyAttached(webob.exc.HTTPClientError):
|
||||
"""
|
||||
subclass of :class:`~HTTPClientError`
|
||||
|
@ -39,7 +39,8 @@ class Controller(common.QuantumController):
|
||||
"port": ["id", "state"],
|
||||
"attachment": ["id"]
|
||||
},
|
||||
"plurals": {"networks": "network"}
|
||||
"plurals": {"networks": "network",
|
||||
"ports": "port"}
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -51,14 +51,23 @@ class Controller(common.QuantumController):
|
||||
port_details=False):
|
||||
""" Returns a list of ports. """
|
||||
try:
|
||||
ports = self._plugin.get_all_ports(tenant_id, network_id)
|
||||
port_list = self._plugin.get_all_ports(tenant_id, network_id)
|
||||
builder = ports_view.get_view_builder(request)
|
||||
|
||||
# Load extra data for ports if required.
|
||||
if port_details:
|
||||
port_list_detail = \
|
||||
[self._plugin.get_port_details(
|
||||
tenant_id, network_id, port['port-id'])
|
||||
for port in port_list]
|
||||
port_list = port_list_detail
|
||||
|
||||
result = [builder.build(port, port_details)['port']
|
||||
for port in ports]
|
||||
for port in port_list]
|
||||
return dict(ports=result)
|
||||
except exception.NetworkNotFound as e:
|
||||
return faults.Fault(faults.NetworkNotFound(e))
|
||||
|
||||
|
||||
def _item(self, request, tenant_id, network_id, port_id,
|
||||
att_details=False):
|
||||
""" Returns a specific port. """
|
||||
@ -88,11 +97,11 @@ class Controller(common.QuantumController):
|
||||
port_id = kwargs.get('id')
|
||||
if port_id:
|
||||
# show details for a given network
|
||||
return self._item(request, tenant_id,
|
||||
return self._item(request, tenant_id,
|
||||
network_id, port_id, att_details=True)
|
||||
else:
|
||||
# show details for all port
|
||||
return self._items(request, tenant_id,
|
||||
return self._items(request, tenant_id,
|
||||
network_id, port_details=True)
|
||||
|
||||
def create(self, request, tenant_id, network_id):
|
||||
|
@ -32,8 +32,8 @@ class ViewBuilder(object):
|
||||
def build(self, port_data, port_details=False, att_details=False):
|
||||
"""Generic method used to generate a port entity."""
|
||||
port = dict(port=dict(id=port_data['port-id']))
|
||||
if port_details:
|
||||
if port_details:
|
||||
port['port']['state'] = port_data['port-state']
|
||||
if att_details and port_data['attachment-id']:
|
||||
port['attachment'] = dict(id=port_data['attachment-id'])
|
||||
port['port']['attachment'] = dict(id=port_data['attachment-id'])
|
||||
return port
|
||||
|
@ -102,6 +102,12 @@ class PortInUse(QuantumException):
|
||||
"is plugged into the logical port.")
|
||||
|
||||
|
||||
class PortIsDown(QuantumException):
|
||||
message = _("Unable to perform operation on port %(port_id)s " \
|
||||
"for network %(net_id)s. The port is currently " \
|
||||
"administratively down.")
|
||||
|
||||
|
||||
class AlreadyAttached(QuantumException):
|
||||
message = _("Unable to plug the attachment %(att_id)s into port " \
|
||||
"%(port_id)s for network %(net_id)s. The attachment is " \
|
||||
|
@ -129,13 +129,13 @@ class Request(webob.Request):
|
||||
format = parts[1]
|
||||
if format in ['json', 'xml']:
|
||||
return 'application/{0}'.format(parts[1])
|
||||
|
||||
|
||||
#Then look up content header
|
||||
type_from_header = self.get_content_type()
|
||||
if type_from_header:
|
||||
return type_from_header
|
||||
ctypes = ['application/json', 'application/xml']
|
||||
|
||||
|
||||
#Finally search in Accept-* headers
|
||||
bm = self.accept.best_match(ctypes)
|
||||
return bm or 'application/json'
|
||||
|
@ -405,10 +405,13 @@ class FakePlugin(object):
|
||||
specified Virtual Network.
|
||||
"""
|
||||
LOG.debug("FakePlugin.plug_interface() called")
|
||||
port = self._get_port(tenant_id, net_id, port_id)
|
||||
# Verify port state
|
||||
if port['state'] == 'DOWN':
|
||||
raise exc.PortIsDown(net_id=net_id, port_id=port_id)
|
||||
# Validate attachment
|
||||
self._validate_attachment(tenant_id, net_id, port_id,
|
||||
remote_interface_id)
|
||||
port = self._get_port(tenant_id, net_id, port_id)
|
||||
if port['interface_id']:
|
||||
raise exc.PortInUse(net_id=net_id, port_id=port_id,
|
||||
att_id=port['interface_id'])
|
||||
|
@ -101,6 +101,25 @@ class APITest(unittest.TestCase):
|
||||
self.assertEqual(len(network_data['networks']), 2)
|
||||
LOG.debug("_test_list_networks - format:%s - END", format)
|
||||
|
||||
def _test_list_networks_detail(self, format):
|
||||
LOG.debug("_test_list_networks_detail - format:%s - START", format)
|
||||
content_type = "application/%s" % format
|
||||
self._create_network(format, "net_1")
|
||||
self._create_network(format, "net_2")
|
||||
list_network_req = testlib.network_list_detail_request(self.tenant_id,
|
||||
format)
|
||||
list_network_res = list_network_req.get_response(self.api)
|
||||
self.assertEqual(list_network_res.status_int, 200)
|
||||
network_data = self._net_serializer.deserialize(
|
||||
list_network_res.body, content_type)
|
||||
# Check network count: should return 2
|
||||
self.assertEqual(len(network_data['networks']), 2)
|
||||
# Check contents - id & name for each network
|
||||
for network in network_data['networks']:
|
||||
self.assertTrue('id' in network and 'name' in network)
|
||||
self.assertTrue(network['id'] and network['name'])
|
||||
LOG.debug("_test_list_networks_detail - format:%s - END", format)
|
||||
|
||||
def _test_show_network(self, format):
|
||||
LOG.debug("_test_show_network - format:%s - START", format)
|
||||
content_type = "application/%s" % format
|
||||
@ -117,6 +136,29 @@ class APITest(unittest.TestCase):
|
||||
network_data['network'])
|
||||
LOG.debug("_test_show_network - format:%s - END", format)
|
||||
|
||||
def _test_show_network_detail(self, format):
|
||||
LOG.debug("_test_show_network_detail - format:%s - START", format)
|
||||
content_type = "application/%s" % format
|
||||
# Create a network and a port
|
||||
network_id = self._create_network(format)
|
||||
port_id = self._create_port(network_id, "ACTIVE", format)
|
||||
show_network_req = testlib.show_network_detail_request(
|
||||
self.tenant_id, network_id, format)
|
||||
show_network_res = show_network_req.get_response(self.api)
|
||||
self.assertEqual(show_network_res.status_int, 200)
|
||||
network_data = self._net_serializer.deserialize(
|
||||
show_network_res.body, content_type)
|
||||
self.assertEqual({'id': network_id,
|
||||
'name': self.network_name,
|
||||
'ports': [
|
||||
{
|
||||
'id': port_id,
|
||||
'state': 'ACTIVE'
|
||||
}
|
||||
]},
|
||||
network_data['network'])
|
||||
LOG.debug("_test_show_network_detail - format:%s - END", format)
|
||||
|
||||
def _test_show_network_not_found(self, format):
|
||||
LOG.debug("_test_show_network_not_found - format:%s - START", format)
|
||||
show_network_req = testlib.show_network_request(self.tenant_id,
|
||||
@ -240,6 +282,27 @@ class APITest(unittest.TestCase):
|
||||
self.assertEqual(len(port_data['ports']), 2)
|
||||
LOG.debug("_test_list_ports - format:%s - END", format)
|
||||
|
||||
def _test_list_ports_detail(self, format):
|
||||
LOG.debug("_test_list_ports_detail - format:%s - START", format)
|
||||
content_type = "application/%s" % format
|
||||
port_state = "ACTIVE"
|
||||
network_id = self._create_network(format)
|
||||
self._create_port(network_id, port_state, format)
|
||||
self._create_port(network_id, port_state, format)
|
||||
list_port_req = testlib.port_list_detail_request(self.tenant_id,
|
||||
network_id, format)
|
||||
list_port_res = list_port_req.get_response(self.api)
|
||||
self.assertEqual(list_port_res.status_int, 200)
|
||||
port_data = self._port_serializer.deserialize(
|
||||
list_port_res.body, content_type)
|
||||
# Check port count: should return 2
|
||||
self.assertEqual(len(port_data['ports']), 2)
|
||||
# Check contents - id & name for each network
|
||||
for port in port_data['ports']:
|
||||
self.assertTrue('id' in port and 'state' in port)
|
||||
self.assertTrue(port['id'] and port['state'])
|
||||
LOG.debug("_test_list_ports_detail - format:%s - END", format)
|
||||
|
||||
def _test_show_port(self, format):
|
||||
LOG.debug("_test_show_port - format:%s - START", format)
|
||||
content_type = "application/%s" % format
|
||||
@ -257,6 +320,44 @@ class APITest(unittest.TestCase):
|
||||
port_data['port'])
|
||||
LOG.debug("_test_show_port - format:%s - END", format)
|
||||
|
||||
def _test_show_port_detail(self, format):
|
||||
LOG.debug("_test_show_port - format:%s - START", format)
|
||||
content_type = "application/%s" % format
|
||||
port_state = "ACTIVE"
|
||||
network_id = self._create_network(format)
|
||||
port_id = self._create_port(network_id, port_state, format)
|
||||
|
||||
# Part 1 - no attachment
|
||||
show_port_req = testlib.show_port_detail_request(self.tenant_id,
|
||||
network_id, port_id, format)
|
||||
show_port_res = show_port_req.get_response(self.api)
|
||||
self.assertEqual(show_port_res.status_int, 200)
|
||||
port_data = self._port_serializer.deserialize(
|
||||
show_port_res.body, content_type)
|
||||
self.assertEqual({'id': port_id, 'state': port_state},
|
||||
port_data['port'])
|
||||
|
||||
# Part 2 - plug attachment into port
|
||||
interface_id = "test_interface"
|
||||
put_attachment_req = testlib.put_attachment_request(self.tenant_id,
|
||||
network_id,
|
||||
port_id,
|
||||
interface_id,
|
||||
format)
|
||||
put_attachment_res = put_attachment_req.get_response(self.api)
|
||||
self.assertEqual(put_attachment_res.status_int, 204)
|
||||
show_port_req = testlib.show_port_detail_request(self.tenant_id,
|
||||
network_id, port_id, format)
|
||||
show_port_res = show_port_req.get_response(self.api)
|
||||
self.assertEqual(show_port_res.status_int, 200)
|
||||
port_data = self._port_serializer.deserialize(
|
||||
show_port_res.body, content_type)
|
||||
self.assertEqual({'id': port_id, 'state': port_state,
|
||||
'attachment': {'id': interface_id}},
|
||||
port_data['port'])
|
||||
|
||||
LOG.debug("_test_show_port_detail - format:%s - END", format)
|
||||
|
||||
def _test_show_port_networknotfound(self, format):
|
||||
LOG.debug("_test_show_port_networknotfound - format:%s - START",
|
||||
format)
|
||||
@ -580,6 +681,22 @@ class APITest(unittest.TestCase):
|
||||
LOG.debug("_test_put_attachment_portnotfound - format:%s - END",
|
||||
format)
|
||||
|
||||
def _test_put_attachment_portisdown(self, format):
|
||||
LOG.debug("_test_put_attachment_portisdown - format:%s - START",
|
||||
format)
|
||||
port_state = "DOWN"
|
||||
network_id = self._create_network(format)
|
||||
interface_id = "test_interface"
|
||||
port_id = self._create_port(network_id, port_state, format)
|
||||
put_attachment_req = testlib.put_attachment_request(self.tenant_id,
|
||||
network_id,
|
||||
port_id,
|
||||
interface_id,
|
||||
format)
|
||||
put_attachment_res = put_attachment_req.get_response(self.api)
|
||||
self.assertEqual(put_attachment_res.status_int, 433)
|
||||
LOG.debug("_test_put_attachment_portisdown - format:%s - END", format)
|
||||
|
||||
def _test_delete_attachment(self, format):
|
||||
LOG.debug("_test_delete_attachment - format:%s - START", format)
|
||||
port_state = "ACTIVE"
|
||||
@ -669,6 +786,12 @@ class APITest(unittest.TestCase):
|
||||
def test_list_networks_xml(self):
|
||||
self._test_list_networks('xml')
|
||||
|
||||
def test_list_networks_detail_json(self):
|
||||
self._test_list_networks_detail('json')
|
||||
|
||||
def test_list_networks_detail_xml(self):
|
||||
self._test_list_networks_detail('xml')
|
||||
|
||||
def test_create_network_json(self):
|
||||
self._test_create_network('json')
|
||||
|
||||
@ -693,6 +816,12 @@ class APITest(unittest.TestCase):
|
||||
def test_show_network_xml(self):
|
||||
self._test_show_network('xml')
|
||||
|
||||
def test_show_network_detail_json(self):
|
||||
self._test_show_network_detail('json')
|
||||
|
||||
def test_show_network_detail_xml(self):
|
||||
self._test_show_network_detail('xml')
|
||||
|
||||
def test_delete_network_json(self):
|
||||
self._test_delete_network('json')
|
||||
|
||||
@ -729,12 +858,24 @@ class APITest(unittest.TestCase):
|
||||
def test_list_ports_xml(self):
|
||||
self._test_list_ports('xml')
|
||||
|
||||
def test_list_ports_detail_json(self):
|
||||
self._test_list_ports_detail('json')
|
||||
|
||||
def test_list_ports_detail_xml(self):
|
||||
self._test_list_ports_detail('xml')
|
||||
|
||||
def test_show_port_json(self):
|
||||
self._test_show_port('json')
|
||||
|
||||
def test_show_port_xml(self):
|
||||
self._test_show_port('xml')
|
||||
|
||||
def test_show_port_detail_json(self):
|
||||
self._test_show_port_detail('json')
|
||||
|
||||
def test_show_port_detail_xml(self):
|
||||
self._test_show_port_detail('xml')
|
||||
|
||||
def test_show_port_networknotfound_json(self):
|
||||
self._test_show_port_networknotfound('json')
|
||||
|
||||
@ -855,6 +996,12 @@ class APITest(unittest.TestCase):
|
||||
def test_put_attachment_portnotfound_json(self):
|
||||
self._test_put_attachment_portnotfound('json')
|
||||
|
||||
def test_put_attachment_portisdown_xml(self):
|
||||
self._test_put_attachment_portisdown('xml')
|
||||
|
||||
def test_put_attachment_portisdown_json(self):
|
||||
self._test_put_attachment_portisdown('json')
|
||||
|
||||
def test_delete_attachment_xml(self):
|
||||
self._test_delete_attachment('xml')
|
||||
|
||||
|
@ -12,19 +12,38 @@ def create_request(path, body, content_type, method='GET'):
|
||||
return req
|
||||
|
||||
|
||||
def network_list_request(tenant_id, format='xml'):
|
||||
def _network_list_request(tenant_id, format='xml', detail=False):
|
||||
method = 'GET'
|
||||
path = "/tenants/%(tenant_id)s/networks.%(format)s" % locals()
|
||||
detail_str = detail and '/detail' or ''
|
||||
path = "/tenants/%(tenant_id)s/networks" \
|
||||
"%(detail_str)s.%(format)s" % locals()
|
||||
content_type = "application/%s" % format
|
||||
return create_request(path, None, content_type, method)
|
||||
|
||||
|
||||
def network_list_request(tenant_id, format='xml'):
|
||||
return _network_list_request(tenant_id, format)
|
||||
|
||||
|
||||
def network_list_detail_request(tenant_id, format='xml'):
|
||||
return _network_list_request(tenant_id, format, detail=True)
|
||||
|
||||
|
||||
def _show_network_request(tenant_id, network_id, format='xml', detail=False):
|
||||
method = 'GET'
|
||||
detail_str = detail and '/detail' or ''
|
||||
path = "/tenants/%(tenant_id)s/networks" \
|
||||
"/%(network_id)s%(detail_str)s.%(format)s" % locals()
|
||||
content_type = "application/%s" % format
|
||||
return create_request(path, None, content_type, method)
|
||||
|
||||
|
||||
def show_network_request(tenant_id, network_id, format='xml'):
|
||||
method = 'GET'
|
||||
path = "/tenants/%(tenant_id)s/networks" \
|
||||
"/%(network_id)s.%(format)s" % locals()
|
||||
content_type = "application/%s" % format
|
||||
return create_request(path, None, content_type, method)
|
||||
return _show_network_request(tenant_id, network_id, format)
|
||||
|
||||
|
||||
def show_network_detail_request(tenant_id, network_id, format='xml'):
|
||||
return _show_network_request(tenant_id, network_id, format, detail=True)
|
||||
|
||||
|
||||
def new_network_request(tenant_id, network_name='new_name',
|
||||
@ -56,20 +75,41 @@ def network_delete_request(tenant_id, network_id, format='xml'):
|
||||
return create_request(path, None, content_type, method)
|
||||
|
||||
|
||||
def port_list_request(tenant_id, network_id, format='xml'):
|
||||
def _port_list_request(tenant_id, network_id, format='xml', detail=False):
|
||||
method = 'GET'
|
||||
detail_str = detail and '/detail' or ''
|
||||
path = "/tenants/%(tenant_id)s/networks/" \
|
||||
"%(network_id)s/ports.%(format)s" % locals()
|
||||
"%(network_id)s/ports%(detail_str)s.%(format)s" % locals()
|
||||
content_type = "application/%s" % format
|
||||
return create_request(path, None, content_type, method)
|
||||
|
||||
|
||||
def port_list_request(tenant_id, network_id, format='xml'):
|
||||
return _port_list_request(tenant_id, network_id, format)
|
||||
|
||||
|
||||
def port_list_detail_request(tenant_id, network_id, format='xml'):
|
||||
return _port_list_request(tenant_id, network_id,
|
||||
format, detail=True)
|
||||
|
||||
|
||||
def _show_port_request(tenant_id, network_id, port_id,
|
||||
format='xml', detail=False):
|
||||
method = 'GET'
|
||||
detail_str = detail and '/detail' or ''
|
||||
path = "/tenants/%(tenant_id)s/networks/%(network_id)s" \
|
||||
"/ports/%(port_id)s%(detail_str)s.%(format)s" % locals()
|
||||
content_type = "application/%s" % format
|
||||
return create_request(path, None, content_type, method)
|
||||
|
||||
|
||||
def show_port_request(tenant_id, network_id, port_id, format='xml'):
|
||||
method = 'GET'
|
||||
path = "/tenants/%(tenant_id)s/networks/%(network_id)s" \
|
||||
"/ports/%(port_id)s.%(format)s" % locals()
|
||||
content_type = "application/%s" % format
|
||||
return create_request(path, None, content_type, method)
|
||||
return _show_port_request(tenant_id, network_id, port_id, format)
|
||||
|
||||
|
||||
def show_port_detail_request(tenant_id, network_id, port_id, format='xml'):
|
||||
return _show_port_request(tenant_id, network_id, port_id,
|
||||
format, detail=True)
|
||||
|
||||
|
||||
def new_port_request(tenant_id, network_id, port_state,
|
||||
|
Loading…
x
Reference in New Issue
Block a user