Steps to reproduce:
1. Create network and subnet.
2. Open network overview page.
3. Delete subnet. Port remains existing.
4. Click port overview. The folowing error is displayed:
Traceback:
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
111. response = callback(request, *callback_args, **callback_kwargs)
File "/opt/stack/horizon/openstack_dashboard/wsgi/../../horizon/decorators.py" in dec
38. return view_func(request, *args, **kwargs)
File "/opt/stack/horizon/openstack_dashboard/wsgi/../../horizon/decorators.py" in dec
54. return view_func(request, *args, **kwargs)
File "/opt/stack/horizon/openstack_dashboard/wsgi/../../horizon/decorators.py" in dec
38. return view_func(request, *args, **kwargs)
File "/opt/stack/horizon/openstack_dashboard/wsgi/../../horizon/decorators.py" in dec
86. return view_func(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/views/generic/base.py" in view
48. return self.dispatch(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/views/generic/base.py" in dispatch
69. return handler(request, *args, **kwargs)
File "/opt/stack/horizon/openstack_dashboard/wsgi/../../horizon/tabs/views.py" in get
60. context = self.get_context_data(**kwargs)
File "/opt/stack/horizon/openstack_dashboard/wsgi/../../horizon/tabs/views.py" in get_context_data
44. exceptions.handle(self.request)
File "/opt/stack/horizon/openstack_dashboard/wsgi/../../horizon/tabs/views.py" in get_context_data
42. context["tab_group"].load_tab_data()
File "/opt/stack/horizon/openstack_dashboard/wsgi/../../horizon/tabs/base.py" in load_tab_data
122. exceptions.handle(self.request)
File "/opt/stack/horizon/openstack_dashboard/wsgi/../../horizon/tabs/base.py" in load_tab_data
119. tab._data = tab.get_context_data(self.request)
File "/opt/stack/horizon/openstack_dashboard/wsgi/../../openstack_dashboard/dashboards/project/networks/ports/tabs.py" in get_context_data
43. exceptions.handle(request, msg, redirect=redirect)
File "/opt/stack/horizon/openstack_dashboard/wsgi/../../openstack_dashboard/dashboards/project/networks/ports/tabs.py" in get_context_data
39. port = api.quantum.port_get(self.request, port_id)
File "/opt/stack/horizon/openstack_dashboard/wsgi/../../openstack_dashboard/api/quantum.py" in port_get
352. port = quantumclient(request).show_port(port_id, **params).get('port')
File "/opt/stack/python-quantumclient/quantumclient/v2_0/client.py" in with_params
106. ret = self.function(instance, *args, **kwargs)
File "/opt/stack/python-quantumclient/quantumclient/v2_0/client.py" in show_port
252. return self.get(self.port_path % (port), params=_params)
File "/opt/stack/python-quantumclient/quantumclient/v2_0/client.py" in get
817. headers=headers, params=params)
File "/opt/stack/python-quantumclient/quantumclient/v2_0/client.py" in retry_request
802. headers=headers, params=params)
File "/opt/stack/python-quantumclient/quantumclient/v2_0/client.py" in do_request
747. self._handle_fault_response(status_code, replybody)
File "/opt/stack/python-quantumclient/quantumclient/v2_0/client.py" in _handle_fault_response
728. exception_handler_v20(status_code, des_error_body)
File "/opt/stack/python-quantumclient/quantumclient/v2_0/client.py" in exception_handler_v20
79. message=error_dict)
Exception Type: QuantumClientException at /project/networks/ports/53366faf-55ef-4a63-91d9-6d3a817d8837/detail
Exception Value: Port 53366faf-55ef-4a63-91d9-6d3a817d8837 could not be found on network None
I investigated the problem.
In Neutron/Quantum, a dhcp port for a subnet is deleted automatically when the subnet is deleted. This deletion of the dhcp port is done asynchronously.
As a result, when Horizon retrieves the network detail just after the subnet deletion succeeds, the dhcp port being deleted is displayed and when you click the port the port has disappeared.
IMO, we need to change both neutron side and horizon side to address this issue.
Neutron needs to introduce the new status for a port which indicates it is being deleted.
On Horizon side, we need to update the list based on its status as the instance list does.
What do you think?