control your panel

原创 2015年07月10日 10:58:41

本科的时候学了点儿UI开发的皮毛,研究生的时候摆弄过Django,后来终究还是把UI那一套东西留在某个角落了,虽然horizon提供了极为动态的扩展修改机制,

并不需要对UI有太多的了解就能开发出不错的效果(终究是一个Django项目,要想实现自己的复杂的js效果,还是需要专门搞UI的人来写html页面的), 前面讲了好

几篇关于怎么实现horizon的东西,有几个疑问需要收尾:

1. 各种settings文件的关系, RDO装好之后又/etc/openstack-dashboard/local_settings(使用virtual env时候,要配置的local setting也是这个), 有

/usr/share/openstack-dashboard/openstack_dashboard/settings, 还有配apache之后/etc/httpd/conf.d/15-horizon_vhost.conf,主要是这三个

2.  如何控制panel的显示?比如在/usr/share/openstack-dashboard/openstack_dashboard/dashboards/project中的dashboard.py中:

class Project(horizon.Dashboard):
    name = _("Project")
    slug = "project"
    panels = (
        BasePanels,
        NetworkPanels,
        ObjectStorePanels,

        OrchestrationPanels,
        DatabasePanels,
        DataProcessingPanels,)
    default_panel = 'overview'

红色的是我们常规可以看到的compute,network,object store三个panel group,我们在panel group中添加panel前面已经说过很多,没有问题,会显示出来,但是

这些剩下的heat,trove,sahara为什么没有显示出来呢?

3. 在template中call url怎么做到呢,我们事先自己的页面,初始化的数据可以传进去,想tabview那样,但是如果动态获取数据怎么得到呢?

整个horizon的问题很多,虽然horizon是openstack的一个模块,然而它并不影响openstack的逻辑,你也可以实现自己的完全新的UI,国内的利用openstack搞公有云的

都是这个路子。


查阅资料,但看horizon的源码,我的理解是:

1. 几个setting文件的作用,/usr/share/openstack-dashboard/openstack_dashboard/settings是基本的配置,/etc/openstack-dashboard/local_settings则可以

修改它,在local_settings中做的配置可以覆盖基本配置,关于STATIC_ROOT, error log等则在/etc/httpd/conf.d/15-horizon_vhost.conf中(关于horizon和apache的

配置可以参看horizon官网配置), Ubuntu上在openstack-dashboard/openstack_dashboard/dashboards/local/local_settings.py中的修改才会起作用(为什么ubuntu和Centos表现出来的不一样的,难道是J版和K版的差异?需要再看看。。。)


2. 即使我们在 openstack_dashboards/dashboards/project中的dashboard.py中添加Panel,还是不一定会显示,实际控制Panel显示的是keystone, 只有在

keystone中注册service才可以看到对应的panel,比如data_processing/clusters/panel.py和firewall/panel.py中我们可以看到:

permissions = ('openstack.services.network',)

    permissions = (('openstack.services.data-processing',
                    'openstack.services.data_processing'),) #本来是个bug,这里填写两个,表示两者均可, 是OR的关系

参照: https://bugs.launchpad.net/horizon/+bug/1429987

然而即便是permissions的限制解除,仍有方法限制是否显示,比如在firewall/panel.py中:

 def allowed(self, context):
        request = context['request']
        if not request.user.has_perms(self.permissions):
            return False
        try:
            if not neutron.is_service_enabled(request,
                                              config_name='enable_firewall',
                                              ext_name='fwaas'):

                return False

看neutron的api中代码,找到is_service_enabled方法,

def is_service_enabled(request, config_name, ext_name):
    return (is_enabled_by_config(config_name) and
            is_extension_supported(request, ext_name))

最终走到settings配置文件中(local_setting):

OPENSTACK_NEUTRON_NETWORK = {
    'enable_lb': False,
    'enable_firewall': False,
    'enable_quotas': True,
    'enable_security_group': True,
    'enable_vpn': False,
    'enable_distributed_router': False,
    'enable_ha_router': False,

所以既要enabled by 配置文件,也要extension supported,这里的extension supported在分析neutron时候提过。


3.之前写了如何加入自己的static file比如css或者js库,这里第三个问题更多的时候如何写完整的,特殊效果的html页, 看一个最典型的例子,

network_topology panel中的index.html.

首先是include了三个html页面,都是{% extends "horizon/client_side/template.html" %},且包含一个block id,什么时候体现作用,我们稍后提到

{% include "project/network_topology/client_side/_balloon_container.html" %}
{% include "project/network_topology/client_side/_balloon_device.html" %}
{% include "project/network_topology/client_side/_balloon_port.html" %}

接着定义了几个button,看一个create network的button:

{% if create_network_allowed %}
      <a href="{% url 'horizon:project:network_topology:createnetwork' %}" id="networks__action_create" class="btn btn-default btn-sm ajax-modal

{% if network_quota_exceeded %}disabled

{% endif %}">

<span class="fa fa-plus"></span> {% if network_quota_exceeded %}{% trans "Create Network (Quota exceeded)"%}

{% else %}{% trans "Create Network"%}{% endif %}</a>

点击create network button弹出创建网络的template。


再看一句:

<span data-networktopology="{% url 'horizon:project:network_topology:json' %}" id="networktopology"></span>

要想在html里面获得数据怎么办?答案就在这里,trace horizon:project:network_topology:json最终在network_toplogy的view中得到:

    def get(self, request, *args, **kwargs):
        data = {'servers': self._get_servers(request),
                'networks': self._get_networks(request),
                'ports': self._get_ports(request),
                'routers': self._get_routers(request)}
        self._prepare_gateway_ports(data['routers'], data['ports'])
        json_string = json.dumps(data, ensure_ascii=False)
        return HttpResponse(json_string, content_type='text/json')

得到数据了!

在哪儿用的呢?

<script type="text/javascript">
  if (typeof horizon.network_topology !== 'undefined') {
    horizon.network_topology.init();
  } else {
    addHorizonLoadEvent(function () {
      horizon.network_topology.init();
    });
  }
</script>

我们看看horizon.network_toplogy.init()最终调用的是什么?

horizon/static/horizon/js/horizon.network_topoligy.js中的init()方法,在该方法中我们可以看到:

    self.balloon_tmpl = Hogan.compile($('#balloon_container').html());
    self.balloon_device_tmpl = Hogan.compile($('#balloon_device').html());
    self.balloon_port_tmpl = Hogan.compile($('#balloon_port').html());

红色的部分就是前面提到的include进来的三个html页的id, 在init函数中通过:

$.getJSON($('#networktopology').data('networktopology') + '?' + $.now(),
      function(data) {
        self.model = data;
        self.data_convert();
        setTimeout(function(){
          self.load_network_info();
        }, self.reload_duration);
      }
    );

拿到数据, 点击不同按钮或者不同操作时,用js生成不同效果。

到这里,三个问题就回答完了,最后mark一个关于url解析的文章,写的不错:

http://blog.csdn.net/feelang/article/details/25464261




Psoc Creator入门——EZI2C 通信

用了两天的时间搞懂了赛普拉斯的Psoc 4000芯片作为iic从设备的通信,现在简单介绍一下怎么使用。 先说下我手上的开发套件,这是一块CY8CKIT-042的开发板和一个MiniProg3仿真器。 ...
  • ma57457
  • ma57457
  • 2017年08月07日 22:17
  • 438

Linux环境PHP7.0安装

PHP7和HHVM比较 PHP7的在真实场景的性能确实已经和HHVM相当, 在一些场景甚至超过了HHVM。HHVM的运维复杂, 是多线程模型, 这就代表着如果一个线程导致crash了, 那么整个服务...
  • qq_16399991
  • qq_16399991
  • 2017年06月22日 21:15
  • 266

Android BLE学习(三):编写自己的 BLE蓝牙读写工具(功能仿照nrf master control panel)

背景由于nordic官方的nrf master control panel只提供了apk,很多同学学习起来都得自己摸索蓝牙的读写,项目中整理了BLE模块的基本读写方法以及一些常用的UUID,并且抽取了...
  • lidec
  • lidec
  • 2016年03月22日 00:28
  • 8872

Xcode5中的版本管理(中英对照)

Beginning Source Control in Xcode 5 Xcode5中的版本管理 By Felipe Laso Marsetti [Vicki will update the f...
  • xiebaochun
  • xiebaochun
  • 2013年12月27日 09:06
  • 8456

C# WinForm技巧“将Form嵌入到Panel”

C# WinForm技巧“将Form嵌入到Panel” 来自:http://greatverve.cnblogs.com/archive/2011/07/11/panel-form.html ...
  • gaofang2009
  • gaofang2009
  • 2013年01月18日 15:12
  • 2229

C# 容器上控件排序

public static class Sort { #region 设置PanelControl上按钮显示位置 /// /// 设置按钮显...
  • xunzaosiyecao
  • xunzaosiyecao
  • 2015年06月17日 08:22
  • 2655

怎样用swift制作一个滑出的导航控制面板

这个教程会展示给你如何制作一个侧滑导航面板,就像是facebook或者IOS apps的侧滑页面。...
  • philar2016
  • philar2016
  • 2016年09月13日 10:33
  • 628

Windows7 64位利用Git+COPSSH搭建局域网协同开发环境(2人或2人以上)

工具:msysgit+copssh 一、安装程序 1、  安装git 2、  安装copssh(注意安装在分区根目录,路径避免出现空格)注意:如果卸载重装Copssh要记得手动删除系统用户S...
  • henrytam123
  • henrytam123
  • 2014年08月03日 02:57
  • 4067

panel的常见用法小计

我刚才禁不住诱惑去看了一下Ext.Window的API文档,发现只是比Panel多了点什么最大化、最小化、关闭、置前、置后、动画引发目标设置、可调整大小这些功能。像什么标题栏、工具栏之类的东西在Ext...
  • u013829202
  • u013829202
  • 2016年03月10日 10:03
  • 1331

如何在Xcode中使用版本控制

Whether you’re a solo developer or working on a team, if you’re not using source control for your pr...
  • guoshenglong11
  • guoshenglong11
  • 2013年07月17日 10:55
  • 1919
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:control your panel
举报原因:
原因补充:

(最多只允许输入30个字)