OpenStack Horizon: Controlling the Cloud using Django David Lapsley - - PowerPoint PPT Presentation

openstack horizon
SMART_READER_LITE
LIVE PREVIEW

OpenStack Horizon: Controlling the Cloud using Django David Lapsley - - PowerPoint PPT Presentation

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


slide-1
SLIDE 1

OPENSTACK THAT JUST WORKS

OpenStack Horizon:

Controlling the Cloud using Django

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

slide-2
SLIDE 2

OPENSTACK THAT JUST WORKS

OpenStack Horizon in Action

slide-3
SLIDE 3

Launching an Instance

slide-4
SLIDE 4

Admin Overview

slide-5
SLIDE 5

Project Overview

slide-6
SLIDE 6

Launching an Instance

slide-7
SLIDE 7

Launching an Instance

slide-8
SLIDE 8

Launching an Instance

slide-9
SLIDE 9

Launching an Instance

slide-10
SLIDE 10

Launching an Instance

slide-11
SLIDE 11

Launching an Instance

slide-12
SLIDE 12

OPENSTACK THAT JUST WORKS

OpenStack Clouds Architecture and Model

slide-13
SLIDE 13

OpenStack Model

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

slide-14
SLIDE 14

OpenStack Projects

  • Nova (Compute)
  • Nova (Network)
  • VM Registration (Glance)
  • Identity (Keystone)
  • Object Storage (Swift)
  • Block Storage (Cinder)
  • Dashboard (Horizon)
slide-15
SLIDE 15

OPENSTACK THAT JUST WORKS

OpenStack Horizon Controlling the Cloud with Django

slide-16
SLIDE 16

Horizon Overview

  • Django-based application deployed via

Apache and WSGI

  • Provides access to OpenStack services
  • Leverages existing technologies
  • Bootstrap, jQuery, Underscore.js,

AngularJS, D3.js, Rickshaw, LESS CSS

  • Extends Django to enhance extensibility
slide-17
SLIDE 17

Django Stack

slide-18
SLIDE 18

Horizon Stack

slide-19
SLIDE 19

Horizon UI Structure

Branding Dashboard Panel Group Panel Sidebar User Info Projects Panel Content

slide-20
SLIDE 20

Admin Dashboard

slide-21
SLIDE 21

Admin Dashboard

slide-22
SLIDE 22

Project Dashboard

slide-23
SLIDE 23

Horizon CSS Structure

slide-24
SLIDE 24

OPENSTACK THAT JUST WORKS

OpenStack Horizon Panels and Features

slide-25
SLIDE 25

Instance List

slide-26
SLIDE 26

Filtering

slide-27
SLIDE 27

Sorting

slide-28
SLIDE 28

Sorting

slide-29
SLIDE 29

Row Actions

slide-30
SLIDE 30

Table Actions

slide-31
SLIDE 31

Table Actions

slide-32
SLIDE 32

Table Actions

slide-33
SLIDE 33

Table Actions

slide-34
SLIDE 34

Instance Details

slide-35
SLIDE 35

Instance Details

slide-36
SLIDE 36

Instance Log

slide-37
SLIDE 37

Instance Console

slide-38
SLIDE 38

OPENSTACK THAT JUST WORKS

OpenStack Horizon Interesting Patterns

slide-39
SLIDE 39

Dashboards & Panels

  • Horizon provides a flexible framework for

creating Dashboards and Panels

  • Panels grouped into PanelGroups
  • PanelGroups into Dashboards
slide-40
SLIDE 40

Dashboard App

  • Dashboards created as Django Applications
  • Dashboard modules partitioned into:
  • static
  • templates
  • python modules
slide-41
SLIDE 41

Directory Structure

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

slide-42
SLIDE 42

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', ... )

slide-43
SLIDE 43

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)

slide-44
SLIDE 44

CloudOpen Dashboard

Dashboard PanelGroup

slide-45
SLIDE 45

View ¡Module ¡

  • View ¡module ¡,es ¡together ¡everything: ¡
  • Tables, ¡Templates, ¡API ¡Calls ¡
  • Horizon ¡base ¡views: ¡
  • APIView, ¡LoginView, ¡Mul,TableView, ¡

DataTableView, ¡MixedDataTableView, ¡ TabView, ¡TabbedTableView, ¡WorkflowView ¡

slide-46
SLIDE 46

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

slide-47
SLIDE 47

Table ¡Module ¡

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

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)

slide-49
SLIDE 49

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)

slide-50
SLIDE 50

Template

  • Standard Django template format
  • Typically leverage base horizon templates

(e.g. base.html)

slide-51
SLIDE 51

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 %}

slide-52
SLIDE 52

URLs ¡Modules ¡

  • Provides ¡URL ¡to ¡View ¡mappings ¡
slide-53
SLIDE 53

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'), )

slide-54
SLIDE 54

Completed Dashboard!

Nav entries Column sorting Panel rendering Linking RPC Data retrieval Row actions

slide-55
SLIDE 55

Click through to Instances

slide-56
SLIDE 56

Authen,ca,on ¡

  • Keystone ¡manages ¡all ¡Authen,ca,on ¡for ¡

OpenStack ¡

  • To ¡access ¡an ¡OpenStack ¡service: ¡
  • authen,cate ¡with ¡Keystone ¡and ¡obtain ¡a ¡

TOKEN ¡

  • Use ¡TOKEN ¡for ¡transac,ons ¡with ¡Service ¡
  • Horizon ¡passes ¡all ¡Auth ¡requests ¡to ¡Keystone ¡
slide-57
SLIDE 57

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

slide-58
SLIDE 58

Customiza,on ¡Hooks ¡

  • Change ¡Site ¡Title, ¡Logo, ¡Brand ¡Links ¡
  • Modify ¡Dashboards ¡and ¡Panels ¡
  • Change ¡BuRon ¡Styles ¡
  • Use ¡Custom ¡Stylesheets ¡
  • Use ¡Custom ¡Javascript ¡
slide-59
SLIDE 59

Custom ¡Overrides ¡Module ¡

  • For ¡site-­‑wide ¡customiza,on, ¡Horizon ¡allows ¡for ¡a ¡

user-­‑defined ¡python ¡customiza,on ¡module ¡

  • Customiza,ons ¡can ¡include: ¡
  • Registering/unregistering ¡panels ¡
  • Modifying ¡dashboard ¡or ¡panel ¡aRributes ¡
  • Moving ¡panels ¡between ¡dashboards ¡
  • Modifying ¡aRributes ¡of ¡exis,ng ¡UI ¡elements ¡
slide-60
SLIDE 60

local_settings.py

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

slide-61
SLIDE 61
  • verrides.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', )

slide-62
SLIDE 62

Full CloudOpen Dashboard

slide-63
SLIDE 63

Test Panel

slide-64
SLIDE 64

Pluggable Settings

  • Since Icehouse release, Horizon enables

pluggable settings to control structure

  • Enable/Disable new Dashboards
  • Add new PanelGroups
  • Add/Remove Panels to/from PanelGroups
  • Settings all live in:
  • openstack_dashboard/local/enabled
slide-65
SLIDE 65

Pluggable Settings

_10_cloudopen.py _20_cloudopen_add_panel_group.py _30_tests_add_panel.py __init__.py

slide-66
SLIDE 66

Pluggable Settings

_10_cloudopen.py

DASHBOARD = 'cloudopen' DISABLED = False ADD_INSTALLED_APPS = [ 'openstack_dashboard.dashboards.cloudopen', ]

slide-67
SLIDE 67

Pluggable Settings

_20_cloudopen_add_panel_group.py

DASHBOARD = 'cloudopen' DISABLED = False ADD_INSTALLED_APPS = [ 'openstack_dashboard.dashboards.cloudopen', ]

slide-68
SLIDE 68

Pluggable Settings

_30_tests_add_panel.py

PANEL = 'test' PANEL_DASHBOARD = 'cloudopen' PANEL_GROUP = 'tests' ADD_PANEL = \ 'openstack_dashboard.dashboards.cloudopen.test.panel.Tests'

slide-69
SLIDE 69

Pluggable Settings

_30_tests_add_panel.py

PANEL = 'test' PANEL_DASHBOARD = 'cloudopen' PANEL_GROUP = 'tests' ADD_PANEL = \ 'openstack_dashboard.dashboards.cloudopen.test.panel.Tests'

slide-70
SLIDE 70

Pluggable Settings

slide-71
SLIDE 71

Pluggable Settings

_30_overview_add_panel.py

PANEL = 'test' PANEL_DASHBOARD = 'cloudopen' PANEL_GROUP = 'overview' ADD_PANEL = \ 'openstack_dashboard.dashboards.cloudopen.test.panel.Tests'

slide-72
SLIDE 72

Pluggable Settings

slide-73
SLIDE 73

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 ¡

slide-74
SLIDE 74

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>

slide-75
SLIDE 75

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 %}

slide-76
SLIDE 76

Horizon Base View

slide-77
SLIDE 77

Custom View

Home button Project selector Simplified Nav Context-driven Admin Panel

slide-78
SLIDE 78

Custom View

slide-79
SLIDE 79

Customized UI

slide-80
SLIDE 80

Customized UI

Instance locking

slide-81
SLIDE 81

Customized UI

Hypervisor Actions Controller Page

slide-82
SLIDE 82

OPENSTACK THAT JUST WORKS

Advanced Features

slide-83
SLIDE 83

Client-side Rendering

“Full” dataset search Cache up to 1K records client-side “Full” pagination

slide-84
SLIDE 84

Real-time Data

Updates every 5s Increased platform visibility Every node instrumented

slide-85
SLIDE 85

Historical Metrics

Up to 1 year of data Increased platform visibility Every node instrumented Convenient access

slide-86
SLIDE 86

OPENSTACK THAT JUST WORKS

OpenStack Horizon Contributing

slide-87
SLIDE 87

Devstack ¡and ¡Contribu,ng ¡

  • Devstack: ¡
  • “A ¡documented ¡shell ¡script ¡to ¡build ¡complete ¡

OpenStack ¡development ¡environments.” ¡

  • hRp://devstack.org ¡
  • Contributing to Horizon:

– http://docs.openstack.org/developer/ horizon/contributing.html

slide-88
SLIDE 88

OPENSTACK THAT JUST WORKS

Thank You

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

slide-89
SLIDE 89