Download - openstack horizon
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 Clouds Architecture 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 ● Nova (Compute) ● Nova (Network) ● VM Registration (Glance) ● Identity (Keystone)
● Object Storage (Swift) ● Block Storage (Cinder) ● Dashboard (Horizon)
OPENSTACK THAT JUST WORKS
OpenStack Horizon Controlling the Cloud with Django
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
Branding
Dashboard
Panel Group
Panel
Sidebar
User Info Projects
Panel Content
Admin Dashboard
Admin Dashboard
Project Dashboard
Horizon CSS Structure
OPENSTACK THAT JUST WORKS
OpenStack Horizon Panels 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 Horizon Interesting Patterns
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, 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 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
Column sorting
Panel rendering
Linking
RPC Data retrieval
Row actions
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-‐defined 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
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 Metrics Up to 1 year of data
Increased platform visibility Every node instrumented
Convenient access
OPENSTACK THAT JUST WORKS
OpenStack Horizon Contributing
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