You are on page 1of 89

OpenStack Horizon:

Controlling the Cloud using Django


David Lapsley
@devlaps, david.lapsley@metacloud.com
August 21, 2014

OPENSTACK THAT JUST WORKS

OpenStack Horizon in Action

OPENSTACK THAT JUST WORKS

Launching an Instance

Admin Overview

Project Overview

Launching an Instance

Launching an Instance

Launching an Instance

Launching an Instance

Launching an Instance

Launching an Instance

OpenStack Clouds
Architecture and Model

OPENSTACK THAT JUST WORKS

OpenStack Model

http://docs.openstack.org/training-guides/content/module001-ch004-openstack-architecture.html

http://docs.openstack.org/openstack-ops/content/example_architecture.html

OpenStack Projects
Nova (Compute)
Nova (Network)
VM Registration (Glance)
Identity (Keystone)
Object Storage (Swift)
Block Storage (Cinder)
Dashboard (Horizon)

OpenStack Horizon
Controlling the Cloud with Django

OPENSTACK THAT JUST WORKS

Horizon Overview
Django-based application deployed via
Apache and WSGI
Provides access to OpenStack services
Leverages existing technologies
o Bootstrap, jQuery, Underscore.js,
AngularJS, D3.js, Rickshaw, LESS CSS
Extends Django to enhance extensibility

Django Stack

Horizon Stack

Horizon UI Structure
Dashboard

Projects
Branding

Panel Group

Panel
Panel Content
Sidebar

User Info

Admin Dashboard

Admin Dashboard

Project Dashboard

Horizon CSS Structure

OpenStack Horizon
Panels and Features

OPENSTACK THAT JUST WORKS

Instance List

Filtering

Sorting

Sorting

Row Actions

Table Actions

Table Actions

Table Actions

Table Actions

Instance Details

Instance Details

Instance Log

Instance Console

OpenStack Horizon
Interesting Patterns

OPENSTACK THAT JUST WORKS

Dashboards & Panels


Horizon provides a flexible framework for
creating Dashboards and Panels
Panels grouped into PanelGroups
PanelGroups into Dashboards

Dashboard App
Dashboards created as Django Applications
Dashboard modules partitioned into:
o static
o templates
o python modules

Directory Structure
cloudopen/
__init__.py
dashboard.py
templates/
cloudopen/
static/
cloudopen/
css/
img/
js/

settings.py
INSTALLED_APPS = (
...
'horizon',
'openstack_dashboard.dashboards.project',
'openstack_dashboard.dashboards.admin',
'openstack_dashboard.dashboards.metacloud',
'openstack_dashboard.dashboards.settings',
'openstack_dashboard.dashboards.cloudopen',
...
)

dashboard.py
class BasePanelGroup(horizon.PanelGroup):
slug = "overview"
name = _("Overview")
panels = ("hypervisors",)
class CloudOpen(horizon.Dashboard):
name = _("Linuxcon")
slug = "linuxcon"
panels = (BasePanelGroup,)
default_panel = "hypervisors"
roles = ("admin",)

horizon.register(CloudOpen)

CloudOpen Dashboard
Dashboard

PanelGroup

View Module
View module ,es together everything:
o Tables, Templates, API Calls
Horizon base views:
o APIView, LoginView, Mul,TableView,
DataTableView, MixedDataTableView,
TabView, TabbedTableView, WorkowView

views.py
from horizon import tables
class HypervisorsIndexView(tables.DataTableView):
table_class = hv_tables.AdminHypervisorsTable
template_name = cloudopen/hypervisors/index.html
def get_data(self):
hypervisors = []
states = {}
hypervisors = api.nova.hypervisor_list(self.request)

return hypervisors

Table Module
Table classes provide framework for tables:
o consistent look and feel
o configurable table_actions and row_actions
o select/multi-select column
o sorting
o pagination
Functionality is split server- and client-side

tables.py
class EnableAction(tables.BatchAction):

class DisableAction(tables.BatchAction):
name = 'disable'
classes = ('btn-danger',)
def allowed(self, request, hv):
return hv.service.get('status') == 'enabled'
def action(self, request, obj_id):
hv = api.nova.hypervisor_get(request, obj_id)
host = getattr(hv, hv.NAME_ATTR)
return api.nova.service_disable(request, host, 'nova-compute')
def search_link(x):
return '/admin/instances?q={0}'.format(x.hypervisor_hostname)

tables.py
class AdminHypervisorsTable(tables.DataTable):
hypervisor_hostname = tables.Column(
'hypervisor_hostname', verbose_name=_('Hostname'))
state = tables.Column(
lambda hyp: hyp.service.get('state', _('UNKNOWN')).title(),
verbose_name=_('State'))
running_vms = tables.Column(
'running_vms', link=search_link, verbose_name=_('Instances'))
...
class Meta:
name = 'hypervisors'
verbose_name = _('Hypervisors')
row_actions = (EnableAction, DisableAction)

Template
Standard Django template format
Typically leverage base horizon templates
(e.g. base.html)

index.html
{% extends 'base.html' %}
{% load i18n horizon humanize sizeformat %}
{% block title %}{% trans 'Hypervisors' %}{% endblock %}
{% block page_header %}
{% include 'horizon/common/_page_header.html' with title=_('All
Hypervisors') %}
{% endblock page_header %}
{% block main %}
{{ table.render }}
{% endblock %}

URLs Modules
Provides URL to View mappings

index.html
from django.conf.urls import patterns
from django.conf.urls import url

from openstack_dashboard.dashboards.cloudopen.hypervisors import views


urlpatterns = patterns(
'openstack_dashboard.dashboards.cloudopen.hypervisors.views'
url(r'^$', views.IndexView.as_view(), name='index'),
)

Completed Dashboard!
Nav entries

Panel rendering

Column sorting

Data retrieval

Linking

Row actions

RPC

Click through to Instances

Authen,ca,on
Keystone manages all Authen,ca,on for
OpenStack
To access an OpenStack service:
o authen,cate with Keystone and obtain a
TOKEN
o Use TOKEN for transac,ons with Service
Horizon passes all Auth requests to Keystone

backend.py
class MetacloudKeystoneBackend(KeystoneBackend):
def authenticate(self, request=None, username=None, password=None,
user_domain_name=None, auth_url=None):
keystone_client = get_keystone_client()
client = keystone_client.Client(
user_domain_name=user_domain_name, username=username,
password=password, auth_url=auth_url, )
# auth_ref gets assigned here

# If we made it here we succeeded. Create our User!


user = create_user_from_token(request, Token(auth_ref))
request.user = user
return user

Customiza,on Hooks
Change Site Title, Logo, Brand Links
Modify Dashboards and Panels
Change BuRon Styles
Use Custom Stylesheets
Use Custom Javascript

Custom Overrides Module


For site-wide customiza,on, Horizon allows for a
user-dened python customiza,on module
Customiza,ons can include:
o Registering/unregistering panels
o Modifying dashboard or panel aRributes
o Moving panels between dashboards
o Modifying aRributes of exis,ng UI elements

local_settings.py

HORIZON_CONFIG = {
...
'customization_module':
'openstack_dashboard.dashboards.cloudopen.overrides',
'test_enabled': True,
}

overrides.py
from openstack_dashboard.dashboards.cloudopen.test import panel\
as test_panel
from openstack_dashboard.dashboards.cloudopen import dashboard \
as cloudopen_dashboard
from django.conf import settings
import horizon

CLOUDOPEN_DASHBOARD_SETTINGS = horizon.get_dashboard('cloudopen')
if settings.HORIZON_CONFIG.get('test_enabled'):
CLOUDOPEN_DASHBOARD_SETTINGS .register(test_panel.Tests)
cloudopen_dashboard.BasePanels.panels += ('ui', )

Full CloudOpen Dashboard

Test Panel

Pluggable Settings
Since Icehouse release, Horizon enables
pluggable settings to control structure
o Enable/Disable new Dashboards
o Add new PanelGroups
o Add/Remove Panels to/from PanelGroups
Settings all live in:
o openstack_dashboard/local/enabled

Pluggable Settings
_10_cloudopen.py
_20_cloudopen_add_panel_group.py
_30_tests_add_panel.py
__init__.py

Pluggable Settings
_10_cloudopen.py
DASHBOARD = 'cloudopen'
DISABLED = False
ADD_INSTALLED_APPS = [
'openstack_dashboard.dashboards.cloudopen',
]

Pluggable Settings
_20_cloudopen_add_panel_group.py
DASHBOARD = 'cloudopen'
DISABLED = False
ADD_INSTALLED_APPS = [
'openstack_dashboard.dashboards.cloudopen',
]

Pluggable Settings
_30_tests_add_panel.py
PANEL = 'test'
PANEL_DASHBOARD = 'cloudopen'
PANEL_GROUP = 'tests'
ADD_PANEL = \
'openstack_dashboard.dashboards.cloudopen.test.panel.Tests'

Pluggable Settings
_30_tests_add_panel.py
PANEL = 'test'
PANEL_DASHBOARD = 'cloudopen'
PANEL_GROUP = 'tests'
ADD_PANEL = \
'openstack_dashboard.dashboards.cloudopen.test.panel.Tests'

Pluggable Settings

Pluggable Settings
_30_overview_add_panel.py
PANEL = 'test'
PANEL_DASHBOARD = 'cloudopen'
PANEL_GROUP = 'overview'
ADD_PANEL = \
'openstack_dashboard.dashboards.cloudopen.test.panel.Tests'

Pluggable Settings

Custom CSS and Javascript


Horizon templates provides blocks for custom
CSS and Javascript
To add custom CSS/JS, can either extend exis,ng
templates, or replace with your own custom
templates

base.html
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}{% endblock %} - {% site_branding %}</title>
{% block css %}
{% include "_stylesheets.html" %}
{% endblock %}
. . .
</head>
<body id="{% block body_id %}{% endblock %}">
{% block content %}
. . .
{% endblock %}
<div id="footer">{% block footer %}{% endblock %}</div>
{% block js %}
{% include "horizon/_scripts.html" %}
{% endblock %}
</body>
</html>

index.html
{% extends "base.html" %}
{% load i18n %}
{% block title %}{% trans "Volumes" %}{% endblock %}
{% block css %}
{% include "cloudopen/_stylesheets.html" %}
{% endblock %}
{% block page_header %}
{% include "horizon/common/_page_header.html" with title=_("Volumes") %}
{% endblock page_header %}
{% block main %}
<div id="volumes">{{ volumes_table.render }}</div>
<div id="volume-types">{{ volume_types_table.render }}</div>
{% endblock %}
{% block js%}
{% include "cloudopen/_scripts.html" %}
{% endblock %}

Horizon Base View

Custom View
Home button

Project selector

Simplified Nav

Context-driven Admin Panel

Custom View

Customized UI

Customized UI

Instance locking

Customized UI
Controller Page

Hypervisor Actions

Advanced Features

OPENSTACK THAT JUST WORKS

Client-side Rendering
Full dataset search

Full pagination

Cache up to 1K records client-side

Real-time Data

Updates every 5s

Increased platform visibility


Every node instrumented

Historical Metrics
Convenient access

Increased platform visibility

Every node instrumented

Up to 1 year of data

OpenStack Horizon
Contributing

OPENSTACK THAT JUST WORKS

Devstack and Contribu,ng


Devstack:
o A documented shell script to build complete
OpenStack development environments.
o hRp://devstack.org
Contributing to Horizon:
http://docs.openstack.org/developer/
horizon/contributing.html

Thank You
David Lapsley
@devlaps, david.lapsley@metacloud.com

OPENSTACK THAT JUST WORKS

You might also like