Articles - Sharing Knowledge

Horizon Panel Learnings

Welcome reader, as you have opened this page, I assume you have come to learn about Horizon and it’s intricate web of Dashboards and Panels out of which is built. If this is the case read on, otherwise, you might have miss-clicked.

If this sounds confusing, do not despair for I shall enlighten you (or try my hardest to do so). But first, let me introduce myself, My name is Koen, I’m an intern here at Fuga Cloud and have spent the last couple of weeks becoming familiar with Horizon, its Dashboards, its Panels and Django on which Horizon is built. If these words mean nothing to you yet, don’t worry as I will explain later.

Before we can start with the Panels, we first need to know a bit about Horizon, and before we can do that we first have to take a look at OpenStack.

OpenStack? Has that something to do with stacking?

As the details of the OpenStack platform are far beyond the scope of this post, the basics will suffice for now:

What is OpenStack? “OpenStack is a free and open-source software platform for cloud computing, mostly deployed as infrastructure-as-a-service (IaaS), whereby virtual servers and other resources are made available to customers.” OpenStack website (

How is OpenStack Relevant to this post? You might have guessed it (or already knew) that Fuga is built upon OpenStack, and thus it uses many of the services from OpenStack, one of which -you guessed right- is the Horizon UI.

I know the horizon, but I can’t see it having “Panels”

When this post uses Horizon we will be referring to the UI of OpenStack, not to the non-capitalized horizon (ie. the skyline).

To get an idea how Horizon is built see Fig 1, and even though this image displays the Fuga dashboard, it still is Horizon but with a different theme.

A central page with the actual page is displayed in the center, extending down and to the right. The space above and to the left is reserved for the navigation and displaying user information.

For Dashboards and Panels, we have to look towards the navigation on the left, See Fig 2.

Here we see the following tabs: Project and Identity, these are the Dashboards. Dashboards can contain groups of panels, panel groups or a combination of both which become visible as the Dashboard is clicked.

As the Dashboard “Project” is folded open we can see COMPUTE, NETWORK, ORCHESTRATION and OBJECT STORE, these are panel groups. Panel groups are sub-tabs of a Dashboard and hide one or more panels which become visible as the group is clicked.

As the panel group “Overview” is folded open we can see “Instances”, “Volumes”, “Images” and “Access & Security”, these are panels. A panel is little more than a link to a page on Horizon which might as well be accessible via a URL.

Fuga Overview Dashboard Fig 1: Fuga Overview Dashboard

Dashboard Overview Fig 2: Dashboard Overview

So why do we need a panel?

As we learned in the previous section, Dashboards consist of panels and/or panel groups which consist out of panels, and as Panels are links to pages and pages in Horizon, you are expanding Horizon by adding new panels (or a Dashboard with panels) to it.

And how does one make a panel, dashboard or a panel group?

First off we need access to a working OpenStack platform. There are various ways to achieve this, like DevStack[2][1] to only name two. After OpenStack is set up, we can start with the Dashboard, this is an easy task as Horizon has an integrated command to create a Boilerplate Dashboard. Run the following commands from the root of your Horizon installation. This example creates the dashboard: “mydashboard” and the panel: “mypanel”, but these names can be altered.

$ mkdir openstack_dashboard/dashboards/mydashboard

$ tox -e manage -- startdash mydashboard \
--target openstack_dashboard/dashboards/mydashboard

$ mkdir openstack_dashboard/dashboards/mydashboard/mypanel

$ tox -e manage -- startpanel mypanel \
--dashboard=openstack_dashboard.dashboards.mydashboard \

Hereafter you should have a folder named under /horizon/openstack_dashboard/dashboards/ with the name you used in de previous code.

Using the tree command from the command line in the new directory should result in the following:

$ tree mydashboard
├── mypanel
│ ├──
│ ├──
│ ├── templates
│ │ └── mypanel
│ │ └── index.html
│ ├──
│ ├──
│ └──
├── static
│ └── mydashboard
│ ├── css
│ │ └── mydashboard.css
│ └── js
│ └── mydashboard.js
└── templates
└── mydashboard
└── base.html

The OpenStack documents[3]</sup have some great information to change this boilerplate code into something which is a bit more.

The code that was just generated is a Dashboard with a panel, to create a panel group, change so it looks like this:

from django.utils.translation import ugettext_lazy as _

import horizon

class Mygroup(horizon.PanelGroup):
slug = "mygroup"
name = _("My Group")
panels = ('mypanel',)

class Mydashboard(horizon.Dashboard):
name = _("My Dashboard")
slug = "mydashboard"
panels = (Mygroup,) # Add your panels here.
default_panel = 'mypanel' # Specify the slug of the default panel.


So I made a panel, following your directions. It is not here, you lied to me!

As always, the previous commands are not the only things required for a working Panel/Dashboard, we still need to enable it. This is easily accomplished as it only requires the creation of a file in the /horizon/openstack_dashboard/enable/ folder, below is an example how one such file should look:

# The name of the dashboard to be added to HORIZON['dashboards']. Required.
DASHBOARD = 'mydashboard'# this must have the same name as the directory which was created in the previous step

# If set to True, this dashboard will not be added to the settings.

# A list of applications to be added to INSTALLED_APPS.
'openstack_dashboard.dashboards.mydashboard', # this too must refer to the directory of the created in the previous step

The enable file should be named following this format: _[A number which indicates the load order]_[Name of the dashboard].py

Note! This tutorial is based upon directly editing the Horizon core. In reality, you should wrap this is a plugin.

I want to know more:

If you want to know more, down here are a couple of links to OpenStack documentation which are relevant to this subject.

  1. Panels:
  2. Plugin:
  3. Dashboards:


Was this article helpful?

Go to the next tutorial in Articles

How to stabilize Calico's IP-in-IP tunnels in virtual environments

When you work with bleeding edge technology you can expect the unexpected As most of us know software is never without bugs and due to technical diversity most of us won’t be able to fix these bugs ourselves. Instead we can develop and deploy workarounds while we wait for specialists to release a fix. In this post I’d like to share how we resolved a connectivity issue between pods in our Kubernetes cluster due to a tunnelling issue in Calico.
Fuga OpenStack


Terms of use