added Network Agents to System Info panel
Added a new tab to the System Info panel showing all Network Agents. fixes bug #1204375 Change-Id: I9c23105dde8528749275aba70065384dec354fb7
This commit is contained in:
parent
bef4ee0489
commit
240419544f
|
@ -54,6 +54,15 @@ class NeutronAPIDictWrapper(base.APIDictWrapper):
|
||||||
return self._apidict.items()
|
return self._apidict.items()
|
||||||
|
|
||||||
|
|
||||||
|
class Agent(NeutronAPIDictWrapper):
|
||||||
|
"""Wrapper for neutron agents"""
|
||||||
|
|
||||||
|
def __init__(self, apiresource):
|
||||||
|
apiresource['admin_state'] = \
|
||||||
|
'UP' if apiresource['admin_state_up'] else 'DOWN'
|
||||||
|
super(Agent, self).__init__(apiresource)
|
||||||
|
|
||||||
|
|
||||||
class Network(NeutronAPIDictWrapper):
|
class Network(NeutronAPIDictWrapper):
|
||||||
"""Wrapper for neutron Networks"""
|
"""Wrapper for neutron Networks"""
|
||||||
|
|
||||||
|
@ -627,6 +636,11 @@ def list_extensions(request):
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|
||||||
|
def agent_list(request):
|
||||||
|
agents = neutronclient(request).list_agents()
|
||||||
|
return [Agent(a) for a in agents['agents']]
|
||||||
|
|
||||||
|
|
||||||
def is_extension_supported(request, extension_alias):
|
def is_extension_supported(request, extension_alias):
|
||||||
extensions = list_extensions(request)
|
extensions = list_extensions(request)
|
||||||
|
|
||||||
|
|
|
@ -149,3 +149,50 @@ class AggregatesTable(tables.DataTable):
|
||||||
class Meta:
|
class Meta:
|
||||||
name = "aggregates"
|
name = "aggregates"
|
||||||
verbose_name = _("Host Aggregates")
|
verbose_name = _("Host Aggregates")
|
||||||
|
|
||||||
|
|
||||||
|
class NetworkAgentsFilterAction(tables.FilterAction):
|
||||||
|
def filter(self, table, agents, filter_string):
|
||||||
|
q = filter_string.lower()
|
||||||
|
|
||||||
|
def comp(agent):
|
||||||
|
if q in agent.agent_type.lower():
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
return filter(comp, agents)
|
||||||
|
|
||||||
|
|
||||||
|
def get_network_agent_status(agent):
|
||||||
|
if agent.admin_state_up:
|
||||||
|
return 'enabled'
|
||||||
|
|
||||||
|
return 'disabled'
|
||||||
|
|
||||||
|
|
||||||
|
def get_network_agent_state(agent):
|
||||||
|
if agent.alive:
|
||||||
|
return 'up'
|
||||||
|
|
||||||
|
return 'down'
|
||||||
|
|
||||||
|
|
||||||
|
class NetworkAgentsTable(tables.DataTable):
|
||||||
|
agent_type = tables.Column('agent_type', verbose_name=_('Type'))
|
||||||
|
binary = tables.Column("binary", verbose_name=_('Name'))
|
||||||
|
host = tables.Column('host', verbose_name=_('Host'))
|
||||||
|
status = tables.Column(get_network_agent_status, verbose_name=_('Status'))
|
||||||
|
state = tables.Column(get_network_agent_state, verbose_name=_('State'))
|
||||||
|
heartbeat_timestamp = tables.Column('heartbeat_timestamp',
|
||||||
|
verbose_name=_('Updated At'),
|
||||||
|
filters=(utils_filters.parse_isotime,
|
||||||
|
filters.timesince))
|
||||||
|
|
||||||
|
def get_object_id(self, obj):
|
||||||
|
return "%s-%s" % (obj.binary, obj.host)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
name = "network_agents"
|
||||||
|
verbose_name = _("Network Agents")
|
||||||
|
table_actions = (NetworkAgentsFilterAction,)
|
||||||
|
multi_select = False
|
||||||
|
|
|
@ -19,7 +19,9 @@ from django.utils.translation import ugettext_lazy as _ # noqa
|
||||||
from horizon import exceptions
|
from horizon import exceptions
|
||||||
from horizon import tabs
|
from horizon import tabs
|
||||||
|
|
||||||
|
from openstack_dashboard.api import base
|
||||||
from openstack_dashboard.api import keystone
|
from openstack_dashboard.api import keystone
|
||||||
|
from openstack_dashboard.api import neutron
|
||||||
from openstack_dashboard.api import nova
|
from openstack_dashboard.api import nova
|
||||||
|
|
||||||
from openstack_dashboard.dashboards.admin.info import tables
|
from openstack_dashboard.dashboards.admin.info import tables
|
||||||
|
@ -92,7 +94,30 @@ class NovaServicesTab(tabs.TableTab):
|
||||||
return services
|
return services
|
||||||
|
|
||||||
|
|
||||||
|
class NetworkAgentsTab(tabs.TableTab):
|
||||||
|
table_classes = (tables.NetworkAgentsTable,)
|
||||||
|
name = _("Network Agents")
|
||||||
|
slug = "network_agents"
|
||||||
|
template_name = ("horizon/common/_detail_table.html")
|
||||||
|
|
||||||
|
def allowed(self, request):
|
||||||
|
return base.is_service_enabled(request, 'network')
|
||||||
|
|
||||||
|
def get_network_agents_data(self):
|
||||||
|
try:
|
||||||
|
agents = neutron.agent_list(self.tab_group.request)
|
||||||
|
except Exception:
|
||||||
|
agents = []
|
||||||
|
msg = _('Unable to get network agents list.')
|
||||||
|
exceptions.check_message(["Connection", "refused"], msg)
|
||||||
|
raise
|
||||||
|
|
||||||
|
return agents
|
||||||
|
|
||||||
|
|
||||||
class SystemInfoTabs(tabs.TabGroup):
|
class SystemInfoTabs(tabs.TabGroup):
|
||||||
slug = "system_info"
|
slug = "system_info"
|
||||||
tabs = (ServicesTab, NovaServicesTab, ZonesTab, HostAggregatesTab)
|
tabs = (ServicesTab, NovaServicesTab,
|
||||||
|
ZonesTab, HostAggregatesTab,
|
||||||
|
NetworkAgentsTab)
|
||||||
sticky = True
|
sticky = True
|
||||||
|
|
|
@ -28,7 +28,8 @@ class SystemInfoViewTests(test.BaseAdminViewTests):
|
||||||
|
|
||||||
@test.create_stubs({api.nova: ('service_list',
|
@test.create_stubs({api.nova: ('service_list',
|
||||||
'availability_zone_list',
|
'availability_zone_list',
|
||||||
'aggregate_list')})
|
'aggregate_list'),
|
||||||
|
api.neutron: ('agent_list',)})
|
||||||
def test_index(self):
|
def test_index(self):
|
||||||
services = self.services.list()
|
services = self.services.list()
|
||||||
api.nova.service_list(IsA(http.HttpRequest)).AndReturn(services)
|
api.nova.service_list(IsA(http.HttpRequest)).AndReturn(services)
|
||||||
|
@ -36,6 +37,8 @@ class SystemInfoViewTests(test.BaseAdminViewTests):
|
||||||
.AndReturn(self.availability_zones.list())
|
.AndReturn(self.availability_zones.list())
|
||||||
api.nova.aggregate_list(IsA(http.HttpRequest)) \
|
api.nova.aggregate_list(IsA(http.HttpRequest)) \
|
||||||
.AndReturn(self.aggregates.list())
|
.AndReturn(self.aggregates.list())
|
||||||
|
agents = self.agents.list()
|
||||||
|
api.neutron.agent_list(IsA(http.HttpRequest)).AndReturn(agents)
|
||||||
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
@ -63,3 +66,9 @@ class SystemInfoViewTests(test.BaseAdminViewTests):
|
||||||
aggregates_tab = res.context['tab_group'].get_tab('aggregates')
|
aggregates_tab = res.context['tab_group'].get_tab('aggregates')
|
||||||
self.assertQuerysetEqual(aggregates_tab._tables['aggregates'].data,
|
self.assertQuerysetEqual(aggregates_tab._tables['aggregates'].data,
|
||||||
['<Aggregate: 1>', '<Aggregate: 2>'])
|
['<Aggregate: 1>', '<Aggregate: 2>'])
|
||||||
|
|
||||||
|
network_agents_tab = res.context['tab_group'].get_tab('network_agents')
|
||||||
|
self.assertQuerysetEqual(
|
||||||
|
network_agents_tab._tables['network_agents'].data,
|
||||||
|
[agent.__repr__() for agent in self.agents.list()]
|
||||||
|
)
|
||||||
|
|
|
@ -24,6 +24,7 @@ from openstack_dashboard.test.test_data import utils
|
||||||
|
|
||||||
def data(TEST):
|
def data(TEST):
|
||||||
# data returned by openstack_dashboard.api.neutron wrapper
|
# data returned by openstack_dashboard.api.neutron wrapper
|
||||||
|
TEST.agents = utils.TestDataContainer()
|
||||||
TEST.networks = utils.TestDataContainer()
|
TEST.networks = utils.TestDataContainer()
|
||||||
TEST.subnets = utils.TestDataContainer()
|
TEST.subnets = utils.TestDataContainer()
|
||||||
TEST.ports = utils.TestDataContainer()
|
TEST.ports = utils.TestDataContainer()
|
||||||
|
@ -38,6 +39,7 @@ def data(TEST):
|
||||||
TEST.neutron_quotas = utils.TestDataContainer()
|
TEST.neutron_quotas = utils.TestDataContainer()
|
||||||
|
|
||||||
# data return by neutronclient
|
# data return by neutronclient
|
||||||
|
TEST.api_agents = utils.TestDataContainer()
|
||||||
TEST.api_networks = utils.TestDataContainer()
|
TEST.api_networks = utils.TestDataContainer()
|
||||||
TEST.api_subnets = utils.TestDataContainer()
|
TEST.api_subnets = utils.TestDataContainer()
|
||||||
TEST.api_ports = utils.TestDataContainer()
|
TEST.api_ports = utils.TestDataContainer()
|
||||||
|
@ -473,3 +475,42 @@ def data(TEST):
|
||||||
extensions = {}
|
extensions = {}
|
||||||
extensions['extensions'] = [extension_1, extension_2]
|
extensions['extensions'] = [extension_1, extension_2]
|
||||||
TEST.api_extensions.add(extensions)
|
TEST.api_extensions.add(extensions)
|
||||||
|
|
||||||
|
#------------------------------------------------------------
|
||||||
|
# 1st agent
|
||||||
|
agent_dict = {"binary": "neutron-openvswitch-agent",
|
||||||
|
"description": None,
|
||||||
|
"admin_state_up": True,
|
||||||
|
"heartbeat_timestamp": "2013-07-26 06:51:47",
|
||||||
|
"alive": True,
|
||||||
|
"id": "c876ff05-f440-443e-808c-1d34cda3e88a",
|
||||||
|
"topic": "N/A",
|
||||||
|
"host": "devstack001",
|
||||||
|
"agent_type": "Open vSwitch agent",
|
||||||
|
"started_at": "2013-07-26 05:23:28",
|
||||||
|
"created_at": "2013-07-26 05:23:28",
|
||||||
|
"configurations": {"devices": 2}}
|
||||||
|
TEST.api_agents.add(agent_dict)
|
||||||
|
TEST.agents.add(neutron.Agent(agent_dict))
|
||||||
|
|
||||||
|
# 2nd agent
|
||||||
|
agent_dict = {"binary": "neutron-dhcp-agent",
|
||||||
|
"description": None,
|
||||||
|
"admin_state_up": True,
|
||||||
|
"heartbeat_timestamp": "2013-07-26 06:51:48",
|
||||||
|
"alive": True,
|
||||||
|
"id": "f0d12e3d-1973-41a2-b977-b95693f9a8aa",
|
||||||
|
"topic": "dhcp_agent",
|
||||||
|
"host": "devstack001",
|
||||||
|
"agent_type": "DHCP agent",
|
||||||
|
"started_at": "2013-07-26 05:23:30",
|
||||||
|
"created_at": "2013-07-26 05:23:30",
|
||||||
|
"configurations": {
|
||||||
|
"subnets": 1,
|
||||||
|
"use_namespaces": True,
|
||||||
|
"dhcp_lease_duration": 120,
|
||||||
|
"dhcp_driver": "neutron.agent.linux.dhcp.Dnsmasq",
|
||||||
|
"networks": 1,
|
||||||
|
"ports": 1}}
|
||||||
|
TEST.api_agents.add(agent_dict)
|
||||||
|
TEST.agents.add(neutron.Agent(agent_dict))
|
||||||
|
|
Loading…
Reference in New Issue