adding hypervisors panel to admin dashboard
This commit adds a new panel "Hypervisors" to the system panel in the admin dashboard listing all registered hypervisors hosts by using the os-hypervisors extension of the Nova API. fixes bug #1197763 Change-Id: I3f9a7858342c3592521b7fa8ecf17e2fb5af6cda
This commit is contained in:
parent
8bca5a4705
commit
f678336cd7
@ -575,6 +575,10 @@ def instance_volumes_list(request, instance_id):
|
||||
return volumes
|
||||
|
||||
|
||||
def hypervisor_list(request):
|
||||
return novaclient(request).hypervisors.list()
|
||||
|
||||
|
||||
def tenant_absolute_limits(request, reserved=False):
|
||||
limits = novaclient(request).limits.get(reserved=reserved).absolute
|
||||
limits_dict = {}
|
||||
|
@ -22,7 +22,7 @@ import horizon
|
||||
class SystemPanels(horizon.PanelGroup):
|
||||
slug = "admin"
|
||||
name = _("System Panel")
|
||||
panels = ('overview', 'instances', 'volumes', 'flavors',
|
||||
panels = ('overview', 'hypervisors', 'instances', 'volumes', 'flavors',
|
||||
'images', 'domains', 'projects', 'users', 'groups',
|
||||
'roles', 'networks', 'routers', 'info')
|
||||
|
||||
|
29
openstack_dashboard/dashboards/admin/hypervisors/panel.py
Normal file
29
openstack_dashboard/dashboards/admin/hypervisors/panel.py
Normal file
@ -0,0 +1,29 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2013 B1 Systems GmbH
|
||||
#
|
||||
# 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.
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
import horizon
|
||||
from openstack_dashboard.dashboards.admin import dashboard
|
||||
|
||||
|
||||
class Hypervisors(horizon.Panel):
|
||||
name = _("Hypervisors")
|
||||
slug = 'hypervisors'
|
||||
permissions = ('openstack.roles.admin',)
|
||||
|
||||
|
||||
dashboard.Admin.register(Hypervisors)
|
75
openstack_dashboard/dashboards/admin/hypervisors/tables.py
Normal file
75
openstack_dashboard/dashboards/admin/hypervisors/tables.py
Normal file
@ -0,0 +1,75 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2013 B1 Systems GmbH
|
||||
#
|
||||
# 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.
|
||||
|
||||
import logging
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from horizon import tables
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_memory(hypervisor):
|
||||
return _("%s MB") % hypervisor.memory_mb
|
||||
|
||||
|
||||
def get_memory_used(hypervisor):
|
||||
return _("%s MB") % hypervisor.memory_mb_used
|
||||
|
||||
|
||||
def get_local(hypervisor):
|
||||
return _("%s GB") % hypervisor.local_gb
|
||||
|
||||
|
||||
def get_local_used(hypervisor):
|
||||
return _("%s GB") % hypervisor.local_gb_used
|
||||
|
||||
|
||||
class AdminHypervisorsTable(tables.DataTable):
|
||||
hypervisor_hostname = tables.Column("hypervisor_hostname",
|
||||
verbose_name=_("Hostname"))
|
||||
|
||||
hypervisor_type = tables.Column("hypervisor_type",
|
||||
verbose_name=_("Type"))
|
||||
|
||||
vcpus = tables.Column("vcpus",
|
||||
verbose_name=_("VCPUs (total)"))
|
||||
|
||||
vcpus_used = tables.Column("vcpus_used",
|
||||
verbose_name=_("VCPUs (used)"))
|
||||
|
||||
memory = tables.Column(get_memory,
|
||||
verbose_name=_("RAM (total)"),
|
||||
attrs={'data-type': 'size'})
|
||||
|
||||
memory_used = tables.Column(get_memory_used,
|
||||
verbose_name=_("RAM (used)"),
|
||||
attrs={'data-type': 'size'})
|
||||
|
||||
local = tables.Column(get_local,
|
||||
verbose_name=_("Storage (total)"),
|
||||
attrs={'data-type': 'size'})
|
||||
|
||||
local_used = tables.Column(get_local_used,
|
||||
verbose_name=_("Storage (used)"),
|
||||
attrs={'data-type': 'size'})
|
||||
|
||||
running_vms = tables.Column("running_vms",
|
||||
verbose_name=_("Instances"))
|
||||
|
||||
class Meta:
|
||||
name = "hypervisors"
|
||||
verbose_name = _("Hypervisors")
|
@ -0,0 +1,11 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Hypervisors" %}{% endblock %}
|
||||
|
||||
{% block page_header %}
|
||||
{% include "horizon/common/_page_header.html" with title=_("All Hypervisors") %}
|
||||
{% endblock page_header %}
|
||||
|
||||
{% block main %}
|
||||
{{ table.render }}
|
||||
{% endblock %}
|
34
openstack_dashboard/dashboards/admin/hypervisors/tests.py
Normal file
34
openstack_dashboard/dashboards/admin/hypervisors/tests.py
Normal file
@ -0,0 +1,34 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2013 B1 Systems GmbH
|
||||
#
|
||||
# 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.
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
from django import http
|
||||
from mox import IsA
|
||||
|
||||
from openstack_dashboard import api
|
||||
from openstack_dashboard.test import helpers as test
|
||||
|
||||
|
||||
class HypervisorViewTest(test.BaseAdminViewTests):
|
||||
@test.create_stubs({api.nova: ('hypervisor_list',)})
|
||||
def test_index(self):
|
||||
hypervisors = self.hypervisors.list()
|
||||
api.nova.hypervisor_list(IsA(http.HttpRequest)).AndReturn(hypervisors)
|
||||
self.mox.ReplayAll()
|
||||
|
||||
res = self.client.get(reverse('horizon:admin:hypervisors:index'))
|
||||
self.assertTemplateUsed(res, 'admin/hypervisors/index.html')
|
||||
self.assertItemsEqual(res.context['table'].data, hypervisors)
|
26
openstack_dashboard/dashboards/admin/hypervisors/urls.py
Normal file
26
openstack_dashboard/dashboards/admin/hypervisors/urls.py
Normal file
@ -0,0 +1,26 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2013 B1 Systems GmbH
|
||||
#
|
||||
# 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.
|
||||
|
||||
from django.conf.urls.defaults import patterns
|
||||
from django.conf.urls.defaults import url
|
||||
|
||||
from .views import AdminIndexView
|
||||
|
||||
|
||||
urlpatterns = patterns(
|
||||
'openstack_dashboard.dashboards.admin.hypervisors.views',
|
||||
url(r'^$', AdminIndexView.as_view(), name='index')
|
||||
)
|
42
openstack_dashboard/dashboards/admin/hypervisors/views.py
Normal file
42
openstack_dashboard/dashboards/admin/hypervisors/views.py
Normal file
@ -0,0 +1,42 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2013 B1 Systems GmbH
|
||||
#
|
||||
# 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.
|
||||
|
||||
import logging
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import exceptions
|
||||
from horizon import tables
|
||||
from openstack_dashboard import api
|
||||
from openstack_dashboard.dashboards.admin.hypervisors.tables import \
|
||||
AdminHypervisorsTable
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class AdminIndexView(tables.DataTableView):
|
||||
table_class = AdminHypervisorsTable
|
||||
template_name = 'admin/hypervisors/index.html'
|
||||
|
||||
def get_data(self):
|
||||
hypervisors = []
|
||||
try:
|
||||
hypervisors = api.nova.hypervisor_list(self.request)
|
||||
except:
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to retrieve hypervisor list.'))
|
||||
|
||||
return hypervisors
|
@ -19,6 +19,7 @@ from novaclient.v1_1 import availability_zones
|
||||
from novaclient.v1_1 import certs
|
||||
from novaclient.v1_1 import flavors
|
||||
from novaclient.v1_1 import floating_ips
|
||||
from novaclient.v1_1 import hypervisors
|
||||
from novaclient.v1_1 import keypairs
|
||||
from novaclient.v1_1 import quotas
|
||||
from novaclient.v1_1 import security_group_rules as rules
|
||||
@ -162,6 +163,7 @@ def data(TEST):
|
||||
TEST.volume_snapshots = TestDataContainer()
|
||||
TEST.volume_types = TestDataContainer()
|
||||
TEST.availability_zones = TestDataContainer()
|
||||
TEST.hypervisors = TestDataContainer()
|
||||
|
||||
# Data return by novaclient.
|
||||
# It is used if API layer does data conversion.
|
||||
@ -483,3 +485,30 @@ def data(TEST):
|
||||
{'zoneName': 'nova', 'zoneState': {'available': True}}
|
||||
)
|
||||
)
|
||||
|
||||
# hypervisors
|
||||
hypervisor_1 = hypervisors.Hypervisor(hypervisors.HypervisorManager(None),
|
||||
{
|
||||
"service": {"host": "devstack001", "id": 3},
|
||||
"vcpus_used": 1,
|
||||
"hypervisor_type": "QEMU",
|
||||
"local_gb_used": 20,
|
||||
"hypervisor_hostname": "devstack001",
|
||||
"memory_mb_used": 1500,
|
||||
"memory_mb": 2000,
|
||||
"current_workload": 0,
|
||||
"vcpus": 1,
|
||||
"cpu_info": '{"vendor": "Intel", "model": "core2duo",'
|
||||
'"arch": "x86_64", "features": ["lahf_lm"'
|
||||
', "rdtscp"], "topology": {"cores": 1, "t'
|
||||
'hreads": 1, "sockets": 1}}',
|
||||
"running_vms": 1,
|
||||
"free_disk_gb": 9,
|
||||
"hypervisor_version": 1002000,
|
||||
"disk_available_least": 6,
|
||||
"local_gb": 29,
|
||||
"free_ram_mb": 500,
|
||||
"id": 1
|
||||
}
|
||||
)
|
||||
TEST.hypervisors.add(hypervisor_1)
|
||||
|
Loading…
Reference in New Issue
Block a user