20140821 delapsley-cloudopen-public

95
OPENSTACK THAT JUST WORKS OpenStack Horizon: Controlling the Cloud using Django David Lapsley @devlaps, [email protected] August 21, 2014

Upload: david-lapsley

Post on 15-Jan-2015

226 views

Category:

Documents


2 download

DESCRIPTION

The OpenStack project was launched by Rackspace and NASA in July 2010. Since then it has gained considerable momentum, with over 200 companies joining the project. Horizon is OpenStack’s web-based user interface. 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. Customization is key to the Horizon framework. It allows developers to construct their own dashboards, panel groups, and panels, and assemble them via a common navigation/presentation framework. In this presentation, David will provide a brief introduction to OpenStack and Horizon. Then he will review Horizon’s architecture, explain how it integrates with other OpenStack services, examine its most interesting features, and describe how to start developing with it.

TRANSCRIPT

OPENSTACK THAT JUST WORKS

OpenStack Horizon:Controlling the Cloud using Django

David Lapsley@devlaps, [email protected]

August 21, 2014

OPENSTACK THAT JUST WORKS

OpenStack Horizon in Action

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 THAT JUST WORKS

OpenStack CloudsArchitecture and Model

OpenStack Model

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

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

OpenStack Projects

● Compute (Nova)

● Network (Nova, Neutron)

● VM Registration (Glance)

● Identity (Keystone)

● Object Storage (Swift, …)

● Block Storage (Cinder)

● Dashboard (Horizon)

OPENSTACK THAT JUST WORKS

OpenStack HorizonControlling the Cloud with Django

Horizon Overview

● Django-based application deployed via

Apache and WSGI

● Provides access to OpenStack services

● Leverages existing technologieso Bootstrap, jQuery, Underscore.js,

AngularJS, D3.js, Rickshaw, LESS CSS

● Extends Django to enhance

extensibility

Django Stack

Horizon Stack

Horizon UI Structure

Branding

Dashboard

Panel Group

Panel

Sidebar

User InfoProjects

Panel Content

Admin Dashboard

Admin Dashboard

Project Dashboard

Project Dashboard

Horizon CSS Structure

OPENSTACK THAT JUST WORKS

OpenStack HorizonPanels and Features

Instance List

Filtering

Sorting

Sorting

Row Actions

Table Actions

Table Actions

Table Actions

Table Actions

Instance Details

Instance Details

Instance Log

Instance Console

OPENSTACK THAT JUST WORKS

OpenStack HorizonDashboards and Panels

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 statico templateso python modules

Directory Structurecloudopen/ __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.pyclass BasePanelGroup(horizon.PanelGroup): slug = "overview" name = _("Overview") panels = ("hypervisors",)

class CloudOpen(horizon.Dashboard): name = _("Cloudopen") slug = "cloudopen" panels = (BasePanelGroup,) default_panel = "hypervisors" roles = ("admin",)

horizon.register(CloudOpen)

CloudOpen DashboardDashboard

PanelGroup

Panel● Panels are created as Python Modules● Panel modules partitioned into:o static/o templates/o python modules:

urls.py, views.py, panel.pytables.py, forms.py, tabs.py, tests.py

Directory Structurecloudopen/ hypervisors/

__init__.py panel.py urls.py views.py

tests.py tables.py templates/

cloudopen/ hypervisors/ index.html static/

cloudopen/ hypervisors /

panel.py

from django.utils.translation import ugettext_lazy as _ import horizon from openstack_dashboard.dashboards.cloudopen import dashboard class Hypervisors(horizon.Panel): name = _(”Hypervisors") slug = 'hypervisors' dashboard.CloudOpen.register(Hypervisors)

CloudOpen DashboardDashboard

PanelGroup

Panel

View Module● View module ties together everything:o Tables, Templates, API Calls

● Horizon base views:o APIView, LoginView, MultiTableView,

DataTableView, MixedDataTableView, TabView,

TabbedTableView, WorkflowView

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 feelo configurable table_actions and

row_actionso select/multi-select columno sortingo pagination

● Functionality is split server- and client-side

tables.pyclass 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.pyclass 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 %}<div class="quota-dynamic"> <h3>{% trans "Hypervisor Summary" %}</h3> <div class="d3_quota_bar">

<div class="d3_pie_chart" …></div> </div> …</div>

{{ table.render }} {% endblock %}

URLs Modules● Provides URL to View mappings

urls.py

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

Column sorting

Panel rendering

Linking

RPCData retrieval

Row actions

Click through to Instances

OPENSTACK THAT JUST WORKS

OpenStack HorizonCustomization Hooks

Customization Hooks● Change Site Title, Logo, Brand Links● Modify Dashboards and Panels● Change Button Styles● Use Custom Stylesheets● Use Custom Javascript

Custom Overrides Module● For site-wide customization, Horizon allows for a

user-defined python customization module● Customizations can include:o Registering/unregistering panelso Modifying dashboard or panel attributeso Moving panels between dashboardso Modifying attributes of existing 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)

Full CloudOpen Dashboard

Test Panel

OPENSTACK THAT JUST WORKS

OpenStack HorizonPluggable Settings

Pluggable Settings

● Since Icehouse release, Horizon enables

pluggable settings to control structureo Enable/Disable new Dashboardso Add new PanelGroupso 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

PANEL_GROUP = 'tests'

PANEL_GROUP_NAME = 'Tests'

PANEL_GROUP_DASHBOARD = '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

OPENSTACK THAT JUST WORKS

OpenStack HorizonCustom CSS and JS

Custom CSS and Javascript● Horizon templates provides blocks for custom

CSS and Javascript● To add custom CSS/JS, can either extend existing

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

Customized UIHome button Project selector

Simplified Nav

Context-driven Admin Panel

Customized UI

Customized UI

Customized UI

Instance locking

Customized UI

Hypervisor Actions

Controller Page

OPENSTACK THAT JUST WORKS

Advanced Features

Client-side Rendering

“Full” dataset search

Cache up to 1K records client-side

“Full” pagination

Real-time Data Updates every 5s

Increased platform visibility

Every node instrumented

Historical MetricsUp to 1 year of

data

Increased platform visibility

Every node instrumented

Convenient access

OPENSTACK THAT JUST WORKS

OpenStack HorizonContributing

Devstack and Contributing● Devstack:o “A documented shell script to build complete

OpenStack development environments.”o http://devstack.org

● Contributing to Horizon:

– http://docs.openstack.org/developer/

horizon/contributing.html

OPENSTACK THAT JUST WORKS

Thank You

David Lapsley@devlaps, [email protected]