实现功能:
增加一个计算节点列表,并连接到该计算节点的所有虚拟机列表
因为目前没有取得计算几点的api。所以这个功能目前先按照实例列表中过滤存在实例的主机列表。 点击主机名称进入查找该主机下的所有实例列表
1.增加菜单(主机)
参照http://blog.youkuaiyun.com/washli2001/article/details/8331441
horizon源码修改——加菜单和菜单汉化
2.控制页面上内容显示(只显示主机列)
tables.py
增加一个类:主机列表类
class SyspanelHostsTable(tables.DataTable):
tenant = tables.Column("tenant_name", link="horizon:nova:instances_and_volumes:" \
"instances:detail",
verbose_name=_("Tenant"))
host = tables.Column("OS-EXT-SRV-ATTR:host",#link="horizon:nova:instances_and_volumes:instances:detail",
#link="instance",
link="horizon:syspanel:hosts:instance",
verbose_name=_("Host"),
classes=('nowrap-col',))
name = tables.Column("name", link="horizon:nova:instances_and_volumes:" \
"instances:detail",
verbose_name=_("Instance Name"))
class Meta:
name = "instances"
verbose_name = _("Instances")
columns = ("host",)
如果控制显示列数有2个方法
1.删除这里面的某一列
如虚拟机列表只显示
class SyspanelHostsTable(tables.DataTable):
tenant = tables.Column("tenant_name", verbose_name=_("Tenant"))
host = tables.Column("OS-EXT-SRV-ATTR:host",
verbose_name=_("Host"),
classes=('nowrap-col',)
, link = "horizon:syspanel:hosts:index")
name = tables.Column("name", link="horizon:nova:instances_and_volumes:" \
"instances:detail",
verbose_name=_("Instance Name"))
这里可以删除name和tenant ,不显示name 也可以用下面的方法columns = ("host", "tenant")
2.在Table类的class Meta:
增加columns属性
class Meta:
name = "instances"
verbose_name = _("Instances")
multi_select = True
columns = ("host",)#columns = ("host", "tenant")
注意:只显示一列的时候,括号里边必须带逗号(,)
multi_select = False #True 列表前面的多选按钮是否显示
列表如果连接到一个地址,点击主机项跳转到该主机下所有的实例列表
host = tables.Column("OS-EXT-SRV-ATTR:host
link="horizon:syspanel:hosts:instance",
verbose_name=_("Host"),
classes=('nowrap-col',))
注意“连接参数好像只能是instanceid (主键为传递参数,以位置为传递参数的方法正在找)
上面link要写全,否则不能跟上参数,不能只写link = "instance"
3.URLConf
urls.py
from 增加AdminHostsView
from .views import DetailView, AdminIndexView ,AdminHostsView
INSTANCES = r'^(?P<instance_id>[^/]+)/%s$'
修改indexurl为跳转到主机列表页
url(r'^$', AdminHostsView.as_view(), name='index'),
增加下面内容,(主键为传递参数,以位置为传递参数的方法正在找)
url(INSTANCES % 'instance', AdminIndexView.as_view(), name='instance'),
Server类如下
class Server(APIResourceWrapper):
增加一个属性:host_name
@property
def host_name(self):
return getattr(self, 'OS-EXT-SRV-ATTR:host', "")
这样views.py中就可以直接使用host_name属性了。
因为还有一个需求就是实例列表加入分页,所以在nova.py
server_list中增加了分页。
如果过滤主机显然需要取全部数据
于是在nova.py中增加方法server_list_all 该方法复制最原始的server_list方法。
5.views.py
增加
from horizon.dashboards.syspanel.hosts.tables import SyspanelInstancesTable
from horizon.dashboards.syspanel.hosts.tables import SyspanelHostsTable
class AdminHostsView(tables.DataTableView):
table_class = SyspanelHostsTable
template_name = 'syspanel/hosts/index.html'
中过滤主机的实现方法
def get_data(self):
instances = []
instances2 = []
try:
instances = api.nova.server_list_all(self.request, all_tenants=True)
except:
exceptions.handle(self.request,
_('Unable to retrieve instance list.'))
if instances:
for inst in instances:
hflag = 0
if len(instances2)==0:
instances2.append(inst)
else:
for inst2 in instances2:
if inst.host_name == inst2.host_name:
hflag = 1
if hflag ==0:
instances2.append(inst)
#LOG.error(instances2)
return instances2
点击一个主机名字进入实例列表页面实现
class AdminIndexView(tables.DataTableView):
table_class = SyspanelInstancesTable
template_name = 'syspanel/hosts/index.html'
def get_data(self):修改为get_data(self , *args, **kwargs):
def get_data(self , *args, **kwargs):
instances = []
search_opts = {}
instance_id = self.kwargs["instance_id"]
if not hasattr(self, "instance"):
instance = api.server_get(self.request,instance_id)
search_opts["host"] =instance.host_name
try:
instances = api.nova.server_list(self.request, search_opts, all_tenants=True)
except:
exceptions.handle(self.request,
_('Unable to retrieve instance list.'))
if instances:
# Gather our flavors to correlate against IDs
try:
flavors = api.nova.flavor_list(self.request)
except:
flavors = []
msg = _('Unable to retrieve instance size information.')
exceptions.handle(self.request, msg)
# Gather our tenants to correlate against IDs
try:
tenants = api.keystone.tenant_list(self.request, admin=True)
except:
tenants = []
msg = _('Unable to retrieve instance tenant information.')
exceptions.handle(self.request, msg)
full_flavors = SortedDict([(f.id, f) for f in flavors])
tenant_dict = SortedDict([(t.id, t) for t in tenants])
for inst in instances:
inst.full_flavor = full_flavors.get(inst.flavor["id"], None)
tenant = tenant_dict.get(inst.tenant_id, None)
inst.tenant_name = getattr(tenant, "name", None)
return instances
6.页面文件
horizon/dashboards/syspanel/templates/syspanel/hosts
index.html
{% extends 'syspanel/base.html' %}
{% load i18n %}
{% block title %}Instance {% endblock %}
{% block page_header %}
{% url horizon:syspanel:hosts:index as refresh_link %}
{# to make searchable false, just remove it from the include statement #}
{% include "horizon/common/_page_header.html" with title=_("Instances") refresh_link=refresh_link searchable="true" %}
{% endblock page_header %}
{% block syspanel_main %}
{{ table.render}}
{% endblock %}
hosts.html
{% extends 'syspanel/base.html' %}
{% load i18n %}
{% block title %}Host{% endblock %}
{% block page_header %}
{% url horizon:syspanel:hosts:index as refresh_link %}
{# to make searchable false, just remove it from the include statement #}
{% include "horizon/common/_page_header.html" with title=_("Host") refresh_link=refresh_link searchable="true" %}
{% endblock page_header %}
{% block syspanel_main %}
{{ table.render}}
{% endblock %}