這篇文章主要介紹Newton版Openstack如何實(shí)現(xiàn)Dashboard開發(fā),文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!
創(chuàng)新互聯(lián)建站專業(yè)為企業(yè)提供古浪網(wǎng)站建設(shè)、古浪做網(wǎng)站、古浪網(wǎng)站設(shè)計(jì)、古浪網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)與制作、古浪企業(yè)網(wǎng)站模板建站服務(wù),10余年古浪做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。
Openstack的Dashboard項(xiàng)目一般被稱為Horizon,根據(jù)官網(wǎng)安裝部署及其簡單,yum install openstack-dashboard即可,配置也簡單只要修改/etc/openstack-dashboard/local_settings以及/etc/sysconfig/memcached,再啟動httpd服務(wù)就可以登錄了。
但是在查看它的源碼就會發(fā)現(xiàn),它并不是你想的那么簡單。
Horizon:它是一個(gè)基于django webframework開發(fā)的標(biāo)準(zhǔn)的python wsgi程序,一般運(yùn)行在webserver(apache httpd)之上。
Horizon的源碼中,包含兩個(gè)代碼文件夾
horizon ### /usr/lib/python2.7/site-packages/horizon
openstack_dashboard ### /usr/share/openstack-dashboard
操作系統(tǒng) | Centos7.2 |
---|---|
Openstack | Newton |
Python | 2.7.5 |
Django | 1.8.14 |
查看Django版本
# python Python 2.7.5 (default, Nov 6 2016, 00:28:07) [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import django >>> print django.VERSION (1, 8, 14, 'final', 0)
既然每個(gè)dashboard都是django中的一個(gè)app,那就可以使用django的命令來創(chuàng)建一個(gè)dashboard目錄結(jié)構(gòu)
# cd /usr/share/openstack-dashboard # python manage.py Type 'manage.py help' for help on a specific subcommand. Available subcommands: [auth] changepassword createsuperuser [compressor] compress mtime_cache [django] check compilemessages createcachetable dbshell diffsettings dumpdata flush inspectdb loaddata makemessages makemigrations migrate runfcgi shell showmigrations sql sqlall sqlclear sqlcustom sqldropindexes sqlflush sqlindexes sqlmigrate sqlsequencereset squashmigrations startapp startproject syncdb test testserver validate [horizon] startdash startpanel [openstack_dashboard] make_web_conf migrate_settings [sessions] clearsessions [staticfiles] collectstatic findstatic runserver
可以看到horizon部分有startdash和startpanel兩個(gè)命令,可以直接使用:
# mkdir -p openstack_dashboard/dashboards/dlwdashboard # python manage.py startdash dlwdashboard --target openstack_dashboard/dashboards/dlwdashboard # mkdir -p openstack_dashboard/dashboards/dlwdashboard/dlwpanel # python manage.py startpanel dlwpanel --dashboard=openstack_dashboard.dashboards.dlwdashboard --target=openstack_dashboard/dashboards/dlwdashboard/dlwpanel
# cd openstack_dashboard/dashboards/ # tree dlwdashboard/ dlwdashboard/ ├── dashboard.py ├── dashboard.pyc ├── dlwpanel │ ├── __init__.py │ ├── panel.py │ ├── templates │ │ └── dlwpanel │ │ └── index.html │ ├── tests.py │ ├── urls.py │ └── views.py ├── __init__.py ├── __init__.pyc ├── static │ └── dlwdashboard │ ├── js │ │ └── dlwdashboard.js │ └── scss │ └── dlwdashboard.scss └── templates └── dlwdashboard └── base.html 9 directories, 13 files
# cd dlwdashboard/ # vi dashboard.py # 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 class Dlwgroup(horizon.PanelGroup): slug = "dlwgroup" name = _("Dlw Group") panels = ('dlwpanel',) class Dlwdashboard(horizon.Dashboard): # name = _("Dlw dashboard") name = _("Dlw") slug = "dlwdashboard" panels = (Dlwgroup,) # Add your panels here. default_panel = 'dlwpanel' # Specify the slug of the dashboard's default panel. horizon.register(Dlwdashboard)
可以定義修改dashboard的名字
name = _("Dlw")
# tree dlwpanel/ dlwpanel/ ├── __init__.py ├── panel.py ├── templates │ └── dlwpanel │ └── index.html ├── tests.py ├── urls.py └── views.py 2 directories, 6 files
# cd dlwpanel # vi panel.py # 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.dlwdashboard import dashboard class Dlwpanel(horizon.Panel): name = _("Dlw panel") slug = "dlwpanel" dashboard.Dlwdashboard.register(Dlwpanel)
# vi tables.py from django.utils.translation import ugettext_lazy as _ from horizon import tables class MyFilterAction(tables.FilterAction): name = "myfilter" class InstancesTable(tables.DataTable): name = tables.Column('name', \ verbose_name=_("Name")) status = tables.Column('status', \ verbose_name=_("Status")) zone = tables.Column('availability_zone', \ verbose_name=_("Availability Zone")) image_name = tables.Column('image_name', \ verbose_name=_("Image Name")) class Meta(object): name = "instances" verbose_name = _("Instances") table_actions = (MyFilterAction,)
# vi tab.py from django.utils.translation import ugettext_lazy as _ from horizon import exceptions from horizon import tabs from openstack_dashboard import api from openstack_dashboard.dashboards.dlwdashboard.dlwpanel import tables class InstanceTab(tabs.TableTab): name = _("Instances Tab") slug = "instances_tab" table_classes = (tables.InstancesTable,) template_name = ("horizon/common/_detail_table.html") preload = False def has_more_data(self, table): return self._has_more def get_instances_data(self): try: marker = self.request.GET.get( tables.InstancesTable._meta.pagination_param, None) instances, self._has_more = api.nova.server_list( self.request, search_opts={'marker': marker, 'paginate': True}) return instances except Exception: self._has_more = False error_message = _('Unable to get instances') exceptions.handle(self.request, error_message) return [] class DlwpanelTabs(tabs.TabGroup): slug = "dlwpanel_tabs" tabs = (InstanceTab,) sticky = True
# vi views.py # 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 horizon import tabs from openstack_dashboard.dashboards.dlwdashboard.dlwpanel \ import tabs as dlwdashboard_tabs class IndexView(tabs.TabbedTableView): tab_group_class = dlwdashboard_tabs.DlwpanelTabs template_name = 'dlwdashboard/dlwpanel/index.html' def get_data(self, request, context, *args, **kwargs): # Add data to the context here... return context
# vi url.py # 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 import url from openstack_dashboard.dashboards.dlwdashboard.dlwpanel import views urlpatterns = [ url(r'^$', views.IndexView.as_view(), name='index'), ]
# cd templates/dlwpanel/ # vi index.html {% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "DlwPanel" %}{% endblock %} {% block page_header %} {% include "horizon/common/_page_header.html" with title=_("DlwPanel") %} {% endblock page_header %} {% block main %}{% endblock %}{{ tab_group.render }}
# cd /usr/share/openstack-dashboard/openstack_dashboard/enabled # vi _50_dlwdashboard.py # The name of the dashboard to be added to HORIZON['dashboards']. Required. DASHBOARD = 'dlwdashboard' # If set to True, this dashboard will not be added to the settings. DISABLED = False # A list of applications to be added to INSTALLED_APPS. ADD_INSTALLED_APPS = [ 'openstack_dashboard.dashboards.dlwdashboard', ]
重啟httpd服務(wù)
頁面查看
添加一個(gè)ip,在上面定義的tables.py里添加ip的代碼,可以直接從原有的openstack代碼里摘(因?yàn)檫@里的name,status,zone,image_name就是摘的)
# cat tables.py from django.utils.translation import ugettext_lazy as _ from horizon import tables from django import template class MyFilterAction(tables.FilterAction): name = "myfilter" import six def get_ips(instance): template_name = 'project/instances/_instance_ips.html' ip_groups = {} for ip_group, addresses in six.iteritems(instance.addresses): ip_groups[ip_group] = {} ip_groups[ip_group]["floating"] = [] ip_groups[ip_group]["non_floating"] = [] for address in addresses: if ('OS-EXT-IPS:type' in address and address['OS-EXT-IPS:type'] == "floating"): ip_groups[ip_group]["floating"].append(address) else: ip_groups[ip_group]["non_floating"].append(address) context = { "ip_groups": ip_groups, } return template.loader.render_to_string(template_name, context) class InstancesTable(tables.DataTable): name = tables.Column('name', \ verbose_name=_("Name")) status = tables.Column('status', \ verbose_name=_("Status")) zone = tables.Column('availability_zone', \ verbose_name=_("Availability Zone")) image_name = tables.Column('image_name', \ verbose_name=_("Image Name")) ip = tables.Column(get_ips, verbose_name=_("IP Address"), attrs={'data-type': "ip"}) class Meta(object): name = "instances" verbose_name = _("Instances") table_actions = (MyFilterAction,)
重啟httpd服務(wù) 頁面查看
創(chuàng)建一個(gè)新的dashboard,下面有g(shù)roup還有面板panel整個(gè)的流程:
1.app 2.dashboard.py 3.panel.py 4.tables.py 5.tabs.py 6.views 7.url.py 8.template 9.enabled 10.httpd
Horizon面板的設(shè)計(jì)分成三層:Dashboard → PanelGroup → Panel
Horizon中現(xiàn)有的dashboard有4個(gè):
1. project 普通用戶登陸后看到的項(xiàng)目面板 2. admin 管理登陸后可見,左側(cè)的管理員面板 3. settings 右上角的設(shè)置面板,里面可設(shè)置語言,時(shí)區(qū),更改密碼 4. router(配置文件中將profile_support打開可見),ciso nexus 1000v的管理面板
每一個(gè)dashboard都是django中的一個(gè)app,django中的app可以理解成對業(yè)務(wù)邏輯模塊化的一種手段,里面可以包含自己獨(dú)有的url設(shè)定,模板,和業(yè)務(wù)邏輯代碼
每個(gè)dashboard下定義了一系列的PanelGroup,虛擬機(jī)管理對應(yīng)到界面上就是一個(gè)PanelGroup(Manage Compute), 里面有一系列的子panel(Overview, Instances, Volumes…)。Swift,heat,neutron的管理面板各自都是一個(gè)PanelGroup,底下有各自的子panel.
此處選擇在project下建一個(gè)名為dbc的空白面板 有了上面的步驟,這里就很簡單了,建一個(gè)空白的面板,只需要三步
# /usr/share/openstack-dashboard/openstack_dashboard/dashboards/project/ # mkdir bdc # cd /usr/share/openstack-dashboard/ # python manage.py startpanel bdc --dashboard=openstack_dashboard.dashboards.project --target=openstack_dashboard/dashboards/project/bdc
# cd /usr/share/openstack-dashboard/openstack_dashboard/enabled # cp _1050_project_images_panel.py _1051_project_bdc_panel.py # vi _1051_project_bdc_panel.py # (c) Copyright 2016 Hewlett Packard Enterprise Development Company LP # # 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. # The slug of the panel to be added to HORIZON_CONFIG. Required. PANEL = 'bdc' # The slug of the dashboard the PANEL associated with. Required. PANEL_DASHBOARD = 'project' # The slug of the panel group the PANEL is associated with. PANEL_GROUP = 'compute' # Python panel class of the PANEL to be added. ADD_PANEL = 'openstack_dashboard.dashboards.project.bdc.panel.Bdc'
3.重啟httpd
# systemctl restart httpd
頁面查看
國際化,django的一個(gè)組成部分,支持多國語言,不同的機(jī)器打開的頁面顯示不同的語言,這里做個(gè)中英文對照關(guān)系的簡單改造。 在/usr/share/openstack-dashboard/openstack_dashboard/locale/zh_CN/LC_MESSAGES目錄下有個(gè)django.mo文件,這里就是作為中英文翻譯的依據(jù),將該文件取出來放在G:/Python練習(xí)目錄下:
sftp> cd /usr/share/openstack-dashboard/openstack_dashboard/locale/zh_CN/LC_MESSAGES sftp> lcd G:/Python練習(xí) sftp> get django.mo
mo文件是不可以編輯文件,需要將其反編譯為.po文件
安裝一個(gè)工具軟件Poedit
使用cmd或者powershell進(jìn)行反編譯操作
命令行進(jìn)入Poedit的安裝目錄目錄
cd E:\Program Files (x86)\Poedit\GettextTools\bin msgunfmt.exe G:\Python練習(xí)\django.mo -o G:\Python練習(xí)\django.po
生成django.po文件,可以使用Pycharm工具打開該po文件,照葫蘆翻譯之前新建的Bdc面板
使用Poedit將po文件編譯為mo文件
上傳至/usr/share/openstack-dashboard/openstack_dashboard/locale/zh_CN/LC_MESSAGES
重啟httpd服務(wù)
以上是“Newton版Openstack如何實(shí)現(xiàn)Dashboard開發(fā)”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!