Merge remote-tracking branch 'starlingx/master' into HEAD
Change-Id: I05483a87c6db4c900ca75b5ffa5bee3e0b7ae07a Signed-off-by: Scott Little <scott.little@windriver.com>
This commit is contained in:
commit
79f16e85fd
|
@ -136,6 +136,39 @@ def cgtsclient(request):
|
||||||
insecure=insecure, cacert=cacert)
|
insecure=insecure, cacert=cacert)
|
||||||
|
|
||||||
|
|
||||||
|
class Label(base.APIResourceWrapper):
|
||||||
|
"""Wrapper for Inventory Labels"""
|
||||||
|
|
||||||
|
_attrs = ['uuid',
|
||||||
|
'label_key',
|
||||||
|
'label_value',
|
||||||
|
'host_uuid'
|
||||||
|
]
|
||||||
|
|
||||||
|
def __init__(self, apiresource):
|
||||||
|
super(Label, self).__init__(apiresource)
|
||||||
|
|
||||||
|
|
||||||
|
def host_label_list(request, host_id):
|
||||||
|
labels = cgtsclient(request).label.list(host_id)
|
||||||
|
return [Label(n) for n in labels]
|
||||||
|
|
||||||
|
|
||||||
|
def host_label_get(request, label_id):
|
||||||
|
label = cgtsclient(request).label.get(label_id)
|
||||||
|
if not label:
|
||||||
|
raise ValueError('No match found for label ID "%s".' % label_id)
|
||||||
|
return Label(label)
|
||||||
|
|
||||||
|
|
||||||
|
def host_label_assign(request, host_uuid, label):
|
||||||
|
return cgtsclient(request).label.assign(host_uuid, label)
|
||||||
|
|
||||||
|
|
||||||
|
def host_label_remove(request, label_id):
|
||||||
|
return cgtsclient(request).label.remove(label_id)
|
||||||
|
|
||||||
|
|
||||||
class Memory(base.APIResourceWrapper):
|
class Memory(base.APIResourceWrapper):
|
||||||
"""Wrapper for Inventory System"""
|
"""Wrapper for Inventory System"""
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2019 Wind River Systems, Inc.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
|
||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from cgtsclient import exc
|
||||||
|
from django.core.urlresolvers import reverse # noqa
|
||||||
|
from django import shortcuts
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from horizon import exceptions
|
||||||
|
from horizon import forms
|
||||||
|
from horizon import messages
|
||||||
|
from starlingx_dashboard import api as stx_api
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class AssignLabel(forms.SelfHandlingForm):
|
||||||
|
host_uuid = forms.CharField(
|
||||||
|
label=_("host_uuid"),
|
||||||
|
initial='host_uuid',
|
||||||
|
required=False,
|
||||||
|
widget=forms.widgets.HiddenInput)
|
||||||
|
|
||||||
|
host_id = forms.CharField(
|
||||||
|
label=_("host_id"),
|
||||||
|
initial='host_id',
|
||||||
|
required=False,
|
||||||
|
widget=forms.widgets.HiddenInput)
|
||||||
|
|
||||||
|
labelkey = forms.CharField(
|
||||||
|
label=_("Label Key"),
|
||||||
|
required=True)
|
||||||
|
|
||||||
|
labelvalue = forms.CharField(
|
||||||
|
label=_("Label Value"),
|
||||||
|
required=True)
|
||||||
|
|
||||||
|
failure_url = 'horizon:admin:inventory:detail'
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(AssignLabel, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
cleaned_data = super(AssignLabel, self).clean()
|
||||||
|
return cleaned_data
|
||||||
|
|
||||||
|
def handle(self, request, data):
|
||||||
|
labelkey = data['labelkey']
|
||||||
|
labelvalue = data['labelvalue']
|
||||||
|
attributes = {}
|
||||||
|
attributes[labelkey] = labelvalue
|
||||||
|
try:
|
||||||
|
new_labels = stx_api.sysinv.host_label_assign(
|
||||||
|
request,
|
||||||
|
data['host_uuid'],
|
||||||
|
attributes)
|
||||||
|
|
||||||
|
# Check if the label is successfully assigned
|
||||||
|
if not new_labels.labels:
|
||||||
|
raise exc.ClientException(
|
||||||
|
"Label Not Created: %s" % labelkey)
|
||||||
|
uuid = new_labels.labels[0]['uuid']
|
||||||
|
label_obj = stx_api.sysinv.host_label_get(
|
||||||
|
request,
|
||||||
|
uuid)
|
||||||
|
|
||||||
|
msg = _('Label "%s" was successfully created.') % \
|
||||||
|
getattr(label_obj, 'label_key')
|
||||||
|
LOG.debug(msg)
|
||||||
|
messages.success(request, msg)
|
||||||
|
return label_obj
|
||||||
|
except exc.HTTPNotFound:
|
||||||
|
msg = _("Label Not Created: %s") % labelkey
|
||||||
|
LOG.error(msg)
|
||||||
|
|
||||||
|
# Redirect to failure pg
|
||||||
|
redirect = reverse(self.failure_url, args=[data['host_id']])
|
||||||
|
return shortcuts.redirect(redirect)
|
||||||
|
except exc.ClientException as ce:
|
||||||
|
# Display REST API error message on UI
|
||||||
|
messages.error(request, ce)
|
||||||
|
LOG.error(ce)
|
||||||
|
|
||||||
|
# Redirect to failure pg
|
||||||
|
redirect = reverse(self.failure_url, args=[data['host_id']])
|
||||||
|
return shortcuts.redirect(redirect)
|
||||||
|
except Exception:
|
||||||
|
msg = _('Failed to assign label "%(label)s" to "%(uuid)s".') % \
|
||||||
|
{'label': labelkey, 'uuid': data['host_uuid']}
|
||||||
|
LOG.error(msg)
|
||||||
|
redirect = reverse(self.failure_url,
|
||||||
|
args=[data['host_id']])
|
||||||
|
exceptions.handle(request, msg, redirect=redirect)
|
|
@ -0,0 +1,93 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2019 Wind River Systems, Inc.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from django.core.urlresolvers import reverse # noqa
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
from django.utils.translation import ungettext_lazy
|
||||||
|
|
||||||
|
from horizon import exceptions
|
||||||
|
from horizon import tables
|
||||||
|
from starlingx_dashboard import api as stx_api
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def host_locked(host=None):
|
||||||
|
if not host:
|
||||||
|
return False
|
||||||
|
return host._administrative == 'locked'
|
||||||
|
|
||||||
|
|
||||||
|
class AssignKubeLabel(tables.LinkAction):
|
||||||
|
name = "assignKubelabel"
|
||||||
|
verbose_name = _("Assign Kube Label")
|
||||||
|
url = "horizon:admin:inventory:assignlabel"
|
||||||
|
classes = ("ajax-modal", "btn-create")
|
||||||
|
|
||||||
|
def get_link_url(self, datum=None):
|
||||||
|
host_id = self.table.kwargs['host_id']
|
||||||
|
return reverse(self.url, args=(host_id,))
|
||||||
|
|
||||||
|
def allowed(self, request, datum):
|
||||||
|
host = self.table.kwargs['host']
|
||||||
|
return host_locked(host)
|
||||||
|
|
||||||
|
|
||||||
|
class RemoveLabel(tables.DeleteAction):
|
||||||
|
@staticmethod
|
||||||
|
def action_present(count):
|
||||||
|
return ungettext_lazy(
|
||||||
|
"Delete Label",
|
||||||
|
"Delete Labels",
|
||||||
|
count
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def action_past(count):
|
||||||
|
return ungettext_lazy(
|
||||||
|
"Deleted Label",
|
||||||
|
"Deleted Labels",
|
||||||
|
count
|
||||||
|
)
|
||||||
|
|
||||||
|
def allowed(self, request, datum):
|
||||||
|
host = self.table.kwargs['host']
|
||||||
|
return host_locked(host)
|
||||||
|
|
||||||
|
def delete(self, request, label_id):
|
||||||
|
host_id = self.table.kwargs['host_id']
|
||||||
|
try:
|
||||||
|
stx_api.sysinv.host_label_remove(request, label_id)
|
||||||
|
except Exception:
|
||||||
|
msg = _('Failed to delete host %(hid)s label %(lid)s') % {
|
||||||
|
'hid': host_id, 'lid': label_id}
|
||||||
|
LOG.error(msg)
|
||||||
|
redirect = reverse('horizon:admin:inventory:detail',
|
||||||
|
args=(host_id,))
|
||||||
|
exceptions.handle(request, msg, redirect=redirect)
|
||||||
|
|
||||||
|
|
||||||
|
class LabelTable(tables.DataTable):
|
||||||
|
uuid = tables.Column('uuid',
|
||||||
|
verbose_name=_('UUID'))
|
||||||
|
|
||||||
|
label_key = tables.Column('label_key',
|
||||||
|
verbose_name=_('Label Key'))
|
||||||
|
|
||||||
|
label_value = tables.Column('label_value',
|
||||||
|
verbose_name=_('Label Value'))
|
||||||
|
|
||||||
|
def get_object_id(self, datum):
|
||||||
|
return str(datum.uuid)
|
||||||
|
|
||||||
|
class Meta(object):
|
||||||
|
name = "labels"
|
||||||
|
verbose_name = _("Label")
|
||||||
|
multi_select = False
|
||||||
|
row_actions = (RemoveLabel, )
|
||||||
|
table_actions = (AssignKubeLabel, )
|
|
@ -0,0 +1,50 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2019 Wind River Systems, Inc.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
|
||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from django.core.urlresolvers import reverse
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from horizon import exceptions
|
||||||
|
from horizon import forms
|
||||||
|
from starlingx_dashboard import api as stx_api
|
||||||
|
from starlingx_dashboard.dashboards.admin.inventory.kubernetes_labels.forms \
|
||||||
|
import AssignLabel
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class AssignLabelView(forms.ModalFormView):
|
||||||
|
form_class = AssignLabel
|
||||||
|
template_name = 'admin/inventory/kubelabels/assignkubelabel.html'
|
||||||
|
success_url = 'horizon:admin:inventory:detail'
|
||||||
|
failure_url = 'horizon:admin:inventory:detail'
|
||||||
|
|
||||||
|
def get_success_url(self):
|
||||||
|
return reverse(self.success_url,
|
||||||
|
args=(self.kwargs['host_id'],))
|
||||||
|
|
||||||
|
def get_failure_url(self):
|
||||||
|
return reverse(self.failure_url,
|
||||||
|
args=(self.kwargs['host_id'],))
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super(AssignLabelView, self).get_context_data(**kwargs)
|
||||||
|
context['host_id'] = self.kwargs['host_id']
|
||||||
|
return context
|
||||||
|
|
||||||
|
def get_initial(self):
|
||||||
|
initial = super(AssignLabelView, self).get_initial()
|
||||||
|
initial['host_id'] = self.kwargs['host_id']
|
||||||
|
try:
|
||||||
|
host = stx_api.sysinv.host_get(self.request, initial['host_id'])
|
||||||
|
except Exception:
|
||||||
|
exceptions.handle(self.request, _('Unable to retrieve host.'))
|
||||||
|
initial['host_uuid'] = host.uuid
|
||||||
|
return initial
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
# Copyright (c) 2013-2019 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
|
|
|
@ -22,6 +22,8 @@ from starlingx_dashboard.dashboards.admin.inventory.devices import \
|
||||||
tables as device_tables
|
tables as device_tables
|
||||||
from starlingx_dashboard.dashboards.admin.inventory.interfaces import \
|
from starlingx_dashboard.dashboards.admin.inventory.interfaces import \
|
||||||
tables as interface_tables
|
tables as interface_tables
|
||||||
|
from starlingx_dashboard.dashboards.admin.inventory.kubernetes_labels import \
|
||||||
|
tables as label_tables
|
||||||
from starlingx_dashboard.dashboards.admin.inventory.lldp import \
|
from starlingx_dashboard.dashboards.admin.inventory.lldp import \
|
||||||
tables as lldp_tables
|
tables as lldp_tables
|
||||||
from starlingx_dashboard.dashboards.admin.inventory.memories import \
|
from starlingx_dashboard.dashboards.admin.inventory.memories import \
|
||||||
|
@ -677,8 +679,20 @@ class LldpTab(tabs.TableTab):
|
||||||
return host.lldpneighbours
|
return host.lldpneighbours
|
||||||
|
|
||||||
|
|
||||||
|
class LabelsTab(tabs.TableTab):
|
||||||
|
table_classes = (label_tables.LabelTable, )
|
||||||
|
name = _("Labels")
|
||||||
|
slug = "labels"
|
||||||
|
template_name = ("admin/inventory/_detail_labels.html")
|
||||||
|
|
||||||
|
def get_labels_data(self):
|
||||||
|
host = self.tab_group.kwargs['host']
|
||||||
|
host.labels.sort(key=lambda f: (f.host_uuid))
|
||||||
|
return host.labels
|
||||||
|
|
||||||
|
|
||||||
class HostDetailTabs(tabs.TabGroup):
|
class HostDetailTabs(tabs.TabGroup):
|
||||||
slug = "inventory_details"
|
slug = "inventory_details"
|
||||||
tabs = (OverviewTab, CpuFunctionsTab, MemorysTab, StorageTab, PortsTab,
|
tabs = (OverviewTab, CpuFunctionsTab, MemorysTab, StorageTab, PortsTab,
|
||||||
InterfacesTab, LldpTab, SensorTab, DevicesTab, )
|
InterfacesTab, LldpTab, SensorTab, DevicesTab, LabelsTab, )
|
||||||
sticky = True
|
sticky = True
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
{% load i18n sizeformat %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
{% autoescape off %}
|
||||||
|
<div id="labels">
|
||||||
|
{{ labels_table.render }}
|
||||||
|
</div>
|
||||||
|
{% endautoescape %}
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,24 @@
|
||||||
|
{% extends "horizon/common/_modal_form.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block form_id %}assign_label_form{% endblock %}
|
||||||
|
{% block form_action %}{% url 'horizon:admin:inventory:assignlabel' host_id %}{% endblock %}
|
||||||
|
|
||||||
|
{% block modal-header %}{% trans "Assign Kubenetes Label" %}{% endblock %}
|
||||||
|
|
||||||
|
{% block modal-body %}
|
||||||
|
<div class="left">
|
||||||
|
<fieldset>
|
||||||
|
{% include "horizon/common/_form_fields.html" %}
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
<div class="right">
|
||||||
|
<h3>{% trans "Description" %}:</h3>
|
||||||
|
<p>{% trans "Assign a kubernetes label to the host." %}</p>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block modal-footer %}
|
||||||
|
<a class="btn btn-default cancel" data-dismiss="modal">Cancel</a>
|
||||||
|
<input class="btn btn-primary pull-right" type="submit" value="{% trans "Assign Kubernetes Label" %}" />
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,11 @@
|
||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% block title %}{% trans "Assign Kubernetes Label" %}{% endblock %}
|
||||||
|
|
||||||
|
{% block page_header %}
|
||||||
|
{% include "horizon/common/_page_header.html" with title=_("Assign Kubernetes Label") %}
|
||||||
|
{% endblock page_header %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
{% include "admin/inventory/kubelabels/_assignkubelabel.html" %}
|
||||||
|
{% endblock %}
|
|
@ -19,6 +19,8 @@ from starlingx_dashboard.dashboards.admin.inventory.interfaces.route import \
|
||||||
views as route_views
|
views as route_views
|
||||||
from starlingx_dashboard.dashboards.admin.inventory.interfaces import \
|
from starlingx_dashboard.dashboards.admin.inventory.interfaces import \
|
||||||
views as interface_views
|
views as interface_views
|
||||||
|
from starlingx_dashboard.dashboards.admin.inventory.kubernetes_labels import \
|
||||||
|
views as label_views
|
||||||
from starlingx_dashboard.dashboards.admin.inventory.lldp import \
|
from starlingx_dashboard.dashboards.admin.inventory.lldp import \
|
||||||
views as lldp_views
|
views as lldp_views
|
||||||
from starlingx_dashboard.dashboards.admin.inventory.memories import \
|
from starlingx_dashboard.dashboards.admin.inventory.memories import \
|
||||||
|
@ -150,5 +152,8 @@ urlpatterns = [
|
||||||
url(r'^(?P<host_id>[^/]+)/storages/(?P<partition_uuid>[^/]+)/'
|
url(r'^(?P<host_id>[^/]+)/storages/(?P<partition_uuid>[^/]+)/'
|
||||||
'editpartition/$',
|
'editpartition/$',
|
||||||
storage_views.EditPartitionView.as_view(),
|
storage_views.EditPartitionView.as_view(),
|
||||||
name='editpartition')
|
name='editpartition'),
|
||||||
|
url(r'^(?P<host_id>[^/]+)/assignlabel/$',
|
||||||
|
label_views.AssignLabelView.as_view(),
|
||||||
|
name='assignlabel')
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
# Copyright (c) 2013-2019 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
|
@ -172,6 +172,10 @@ class DetailView(tabs.TabbedTableView):
|
||||||
host.sensorgroups = stx_api.sysinv.host_sensorgroup_list(
|
host.sensorgroups = stx_api.sysinv.host_sensorgroup_list(
|
||||||
self.request, host.uuid)
|
self.request, host.uuid)
|
||||||
|
|
||||||
|
# Get K8s labels
|
||||||
|
host.labels = stx_api.sysinv.host_label_list(self.request,
|
||||||
|
host.uuid)
|
||||||
|
|
||||||
# Add patching status data to hosts
|
# Add patching status data to hosts
|
||||||
phost = stx_api.patch.get_host(self.request, host.hostname)
|
phost = stx_api.patch.get_host(self.request, host.hostname)
|
||||||
if phost is not None:
|
if phost is not None:
|
||||||
|
|
Loading…
Reference in New Issue