本章的主要内容是如何用horizon的navigation结构添加一个应用的面板。

Horizon中提供了两种为应用添加panel的方法,一种是通过Pluggable Settings的方式,另一种是Django’s INSTALLED_APPS setting 方式。方式一是Horizon在Django框架基础上自主开发的方式,openstack中horizon的指导文档推荐使用方法一。而两种方式从功能上是等效的。本章重点分析pluggable setting这种方式,来看看它有多么cool吧。

当同时使用两种方式(setting dashboard和pluggable dashboard)时,setting dashboard的优先级是大于pluggable dashboard的,这个细节了解即可。为了避免不必要的麻烦,尽量不要两种方式混用。

先写一句总结的话,无论是添加一个Dashboard还是Panelgroup还是Panel。两步走:1.配置 2.根据配置填写相应的实例

然后不要急,在写如何添加dashboard和panel之前,先看看它们之间的关系:

panelgroup和panel一定是在某个dashboard下的,也就是创建一个panelgroup和panel必须指定一个已经存在了的dashboard。而panel指定panelgroup这个过程是不必须的,也就是panel可以直接在某个dashboard下。

接下来看添加dashboard、panelgroup、panel的共同步骤“配置”是什么。

引用官方文档中的说明:

Horizon allows dashboards, panels and panel groups to be added without modifying the default settings. Pluggable settings are a mechanism to allow settings to be stored in separate files. Those files are read at startup and used to modify the default settings.

The default location for the dashboard configuration files is openstack_dashboard/enabled, with another directory, openstack_dashboard/local/enabled for local overrides. Both sets of files will be loaded, but the settings in openstack_dashboard/local/enabled will overwrite the default ones. The settings are applied in alphabetical order of the filenames. If the same dashboard has configuration files in enabled andlocal/enabled, the local name will be used. Note, that since names of python modules can’t start with a digit, the files are usually named with a leading underscore and a number, so that you can control their order easily.

简单解释一下就是:每当开发者想要自主添加一个一个dashboard或panel时,可以不修改openstack_dashboard这个django应用的settings文件。代替之的操作是在openstack_dashboard下的enabled或openstack_dashboard/local/enable下写一个相应的python文件,告诉horizon在渲染dashboard时,请把这两个目录下添加的dashboard和panel也加进去。其中openstack_dashboard/local/enabled是对openstack_dashboard/enabled的一个override,如果在两个目录中配置了相同的dashboard,local下注册的dashboard是最终生效的。enable目录下的dashboard和panel是按照注册时填写的python文件的文件名的字典序添加的,所以当你看到enable下的目录python文件开头是_10_*.py _20_*.py,就应该不感到奇怪了吧,它完全是为了易于控制文件名的字典序而这样命名的。

接下来先看如何添加一个dashboard:

步骤1 “配置”:

在openstack_dashboard/local/enable 创建一个python文件,如_04_test_dashboard.py:

 # The slug of the dashboard to be added to HORIZON['dashboards']. Required.
DASHBOARD = 'test_dashboard' # A list of applications to be added to INSTALLED_APPS.
ADD_INSTALLED_APPS = [
'openstack_dashboard.dashboards.test',
]

分析一下,首先需要填写'DASHBOARD'这个属性,它实际上是你想要添加的dashboard的slug。啰嗦一句,slug可以把它看成是key,dashboard的slug就是相当于标识了这个dashboard,而它和dashboar具体在浏览器中显示的名字不是一码事。然后另一个比较重要的就是'ADD_INSTALLED_APPS'这个列表,这个列表的作用是指定这个dashboard下的application的目录列表。为什么dashboard会跟APP联系?因为在horizon看来,一个panel和一个APP是对应的,而dashboard下是一组panel的集合,所以指定这个list是理所当然的了。APP_INSTALLED_APPS好像可以不必须指定,而博主目前不知道什么情况下不需要指定ADD_INSTALLED_APPS,所以这个基本也是必须的。

可能看到这里,有人会好奇究竟这个配置文件可以配置哪些内容。我暂且罗列一些可以配置的属性,而不具体一一分析。因为这样的属性实在太多了,多数暂时也用不到。本章旨在解决主要的问题——dashboard和panel的添加原理。如果对这些配置属性感兴趣,可以去horizon的开发主页去查。

following keys can be used in any pluggable settings file:

 ADD_EXCEPTIONS
A dictionary of exception classes to be added to HORIZON['exceptions']. ADD_INSTALLED_APPS
A list of applications to be prepended to INSTALLED_APPS. This is needed to expose static files from a plugin. ADD_ANGULAR_MODULES
A list of AngularJS modules to be loaded when Angular bootstraps. These modules are added as dependencies on the root Horizon application hz. ADD_JS_FILES
A list of javascript source files to be included in the compressed set of files that are loaded on every page. This is needed for AngularJS modules that are referenced in ADD_ANGULAR_MODULES and therefore need to be included in every page. ADD_JS_SPEC_FILES
A list of javascript spec files to include for integration with the Jasmine spec runner. Jasmine is a behavior-driven development framework for testing JavaScript code. ADD_SCSS_FILES
A list of scss files to be included in the compressed set of files that are loaded on every page. We recommend one scss file per dashboard, use @import if you need to include additional scss files for panels. AUTO_DISCOVER_STATIC_FILES
If set to True, JavaScript files and static angular html template files will be automatically discovered from the static folder in each apps listed in ADD_INSTALLED_APPS. JavaScript source files will be ordered based on naming convention: files with extension .module.js listed first, followed by other JavaScript source files. JavaScript files for testing will also be ordered based on naming convention: files with extension .mock.js listed first, followed by files with extension .spec.js. If ADD_JS_FILES and/or ADD_JS_SPEC_FILES are also specified, files manually listed there will be appended to the auto-discovered files. DISABLED
If set to True, this settings file will not be added to the settings. UPDATE_HORIZON_CONFIG
A dictionary of values that will replace the values in HORIZON_CONFIG.

values

仅写配置是不够的,因为horizon在渲染页面的时候要有一个dashboard实例才能够进行渲染。

步骤二 “填写实例”

先在openstack_dashboard/dashboards下新建一个名叫test的module,因为上面ADD_INSTALLED_APPS指定的路径是test。dashboard和panelgroup的实例一般是写在dashboard module下的dashboard.py这个文件下,于是/openstack_dashboard/test_dashboard/dashboard.py:

 from django.utils.translation import ugettext_lazy as _
import horizon class Test(horizon.Dashboard):
name = _("TestDashboard")
slug = "test_dashboard"
panels = (TestPanels,)
default_panel = 'test'
permissions = ('openstack.roles.admin',) horizon.register(Test)

分析一下,dashboard实例实际上就是horizon.Dashboard的一个子类,name属性即界面上显示这个dashboard实际的名称。slug属性前面介绍过,实例中的slug与配置文件中的slug是对应的,所以一定要注意保持一致。panels元组的意义比较明显,值得注意的是这里面的元素可以是panlegroup也可以是panel,TestPanel是一个panelgroup,具体定义见后文。default_panel意义也很明显,它需要指明一个panel的slug。permissions是权限控制,只有以admin身份登录才可以看到这个dashboard。permissions不是必须指明的。最后一步调用register实例化。

panelgroup的添加和dashboard是类似的,代码如下:

1.配置

/openstack_dashboard/local/enable/_05_test_panel_group.py

 PANEL_GROUP = 'test_panel_group'
PANEL_GROUP_NAME = 'Test Panelgroup'
PANEL_GROUP_DASHBOARD = 'test_dashboard'

'PANEL_GROUP_DASHBOARD'是指定panelgroup是在哪个dashboard下的,属性的值应该是某个dashboard的slug

2.根据配置写实例

/openstack_dashboard/dashboards/test/dashboard.py

 class TestPanels(horizon.PanelGroup):
slug = "test_panel_group"
name = _("TestPanelGroup")
panels = ('test',)

有了上面的基础,panel的添加也是类似的,不过panel逻辑上就是一个具体的应用。所以第二步的实例一般是写在具体应用目录的panel.py这个文件中的,先在/openstack_dashboard/dashboards/test下新建一个module,test1。

1.配置

/openstack_dashboard/local/enable/_06_test_panel.py

 PANEL = 'test'
PANEL_DASHBOARD = 'test_dashboard'
PANEL_GROUP = 'test_panel_group'
ADD_PANEL = 'openstack_dashboard.dashboards.test.test1.panel.Test'

panel的配置跟dashboard和panelgroup不同,需要指定ADD_PANEL这个属性,这个属性的作用是指定第二步中的需要被实例的类名。如果不指明ADD_PANEL则不能正确添加这个panel。这里可能有人疑问为什么dashboard和panelgroup可以通过slug的对应关系找到实例的类,而panel不能效法这么去做。这个问题我也是疑问的,想要搞明白还需再往深层看,问题暂时先放这里,欢迎大牛指点。

2.根据配置写实例

/openstack_dashboard/dashboards/test/test1/panel.py

 from django.utils.translation import ugettext_lazy as _  # noqa
import horizon
from openstack_dashboard.dashboards.admin import dashboard class Test(horizon.Panel):
name = _("Test")
slug = 'test'
permissions = ('openstack.roles.admin',) dashboard.Admin.register(Test)

最后随便在test1这个module下的urls.py和views.py随便写点视图层代码,更复杂的视图层逻辑将在后面章节讲解。

最后我们来启动server看一下效果:

在最最后,博主做了个实验,分析了一下Pluggable Settings这种添加dashboard和panel方式到底做了什么。

首先,在server启动前,找到openstack_dashboard里的settings.py里的INSTALLED_APPS列表,看看它都有什么:

然后在server启动后,写了一个视图函数display_view:

 from django import http
from openstack_dashboard import settings def display_view(request):
apps = settings.INSTALLED_APPS
apps.sort()
html = []
for i in apps:
html.append('<tr><td>APP:</td><td>%s</td></tr>' % i)
return http.HttpResponse('<head>print INSTALLED_APPS:</head> <table>%s</table>' % '\n'.join(html))

打印下目前的INSTALLED_APPS变成了什么:

INSTALLED_APPS列表在server启动后,界面渲染前,添加了一些新的项。而这些项与horizon中的dashboard是一一对应的,刚刚写的test也里面。所以稍加分析和思考不难知道,其实Pluggable Settings这种方式是在INSTALLED_APPS读取前先读取openstack_dashboard/enable和openstack_dashboard/local/enable中的.py配置文件,解析这些配置,然后动态添加到INSTALLED_APPS中,再渲染界面。它的实质与直接修改配置文件中的INSTALLED_APPS本质并无区别。

但不觉得可扩展性提高了么?加入这么一个看似简单的机制,所有APP变得像零件一样变得可拔插。不觉得有些函数式编程的味道么,即便是修改或删除dashboard或panel,也可以不修改代码,而是定义一个新的配置。扯多了……

本章讲的很粗略,很多内容写的并不完善,可能也有很多错误在里面,通过以后的学习再慢慢细化和改正。

openstack horizon 学习(2) navigation、dashboard、panels的更多相关文章

  1. openstack horizon 学习(3) DataTable

    上一篇中粗略的讲了下openstack中horizon的dashboard和panel的添加,本打算在这章中对有关于pluggable settings中的配置做详细的总结,然放弃了这念头.原因是搞懂 ...

  2. openstack horizon 学习(1) 总览

    关于Horizon的设计理念: 来自官网(http://docs.openstack.org/developer/horizon/intro.html): Horizon holds several ...

  3. 【云计算】OpenStack Horizon DashBoard定制化,完整实现前后台交互

    项目代码见GitHub:https://github.com/junneyang/openstack-customization-example 参考资料: Install and configure ...

  4. 关于OpenStack的学习路线及相关资源汇总

    首先我们想学习openstack,那么openstack是什么?能干什么?涉及的初衷是什么?由什么来组成?刚接触openstack,说openstack不是一个软件,而是由多个组件进行组合,这是一个更 ...

  5. openstack horizon开发第一天

    horizon插件构造 创建一个dashboardmkdir opesntack_dashboard/dashboards/mydashboardpython manage.py startdash ...

  6. openstack horizon CSS 离线 改动

    Openstack horizon 的CSS主要保存在几个文件夹中,各自是horizon/static/dashboard/scss;horizon/openstack_dashboard/stati ...

  7. Apache下配置Openstack Horizon (转)

    非常详尽的Horizon配置介绍,转自 dev.cloudwatt.com Deploy Horizon from source with Apache and SSL Some companies ...

  8. Openstack api 学习文档 & restclient使用文档

    Openstack api 学习文档 & restclient使用文档 转载请注明http://www.cnblogs.com/juandx/p/4943409.html 这篇文档总结一下我初 ...

  9. Openstack neutron学习

    最近在学习openstack neutron的东西,记录下自己的一些理解. 网络基础知识 Switches & Vlan交换机的作用是来连接设备,实现互通的.network host之间通过交 ...

随机推荐

  1. mybatis保存时将数据库自动生成的主键返回

    场景 保存订单数据和订单详情数据时需要将订单的主键作为关联子段添加到明细表中,需要将保存订单时的主键返回给供保存明细表时使用 添加xml中新增数据时的配置 <insert id="in ...

  2. delphi GDI+ [1]

    摘抄自:万一的博客 安装头文件:http://www.cnblogs.com/del/archive/2008/06/06/1215319.html 目录 基本使用方法(绘制直线) 绘制一组直线 绘制 ...

  3. 一个关于vue+mysql+express的全栈项目(一)

    最近学了mysql数据库,寻思着能不能构思一个小的全栈项目,思来想去,于是就有了下面的项目: 先上几张效果图吧       目前暂时前端只有这几个页面,后端开发方面,有登录,注册,完善用户信息,获取用 ...

  4. LeetCode(33)Search in Rotated Sorted Array

    题目 Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 m ...

  5. hihocoder 1515 分数调查(树形dp)

    hihocoder 1515 分数调查 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi的学校总共有N名学生,编号1-N.学校刚刚进行了一场全校的古诗文水平测验. ...

  6. 集训第六周 E题

    E - 期望(经典问题) Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Submit S ...

  7. Jmeter关联,正则表达式提取器使用1

    Jmeter关联,正则表达式提取器使用    一.Jmeter关联的方式: Jmeter中关联可以在需要获取数据的请求上 右键-->后置处理器 选择需要的关联方式,如下图有很多种方法可以提取动态 ...

  8. POJ-20407Relatives/NYOJ-333mdd的烦恼,欧拉函数简单应用,模板A

     poj                         Relatives                                Time Limit: 1000MS   Memory Li ...

  9. SQLSERVER数据库管理员的专用连接DAC

    出处: http://www.cnblogs.com/lyhabc/archive/2012/09/23/2698702.html DAC:Dedicated Admin Connection 当SQ ...

  10. PostgreSQL及PostGIS使用

    基础知识 参考文档:http://www.postgis.net/docs/ PostGIS支持的GIS对象是OpenGIS Consortium(OGC)定义的“简单特征”的超集.OpenGIS规范 ...