2016-01-12 10:51:36 -05:00

276 lines
10 KiB
Python

# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import logging
import json
import pprint
from django.core.urlresolvers import reverse
from django.core.urlresolvers import reverse_lazy
from django.utils.translation import ugettext_lazy as _
from horizon import exceptions
from horizon import forms
from horizon import tables
from horizon import messages
from openstack_dashboard import api
from openstack_dashboard.dashboards.admin.rackhd \
import forms as baremetal_forms
from openstack_dashboard.dashboards.admin.rackhd \
import tables as baremetal_tables
from openstack_dashboard.dashboards.admin.rackhd \
import json2html as j2h
from openstack_dashboard.dashboards.admin.rackhd import shovel
LOG = logging.getLogger(__name__)
class IndexView(tables.DataTableView):
# A very simple class-based view...
table_class = baremetal_tables.BareMetalTable
template_name = "admin/rackhd/index.html"
page_title = _("Baremetal")
class NodeData:
def __init__(self, uuid, name, hwaddr, events, state):
self.id = uuid
self.name = name
self.uuid = uuid
self.hwaddr = hwaddr
self.events = events
self.state = state
def get_data(self):
data = []
try:
nodes = shovel.request_nodes_get()
i = 0
for n in nodes:
dmi = shovel.get_catalog_data_by_source(n['id'],'dmi')
name = dmi['System Information']['Product Name']
hwaddr = n['name']
id = n['id']
events = '0'
n = self._find_ironic_node(id)
if n is not None:
events = n['extra'].get('eventcnt','0')
state = 'Registered'
else:
state = 'Unregistered'
i += i +1
data.append(self.NodeData(id, name, hwaddr, events, state))
return data
except Exception, e:
print
LOG.error("Excepton in get_baremetal_data(): {0}".format(e))
return data
def _find_ironic_node(self, id):
# ISSUE: iterating all nodes because query by name (onrack id) isn't working in ironic?
nodes = shovel.get_ironic_nodes()
for n in nodes['nodes']:
if n['extra'].get('nodeid', None) == id:
return n
return None
class RegisterView(forms.ModalFormView):
context_object_name = 'baremetal'
template_name = 'admin/rackhd/register.html'
form_class = baremetal_forms.RegisterForm
success_url = reverse_lazy('horizon:admin:rackhd:index')
page_title = _("Register Node")
def get_context_data(self, **kwargs):
context = super(RegisterView, self).get_context_data(**kwargs)
context["baremetal"] = self.kwargs['baremetal']
return context
def get_initial(self):
id = self.kwargs['baremetal']
node = shovel.request_node_get(id)
list_drivers = shovel.get_driver_list()['drivers']
drivers = [ elem['name'] for elem in list_drivers ]
ports = str(node['name']).split(',')
list_images = shovel.get_images_list()['images']
images = [ elem['name'] for elem in list_images ]
initial = super(RegisterView, self).get_initial()
initial.update({'nodeid': self.kwargs['baremetal'], 'node': node, 'drivers': drivers,'images':images,'ports': ports})
return initial
class UnregisterView(forms.ModalFormView):
context_object_name = 'baremetal'
template_name = 'admin/rackhd/unregister.html'
form_class = baremetal_forms.UnregisterForm
success_url = reverse_lazy('horizon:admin:rackhd:index')
page_title = _("Unegister Node")
def get_context_data(self, **kwargs):
context = super(UnregisterView, self).get_context_data(**kwargs)
context["baremetal"] = self.kwargs['baremetal']
return context
def get_initial(self):
id = self.kwargs['baremetal']
node = shovel.request_node_get(id)
initial = super(UnregisterView, self).get_initial()
initial.update({'nodeid': self.kwargs['baremetal'], 'node': node})
return initial
class FailoverView(forms.ModalFormView):
context_object_name = 'baremetal'
template_name = 'admin/rackhd/register.html'
form_class = baremetal_forms.RegisterForm
success_url = reverse_lazy('horizon:admin:rackhd:index')
page_title = _("Failover")
def _find_ironic_node(self, id):
nodes = shovel.get_ironic_nodes()
for n in nodes['nodes']:
if n['extra'].get('nodeid', None) == id:
return n
def _remove_node(self,id):
try:
result = shovel.unregister_node_del(id)
return True
except Exception:
redirect = reverse('horizon:admin:rackhd:index')
return False
def get_context_data(self, **kwargs):
context = super(FailoverView, self).get_context_data(**kwargs)
context["baremetal"] = self.kwargs['baremetal']
return context
def get_initial(self):
initial = super(FailoverView, self).get_initial()
current_id = self.kwargs['baremetal']
inode = self._find_ironic_node(current_id)
try:
if inode is not None:
failover = inode['extra'].get('failover', None)
if failover is not None:
node = shovel.request_node_get(failover)
list_drivers = shovel.get_driver_list()['drivers']
drivers = [ elem['name'] for elem in list_drivers ]
initial.update({'nodeid': self.kwargs['baremetal'], 'node': node, 'drivers': drivers})
else:
raise ValueError('Failover node not set')
else:
raise ValueError('Registered node not found')
except ValueError as e:
redirect = reverse('horizon:admin:rackhd:index')
messages.error(self.request, _(e.message))
raise Exception(e.message)
self._remove_node(current_id)
messages.success(self.request, _('Removed node {0}'.format(current_id)))
return initial
class BareMetalDetailView(tables.DataTableView):
table_class = baremetal_tables.BareMetalDetailsTable
template_name = 'admin/rackhd/detail.html'
page_title = _('Details')
class CatalogData:
def __init__(self, id, catalog):
self.id = id
self.catalog = catalog
def get_data(self):
uuid = self.kwargs['baremetal']
dmi = shovel.get_catalog_data_by_source(id = uuid, source = 'dmi')
scsi = shovel.get_catalog_data_by_source(id = uuid, source = 'lsscsi')
del dmi['Processor Information'] # don't feel like rendering this now
dmi.update({'Storage Information' : scsi})
catalog = json.dumps(dmi, sort_keys=True, indent=4, separators=(',', ': '))
data = [ self.CatalogData(id, j2h.json2html.convert( json = catalog, table_attributes="class=\"table-bordered table\"" )) ]
return data
class BareMetalEventView(tables.MultiTableView):
table_classes = (baremetal_tables.BareMetalLastEventTable,
baremetal_tables.BareMetalAllEventsTable,)
template_name = 'admin/rackhd/events.html'
page_title = _('Events')
name = _("Events")
slug = "events"
class HTMLData:
def __init__(self, id, html):
self.id = id
self.html = html
class SELEventData:
def __init__(self, id, type, value, logid, number, time, date, event):
self.id = id
self.date = date
self.event = event
self.logid = logid
self.sensor_num = number
self.sensor_type = type
self.time = time
self.value = value
def _find_ironic_node(self, id):
nodes = shovel.get_ironic_nodes()
for n in nodes['nodes']:
if n['extra'].get('nodeid', None) == id:
return n
def get_lastevent_data(self):
id = self.kwargs['baremetal']
try:
node = self._find_ironic_node(id)
if node is not None:
entry = node['extra']['events']
return [ self.SELEventData(id,
entry['sensorType'],
entry['value'],
str(int(entry['logId'], 16)),
entry['sensorNumber'],
entry['time'],
entry['date'],
entry['event']) ]
except:
pass
return []
def get_allevents_data(self):
id = self.kwargs['baremetal']
try:
sel = shovel.get_current_sel_data(id)[0].get('sel', [])
except KeyError as e:
redirect = reverse('horizon:admin:rackhd:index')
messages.error(self.request, _('No SEL data available, check node {0} poller task'.format(id)))
raise KeyError(e.message)
data = []
if False: # TODO: enable this, view is not iterating the data list correctly
for entry in sel:
data.append(self.SELEventData(id,
entry['sensorType'],
entry['value'],
str(int(entry['logId'], 16)),
entry['sensorNumber'],
entry['time'],
entry['date'],
entry['event'] ))
else: # build html
rsel = list(reversed(sel))
j = json.dumps({"":rsel}, sort_keys=True, indent=4, separators=(',', ': '))
return [ self.HTMLData(id, j2h.json2html.convert(json=j, table_attributes="class=\"table\"")) ]
return data