horizon源码修改_增加计算节点列表 并可查看某计算节点下所有的虚拟机

来源:互联网 发布:crm软件开发 编辑:程序博客网 时间:2024/04/30 15:54

实现功能:

增加一个计算节点列表,并连接到该计算节点的所有虚拟机列表

 因为目前没有取得计算几点的api。所以这个功能目前先按照实例列表中过滤存在实例的主机列表。 点击主机名称进入查找该主机下的所有实例列表

 

1.增加菜单(主机)

参照http://blog.csdn.net/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'),

 

 4.nova.py
主机列表视图需要取得所有的实例列表,然后每个主机取一条。这样过滤出存在实例的主机列表
注意,api返回的实例数据格式为[<horizon.api.nova.Server object at 0x7f9d85602c10>, <horizon.api.nova.Server object at 0x7f9d85602b10>]
要想从中取出host名称,需要在api的Server了增加一个属性def host_name(self):
 
修改horizon/api/nova.py

 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 %}

原创粉丝点击