Developing and using Horizon plugins lessons and know-hows we learned Shu Muto and Akihiro Motoki
Who we are. Shu Muto from NEC Solution Innovators, Ltd. Japan Core developer of Magnum UI, Zaqar UI, Senlin Dashboard, Zun UI and UI Cookiecutter Akihiro Motoki from NEC Japan Core developer of Neutron, Horizon, OSC and I18n
Overture OpenStack Dashboard (Horizon) provides the plugin mechanism. More and more projects implement their dashboard as Horizon plugins. However, the knowledges on Horizon plugins are not shared well, and individual teams maintain their dashboard in their own way.
This talks will share our knowledges like: Basic on how Horizon plugins works and use them. How to organize Horizon plugins from developer perspective. Both Django-based and Angular-based developments. Testing strategy and CI integration, Translation support. How to follow Horizon changes and make good feedback.
Existing Plugins https://docs.openstack.org/horizon/latest/install/plugin-registry.html Django-based: 22 Angular-based: 8 Both-based: 4 Astara Dashboard Mistral Dashboard App Catalog UI (migration in progress) BGPVPN Dashboard Monasca UI Ironic UI Designate Dashboard Blazar Dashboard Murano Dashboard Magnum UI Senlin Dashboard Cerberus Dashboard Neutron FWaaS Dashboard Neutron LBaaS Dashboard Trove Dashboard Cisco UI Neutron VPNaaS Octavia Dashboard Vitrage Dashboard Cloudkitty Dashboard Dashboard Searchlight UI Congress Dashboard Sahara Dashboard Zaqar UI Cue Dashboard Solum Dashboard Zun UI Not Horizon plugin: 1 TripleO UI (React-based) Freezer Web UI Sticks Dashboard Group Based Policy UI Tacker UI Karbor Dashboard Watcher Dashboard Manila UI
Which framework based on?
Installation We can install them using pip from PYPI or GIT repo. To enable them, copy the files in ‘enabled’ directory of the installed plugin destination, and paste it into Horizon’s ‘openstack_daskboard/local/enabled/’ directory. Then restart Horizon.
What we should code for Django-based? We can implement almost with Python. ● Panel with Horizon framework ○ i.e. To use python-XXXclient to access each services. ● Python-client API ○ i.e. to use python-XXXclient ● Django-based main contents ○ i.e. Views for table, details, actions or workflow
What we should code for Angular-based? ● Panel with Horizon framework ○ To load the plugins. ● Python-client API ○ i.e. To use python-XXXclient to access each services. ● Django-based REST API ○ To provide data manipulation paths for JavaScript. ● Angular-based main contents ○ i.e. Table view, details view, actions and etc.
How to create new dashboard plugin Use UI Cookiecutter !! https://github.com/openstack/ui-cookiecutter We can test it only by one command line. $ cookiecutter https://github.com/openstack/ui-cookiecutter.git --no-inputs This generates new sample panel with CRUD operations as plugin.
Sample panel generated by UI Cookiecutter
Sample panel generated by UI Cookiecutter
Sample panel generated by UI Cookiecutter
What is UI Cookiecutter ? Useful OpenStack project template for new Horizon plugin. One of ‘Horizon Official’ project. Angular-based plugin skeleton with working examples. We can customize the example codes in ease!! Good place to gather the best knowledges for plugins. We can feedback the know-hows into the repository by committing code, and report bugs to https://launchpad.net/ui-cookiecutter Please visit https://github.com/openstack/ui-cookiecutter
To customize the client API and REST API [module]/api/ ● Edit client.py to access your endpoint properly. ● Edit rest_api.py to use the client API properly, and to service REST API to JavaScript side.
To customize the service for REST APIs [module]/static/dashboard/[panel]/[panel].service.js ● Edit the service to access your REST API properly. This service uses horizon.framework.util.http.service for accessing Django side REST APIs. ● functions for get, post, patch, put and delete methods are supported by the http service.
To customize the panel [module]/static/dashboard/[panelgroup]/[panel]/ ● Index view and Details view using Horizon framework ○ Edit registerations for load functions and properties of the resource on [panel].module.js horizon.framework.conf.resource-type-registry.service ■ [module]/static/dashboard/[panelgroup]/[panel]/details/ ● For Details view and summary on Index view ○ Edit overview.html and drawer.html hz-resource-property-list ■
To customize the actions [module]/static/dashboard/[panelgroup]/[panel]/actions/ [module]/static/dashboard/[panelgroup]/[panel]/workflow/ Actions are registered into resource-type-registry service, and set into Table view and Details view. ● Create / Update forms use Angular Schema Form ○ https://github.com/json-schema-form/angular-schema-form ● Delete action uses Horizon framework ○ horizon.framework.widgets.modal.deleteModalService
Python tests UI Cookiecutter has settings for Python tests To install test tools: $ pip install tox $ pip install tox Required modules for tests will be installed into virtual environment when run each tests using tox. Write tests To run tests: $ tox -e py27 $ tox -e py27 Code according to hacking: https://docs.openstack.org/hacking/latest/ To run check code style: $ tox -e pep8 $ tox -e pep8
JavaScript tests UI Cookiecutter has settings for JavaScript tests To install test tools: $ npm install . $ npm install . Write test using Jasmine To run tests: $ npm run test $ npm run test Code according to https://github.com/johnpapa/angular-styleguide To check code style: $npm run lint $ npm run lint
Translation support <translate>Translate me!!</translate> <p translate>The word ‘internationalization’ is a too long.</p> Django: ‘translate’ tag or attribute for template HTML. use django.utils.translation module for Python code. Angular: ‘translate’ tag or attribute for template HTML. ‘gettext’ or ‘ngettext’ functions for JavaScript code. Extract strings to be translated using Babel. If your project is OpenStack Official, set jobs for translation on OpenStack CI infra, and translate using Zanata.
Documentations Write document in RST format ● https://docs.openstack.org/doc-contrib-guide/rst-conv.html ● Add release note using `reno` command and write contents in RST https://docs.openstack.org/reno/latest/ Build them into HTML ● Write settings into setup.cfg or command in tox.ini and run sphinx-build using or . $ tox -e docs $ tox -e releasenotes Specs for documentations in Pike ● https://specs.openstack.org/openstack/docs-specs/specs/pike/os-manuals-migration.html
Project setup for OpenStack CI Basically follow “Project Creator’s Guide” https://docs.openstack.org/infra/manual/creators.html Make good name for your project and create repositories on PYPI and ● Launchpad. ● Upload some patches into openstack-infra/project-config repo. Use UI Cookiecutter to generate your Horizon plugin. ●
Jenkins jobs to be set on OpenStack CI infra Set jobs for your project on openstack-infra/project-config e.g. https://github.com/openstack-infra/project-config/blob/master/jenkins/jobs/projects.yaml - project: name: [project] jobs: - python-jobs : for all plugins. i.e. pep8, py27, py35 and docs - nodejs4-jobs : for all Angular-based plugins. i.e. test and lint - openstack-server-release-jobs: for official project - openstack-publish-jobs : for official project. i.e. publish to document site https://docs.openstack.org/developer/[project] - openstack-releasenotes-jobs : for official project. i.e. publish to release note site https://docs.openstack.org/releasenotes/[project] - translation-jobs : for official project. i.e. export strings to be translated to Zanata and import translated files
Migrating Django-based to Angular-based We can recycle the codes for only python-client API from Django-based plugin. So we should re-implement almost logics into Angular-based JavaScript codes. To create Angular-based contents area, use UI Cookiecutter and transfer the JavaScript contents and REST API into your plugin. Then customize the JavaScript contents.
To switch Django-based or Angular-based senlin_dashboard.cluster.clusters.urls.py Senlin Dashboard: _59_toggle_angular_senlin_dashb if settings.ANGULAR_FEATURES.get('clusters_panel'): oard.py.example # Angular-based view title = _("Clusters") ANGULAR_FEATURES.update({ urlpatterns = [ 'profiles_panel': True, url('', AngularIndexView.as_view(title=title), 'nodes_panel': True, name='index'), …... ] }) else: copy # Django-based view urlpatterns = [ Horizon: url(r'^$', legacyViews.IndexView.as_view(), openstack_dashboard/local/local_ name='index'), settings.d/_59_toggle_angular_se …... nlin_dashboard.py ]
Thanks!!
Recommend
More recommend