Introduction
The OpenStack Horizon project provides a web-based User Interface to services provided by the OpenStack cloud platform. It is constructed in two parts: (1) a core set of libraries for implementing a Dashboard; (2) a reference dashboard implementation that uses the core set of libraries. Extensibility, customization and testability are key components of the Horizon framework. The framework provides features that enable developers to rapidly construct their own dashboards, panel groups and panels, and assemble them together via a common navigation/presentation framework. It also provides a number of customization hooks that enable developers to customize the application at the CSS, JavaScript, or Python level. The Horizon framework also provides a number of sophisticated and interactive widgets that are very easy to re-use. And it provides a framework for streamlining the testing of the application.
In this post, we will provide a brief introduction to Horizon. We will review Horizon’s high level architecture and describe the structure of the Horizon/OpenStack Dashboard UI. We will then review the Horizon application stack and describe the enhancements Horizon makes to the standard Django application stack. We will examine some of the interesting and potentially generic patterns Horizon provides, and conclude by describing how interested developers can go about joining the online Horizon community and contribute to the Horizon project. This is the first in a series of posts that will increasingly go into the details of OpenStack Horizon.
Horizon Overview
OpenStack Horizon is a Django-based application that provides access to OpenStack services. It is typically deployed as an Apache WSGI application and leverages well known existing technologies: Bootstrap, jQuery, Underscore.js, AngularJS, D3.js, Rickshaw, LESS CSS.
OpenStack Dashboard Structure
Horizon provides separate dashboards for cloud administrators and cloud users. Cloud administrators are able to monitor and manage hypervisors, view and update system default information, manage project and identity information, manage security group information and a host of other useful functions. Cloud users are able to create, manage, and delete virtual machines, volumes, virtual machine flavors, images, and other cloud-related resources.
Figure 1 shows a screen shot of the OpenStack Dashboard. The top-level navigation component is a “Dashboard”. Dashboards may contain one or more Panels (usually grouped into Panel Groups – although Panels may exist independently of Panel Groups). A Panel corresponds to a single Page rendered in the browser. A navigation sidebar displays the currently selected Dashboard as a tab (as shown in Figure 1) and also displays the hierarchy of Panel Groups and Panels. Clicking on a Dashboard or Panel link in the sidebar redirects the user to the appropriate page. The Panel Body is where the content for a Panel is rendered. Often, the Panel Body will comprise one or more Data Tables which will display information and associated actions relevant to the page.
A Dashboard page also includes some other useful elements: a Branding element for customizable branding of the application, a common Page Header element, and a User Information section which includes options for changing user settings and preferences, a help menu, and a Sign Out link.
ScreenCapDavidsblog
Figure 1 OpenStack Dashboard UI Structure.
Horizon Application Stack
The Horizon software repository is divided into two components[1]:
Horizon Base: a library of core components that can be used to construct a user interface for controlling an OpenStack cloud. This library extends the Django stack to enhance application extensibility, and provide facilities that streamline the construction of the user interface.
OpenStack Dashboard: an application built using Horizon Base. This is the application that is actually run and used.
Figure 1 shows the standard Django and Horizon application stacks side by side. On the left we see the standard Django stack. Below the stack we have the database layer that most Django applications access. The main portion of the stack consists of Django’s Model View Template (MVT) framework. Django also includes libraries for simplifying testing, a URL dispatcher mechanism for routing incoming requests to the appropriate view, and a framework that includes a large number of libraries that simplify common developer tasks.
The right hand side of Figure 1 shows the Horizon application stack. New or different elements are highlighted in green. The first thing to note is that the application stack runs on top of a layer of OpenStack services rather than a database. These services are accessed via a REST-ful API. The bottom layer of the Horizon stack is an API layer that provides an abstraction for accessing the OpenStack services layer (in much the same way a traditional Django stack has the Model abstraction for accessing the database). The major components in the remainder of the Horizon stack map one to one with the Django stack, but include additional modules that make the task of constructing an OpenStack Dashboards easier. In the following sections, we will take a brief look at some of the enhancements Horizon makes to the default Django application stack.
Enhanced Views
The View component includes the following additional components:
Dashboards and Panels: OpenStack dashboards are constructed using a combination of Dashboards, PanelGroups and Panels (as shown in Figure 1). This navigational hierarchy makes it easy to extend and modify the Dashboard application. Dashboards are top-level navigational elements, while Panels correspond to a single page. Developers can create new Dashboards, PanelGroups and Panels with a minimal amount of code by inheriting from the base classes present in Horizon. These elements can then be registered with the main Horizon application. By doing this, new elements are automatically included in the sidebar navigation, and are also subject to Horizon’s authentication and authorization scheme. The developer can now focus on adding functionality to the new Panel elements.
Tabs and TabGroups: OpenStack dashboard applications may partition a page into multiple tabs. These tabs are created using the Tab and TabGroup classes provided by Horizon. In addition to automating the rendering of these tabs, and tab switching, Horizon also provides optional lazy-loading, where a tab is only loaded when it is clicked (as opposed to pre-loading, where all tabs are pre-loaded on page render).
DataTables: A significant portion of the data presented to OpenStack Dashboard users is presented in table format. The DataTable class automates the construction and rendering of highly interactive and functional Table widgets. These DataTables include functionality such as: multi-select columns that enable one or more rows to be selected for batch actions, real-time table search filtering, configurable table-wide actions, configurable row-based drop down action menus, ajax-based table updating/polling, OpenStack API integration, View and Template integration. Developers can implement their on the server-side in python, in a declarative fashion, while taking advantage of heavy server- and client-side logic that has already been implemented by Horizon.
Decorators: Horizon includes a number of decorators for enforcing permissioning etc. These decorators use role flags embedded within Dashboard and Panel classes to control user access to these UI elements.
Enhanced Templates
The Template component has also been significantly enhanced by Horizon. Horizon includes a number of base templates that developers can inherit from. These templates include functionality to automatically load CSS scripts, JavaScript modules, and render pages. The following additional components are also included:
Permissions: Templates are able to enforce permissions. For example, some pages may only be shown if the user has an administration role.
Nav: Templates and templatetags manage the automated rendering of the navigation sidebar.
Misc: Branding customization is implemented using templates and templatetags, as well as other features to improve the formatting of data as it is presented to the user.
Other Enhancements
Horizon extends the Test Infrastructure component with additional library classes that simplify the task of generating and executing test cases for API and View components.
Horizon also includes a library for implementing custom Workflows. These Workflows comprise a series of steps that an end user must go through in order to perform a particular function (e.g. launching a virtual machine). At each step, the user is required to enter some information, which is validated and passed to the backend. Once the workflow is completed successfully, the action is executed. Workflows are an extremely powerful tool, and used extensively through the OpenStack Dashboard application.
Figure2Left Figure2Right
Figure 2 Application Stacks: The application stack on the top is the standard Django Application Stack. The application stack on the bottom is the enhanced Horizon application stack.
Interesting Patterns
Horizon includes a number of interesting patterns that seem to be generally applicable. Dashboards, PanelGroups, Panels, Tabs/TabGroups, and DataTables in particular are very useful constructs that greatly simplify the task of extending Horizon functionality. These constructs enable Developers to focus almost exclusively on the implementation of new page functionality, while minimizing the amount of boilerplate they need to implement.
Horizon also includes customization hooks at every level. Developers can add or modify functionality on either the client-side or server-side. On the client-side, new CSS, HTML, or JavaScript modules can easily be inserted via Django template “block” constructs. On the server-side, Horizon includes a customization module mechanism, which loads a developer-supplied python customization module just after the application is loaded. This customization module can be used for many things, including adding, moving or removing panels, changing fields available in forms, and so on. It is an extremely powerful mechanism.
Horizon also includes its own authentication module, which is inserted via the Django AUTHENTICATION_BACKENDS settings mechanism. This module authenticates via the keystone identity service rather than the traditional Django database user authentication mechanism.
Contributing to Horizon
Horizon is an extremely interesting and challenging Django application. The online Horizon community is extremely active, very knowledgeable, and extremely welcoming of new contributors. Contributions to Horizon can take many forms: reporting of bugs, documentation enhancements, bug fixes, new features, code reviews, etc. If you are interested in contributing to Horizon, here are a couple of websites that will help get you started:
Devstack[1] provides a complex shell script that enables developers to standup a complete OpenStack development environment.
The Horizon Contributing[2] web page provides some excellent pointers on how to get started developing with Horizon.
Summary
The OpenStack Horizon UI provides a Django-based application that controls OpenStack clouds. It is an extremely extensible, customizable, and testable framework that has been developed by a large community of knowledgeable and passionate open source developers. Horizon extends the standard Django application stack with functionality that is generically useful to other Django applications. This functionality significantly simplifies the development process and enables OpenStack Horizon developers to focus on the implementation of new functionality.
In future posts, we will dive into the details or Horizon by working through example tutorials. If you have any questions, comments, or thoughts on this post or how to get involved with the OpenStack community, please feel free to contact me: david.lapsley@metacloud.com, @devlaps.
[1] While Horizon is commonly used to refer to the both components, it is technically more precise to refer to the application as “OpenStack Dashboard”, and the supporting libraries as “Horizon”. In this post, we will follow this convention.
[2] http://devstack.org:
[3] http://docs.openstack.org/developer/horizon/contributing.html
- See more at: http://www.metacloud.com/2014/03/17/openstack-horizon-controlling-cloud-using-django/#sthash.ln0TwVT7.dpuf