diff --git a/starlingx-dashboard/centos/build_srpm.data b/starlingx-dashboard/centos/build_srpm.data index 4e455cc3..a9a7d14a 100644 --- a/starlingx-dashboard/centos/build_srpm.data +++ b/starlingx-dashboard/centos/build_srpm.data @@ -1,2 +1,2 @@ SRC_DIR="starlingx-dashboard" -TIS_PATCH_VER=22 +TIS_PATCH_VER=23 diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/api/fm.py b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/api/fm.py index 38263f6d..6d395b7a 100644 --- a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/api/fm.py +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/api/fm.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2018 Wind River Systems, Inc. +# Copyright (c) 2018-2019 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -248,9 +248,14 @@ class EventSuppression(base.APIResourceWrapper): super(EventSuppression, self).__init__(apiresource) -def event_suppression_list(request): +def event_suppression_list(request, include_unsuppressed=False): + q = [] + if not include_unsuppressed: + q.append( + dict(field='suppression_status', value='suppressed', op='eq', + type='string')) - suppression_list = fmclient(request).event_suppression.list() + suppression_list = fmclient(request).event_suppression.list(q) return [EventSuppression(n) for n in suppression_list] diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/api/rest/fm.py b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/api/rest/fm.py index c214c462..b2be0521 100644 --- a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/api/rest/fm.py +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/api/rest/fm.py @@ -1,8 +1,9 @@ # -# Copyright (c) 2018 Wind River Systems, Inc. +# Copyright (c) 2018-2019 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # +import logging from django.views import generic @@ -11,6 +12,9 @@ from openstack_dashboard.api.rest import utils as rest_utils from starlingx_dashboard.api import fm +LOG = logging.getLogger(__name__) + + @urls.register class AlarmSummary(generic.View): """API for retrieving alarm summaries.""" @@ -22,3 +26,81 @@ class AlarmSummary(generic.View): include_suppress = request.GET.get('include_suppress', False) result = fm.alarm_summary_get(request, include_suppress) return result.to_dict() + + +@urls.register +class Alarms(generic.View): + """API for retrieving alarms.""" + url_regex = r'fm/alarm_list/$' + + @rest_utils.ajax() + def get(self, request): + search_opts = {'suppression': 'SUPPRESS_SHOW'} + result = fm.alarm_list(request, search_opts=search_opts) + + return {'items': [sc.to_dict() for sc in result]} + + +@urls.register +class Alarm(generic.View): + """API for retrieving one alarm.""" + url_regex = r'fm/alarm_get/(?P[^/]+|default)/$' + + @rest_utils.ajax() + def get(self, request, uuid): + result = fm.alarm_get(request, uuid) + return result.to_dict() + + +@urls.register +class Events(generic.View): + """API for retrieving events.""" + url_regex = r'fm/event_log_list/$' + + @rest_utils.ajax() + def get(self, request): + search_opts = {'suppression': 'SUPPRESS_SHOW'} + result, _more = fm.event_log_list(request, search_opts=search_opts) + + return {'items': [sc.to_dict() for sc in result]} + + +@urls.register +class Event(generic.View): + """API for retrieving one event.""" + url_regex = r'fm/event_log_get/(?P[^/]+|default)/$' + + @rest_utils.ajax() + def get(self, request, uuid): + result = fm.event_log_get(request, uuid) + return result.to_dict() + + +@urls.register +class EventsSuppression(generic.View): + """API for retrieving events suppression.""" + url_regex = r'fm/events_suppression_list/$' + + @rest_utils.ajax() + def get(self, request): + + if 'include_unsuppressed' in request.GET: + include_unsuppressed = True + else: + include_unsuppressed = False + + result = fm.event_suppression_list( + request, include_unsuppressed=include_unsuppressed) + return {'items': [sc.to_dict() for sc in result]} + + +@urls.register +class EventSuppression(generic.View): + """API for updating the event suppression.""" + url_regex = r'fm/event_suppression/(?P[^/]+)$' + + @rest_utils.ajax(data_required=True) + def patch(self, request, uuid): + + result = fm.event_suppression_update(request, uuid, **(request.DATA)) + return result.to_dict() diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/__init__.py b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/active_alarms/__init__.py old mode 100755 new mode 100644 similarity index 100% rename from starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/__init__.py rename to starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/active_alarms/__init__.py diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/panel.py b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/active_alarms/panel.py old mode 100755 new mode 100644 similarity index 71% rename from starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/panel.py rename to starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/active_alarms/panel.py index ada7b052..59703066 --- a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/panel.py +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/active_alarms/panel.py @@ -1,9 +1,3 @@ -# Copyright 2012 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. -# All Rights Reserved. -# -# Copyright 2012 Nebula, Inc. -# # 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 @@ -16,7 +10,9 @@ # License for the specific language governing permissions and limitations # under the License. # -# Copyright (c) 2013-2017 Wind River Systems, Inc. +# Copyright (c) 2019 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 # from django.utils.translation import ugettext_lazy as _ # noqa @@ -26,10 +22,9 @@ from openstack_dashboard.api import base from openstack_dashboard.dashboards.admin import dashboard -class FaultManagement(horizon.Panel): - name = _("Fault Management") - slug = 'fault_management' - permissions = ('openstack.services.platform',) +class ActiveAlarms(horizon.Panel): + name = _("Active Alarms") + slug = "active_alarms" def allowed(self, context): if context['request'].user.services_region == 'SystemController': @@ -37,7 +32,7 @@ class FaultManagement(horizon.Panel): if not base.is_service_enabled(context['request'], 'platform'): return False else: - return super(FaultManagement, self).allowed(context) + return super(ActiveAlarms, self).allowed(context) def nav(self, context): if context['request'].user.services_region == 'SystemController': @@ -48,4 +43,4 @@ class FaultManagement(horizon.Panel): return True -dashboard.Admin.register(FaultManagement) +dashboard.Admin.register(ActiveAlarms) diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/active_alarms/urls.py b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/active_alarms/urls.py new file mode 100644 index 00000000..a429fa0f --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/active_alarms/urls.py @@ -0,0 +1,29 @@ +# 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. +# +# Copyright (c) 2019 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +from django.conf.urls import url +from django.utils.translation import ugettext_lazy as _ +from horizon.browsers import views + +from starlingx_dashboard.dashboards.admin.active_alarms import \ + views as viewsDjango + +title = _("Active Alarms") +urlpatterns = [ + url(r'^$', views.AngularIndexView.as_view(title=title), name='index'), + url(r'^banner/$', viewsDjango.BannerView.as_view(), name='banner') +] diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/active_alarms/views.py b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/active_alarms/views.py new file mode 100755 index 00000000..296172ef --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/active_alarms/views.py @@ -0,0 +1,76 @@ +# 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. +# +# Copyright (c) 2013-2019 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +import logging + +from django.utils.translation import ugettext_lazy as _ # noqa +from django.views.generic import TemplateView + +from horizon import exceptions +from openstack_dashboard.api.base import is_service_enabled +from starlingx_dashboard.api import dc_manager +from starlingx_dashboard.api import fm + + +LOG = logging.getLogger(__name__) + + +class BannerView(TemplateView): + template_name = 'header/_alarm_banner.html' + + def get_context_data(self, **kwargs): + + context = super(BannerView, self).get_context_data(**kwargs) + + if not self.request.is_ajax(): + raise exceptions.NotFound() + + if (not self.request.user.is_authenticated() or + not self.request.user.is_superuser): + context["alarmbanner"] = False + elif 'dc_admin' in self.request.META.get('HTTP_REFERER'): + summaries = self.get_subcloud_data() + central_summary = self.get_data() + summaries.append(central_summary) + context["dc_admin"] = True + context["alarmbanner"] = True + context["OK"] = len( + [s for s in summaries if s.status == 'OK']) + context["degraded"] = len( + [s for s in summaries if s.status == 'degraded']) + context["critical"] = len( + [s for s in summaries if s.status == 'critical']) + context["disabled"] = len( + [s for s in summaries if s.status == 'disabled']) + elif is_service_enabled(self.request, 'platform'): + context["summary"] = self.get_data() + context["alarmbanner"] = True + + return context + + def get_data(self): + summary = None + try: + summary = fm.alarm_summary_get(self.request) + except Exception: + exceptions.handle(self.request, + _('Unable to retrieve alarm summary.')) + + return summary + + def get_subcloud_data(self): + return dc_manager.alarm_summary_list(self.request) diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/events/__init__.py b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/events/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/events/panel.py b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/events/panel.py new file mode 100644 index 00000000..f5479004 --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/events/panel.py @@ -0,0 +1,41 @@ +# 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. +# +# Copyright (c) 2019 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +from django.utils.translation import ugettext_lazy as _ +import horizon +from openstack_dashboard.api import base + + +class Events(horizon.Panel): + name = _("Events") + slug = "events" + + def allowed(self, context): + if context['request'].user.services_region == 'SystemController': + return False + if not base.is_service_enabled(context['request'], 'platform'): + return False + else: + return super(Events, self).allowed(context) + + def nav(self, context): + if context['request'].user.services_region == 'SystemController': + return False + if not base.is_service_enabled(context['request'], 'platform'): + return False + else: + return True diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/events/urls.py b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/events/urls.py new file mode 100644 index 00000000..1bdab5f2 --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/events/urls.py @@ -0,0 +1,25 @@ +# 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. +# +# Copyright (c) 2019 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +from django.conf.urls import url +from django.utils.translation import ugettext_lazy as _ +from horizon.browsers import views + +title = _("Events") +urlpatterns = [ + url('', views.AngularIndexView.as_view(title=title), name='index'), +] diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/events_suppression/__init__.py b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/events_suppression/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/events_suppression/panel.py b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/events_suppression/panel.py new file mode 100644 index 00000000..aacf6f07 --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/events_suppression/panel.py @@ -0,0 +1,41 @@ +# 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. +# +# Copyright (c) 2019 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +from django.utils.translation import ugettext_lazy as _ +import horizon +from openstack_dashboard.api import base + + +class EventsSuppression(horizon.Panel): + name = _("Events Suppression") + slug = "events_suppression" + + def allowed(self, context): + if context['request'].user.services_region == 'SystemController': + return False + if not base.is_service_enabled(context['request'], 'platform'): + return False + else: + return super(EventsSuppression, self).allowed(context) + + def nav(self, context): + if context['request'].user.services_region == 'SystemController': + return False + if not base.is_service_enabled(context['request'], 'platform'): + return False + else: + return True diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/events_suppression/urls.py b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/events_suppression/urls.py new file mode 100644 index 00000000..aa890e82 --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/events_suppression/urls.py @@ -0,0 +1,25 @@ +# 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. +# +# Copyright (c) 2019 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +from django.conf.urls import url +from django.utils.translation import ugettext_lazy as _ +from horizon.browsers import views + +title = _("Events Suppression") +urlpatterns = [ + url('', views.AngularIndexView.as_view(title=title), name='index'), +] diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/tables.py b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/tables.py deleted file mode 100755 index 7c5db5c8..00000000 --- a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/tables.py +++ /dev/null @@ -1,280 +0,0 @@ -# Copyright 2012 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. -# All Rights Reserved. -# -# Copyright 2012 Nebula, Inc. -# -# 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. -# -# Copyright (c) 2013-2018 Wind River Systems, Inc. -# - - -from django.utils.html import escape as escape_html -from django.utils.safestring import mark_safe - -from django.utils.translation import pgettext_lazy -from django.utils.translation import ugettext_lazy as _ # noqa -from django.utils.translation import ungettext_lazy - -from horizon import exceptions -from horizon import tables -from horizon.utils import filters as utils_filters -from starlingx_dashboard import api as stx_api - -SUPPRESSION_STATUS_CHOICES = ( - ("suppressed", False), - ("unsuppressed", True), - ("None", True), -) -SUPPRESSION_STATUS_DISPLAY_CHOICES = ( - ("suppressed", pgettext_lazy("Indicates this type of alarm \ - is suppressed", "suppressed")), - ("unsuppressed", pgettext_lazy("Indicates this type of alarm \ - is unsuppressed", "unsuppressed")), - ("None", pgettext_lazy("Indicates an event type", "None")), -) - - -class AlarmsLimitAction(tables.LimitAction): - verbose_name = _("Alarms") - - -class AlarmFilterAction(tables.FixedWithQueryFilter): - def __init__(self, **kwargs): - super(AlarmFilterAction, self).__init__(**kwargs) - - self.filter_choices = [ - ( - (stx_api.fm.FM_SUPPRESS_SHOW, _("Show Suppressed"), True), - (stx_api.fm.FM_SUPPRESS_HIDE, _('Hide Suppressed'), True) - ) - ] - self.default_value = stx_api.fm.FM_SUPPRESS_HIDE - - self.disabled_choices = ['enabled'] - - -class AlarmsTable(tables.DataTable): - alarm_id = tables.Column('alarm_id', - link="horizon:admin:fault_management:detail", - verbose_name=_('Alarm ID')) - reason_text = tables.Column('reason_text', - verbose_name=_('Reason Text')) - entity_instance_id = tables.Column('entity_instance_id', - verbose_name=_('Entity Instance ID')) - suppression_status = \ - tables.Column('suppression_status', - verbose_name=_('Suppression Status'), - status=True, - status_choices=SUPPRESSION_STATUS_CHOICES, - display_choices=SUPPRESSION_STATUS_DISPLAY_CHOICES) - severity = tables.Column('severity', - verbose_name=_('Severity')) - timestamp = tables.Column('timestamp', - attrs={'data-type': 'timestamp'}, - filters=(utils_filters.parse_isotime,), - verbose_name=_('Timestamp')) - - def get_object_id(self, obj): - return obj.uuid - - class Meta(object): - name = "alarms" - verbose_name = _("Active Alarms") - status_columns = ["suppression_status"] - limit_param = "alarm_limit" - pagination_param = "alarm_marker" - prev_pagination_param = 'prev_alarm_marker' - table_actions = (AlarmFilterAction, AlarmsLimitAction) - multi_select = False - hidden_title = False - - -class EventLogsLimitAction(tables.LimitAction): - verbose_name = _("Events") - - -class EventLogsFilterAction(tables.FixedWithQueryFilter): - def __init__(self, **kwargs): - super(EventLogsFilterAction, self).__init__(**kwargs) - - self.filter_choices = [ - ( - (stx_api.fm.FM_ALL, _("All Events"), True), - (stx_api.fm.FM_ALARM, _('Alarm Events'), True), - (stx_api.fm.FM_LOG, _('Log Events'), True), - ), - ( - (stx_api.fm.FM_SUPPRESS_SHOW, _("Show Suppressed"), True), - (stx_api.fm.FM_SUPPRESS_HIDE, _('Hide Suppressed'), True) - ) - ] - self.default_value = stx_api.fm.FM_ALL_SUPPRESS_HIDE - - self.disabled_choices = ['enabled', 'enabled'] - - -class EventLogsTable(tables.DataTable): - timestamp = tables.Column('timestamp', - attrs={'data-type': 'timestamp'}, - filters=(utils_filters.parse_isotime,), - verbose_name=_('Timestamp')) - - state = tables.Column('state', verbose_name=_('State')) - event_log_id = tables.Column('event_log_id', - link="horizon:admin:fault_management:" - "eventlogdetail", - verbose_name=_('ID')) - reason_text = tables.Column('reason_text', verbose_name=_('Reason Text')) - entity_instance_id = tables.Column('entity_instance_id', - verbose_name=_('Entity Instance ID')) - suppression_status = \ - tables.Column('suppression_status', - verbose_name=_('Suppression Status'), - status=True, - status_choices=SUPPRESSION_STATUS_CHOICES, - display_choices=SUPPRESSION_STATUS_DISPLAY_CHOICES) - severity = tables.Column('severity', verbose_name=_('Severity')) - - def get_object_id(self, obj): - return obj.uuid - - class Meta(object): - name = "eventLogs" - verbose_name = _("Events") - status_columns = ["suppression_status"] - table_actions = (EventLogsFilterAction, - EventLogsLimitAction,) - limit_param = "event_limit" - pagination_param = "event_marker" - prev_pagination_param = 'prev_event_marker' - multi_select = False - - -class SuppressEvent(tables.BatchAction): - name = "suppress" - action_type = 'danger' - icon = "remove" - help_text = _("Events with selected Alarm ID will be suppressed.") - - @staticmethod - def action_present(count): - return ungettext_lazy( - "Suppress Event", - "Suppress Event", - count - ) - - @staticmethod - def action_past(count): - return ungettext_lazy( - "Events suppressed for Alarm ID", - "Events suppressed for Alarm ID", - count - ) - - def allowed(self, request, datum): - """Allow suppress action if Alarm ID is unsuppressed.""" - if datum.suppression_status == stx_api.fm.FM_SUPPRESSED: - return False - - return True - - def action(self, request, obj_id): - kwargs = {"suppression_status": stx_api.fm.FM_SUPPRESSED} - - try: - stx_api.fm.event_suppression_update(request, obj_id, **kwargs) - except Exception: - exceptions.handle(request, - _('Unable to set specified alarm type to \ - suppressed\'s.')) - - -class UnsuppressEvent(tables.BatchAction): - name = "unsuppress" - action_type = 'danger' - icon = "remove" - help_text = _("Events with selected Alarm ID will be unsuppressed.") - - @staticmethod - def action_present(count): - return ungettext_lazy( - "Unsuppress Event", - "Unsuppress Event", - count - ) - - @staticmethod - def action_past(count): - return ungettext_lazy( - "Events unsuppressed for Alarm ID", - "Events unsuppressed for Alarm ID", - count - ) - - def allowed(self, request, datum): - """Allow unsuppress action if Alarm ID is suppressed.""" - if datum.suppression_status == stx_api.fm.FM_UNSUPPRESSED: - return False - - return True - - def action(self, request, obj_id): - kwargs = {"suppression_status": stx_api.fm.FM_UNSUPPRESSED} - - try: - stx_api.fm.event_suppression_update(request, obj_id, **kwargs) - except Exception: - exceptions.handle(request, - _('Unable to set specified alarm type to \ - unsuppressed\'s.')) - - -class EventsSuppressionTable(tables.DataTable): - # noinspection PyMethodParameters - def description_inject(row_data): # pylint: disable=no-self-argument - description = \ - escape_html(str(row_data.description)).replace("\n", "
") - description = description.replace("\t", "    ") - description = description.replace(" " * 4, " " * 4) - description = description.replace(" " * 3, " " * 3) - description = description.replace(" " * 2, " " * 2) - return mark_safe(description) - - alarm_id = tables.Column('alarm_id', - verbose_name=_('Event ID')) - description = tables.Column(description_inject, - verbose_name=_('Description')) - status = tables.Column('suppression_status', - verbose_name=_('Status')) - - def get_object_id(self, obj): - # return obj.alarm_id - return obj.uuid - - def get_object_display(self, datum): - """Returns a display name that identifies this object.""" - if hasattr(datum, 'alarm_id'): - return datum.alarm_id - return None - - class Meta(object): - name = "eventsSuppression" - limit_param = "events_suppression_limit" - pagination_param = "events_suppression_marker" - prev_pagination_param = 'prev_event_ids_marker' - verbose_name = _("Events Suppression") - row_actions = (SuppressEvent, UnsuppressEvent,) - multi_select = False diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/tabs.py b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/tabs.py deleted file mode 100755 index d7c0610e..00000000 --- a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/tabs.py +++ /dev/null @@ -1,309 +0,0 @@ -# Copyright 2012 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. -# All Rights Reserved. -# -# Copyright 2012 Nebula, Inc. -# -# 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. -# -# Copyright (c) 2013-2018 Wind River Systems, Inc. -# - - -from django.utils.translation import ugettext_lazy as _ # noqa - -from horizon import exceptions -from horizon import tabs -from starlingx_dashboard import api as stx_api -from starlingx_dashboard.dashboards.admin.fault_management import tables - -ALARMS_SUPPRESSION_FILTER_GROUP = 0 -EVENT_SUPPRESSION_FILTER_GROUP = 1 - - -class ActiveAlarmsTab(tabs.TableTab): - table_classes = (tables.AlarmsTable,) - name = _("Active Alarms") - slug = "alarms" - template_name = 'admin/fault_management/_active_alarms.html' - - def has_more_data(self, table): - return self._more - - def get_limit_count(self, table): - return self._limit - - def getTableFromName(self, tableName): - table = self._tables[tableName] - return table - - def set_suppression_filter(self, disabled_status): - alarmsTable = self.getTableFromName('alarms') - filter_action = alarmsTable._meta._filter_action - filter_action.set_disabled_filter_field_for_group( - ALARMS_SUPPRESSION_FILTER_GROUP, disabled_status) - filter_action.updateFromRequestDataToSession(self.request) - - def get_context_data(self, request): - context = super(ActiveAlarmsTab, self).get_context_data(request) - - summary = stx_api.fm.alarm_summary_get( - self.request, include_suppress=False) - context["total"] = summary.critical + summary.major + summary.minor \ - + summary.warnings - context["summary"] = summary - - events_types = self.get_event_suppression_data() - suppressed_events_types = len([etype for etype - in events_types - if etype.suppression_status == - 'suppressed']) - - alarms_table = self.getTableFromName('alarms') - - suppress_filter = self.get_filters() - suppress_filter_state = suppress_filter.get('suppression') - - hidden_found = 'hidden' in alarms_table.columns["suppression_status"].\ - classes - - if not hidden_found: - if suppressed_events_types == 0: - self.set_suppression_filter('disabled') - alarms_table.columns["suppression_status"]\ - .classes.append('hidden') - elif suppress_filter_state == stx_api.fm.FM_SUPPRESS_HIDE: - self.set_suppression_filter('enabled') - alarms_table.columns["suppression_status"].classes\ - .append('hidden') - else: - if suppressed_events_types == 0: - self.set_suppression_filter('disabled') - else: - self.set_suppression_filter('enabled') - if suppress_filter_state == stx_api.fm.FM_SUPPRESS_SHOW: - alarms_table.columns["suppression_status"].classes\ - .remove('hidden') - - return context - - def get_filters(self, filters=None): - - filters = filters or {} - alarmsTable = self.getTableFromName('alarms') - filter_action = alarmsTable._meta._filter_action - filter_action.updateFromRequestDataToSession(self.request) - filter_field = filter_action.get_filter_field(self.request) - - if filter_field: - suppression = filter_action.get_filter_field_for_group(0) - filters["suppression"] = suppression - - return filters - - def get_alarms_data(self): - search_opts = {} - # get retrieve parameters from request/session env - limit = \ - self.request.GET.get(tables.AlarmsTable.Meta.limit_param, - None) - - search_opts = self.get_filters() - search_opts.update({ - 'paginate': True, - 'sort_key': 'severity,entity_instance_id', - 'sort_dir': 'asc'}) - - alarms = [] - try: - if 'paginate' in search_opts: - alarms, self._more = stx_api.fm.alarm_list( - self.request, search_opts=search_opts) - else: - alarms = stx_api.fm.alarm_list( - self.request, search_opts=search_opts) - self._limit = limit - except Exception: - self._more = False - self._limit = None - exceptions.handle(self.request, - _('Unable to retrieve alarms list.')) - return alarms - - def get_event_suppression_data(self): - event_types = [] - - try: - if 'suppression_list' not in self.tab_group.kwargs: - self.tab_group.kwargs['suppression_list'] = \ - stx_api.fm.event_suppression_list(self.request) - event_types = self.tab_group.kwargs['suppression_list'] - except Exception: - exceptions.handle(self.request, - _('Unable to retrieve event suppression table' - ' list.')) - return event_types - - -class EventLogTab(tabs.TableTab): - table_classes = (tables.EventLogsTable,) - name = _("Events") - slug = "eventLogs" - template_name = 'admin/fault_management/_summary.html' - preload = False - - def has_more_data(self, table): - return self._more - - def get_limit_count(self, table): - return self._limit - - def getTableFromName(self, tableName): - table = self._tables[tableName] - return table - - def set_suppression_filter(self, disabled_status): - alarmsTable = self.getTableFromName('eventLogs') - filter_action = alarmsTable._meta._filter_action - filter_action.set_disabled_filter_field_for_group( - EVENT_SUPPRESSION_FILTER_GROUP, disabled_status) - filter_action.updateFromRequestDataToSession(self.request) - - def get_context_data(self, request): - context = super(EventLogTab, self).get_context_data(request) - - events_types = self.get_event_suppression_data() - suppressed_events_types = len([etype for etype in events_types - if etype.suppression_status == - 'suppressed']) - - event_log_table = self.getTableFromName('eventLogs') - - filters = self.get_filters({'marker': None, - 'limit': None, - 'paginate': True}) - - suppress_filter_state = filters.get('suppression') - - hidden_found = 'hidden' in event_log_table\ - .columns["suppression_status"].classes - - if not hidden_found: - if suppressed_events_types == 0: - self.set_suppression_filter('disabled') - event_log_table.columns["suppression_status"]\ - .classes.append('hidden') - elif suppress_filter_state == stx_api.fm.FM_SUPPRESS_HIDE: - self.set_suppression_filter('enabled') - event_log_table.columns["suppression_status"].\ - classes.append('hidden') - else: - if suppressed_events_types == 0: - self.set_suppression_filter('disabled') - else: - self.set_suppression_filter('enabled') - if suppress_filter_state == stx_api.fm.FM_SUPPRESS_SHOW: - event_log_table.columns["suppression_status"]\ - .classes.remove('hidden') - - return context - - def get_filters(self, filters): - - eventLogsTable = self.getTableFromName('eventLogs') - filter_action = eventLogsTable._meta._filter_action - filter_action.updateFromRequestDataToSession(self.request) - filter_field = filter_action.get_filter_field(self.request) - - if filter_field: - filters["evtType"] = filter_action.get_filter_field_for_group(0) - filters["suppression"] = filter_action\ - .get_filter_field_for_group(1) - - return filters - - def get_eventLogs_data(self): - - # get retrieve parameters from request/session env - marker = \ - self.request.GET.get(tables.EventLogsTable.Meta.pagination_param, - None) - limit = \ - self.request.GET.get(tables.EventLogsTable.Meta.limit_param, - None) - search_opts = self.get_filters({'marker': marker, - 'limit': limit, - 'paginate': True}) - events = [] - - try: - # now retrieve data from rest API - events, self._more = \ - stx_api.fm.event_log_list(self.request, - search_opts=search_opts) - self._limit = limit - return events - - except Exception: - events = [] - self._more = False - self._limit = None - exceptions.handle(self.request, - _('Unable to retrieve Event Log list.')) - - return events - - def get_event_suppression_data(self): - event_types = [] - - try: - if 'suppression_list' not in self.tab_group.kwargs: - self.tab_group.kwargs['suppression_list'] = \ - stx_api.fm.event_suppression_list(self.request) - event_types = self.tab_group.kwargs['suppression_list'] - except Exception: - exceptions.handle(self.request, - _('Unable to retrieve event suppression \ - table list.')) - return event_types - - -class EventsSuppressionTab(tabs.TableTab): - table_classes = (tables.EventsSuppressionTable,) - name = _("Events Suppression") - slug = "eventsSuppression" - template_name = 'admin/fault_management/_summary.html' - preload = False - - def get_eventsSuppression_data(self): - event_suppression_list = [] - - try: - if 'suppression_list' not in self.tab_group.kwargs: - self.tab_group.kwargs['suppression_list'] = \ - stx_api.fm.event_suppression_list(self.request) - event_suppression_list = self.tab_group.kwargs['suppression_list'] - except Exception: - exceptions.handle(self.request, - _('Unable to retrieve event suppression \ - list\'s.')) - - event_suppression_list.sort(key=lambda a: (a.alarm_id)) - - return event_suppression_list - - -class AlarmsTabs(tabs.TabGroup): - slug = "alarms_tabs" - tabs = (ActiveAlarmsTab, EventLogTab, EventsSuppressionTab) - sticky = True diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/templates/fault_management/_active_alarms.html b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/templates/fault_management/_active_alarms.html deleted file mode 100755 index 56851328..00000000 --- a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/templates/fault_management/_active_alarms.html +++ /dev/null @@ -1,26 +0,0 @@ -{% load i18n %} - -
- - {% trans "Active Alarms" %}: - {{ total }} - - - {% trans "Critical" %}: - {{ summary.critical }} - - - {% trans "Major" %}: - {{ summary.major }} - - - {% trans "Minor" %}: - {{ summary.minor }} - - - {% trans "Warning" %}: - {{ summary.warnings }} - -
- -{{ table.render }} \ No newline at end of file diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/templates/fault_management/_detail_history.html b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/templates/fault_management/_detail_history.html deleted file mode 100755 index 65ee0861..00000000 --- a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/templates/fault_management/_detail_history.html +++ /dev/null @@ -1,58 +0,0 @@ -{% extends 'base.html' %} -{% load i18n breadcrumb_nav %} -{% block title %}{% trans "Historical Alarm Details" %}{% endblock %} - -{% block main %} -{% if history.event_log_id == '' or history.event_log_id == ' ' %} -

{{history.reason_text }}

-{% else %} -

{{history.state }} - {{history.event_log_id }} - {{history.reason_text }}

-{% endif %} - -
-
-
-

{% trans "Info" %}

-
-
-
{% trans "Alarm UUID" %}
-
{{ history.uuid }}
- {% if history.event_log_id != '' and history.event_log_id != ' ' %} -
{% trans "Alarm ID" %}
-
{{ history.event_log_id }}
- {% endif %} -
{% trans "Severity" %}
-
{{ history.severity }}
-
{% trans "Alarm State" %}
-
{{ history.state }}
-
{% trans "Alarm Type" %}
-
{{ history.event_log_type }}
-
{% trans "Timestamp" %}
-
{{ history.timestamp|parse_isotime }}
-
{% trans "Suppression" %}
-
{{ history.suppression }}
-
-
-
{% trans "Entity Instance ID" %}
-
{{ history.entity_instance_id }}
- {% if history.entity_type_id != '' and history.entity_type_id != ' ' %} -
{% trans "Entity Type ID" %}
-
{{ history.entity_type_id }}
- {% endif %} -
{% trans "Probable Cause" %}
-
{{ history.probable_cause }}
- {% if history.proposed_repair_action != '' and history.proposed_repair_action != ' ' %} -
{% trans "Proposed Repair Action" %}
-
{{ history.proposed_repair_action }}
- {% endif %} -
{% trans "Service Affecting" %}
-
{{ history.service_affecting }}
- {% if history.reason_text != '' and history.reason_text != ' ' %} -
{% trans "Reason" %}
-
{{ history.reason_text }}
- {% endif %} -
-
-
-
-{% endblock %} diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/templates/fault_management/_detail_log.html b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/templates/fault_management/_detail_log.html deleted file mode 100755 index 19cfb0dc..00000000 --- a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/templates/fault_management/_detail_log.html +++ /dev/null @@ -1,50 +0,0 @@ -{% extends 'base.html' %} -{% load i18n breadcrumb_nav %} -{% block title %}{% trans "Customer Log Details" %}{% endblock %} - -{% block main %} -{% if log.event_log_id == '' or log.event_log_id == ' ' %} -

{{log.reason_text }}

-{% else %} -

{{log.event_log_id }} - {{log.reason_text }}

-{% endif %} - -
-
-
-

{% trans "Info" %}

-
-
-
{% trans "Log UUID" %}
-
{{ log.uuid }}
- {% if log.event_log_id != '' and log.event_log_id != ' ' %} -
{% trans "Log ID" %}
-
{{ log.event_log_id }}
- {% endif %} -
{% trans "Severity" %}
-
{{ log.severity }}
-
{% trans "Log Type" %}
-
{{ log.event_log_type }}
-
{% trans "Timestamp" %}
-
{{ log.timestamp|parse_isotime }}
-
-
-
{% trans "Entity Instance ID" %}
-
{{ log.entity_instance_id }}
- {% if log.entity_type_id != '' and log.entity_type_id != ' ' %} -
{% trans "Entity Type ID" %}
-
{{ log.entity_type_id }}
- {% endif %} -
{% trans "Probable Cause" %}
-
{{ log.probable_cause }}
-
{% trans "Service Affecting" %}
-
{{ log.service_affecting }}
- {% if log.reason_text != '' and log.reason_text != ' ' %} -
{% trans "Reason" %}
-
{{ log.reason_text }}
- {% endif %} -
-
-
-
-{% endblock %} diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/templates/fault_management/_detail_overview.html b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/templates/fault_management/_detail_overview.html deleted file mode 100755 index f004385a..00000000 --- a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/templates/fault_management/_detail_overview.html +++ /dev/null @@ -1,52 +0,0 @@ -{% extends 'base.html' %} -{% load i18n breadcrumb_nav %} -{% block title %}{% trans "Alarm Details" %}{% endblock %} - -{% block main %} -

{{alarm.alarm_id }} - {{alarm.reason_text }}

- -
-
-
-

{% trans "Info" %}

-
-
-
{% trans "Alarm UUID" %}
-
{{ alarm.uuid }}
-
{% trans "Alarm ID" %}
-
{{ alarm.alarm_id }}
-
{% trans "Severity" %}
-
{{ alarm.severity }}
-
{% trans "Alarm State" %}
-
{{ alarm.alarm_state }}
-
{% trans "Alarm Type" %}
-
{{ alarm.alarm_type }}
-
{% trans "Timestamp" %}
-
{{ alarm.timestamp|parse_isotime }}
-
{% trans "Suppression" %}
-
{{ alarm.suppression }}
-
-
-
{% trans "Entity Instance ID" %}
-
{{ alarm.entity_instance_id }}
-
{% trans "Entity Type ID" %}
-
{{ alarm.entity_type_id }}
-
{% trans "Probable Cause" %}
-
{{ alarm.probable_cause }}
-
{% trans "Proposed Repair Action" %}
-
{{ alarm.proposed_repair_action }}
-
{% trans "Service Affecting" %}
-
{{ alarm.service_affecting }}
-
{% trans "Management Affecting" %}
-
{{ alarm.mgmt_affecting }}
- {% if alarm.reason_text != '' and alarm.reason_text != ' ' %} -
{% trans "Reason" %}
-
{{ alarm.reason_text }}
- {% endif %} -
-
-
-
-{% endblock %} - - diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/templates/fault_management/_summary.html b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/templates/fault_management/_summary.html deleted file mode 100755 index d187f111..00000000 --- a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/templates/fault_management/_summary.html +++ /dev/null @@ -1,5 +0,0 @@ -{% load i18n %} - -{% block main %} - {{ table.render }} -{% endblock %} diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/templates/fault_management/index.html b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/templates/fault_management/index.html deleted file mode 100755 index ee081fae..00000000 --- a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/templates/fault_management/index.html +++ /dev/null @@ -1,29 +0,0 @@ -{% extends 'base.html' %} -{% load i18n %} -{% block title %}{% trans "Fault Management" %}{% endblock %} - -{% block page_header %} - {% include "horizon/common/_page_header.html" with title=_("Fault Management")%} -{% endblock page_header %} - -{% block main %} -
-
- {{ tab_group.render }} -
-
-{% endblock %} - - -{% block js %} - {{ block.super }} - -{% endblock %} diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/urls.py b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/urls.py deleted file mode 100755 index 76d8e1e9..00000000 --- a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/urls.py +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2012 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. -# All Rights Reserved. -# -# Copyright 2012 Nebula, Inc. -# -# 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. -# -# Copyright (c) 2013-2015 Wind River Systems, Inc. -# - - -from django.conf.urls import url # noqa - -from starlingx_dashboard.dashboards.admin.fault_management import views - -urlpatterns = [ - url(r'^$', views.IndexView.as_view(), name='index'), - url(r'^(?P[^/]+)/detail/$', - views.DetailView.as_view(), name='detail'), - url(r'^(?P[^/]+)/eventlogdetail/$', - views.EventLogDetailView.as_view(), name='eventlogdetail'), - url(r'^banner/$', views.BannerView.as_view(), - name='banner') -] diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/views.py b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/views.py deleted file mode 100755 index 0b46f490..00000000 --- a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/views.py +++ /dev/null @@ -1,175 +0,0 @@ -# Copyright 2012 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. -# All Rights Reserved. -# -# Copyright 2012 Nebula, Inc. -# -# 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. -# -# Copyright (c) 2013-2018 Wind River Systems, Inc. -# - - -import logging - -from django.core.urlresolvers import reverse -from django.utils.translation import ugettext_lazy as _ # noqa -from django.views.generic import TemplateView - -from horizon import exceptions -from horizon import tabs -from horizon import views -from openstack_dashboard.api.base import is_service_enabled -from starlingx_dashboard.api import dc_manager -from starlingx_dashboard.api import fm - -from starlingx_dashboard.dashboards.admin.fault_management import \ - tabs as project_tabs - -LOG = logging.getLogger(__name__) - - -class IndexView(tabs.TabbedTableView): - tab_group_class = project_tabs.AlarmsTabs - template_name = 'admin/fault_management/index.html' - page_title = _("Fault Management") - - -class DetailView(views.HorizonTemplateView): - template_name = 'admin/fault_management/_detail_overview.html' - page_title = 'Alarm Details' - - def get_context_data(self, **kwargs): - context = super(DetailView, self).get_context_data(**kwargs) - context["alarm"] = self.get_data() - return context - - def get_data(self): - if not hasattr(self, "_alarm"): - alarm_uuid = self.kwargs['id'] - try: - alarm = fm.alarm_get(self.request, alarm_uuid) - - except Exception: - redirect = reverse('horizon:admin:fault_management:index') - exceptions.handle(self.request, - _('Unable to retrieve details for ' - 'alarm "%s".') % alarm_uuid, - redirect=redirect) - - self._alarm = alarm - return self._alarm - - -class EventLogDetailView(views.HorizonTemplateView): - # Strategy behind this event log detail view is to - # first retrieve the event_log data, then examine the event's - # state property, and from that, determine if it should use - # the _detail_history.html (alarmhistory) template or - # or use the _detail_log.html (customer log) template - - def get_template_names(self): - if self.type == "alarmhistory": - template_name = 'admin/fault_management/_detail_history.html' - else: - template_name = 'admin/fault_management/_detail_log.html' - return template_name - - def _detectEventLogType(self): - if hasattr(self, "type"): - return self.type - if not self._eventlog: - raise Exception("Cannot determine Event Log type for " - "EventLogDetailView. First retrieve " - "Eventlog data") - if self._eventlog.state == "log": - self.type = "log" - elif self._eventlog.state in ["set", "clear"]: - self.type = "alarmhistory" - else: - raise Exception("Invalid state = '{}'. Cannot " - "determine Event log type for " - "event log".format(self._eventlog.state)) - return self.type - - def get_context_data(self, **kwargs): - context = super(EventLogDetailView, self).get_context_data(**kwargs) - data = self.get_data() - if self.type == "alarmhistory": - self.page_title = 'Historical Alarm Details' - self.template_name = 'admin/fault_management/_detail_history.html' - context["history"] = data - else: - self.page_title = 'Customer Log Detail' - self.template_name = 'admin/fault_management/_detail_log.html' - context["log"] = data - - return context - - def get_data(self): - if not hasattr(self, "_eventlog"): - uuid = self.kwargs['id'] - try: - self._eventlog = fm.event_log_get(self.request, uuid) - self._detectEventLogType() - except Exception: - redirect = reverse('horizon:admin:fault_management:index') - exceptions.handle(self.request, - _('Unable to retrieve details for ' - 'event log "%s".') % uuid, - redirect=redirect) - return self._eventlog - - -class BannerView(TemplateView): - template_name = 'header/_alarm_banner.html' - - def get_context_data(self, **kwargs): - context = super(BannerView, self).get_context_data(**kwargs) - - if not self.request.is_ajax(): - raise exceptions.NotFound() - - if (not self.request.user.is_authenticated() or - not self.request.user.is_superuser): - context["alarmbanner"] = False - elif 'dc_admin' in self.request.META.get('HTTP_REFERER'): - summaries = self.get_subcloud_data() - central_summary = self.get_data() - summaries.append(central_summary) - context["dc_admin"] = True - context["alarmbanner"] = True - context["OK"] = len( - [s for s in summaries if s.status == 'OK']) - context["degraded"] = len( - [s for s in summaries if s.status == 'degraded']) - context["critical"] = len( - [s for s in summaries if s.status == 'critical']) - context["disabled"] = len( - [s for s in summaries if s.status == 'disabled']) - elif is_service_enabled(self.request, 'platform'): - context["summary"] = self.get_data() - context["alarmbanner"] = True - return context - - def get_data(self): - summary = None - try: - summary = fm.alarm_summary_get(self.request) - except Exception: - exceptions.handle(self.request, - _('Unable to retrieve alarm summary.')) - return summary - - def get_subcloud_data(self): - return dc_manager.alarm_summary_list(self.request) diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/host_topology/tables.py b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/host_topology/tables.py index a6dfc198..a7df089a 100755 --- a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/host_topology/tables.py +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/host_topology/tables.py @@ -1,15 +1,16 @@ # -# Copyright (c) 2016-2018 Wind River Systems, Inc. +# Copyright (c) 2016-2019 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # +from horizon import tables +from horizon.utils import filters as utils_filters import logging +from django.utils.translation import pgettext_lazy from django.utils.translation import ugettext_lazy as _ -from starlingx_dashboard.dashboards.admin.fault_management import \ - tables as fm_tables from starlingx_dashboard.dashboards.admin.inventory.interfaces import \ tables as if_tables from starlingx_dashboard.dashboards.admin.providernets.providernets.ranges \ @@ -17,6 +18,19 @@ from starlingx_dashboard.dashboards.admin.providernets.providernets.ranges \ LOG = logging.getLogger(__name__) +SUPPRESSION_STATUS_CHOICES = ( + ("suppressed", False), + ("unsuppressed", True), + ("None", True), +) +SUPPRESSION_STATUS_DISPLAY_CHOICES = ( + ("suppressed", pgettext_lazy("Indicates this type of alarm \ + is suppressed", "suppressed")), + ("unsuppressed", pgettext_lazy("Indicates this type of alarm \ + is unsuppressed", "unsuppressed")), + ("None", pgettext_lazy("Indicates an event type", "None")), +) + class ProviderNetworkRangeTable(sr_tables.ProviderNetworkRangeTable): class Meta(object): @@ -26,7 +40,34 @@ class ProviderNetworkRangeTable(sr_tables.ProviderNetworkRangeTable): row_actions = () -class AlarmsTable(fm_tables.AlarmsTable): +def get_alarm_link_url(alarm): + return "/ngdetails/OS::StarlingX::ActiveAlarms/" + alarm.uuid + + +class AlarmsTable(tables.DataTable): + alarm_id = tables.Column('alarm_id', + verbose_name=_('Alarm ID'), + link=get_alarm_link_url) + reason_text = tables.Column('reason_text', + verbose_name=_('Reason Text')) + entity_instance_id = tables.Column('entity_instance_id', + verbose_name=_('Entity Instance ID')) + suppression_status = \ + tables.Column('suppression_status', + verbose_name=_('Suppression Status'), + status=True, + status_choices=SUPPRESSION_STATUS_CHOICES, + display_choices=SUPPRESSION_STATUS_DISPLAY_CHOICES) + severity = tables.Column('severity', + verbose_name=_('Severity')) + timestamp = tables.Column('timestamp', + attrs={'data-type': 'timestamp'}, + filters=(utils_filters.parse_isotime,), + verbose_name=_('Timestamp')) + + def get_object_id(self, obj): + return obj.uuid + class Meta(object): name = "alarms" verbose_name = _("Related Alarms") diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/dc_admin/static/dashboard/dc_admin/cloud_overview/table/central_table.controller.js b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/dc_admin/static/dashboard/dc_admin/cloud_overview/table/central_table.controller.js index 86ea1d21..ddb26ad1 100755 --- a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/dc_admin/static/dashboard/dc_admin/cloud_overview/table/central_table.controller.js +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/dc_admin/static/dashboard/dc_admin/cloud_overview/table/central_table.controller.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2017 Wind River Systems, Inc. + * Copyright (c) 2017-2019 Wind River Systems, Inc. * * SPDX-License-Identifier: Apache-2.0 * @@ -105,7 +105,7 @@ ///////////// function goToCentralAlarmDetails(cloud) { - $window.location.href = "/auth/switch_services_region/RegionOne/?next=/admin/fault_management/"; + $window.location.href = "/auth/switch_services_region/RegionOne/?next=/admin/active_alarms/"; } function goToCentralHostDetails(cloud) { diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/dc_admin/static/dashboard/dc_admin/cloud_overview/table/subcloud_table.controller.js b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/dc_admin/static/dashboard/dc_admin/cloud_overview/table/subcloud_table.controller.js index 9b18bc5d..aaddd66a 100755 --- a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/dc_admin/static/dashboard/dc_admin/cloud_overview/table/subcloud_table.controller.js +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/dc_admin/static/dashboard/dc_admin/cloud_overview/table/subcloud_table.controller.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2017 Wind River Systems, Inc. + * Copyright (c) 2017-2019 Wind River Systems, Inc. * * SPDX-License-Identifier: Apache-2.0 * @@ -386,7 +386,7 @@ keystone.getCurrentUserSession().success(function(session){ session.available_services_regions.indexOf(cloud.name) if (session.available_services_regions.indexOf(cloud.name) > -1) { - $window.location.href = "/auth/switch_services_region/"+ cloud.name + "/?next=/admin/fault_management/"; + $window.location.href = "/auth/switch_services_region/"+ cloud.name + "/?next=/admin/active_alarms/"; } else { toast.add('error', ctrl.endpointErrorMsg); // TODO(tsmith) should we force a logout here with an reason message? diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/dc_admin/static/dashboard/dc_admin/fm.service.js b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/dc_admin/static/dashboard/dc_admin/fm.service.js deleted file mode 100644 index 92c15f7f..00000000 --- a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/dc_admin/static/dashboard/dc_admin/fm.service.js +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Copyright (c) 2018 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - * - */ - -(function () { - 'use strict'; - - angular - .module('horizon.app.core.openstack-service-api') - .factory('horizon.app.core.openstack-service-api.fm', FmAPI); - - FmAPI.$inject = [ - '$q', - 'horizon.framework.util.http.service', - 'horizon.framework.widgets.toast.service', - '$http' - ]; - - function FmAPI($q, apiService, toastService, $http) { - var service = { - getAlarmSummary: getAlarmSummary - }; - - var csrf_token = $('input[name=csrfmiddlewaretoken]').val(); - $http.defaults.headers.post['X-CSRFToken'] = csrf_token; - $http.defaults.headers.common['X-CSRFToken'] = csrf_token; - $http.defaults.headers.put['X-CSRFToken'] = csrf_token; - - return service; - - - /////////////////// - // Alarm Summary // - /////////////////// - - function getAlarmSummary() { - return apiService.get('/api/fm/alarm_summary/') - .error(function () { - toastService.clearErrors(); - toastService.add('error', gettext("Unable to retrieve the System Controller's alarm summary.")); - }); - } - - } -}()); diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/enabled/_1001_starlingx.py b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/enabled/_1001_starlingx.py new file mode 100755 index 00000000..dabbf70d --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/enabled/_1001_starlingx.py @@ -0,0 +1,6 @@ +# A list of applications to be added to INSTALLED_APPS. +ADD_INSTALLED_APPS = ['starlingx_dashboard'] + +FEATURE = ['starlingx_dashboard'] + +AUTO_DISCOVER_STATIC_FILES = True diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/enabled/_2400_starlingx_admin_fault_management_panel_group.py b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/enabled/_2400_starlingx_admin_fault_management_panel_group.py new file mode 100644 index 00000000..40989f00 --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/enabled/_2400_starlingx_admin_fault_management_panel_group.py @@ -0,0 +1,18 @@ +from django.utils.translation import ugettext_lazy as _ + +# The slug of the panel group to be added to HORIZON_CONFIG. Required. +PANEL_GROUP = 'fault_management' +# The display name of the PANEL_GROUP. Required. +PANEL_GROUP_NAME = _('Fault Management') +# The slug of the dashboard the PANEL_GROUP associated with. Required. +PANEL_GROUP_DASHBOARD = 'admin' + +ADD_ANGULAR_MODULES = [ + 'horizon.dashboard.fault_management' +] + +ADD_SCSS_FILES = [ + 'dashboard/fault_management/fault_management.scss' +] + +AUTO_DISCOVER_STATIC_FILES = True diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/enabled/_2032_starlingx_admin_fault_management_panel.py b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/enabled/_2401_starlingx_admin_fault_management_alarms_panel.py old mode 100755 new mode 100644 similarity index 75% rename from starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/enabled/_2032_starlingx_admin_fault_management_panel.py rename to starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/enabled/_2401_starlingx_admin_fault_management_alarms_panel.py index 647551f4..adceb1a1 --- a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/enabled/_2032_starlingx_admin_fault_management_panel.py +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/enabled/_2401_starlingx_admin_fault_management_alarms_panel.py @@ -1,10 +1,10 @@ # The slug of the panel to be added to HORIZON_CONFIG. Required. -PANEL = 'fault_management' +PANEL = 'active_alarms' +# The slug of the panel group the PANEL is associated with. +PANEL_GROUP = 'fault_management' # The slug of the dashboard the PANEL associated with. Required. PANEL_DASHBOARD = 'admin' -# The slug of the panel group the PANEL is associated with. -PANEL_GROUP = 'platform' # Python panel class of the PANEL to be added. ADD_PANEL = 'starlingx_dashboard.dashboards.admin.' \ - 'fault_management.panel.FaultManagement' + 'active_alarms.panel.ActiveAlarms' diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/enabled/_2402_starlingx_admin_fault_management_events_panel.py b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/enabled/_2402_starlingx_admin_fault_management_events_panel.py new file mode 100644 index 00000000..bf02936b --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/enabled/_2402_starlingx_admin_fault_management_events_panel.py @@ -0,0 +1,9 @@ +# The slug of the panel to be added to HORIZON_CONFIG. Required. +PANEL = 'events' +# The slug of the panel group the PANEL is associated with. +PANEL_GROUP = 'fault_management' +# The slug of the dashboard the PANEL associated with. Required. +PANEL_DASHBOARD = 'admin' + +# Python panel class of the PANEL to be added. +ADD_PANEL = 'starlingx_dashboard.dashboards.admin.events.panel.Events' diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/enabled/_2403_starlingx_admin_fault_management_events_suppression_panel.py b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/enabled/_2403_starlingx_admin_fault_management_events_suppression_panel.py new file mode 100644 index 00000000..813a57b2 --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/enabled/_2403_starlingx_admin_fault_management_events_suppression_panel.py @@ -0,0 +1,10 @@ +# The slug of the panel to be added to HORIZON_CONFIG. Required. +PANEL = 'events_suppression' +# The slug of the panel group the PANEL is associated with. +PANEL_GROUP = 'fault_management' +# The slug of the dashboard the PANEL associated with. Required. +PANEL_DASHBOARD = 'admin' + +# Python panel class of the PANEL to be added. +ADD_PANEL = 'starlingx_dashboard.dashboards.admin.events_suppression.panel.' \ + 'EventsSuppression' diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/app/core/fault_management/fm.service.js b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/app/core/fault_management/fm.service.js new file mode 100644 index 00000000..489b2677 --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/app/core/fault_management/fm.service.js @@ -0,0 +1,116 @@ +/** + * Copyright (c) 2018-2019 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +(function () { + 'use strict'; + + angular + .module('horizon.app.core.openstack-service-api') + .factory('horizon.app.core.openstack-service-api.fm', FmAPI); + + FmAPI.$inject = [ + '$q', + 'horizon.framework.util.http.service', + 'horizon.framework.widgets.toast.service', + '$http' + ]; + + function FmAPI($q, apiService, toastService, $http) { + var service = { + getAlarmSummary: getAlarmSummary, + getAlarms: getAlarms, + getAlarm: getAlarm, + getEvents: getEvents, + getEvent: getEvent, + getEventsSuppression: getEventsSuppression, + updateEventSuppression: updateEventSuppression + }; + + var csrf_token = $('input[name=csrfmiddlewaretoken]').val(); + $http.defaults.headers.post['X-CSRFToken'] = csrf_token; + $http.defaults.headers.common['X-CSRFToken'] = csrf_token; + $http.defaults.headers.put['X-CSRFToken'] = csrf_token; + + return service; + + /////////////////////////////// + // Alarms + + function getAlarmSummary() { + return apiService.get('/api/fm/alarm_summary/') + .error(function () { + toastService.clearErrors(); + toastService.add('error', gettext("Unable to retrieve alarm summary.")); + }); + } + + function getAlarms() { + var results = apiService.get('/api/fm/alarm_list/?include_suppress=True') + return results + .error(function () { + toastService.clearErrors(); + toastService.add('error', gettext("Unable to retrieve alarms.")); + }); + } + + function getAlarm(uuid) { + var results = apiService.get('/api/fm/alarm_get/' + uuid) + return results + .error(function() { + var msg = gettext("Unable to retrieve alarm with uuid: %(uuid)s."); + toastService.add('error', interpolate(msg, {uuid: uuid}, true)); + }); + } + + /////////////////////////////// + // Events + + function getEvents() { + var results = apiService.get('/api/fm/event_log_list/') + return results + .error(function () { + toastService.clearErrors(); + toastService.add('error', gettext("Unable to retrieve events.")); + }); + } + + function getEvent(uuid) { + var results = apiService.get('/api/fm/event_log_get/' + uuid) + return results + .error(function() { + var msg = gettext("Unable to retrieve event with uuid: %(uuid)s."); + toastService.add('error', interpolate(msg, {uuid: uuid}, true)); + }); + } + + /////////////////////////////// + // Events Suppression + + function getEventsSuppression(include_unsuppressed) { + var query_string = '/api/fm/events_suppression_list/' + if (include_unsuppressed) { + query_string = query_string + '?include_unsuppressed' + } + + var results = apiService.get(query_string); + + return results + .error(function () { + toastService.clearErrors(); + toastService.add('error', gettext("Unable to retrieve events suppression.")); + }); + } + + function updateEventSuppression(uuid, params) { + var results = apiService.patch('/api/fm/event_suppression/' + uuid, params) + // Errors are expected to be processed by the caller, just return + return results; + } + + + } +}()); diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/active_alarms.module.js b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/active_alarms.module.js new file mode 100644 index 00000000..be980e6a --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/active_alarms.module.js @@ -0,0 +1,194 @@ +/** + * 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. + */ +/** + * Copyright (c) 2019 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +(function() { + 'use strict'; + + /** + * @ngdoc overview + * @name horizon.dashboard.fault_management.active_alarms + * @ngModule + * @description + * Provides all the services and widgets require to display the Alarm + * panel + */ + angular + .module('horizon.dashboard.fault_management.active_alarms', [ + 'ngRoute', + 'horizon.dashboard.fault_management.active_alarms.details' + ]) + .constant('horizon.dashboard.fault_management.active_alarms.resourceType', 'OS::StarlingX::ActiveAlarms') + .run(run) + .config(config); + + run.$inject = [ + 'horizon.framework.conf.resource-type-registry.service', + 'horizon.dashboard.fault_management.active_alarms.service', + 'horizon.dashboard.fault_management.active_alarms.basePath', + 'horizon.dashboard.fault_management.active_alarms.resourceType' + ]; + + function run(registry, service, basePath, resourceType) { + registry.getResourceType(resourceType) + .setNames(gettext('Active Alarm'), gettext('Active Alarms')) + + // for detail summary view on table row + .setSummaryTemplateUrl(basePath + 'details/drawer.html') + + // set default url for index view. this will be used for reproducing + // sidebar and breadcrumb when refreshing or accessing directly + // details view. + // TODO(kbujold): Uncomment when we rebase to Stein, to fix upstream bug 1746706 + //.setDefaultIndexUrl('/admin/fault_management/') + + // specify items for table row items, summary view and details view + .setProperties(properties()) + + // get items for table + .setListFunction(service.getPromise) + + // specify table columns + .tableColumns + .append({ + id: 'alarm_id', + priority: 1, + urlFunction: service.urlFunction + }) + .append({ + id: 'reason_text', + priority: 1 + }) + .append({ + id: 'entity_instance_id', + priority: 1 + }) + .append({ + id: 'severity', + priority: 1, + sortDefault: 'true' + }) + .append({ + id: 'suppression_status', + priority: 1, + allowed: service.suppressColAllowedPromiseFunction + }) + .append({ + id: 'timestamp', + priority: 1 + }); + + // for magic-search + registry.getResourceType(resourceType).filterFacets + .append({ + 'label': gettext('Alarm ID'), + 'name': 'alarm_id', + 'singleton': true + }) + .append({ + 'label': gettext('Entity Instance ID'), + 'name': 'entity_instance_id', + 'singleton': true + }) + .append({ + 'label': gettext('Reason Text'), + 'name': 'reason_text', + 'singleton': true + }) + .append({ + 'label': gettext('Severity'), + 'name': 'severity', + 'singleton': true, + 'options': [ + {label: gettext('critical'), key: 'critical'}, + {label: gettext('major'), key: 'major'}, + {label: gettext('minor'), key: 'minor'}, + {label: gettext('warning'), key: 'warning'} + ] + }) + .append({ + 'label': gettext('Timestamp'), + 'name': 'timestamp', + 'singleton': true + }) + .append({ + 'label': gettext('Management Affecting'), + 'name': 'mgmt_affecting', + 'singleton': true, + 'options': [ + {label: gettext('True'), key: 'True'}, + {label: gettext('False'), key: 'False'} + ] + }) + .append({ + 'label': gettext('UUID'), + 'name': 'uuid', + 'singleton': true + }); + } + + function properties() { + return { + uuid: { label: gettext('Alarm UUID'), filters: ['noValue'] }, + alarm_id: { label: gettext('Alarm ID'), filters: ['noValue'] }, + reason_text: { label: gettext('Reason Text'), filters: ['noValue'] }, + entity_instance_id: { label: gettext('Entity Instance ID'), filters: ['noValue'] }, + severity: { label: gettext('Severity'), filters: ['noValue'] }, + timestamp: { label: gettext('Timestamp'), filters: ['noValue'] }, + mgmt_affecting: { label: gettext('Management Affecting'), filters: ['noValue'] }, + suppression_status: { label: gettext('Suppression Status'), filters: ['noValue'] }, + alarm_state: { label: gettext('Alarm State'), filters: ['noValue'] }, + service_affecting: { label: gettext('Service Affecting'), filters: ['noValue'] }, + alarm_type: { label: gettext('Alarm Type'), filters: ['noValue'] }, + probable_cause: { label: gettext('Probable Cause'), filters: ['noValue'] }, + entity_type_id: { label: gettext('Entity Type ID'), filters: ['noValue'] }, + proposed_repair_action: { label: gettext('Proposed Repair Action'), filters: ['noValue'] }, + is_suppressed: { label: gettext('IsSuppressed'), filters: ['noValue'] }, + }; + } + + config.$inject = [ + '$provide', + '$windowProvider', + '$routeProvider' + ]; + + /** + * @name config + * @param {Object} $provide + * @param {Object} $windowProvider + * @param {Object} $routeProvider + * @description Routes used by this module. + * @returns {undefined} Returns nothing + */ + + function config($provide, $windowProvider, $routeProvider) { + var path = $windowProvider.$get().STATIC_URL + 'dashboard/fault_management/active_alarms/'; + $provide.constant('horizon.dashboard.fault_management.active_alarms.basePath', path); + $routeProvider.when('/admin/active_alarms', { + templateUrl: path + 'panel.html', + resolve: { + searchResults: ['horizon.dashboard.fault_management.active_alarms.service', function (searchService) { + return searchService.getSuppressionList(); + }] + } + + }); + } +})(); diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/active_alarms.module.spec.js b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/active_alarms.module.spec.js new file mode 100644 index 00000000..324b101d --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/active_alarms.module.spec.js @@ -0,0 +1,30 @@ +/** + * 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. + */ +/** + * Copyright (c) 2019 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +(function() { + 'use strict'; + + describe('horizon.dashboard.fault_management.active_alarms', function() { + it('should exist', function() { + expect(angular.module('horizon.dashboard.fault_management.active_alarms')).toBeDefined(); + }); + }); + +})(); diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/active_alarms.service.js b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/active_alarms.service.js new file mode 100644 index 00000000..9cdc0d50 --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/active_alarms.service.js @@ -0,0 +1,136 @@ +/** + * 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. + */ +/** + * Copyright (c) 2019 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +(function() { + "use strict"; + + angular.module('horizon.dashboard.fault_management.active_alarms') + .factory('horizon.dashboard.fault_management.active_alarms.service', + service); + + service.$inject = [ + '$filter', + 'horizon.app.core.detailRoute', + 'horizon.app.core.openstack-service-api.fm', + '$q', + 'horizon.framework.conf.resource-type-registry.service', + 'horizon.dashboard.fault_management.active_alarms.resourceType' + ]; + + /* + * @ngdoc factory + * @name horizon.dashboard.fault_management.active_alarms.service + * + * @description + * This service provides functions that are used through the Alarms + * features. These are primarily used in the module registrations + * but do not need to be restricted to such use. Each exposed function + * is documented below. + */ + function service($filter, detailRoute, api, $q, registry, resourceType) { + + var showSuppressColumn = null; + + return { + getPromise: getPromise, + urlFunction: urlFunction, + suppressColAllowedPromiseFunction: suppressColAllowedPromiseFunction, + getSuppressionList: getSuppressionList + }; + + + function getPromise(params) { + return api.getAlarms(params).then(modifyResponse); + } + + function modifyResponse(response) { + return {data: {items: response.data.items.map(modifyItem)}}; + + function modifyItem(item) { + + item.trackBy = item.uuid; + + if (item.suppression_status == 'suppressed') { + item.is_suppressed = true; + } + else { + item.is_suppressed = false; + } + + return item; + } + } + + function urlFunction(item) { + return detailRoute + 'OS::StarlingX::ActiveAlarms/' + item.uuid; + } + + function getSuppressionList() { + var include_unsuppressed = false; + return api.getEventsSuppression(include_unsuppressed).then(modifyResponseSupp); + } + + function modifyResponseSupp(response) { + if (response.data.items.length == 0) { + showSuppressColumn = false; + } + else { + showSuppressColumn = true; + } + return; + } + + + /** + * @name suppressColAllowedPromiseFunction + * @description + * If there are no unsuppressed events then we do not show the Suppression + * Status column. We also do show the the filter associated with that column. + */ + function suppressColAllowedPromiseFunction() { + var filters = registry.getResourceType(resourceType).filterFacets; + var index = filters.findIndex(obj => obj['id'] === 'suppression_status'); + + if (showSuppressColumn === false) { + if (index >= 0) { + filters.remove('suppression_status') + } + return $q.reject(); + } + else { + if (index < 0) { + filters.append({ + 'label': gettext('Suppression Status'), + 'id': 'suppression_status', + 'name': 'is_suppressed', + 'singleton': false, + 'options': [ + {label: gettext('suppressed'), key: 'true'}, + {label: gettext('unsuppressed'), key: 'false'} + ] + }); + } + return $q.resolve(); + } + } + + } +})(); + diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/active_alarms.service.spec.js b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/active_alarms.service.spec.js new file mode 100644 index 00000000..78a2dce1 --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/active_alarms.service.spec.js @@ -0,0 +1,59 @@ +/** + * 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. + */ +/** + * Copyright (c) 2019 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ +(function() { + "use strict"; + + describe('Active Alarms service', function() { + var service; + beforeEach(module('horizon.app.core.openstack-service-api')); + beforeEach(module('horizon.dashboard.fault_management.active_alarms')); + beforeEach(inject(function($injector) { + service = $injector.get('horizon.dashboard.fault_management.active_alarms.service'); + })); + + describe('getPromise', function() { + it("provides a promise", inject(function($q, $injector, $timeout) { + var api = $injector.get('horizon.app.core.openstack-service-api.fm'); + var deferred = $q.defer(); + spyOn(api, 'getAlarms').and.returnValue(deferred.promise); + var result = service.getPromise({}); + deferred.resolve({ + data:{ + items: [{uuid: '123abc', reason_text: 'resource1'}] + } + }); + $timeout.flush(); + expect(api.getAlarms).toHaveBeenCalled(); + expect(result.$$state.value.data.items[0].reason_text).toBe('resource1'); + })); + }); + + describe('urlFunction', function() { + it("get url", inject(function($injector) { + var detailRoute = $injector.get('horizon.app.core.detailRoute'); + var result = service.urlFunction({uuid:"123abc"}); + expect(result).toBe(detailRoute + "OS::StarlingX::ActiveAlarms/123abc"); + })); + }); + + }); + +})(); + diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/details/details.module.js b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/details/details.module.js new file mode 100644 index 00000000..4f3147cc --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/details/details.module.js @@ -0,0 +1,64 @@ +/** + * 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. + */ +/** + * Copyright (c) 2019 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +(function() { + 'use strict'; + + /** + * @ngdoc overview + * @ngname horizon.dashboard.fault_management.active_alarms.details + * + * @description + * Provides details features for Alarm. + */ + angular + .module('horizon.dashboard.fault_management.active_alarms.details', [ + 'horizon.app.core', + 'horizon.framework.conf' + ]) + .run(registerDetails); + + registerDetails.$inject = [ + 'horizon.app.core.openstack-service-api.fm', + 'horizon.dashboard.fault_management.active_alarms.basePath', + 'horizon.dashboard.fault_management.active_alarms.resourceType', + 'horizon.framework.conf.resource-type-registry.service' + ]; + + function registerDetails( + api, + basePath, + resourceType, + registry + ) { + registry.getResourceType(resourceType) + .setLoadFunction(loadFunction) + .detailsViews.append({ + id: 'alarmsDetailsOverview', + name: gettext('Overview'), + template: basePath + 'details/overview.html' + }); + + + function loadFunction(uuid) { + return api.getAlarm(uuid); + } + } +})(); diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/details/drawer.html b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/details/drawer.html new file mode 100644 index 00000000..e7f6586e --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/details/drawer.html @@ -0,0 +1,5 @@ + + diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/details/overview.controller.js b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/details/overview.controller.js new file mode 100644 index 00000000..4473e5d5 --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/details/overview.controller.js @@ -0,0 +1,44 @@ +/* + * 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. + */ +/** + * Copyright (c) 2019 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +(function() { + "use strict"; + + angular + .module('horizon.dashboard.fault_management.active_alarms') + .controller('horizon.dashboard.fault_management.active_alarms.OverviewController', controller); + + controller.$inject = [ + '$scope' + ]; + + function controller( + $scope + ) { + var ctrl = this; + ctrl.alarm = {}; + + $scope.context.loadPromise.then(onGetAlarm); + + function onGetAlarm(item) { + ctrl.alarm = item.data; + } + } +})(); diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/details/overview.html b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/details/overview.html new file mode 100644 index 00000000..70a10ccc --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/details/overview.html @@ -0,0 +1,17 @@ +
+
+
+

{$ ctrl.alarm.alarm_id $} - {$ ctrl.alarm.reason_text $}

+
+ + +
+
+
diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/panel.html b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/panel.html new file mode 100644 index 00000000..1b087419 --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/panel.html @@ -0,0 +1,6 @@ + + + + + diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/details/details.module.js b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/details/details.module.js new file mode 100644 index 00000000..c4de128e --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/details/details.module.js @@ -0,0 +1,64 @@ +/** + * 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. + */ +/** + * Copyright (c) 2019 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +(function() { + 'use strict'; + + /** + * @ngdoc overview + * @ngname horizon.dashboard.fault_management.events.details + * + * @description + * Provides details features for Event. + */ + angular + .module('horizon.dashboard.fault_management.events.details', [ + 'horizon.app.core', + 'horizon.framework.conf' + ]) + .run(registerDetails); + + registerDetails.$inject = [ + 'horizon.app.core.openstack-service-api.fm', + 'horizon.dashboard.fault_management.events.basePath', + 'horizon.dashboard.fault_management.events.resourceType', + 'horizon.framework.conf.resource-type-registry.service' + ]; + + function registerDetails( + api, + basePath, + resourceType, + registry + ) { + registry.getResourceType(resourceType) + .setLoadFunction(loadFunction) + .detailsViews.append({ + id: 'eventsDetailsOverview', + name: gettext('Overview'), + template: basePath + 'details/overview.html' + }); + + + function loadFunction(uuid) { + return api.getEvent(uuid); + } + } +})(); diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/details/drawer.html b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/details/drawer.html new file mode 100644 index 00000000..d7fa1016 --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/details/drawer.html @@ -0,0 +1,5 @@ + + diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/details/overview.controller.js b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/details/overview.controller.js new file mode 100644 index 00000000..a2ccfcc4 --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/details/overview.controller.js @@ -0,0 +1,48 @@ +/* + * 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. + */ +/** + * Copyright (c) 2019 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +(function() { + "use strict"; + + angular + .module('horizon.dashboard.fault_management.events') + .controller('horizon.dashboard.fault_management.events.OverviewController', controller); + + controller.$inject = [ + '$scope', + 'horizon.dashboard.fault_management.events.service' + ]; + + function controller( + $scope, eventService + ) { + var ctrl = this; + ctrl.event = {}; + + $scope.context.loadPromise.then(onGetEvent); + + function onGetEvent(item) { + + eventService.setEventType(item.data); + + ctrl.event = item.data; + } + } +})(); diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/details/overview.html b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/details/overview.html new file mode 100644 index 00000000..d3b5a02c --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/details/overview.html @@ -0,0 +1,17 @@ +
+
+
+

{$ ctrl.event.state $} - {$ ctrl.event.event_log_id $} - {$ctrl.event.reason_text $}

+
+ + +
+
+
diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/events.module.js b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/events.module.js new file mode 100644 index 00000000..d85c5faf --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/events.module.js @@ -0,0 +1,208 @@ +/** + * 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. + */ +/** + * Copyright (c) 2019 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +(function() { + 'use strict'; + + /** + * @ngdoc overview + * @name horizon.dashboard.fault_management.events + * @ngModule + * @description + * Provides all the services and widgets require to display the Event panel + */ + angular + .module('horizon.dashboard.fault_management.events', [ + 'ngRoute', + 'horizon.dashboard.fault_management.events.details' + ]) + .constant('horizon.dashboard.fault_management.events.resourceType', 'OS::StarlingX::Events') + .run(run) + .config(config); + + run.$inject = [ + 'horizon.framework.conf.resource-type-registry.service', + 'horizon.dashboard.fault_management.events.service', + 'horizon.dashboard.fault_management.events.basePath', + 'horizon.dashboard.fault_management.events.resourceType' + ]; + + function run(registry, service, basePath, resourceType) { + registry.getResourceType(resourceType) + .setNames(gettext('Event'), gettext('Events')) + + // for detail summary view on table row + .setSummaryTemplateUrl(basePath + 'details/drawer.html') + + // set default url for index view. this will be used for reproducing + // sidebar and breadcrumb when refreshing or accessing directly + // details view. + // TODO(kbujold): Uncomment when we rebase to Stein, to fix upstream bug 1746706 + //.setDefaultIndexUrl('/admin/fault_management/') + + // specify items for table row items, summary view and details view + .setProperties(properties()) + + // get items for table + .setListFunction(service.getPromise) + + // specify table columns + .tableColumns + .append({ + id: 'timestamp', + priority: 1, + sortDefault: 'reverse' + }) + .append({ + id: 'state', + priority: 1 + }) + .append({ + id: 'event_log_id', + priority: 1, + urlFunction: service.urlFunction + }) + .append({ + id: 'reason_text', + priority: 1 + }) + .append({ + id: 'entity_instance_id', + priority: 1 + }) + .append({ + id: 'suppression_status', + priority: 1, + allowed: service.suppressColAllowedPromiseFunction + }) + .append({ + id: 'severity', + priority: 2 + }); + + // for magic-search + registry.getResourceType(resourceType).filterFacets + .append({ + 'label': gettext('Event Type'), + 'name': 'event_type', + 'singleton': true, + 'options': [ + {label: gettext('log'), key: 'log'}, + {label: gettext('alarm'), key: 'alarm'} + ] + }) + .append({ + 'label': gettext('ID'), + 'name': 'event_log_id', + 'singleton': true + }) + .append({ + 'label': gettext('Entity Instance ID'), + 'name': 'entity_instance_id', + 'singleton': true + }) + .append({ + 'label': gettext('Reason Text'), + 'name': 'reason_text', + 'singleton': true + }) + .append({ + 'label': gettext('State'), + 'name': 'state', + 'singleton': true, + 'options': [ + {label: gettext('clear'), key: 'clear'}, + {label: gettext('log'), key: 'log'}, + {label: gettext('set'), key: 'set'} + ] + }) + .append({ + 'label': gettext('Severity'), + 'name': 'severity', + 'singleton': true, + 'options': [ + {label: gettext('critical'), key: 'critical'}, + {label: gettext('major'), key: 'major'}, + {label: gettext('minor'), key: 'minor'}, + {label: gettext('warning'), key: 'warning'}, + {label: gettext('not-applicable'), key: 'not-applicable'} + ] + }) + .append({ + 'label': gettext('Timestamp'), + 'name': 'timestamp', + 'singleton': true + }) + .append({ + 'label': gettext('UUID'), + 'name': 'uuid', + 'singleton': true + }); + } + + function properties() { + return { + uuid: { label: gettext('Event UUID'), filters: ['noValue'] }, + event_log_id: { label: gettext('ID'), filters: ['noValue'] }, + reason_text: { label: gettext('Reason Text'), filters: ['noValue'] }, + entity_instance_id: { label: gettext('Entity Instance ID'), filters: ['noValue'] }, + severity: { label: gettext('Severity'), filters: ['noValue'] }, + timestamp: { label: gettext('Timestamp'), filters: ['noValue'] }, + suppression_status: { label: gettext('Suppression Status'), filters: ['noValue'] }, + suppression: { label: gettext('Suppression'), filters: ['noValue'] }, + state: { label: gettext('State'), filters: ['noValue'] }, + service_affecting: { label: gettext('Service Affecting'), filters: ['noValue'] }, + event_log_type: { label: gettext('Alarm Type'), filters: ['noValue'] }, + probable_cause: { label: gettext('Probable Cause'), filters: ['noValue'] }, + entity_type_id: { label: gettext('Entity Type ID'), filters: ['noValue'] }, + proposed_repair_action: { label: gettext('Proposed Repair Action'), filters: ['noValue'] }, + event_type: { label: gettext('Event Type'), filters: ['noValue'] }, + _suppression_status: { label: gettext('_suppression_status'), filters: ['noValue'] } + }; + } + + config.$inject = [ + '$provide', + '$windowProvider', + '$routeProvider' + ]; + + /** + * @name config + * @param {Object} $provide + * @param {Object} $windowProvider + * @param {Object} $routeProvider + * @description Routes used by this module. + * @returns {undefined} Returns nothing + */ + function config($provide, $windowProvider, $routeProvider) { + var path = $windowProvider.$get().STATIC_URL + 'dashboard/fault_management/events/'; + $provide.constant('horizon.dashboard.fault_management.events.basePath', path); + + $routeProvider.when('/admin/events', { + templateUrl: path + 'panel.html', + resolve: { + searchResults: ['horizon.dashboard.fault_management.events.service', function (searchService) { + return searchService.getSuppressionList(); + }] + } + }); + } +})(); diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/events.module.spec.js b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/events.module.spec.js new file mode 100644 index 00000000..72989206 --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/events.module.spec.js @@ -0,0 +1,30 @@ +/** + * 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. + */ +/** + * Copyright (c) 2019 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +(function() { + 'use strict'; + + describe('horizon.dashboard.fault_management.events', function() { + it('should exist', function() { + expect(angular.module('horizon.dashboard.fault_management.events')).toBeDefined(); + }); + }); + +})(); diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/events.service.js b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/events.service.js new file mode 100644 index 00000000..905b95c5 --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/events.service.js @@ -0,0 +1,157 @@ +/** + * 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. + */ +/** + * Copyright (c) 2019 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +(function() { + "use strict"; + + angular.module('horizon.dashboard.fault_management.events') + .factory('horizon.dashboard.fault_management.events.service', + service); + + service.$inject = [ + '$filter', + 'horizon.app.core.detailRoute', + 'horizon.app.core.openstack-service-api.fm', + '$q', + 'horizon.framework.conf.resource-type-registry.service', + 'horizon.dashboard.fault_management.events.resourceType' + ]; + + /* + * @ngdoc factory + * @name horizon.dashboard.fault_management.events.service + * + * @description + * This service provides functions that are used through the Events + * features. These are primarily used in the module registrations + * but do not need to be restricted to such use. Each exposed function + * is documented below. + */ + function service($filter, detailRoute, api, $q, registry, resourceType) { + + var showSuppressColumn = null; + + return { + getPromise: getPromise, + urlFunction: urlFunction, + suppressColAllowedPromiseFunction: suppressColAllowedPromiseFunction, + getSuppressionList: getSuppressionList, + setEventType: setEventType + }; + + function getPromise(params) { + return api.getEvents(params).then(modifyResponse); + } + + function modifyResponse(response) { + return {data: {items: response.data.items.map(modifyItem)}}; + + function modifyItem(item) { + var timestamp = item.updated_at ? item.updated_at : item.created_at; + item.trackBy = item.uuid + timestamp; + + setEventType(item); + + if (item.suppression_status == 'suppressed') { + item._suppression_status = 'True'; + } + else if (item.suppression_status == 'unsuppressed') { + item._suppression_status = 'False'; + } + else { + item._suppression_status = 'None'; + } + + return item; + } + } + + function urlFunction(item) { + return detailRoute + 'OS::StarlingX::Events/' + item.uuid; + } + + function getSuppressionList() { + var include_unsuppressed = false; + return api.getEventsSuppression(include_unsuppressed).then(modifyResponseSupp); + } + + function modifyResponseSupp(response) { + if (response.data.items.length == 0) { + showSuppressColumn = false; + } + else { + showSuppressColumn = true; + } + return; + } + + + /** + * @name suppressColAllowedPromiseFunction + * @description + * If there are no unsuppressed events then we do not show the Suppression + * Status column. We also do show the the filter associated with that column. + */ + function suppressColAllowedPromiseFunction() { + + var filters = registry.getResourceType(resourceType).filterFacets; + var index = filters.findIndex(obj => obj['id'] === 'suppression_status'); + + if (showSuppressColumn === false) { + if (index >= 0) { + filters.remove('suppression_status') + } + return $q.reject(); + } + else { + if (index < 0) { + filters.append({ + 'label': gettext('Suppression Status'), + 'id': 'suppression_status', + 'name': '_suppression_status', + 'singleton': false, + 'options': [ + {label: gettext('suppressed'), key: 'True'}, + {label: gettext('unsuppressed'), key: 'False'}, + {label: gettext('None'), key: 'None'} + ] + }); + } + return $q.resolve(); + } + } + + /////////// + // Utils // + /////////// + + function setEventType(item) { + if (item.state == "clear" || item.state == "set") { + item.event_type = "alarm" + } + else if (item.state == "log" ) { + item.event_type = "log" + } + return item; + } + + } +})(); + diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/events.service.spec.js b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/events.service.spec.js new file mode 100644 index 00000000..424742b5 --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/events.service.spec.js @@ -0,0 +1,60 @@ +/** + * 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. + */ +/** + * Copyright (c) 2019 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +(function() { + "use strict"; + + describe('Event service', function() { + var service; + beforeEach(module('horizon.app.core.openstack-service-api')); + beforeEach(module('horizon.dashboard.fault_management.events')); + beforeEach(inject(function($injector) { + service = $injector.get('horizon.dashboard.fault_management.events.service'); + })); + + describe('getPromise', function() { + it("provides a promise", inject(function($q, $injector, $timeout) { + var api = $injector.get('horizon.app.core.openstack-service-api.fm'); + var deferred = $q.defer(); + spyOn(api, 'getEvents').and.returnValue(deferred.promise); + var result = service.getPromise({}); + deferred.resolve({ + data:{ + items: [{uuid: '123abc', reason_text: 'resource1'}] + } + }); + $timeout.flush(); + expect(api.getEvents).toHaveBeenCalled(); + expect(result.$$state.value.data.items[0].reason_text).toBe('resource1'); + })); + }); + + describe('urlFunction', function() { + it("get url", inject(function($injector) { + var detailRoute = $injector.get('horizon.app.core.detailRoute'); + var result = service.urlFunction({uuid:"123abc"}); + expect(result).toBe(detailRoute + "OS::StarlingX::Events/123abc"); + })); + }); + + }); + +})(); + diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/panel.html b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/panel.html new file mode 100644 index 00000000..3e8ac9cc --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/panel.html @@ -0,0 +1,6 @@ + + + + + diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/actions/actions.module.js b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/actions/actions.module.js new file mode 100644 index 00000000..f43a97f2 --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/actions/actions.module.js @@ -0,0 +1,76 @@ +/** + * 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. + */ +/** + * Copyright (c) 2019 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +(function() { + 'use strict'; + + /** + * @ngdoc overview + * @ngname horizon.dashboard.fault_management.events_suppression.actions + * + * @description + * Provides all of the actions for Events Suppression. + */ + angular + .module('horizon.dashboard.fault_management.events_suppression.actions', [ + 'horizon.framework', + 'horizon.dashboard.fault_management' + ]) + .run(registerEventsSuppressionActions); + + registerEventsSuppressionActions.$inject = [ + 'horizon.framework.conf.resource-type-registry.service', + 'horizon.framework.util.i18n.gettext', + 'horizon.dashboard.fault_management.events_suppression.suppress_event.service', + 'horizon.dashboard.fault_management.events_suppression.unsuppress_event.service', + 'horizon.dashboard.fault_management.events_suppression.resourceType' + ]; + + function registerEventsSuppressionActions ( + registry, + gettext, + suppressEventService, + unsuppressEventService, + resourceType + ) { + var eventSuppressionResourceType = registry.getResourceType(resourceType); + + eventSuppressionResourceType.itemActions + .append({ + id: 'suppressEventAction', + service: suppressEventService, + template: { + type: 'danger', + text: gettext('Suppress Event') + } + }); + + eventSuppressionResourceType.itemActions + .append({ + id: 'unsuppressEventAction', + service: unsuppressEventService, + template: { + type: 'danger', + text: gettext('Unsuppress Event') + } + }); + + } +})(); diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/actions/suppress_event.service.js b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/actions/suppress_event.service.js new file mode 100644 index 00000000..7d27a6fb --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/actions/suppress_event.service.js @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2019 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +(function() { + 'use strict'; + + angular + .module('horizon.dashboard.fault_management') + .factory('horizon.dashboard.fault_management.events_suppression.suppress_event.service', updateService); + + updateService.$inject = [ + '$location', + 'horizon.app.core.openstack-service-api.fm', + 'horizon.framework.widgets.modal.simple-modal.service', + 'horizon.framework.widgets.toast.service', + 'horizon.framework.util.q.extensions' + ]; + + function updateService($location, api, simpleModalService, toastService, $qExtensions) { + + var scope; + + var service = { + perform: perform, + allowed: allowed + }; + + var suppressedText = "Suppress Event"; + var suppressed = "suppressed"; + + return service; + + function perform(selected, newScope) { + + var alarm_id = selected.alarm_id; + + var options = { + title: 'Confirm ' + suppressedText, + body: 'You have selected: "' + alarm_id + + '". Please confirm your selection. Events with selected Alarm ID will be ' + + suppressed + '.', + submit: suppressedText, + cancel: 'Cancel' + }; + + selected = angular.isArray(selected) ? selected : [selected]; + + return simpleModalService.modal(options).result.then(onModalSubmit); + + function onModalSubmit() { + return $qExtensions.allSettled(selected.map(updateEntityPromise)).then(notify); + } + + function updateEntityPromise(selected) { + var status = {'suppression_status': suppressed}; + return {promise: api.updateEventSuppression(selected.uuid, status)}; + } + + function notify(result) { + if (result.pass.length > 0) { + var msg = gettext("Events %(suppressed)s for Alarm ID: %(alarm_id)s"); + toastService.add('success', interpolate(msg, {suppressed: suppressed, alarm_id: alarm_id}, true)); + $location.path('/admin/events_suppression'); + } + + if (result.fail.length > 0) { + var msg = gettext("Failed to %(suppressed)s events for Alarm ID: %(alarm_id)s"); + toastService.add('error', interpolate(msg, {suppressed: suppressed, alarm_id: alarm_id}, true)); + return result; + } + } + } + + function allowed($scope) { + if ($scope.suppression_status == suppressed) { + return $qExtensions.booleanAsPromise(false); + } + else { + return $qExtensions.booleanAsPromise(true); + } + } + + } +})(); diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/actions/unsuppress_event.service.js b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/actions/unsuppress_event.service.js new file mode 100644 index 00000000..15035d55 --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/actions/unsuppress_event.service.js @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2019 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +(function() { + 'use strict'; + + angular + .module('horizon.dashboard.fault_management') + .factory('horizon.dashboard.fault_management.events_suppression.unsuppress_event.service', updateService); + + updateService.$inject = [ + '$location', + 'horizon.app.core.openstack-service-api.fm', + 'horizon.framework.widgets.modal.simple-modal.service', + 'horizon.framework.widgets.toast.service', + 'horizon.framework.util.q.extensions' + ]; + + function updateService($location, api, simpleModalService, toastService, $qExtensions) { + + var scope; + + var service = { + perform: perform, + allowed: allowed + }; + + var unsuppressedText = "Unsuppress Event"; + var unsuppressed = "unsuppressed"; + + return service; + + function perform(selected, newScope) { + + var alarm_id = selected.alarm_id; + + var options = { + title: 'Confirm ' + unsuppressedText, + body: 'You have selected: "' + alarm_id + + '". Please confirm your selection. Events with selected Alarm ID will be ' + + unsuppressed + '.', + submit: unsuppressedText, + cancel: 'Cancel' + }; + + selected = angular.isArray(selected) ? selected : [selected]; + + return simpleModalService.modal(options).result.then(onModalSubmit); + + function onModalSubmit() { + return $qExtensions.allSettled(selected.map(updateEntityPromise)).then(notify); + } + + function updateEntityPromise(selected) { + var status = {'suppression_status': unsuppressed}; + return {promise: api.updateEventSuppression(selected.uuid, status)}; + } + + function notify(result) { + if (result.pass.length > 0) { + var msg = gettext("Events %(unsuppressed)s for Alarm ID: %(alarm_id)s"); + toastService.add('success', interpolate(msg, {unsuppressed: unsuppressed, alarm_id: alarm_id}, true)); + $location.path('/admin/events_suppression'); + } + + if (result.fail.length > 0) { + var msg = gettext("Failed to %(unsuppressed)s events for Alarm ID: %(alarm_id)s"); + toastService.add('error', interpolate(msg, {unsuppressed: unsuppressed, alarm_id: alarm_id}, true)); + return result; + } + } + } + + function allowed($scope) { + if ($scope.suppression_status == unsuppressed) { + return $qExtensions.booleanAsPromise(false); + } + else { + return $qExtensions.booleanAsPromise(true); + } + } + + } +})(); diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/events_suppression.module.js b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/events_suppression.module.js new file mode 100644 index 00000000..c16d670c --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/events_suppression.module.js @@ -0,0 +1,131 @@ +/** + * 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. + */ +/** + * Copyright (c) 2019 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +(function() { + 'use strict'; + + /** + * @ngdoc overview + * @name horizon.dashboard.fault_management.events_suppression + * @ngModule + * @description + * Provides all the services and widgets require to display the Events Suppression + * panel + */ + angular + .module('horizon.dashboard.fault_management.events_suppression', [ + 'ngRoute', + 'horizon.dashboard.fault_management.events_suppression.actions' + ]) + .constant('horizon.dashboard.fault_management.events_suppression.resourceType', 'OS::StarlingX::EventsSuppression') + .run(run) + .config(config); + + + run.$inject = [ + 'horizon.framework.conf.resource-type-registry.service', + 'horizon.dashboard.fault_management.events_suppression.service', + 'horizon.dashboard.fault_management.events_suppression.basePath', + 'horizon.dashboard.fault_management.events_suppression.resourceType' + ]; + + + function run(registry, service, basePath, resourceType) { + registry.getResourceType(resourceType) + .setNames(gettext('Events Suppression'), gettext('Events Suppression')) + + // specify items for table row items, summary view and details view + .setProperties(properties()) + + // get items for table + .setListFunction(service.getPromise) + + // specify table columns + .tableColumns + .append({ + id: 'alarm_id', + priority: 1, + sortDefault: true + }) + .append({ + id: 'description', + priority: 1 + }) + .append({ + id: 'suppression_status', + priority: 1 + }); + // for magic-search + registry.getResourceType(resourceType).filterFacets + .append({ + 'label': gettext('Event ID'), + 'name': 'alarm_id', + 'singleton': true + }) + .append({ + 'label': gettext('Description'), + 'name': 'description', + 'singleton': true + }) + .append({ + 'label': gettext('Status'), + 'name': 'is_suppressed', + 'singleton': true, + 'options': [ + {label: gettext('suppressed'), key: 'true'}, + {label: gettext('unsuppressed'), key: 'false'} + ] + }) + ; + } + + function properties() { + return { + alarm_id: { label: gettext('Event ID'), filters: ['noValue'] }, + description: { label: gettext('Description'), filters: ['noValue'] }, + uuid: { label: gettext('Event UUID'), filters: ['noValue'] }, + suppression_status: { label: gettext('Status'), filters: ['noValue'] }, + links: { label: gettext('Links'), filters: ['noValue'] }, + is_suppressed: { label: gettext('IsSuppressed'), filters: ['noValue'] } + }; + } + + config.$inject = [ + '$provide', + '$windowProvider', + '$routeProvider' + ]; + + /** + * @name config + * @param {Object} $provide + * @param {Object} $windowProvider + * @param {Object} $routeProvider + * @description Routes used by this module. + * @returns {undefined} Returns nothing + */ + function config($provide, $windowProvider, $routeProvider) { + var path = $windowProvider.$get().STATIC_URL + 'dashboard/fault_management/events_suppression/'; + $provide.constant('horizon.dashboard.fault_management.events_suppression.basePath', path); + $routeProvider.when('/admin/events_suppression', { + templateUrl: path + 'panel.html' + }); + } +})(); diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/events_suppression.module.spec.js b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/events_suppression.module.spec.js new file mode 100644 index 00000000..1433a30d --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/events_suppression.module.spec.js @@ -0,0 +1,30 @@ +/** + * 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. + */ +/** + * Copyright (c) 2019 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +(function() { + 'use strict'; + + describe('horizon.dashboard.fault_management.events_suppression', function() { + it('should exist', function() { + expect(angular.module('horizon.dashboard.fault_management.events_suppression')).toBeDefined(); + }); + }); + +})(); diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/events_suppression.scss b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/events_suppression.scss new file mode 100644 index 00000000..b5ce841b --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/events_suppression.scss @@ -0,0 +1,4 @@ +// This enables \n to render properly, we use this for the description col +[resource-type-name="OS::StarlingX::EventsSuppression"] table hz-field.ng-scope.ng-isolate-scope { + white-space: pre-wrap; +} diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/events_suppression.service.js b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/events_suppression.service.js new file mode 100644 index 00000000..0c56074b --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/events_suppression.service.js @@ -0,0 +1,78 @@ +/** + * 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. + */ +/** + * Copyright (c) 2019 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +(function() { + "use strict"; + + angular.module('horizon.dashboard.fault_management.events_suppression') + .factory('horizon.dashboard.fault_management.events_suppression.service', + service); + + service.$inject = [ + '$filter', + 'horizon.app.core.detailRoute', + 'horizon.app.core.openstack-service-api.fm' + ]; + + /* + * @ngdoc factory + * @name horizon.dashboard.fault_management.events_suppression.service + * + * @description + * This service provides functions that are used through the Events Suppression + * features. These are primarily used in the module registrations + * but do not need to be restricted to such use. Each exposed function + * is documented below. + */ + function service($filter, detailRoute, api) { + return { + getPromise: getPromise + }; + + function getPromise(params) { + var include_unsuppressed = true; + return api.getEventsSuppression(include_unsuppressed).then(modifyResponse); + } + + function modifyResponse(response) { + return {data: {items: response.data.items.map(modifyItem)}}; + + function modifyItem(item) { + + // This enables the items to be updated on the view + item.trackBy = [ + item.uuid, + item.suppression_status, + item.alarm_id + ].join('/'); + + if (item.suppression_status == 'suppressed') { + item.is_suppressed = true; + } + else { + item.is_suppressed = false; + } + + return item; + } + } + } +})(); + diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/events_suppression.service.spec.js b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/events_suppression.service.spec.js new file mode 100644 index 00000000..372bbdb2 --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/events_suppression.service.spec.js @@ -0,0 +1,60 @@ +/** + * 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. + */ +/** + * Copyright (c) 2019 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +(function() { + "use strict"; + + describe('Events Suppression service', function() { + var service; + beforeEach(module('horizon.app.core.openstack-service-api')); + beforeEach(module('horizon.dashboard.fault_management.events_suppression')); + beforeEach(inject(function($injector) { + service = $injector.get('horizon.dashboard.fault_management.events_suppression.service'); + })); + + describe('getPromise', function() { + it("provides a promise", inject(function($q, $injector, $timeout) { + var api = $injector.get('horizon.app.core.openstack-service-api.fm'); + var deferred = $q.defer(); + spyOn(api, 'getEventsSuppression').and.returnValue(deferred.promise); + var result = service.getPromise({}); + deferred.resolve({ + data:{ + items: [{uuid: '123abc', description: 'resource1'}] + } + }); + $timeout.flush(); + expect(api.getEventsSuppression).toHaveBeenCalled(); + expect(result.$$state.value.data.items[0].description).toBe('resource1'); + })); + }); + + describe('urlFunction', function() { + it("get url", inject(function($injector) { + var detailRoute = $injector.get('horizon.app.core.detailRoute'); + var result = service.urlFunction({id:"123abc"}); + expect(result).toBe(detailRoute + "OS::StarlingX::EventsSuppression/123abc"); + })); + }); + + }); + +})(); + diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/panel.html b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/panel.html new file mode 100644 index 00000000..2734f711 --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/panel.html @@ -0,0 +1,6 @@ + + + + + diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/fault_management.module.js b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/fault_management.module.js new file mode 100644 index 00000000..2af72fe8 --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/fault_management.module.js @@ -0,0 +1,48 @@ +/** + * 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. + */ +/** + * Copyright (c) 2019 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +(function() { + 'use strict'; + + /** + * @ngdoc overview + * @name horizon.dashboard.fault_management + * @description + * Dashboard module to host various platform panels. + */ + // fixme: if ngRoute and $routeProvider are unnecessary, remove them + /* eslint-disable no-unused-vars */ + angular + .module('horizon.dashboard.fault_management', [ + 'horizon.dashboard.fault_management.active_alarms', + 'horizon.dashboard.fault_management.events', + 'horizon.dashboard.fault_management.events_suppression', + 'ngRoute' + ]) + .config(config); + + config.$inject = ['$provide', '$windowProvider', '$routeProvider']; + + function config($provide, $windowProvider, $routeProvider) { + var path = $windowProvider.$get().STATIC_URL + 'dashboard/fault_management/'; + $provide.constant('horizon.dashboard.fault_management.basePath', path); + } + /* eslint-disable no-unused-vars */ +})(); diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/fault_management.module.spec.js b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/fault_management.module.spec.js new file mode 100644 index 00000000..ba2dba7c --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/fault_management.module.spec.js @@ -0,0 +1,30 @@ +/** + * 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. + */ +/** + * Copyright (c) 2019 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +(function() { + 'use strict'; + + describe('horizon.dashboard.fault_management', function() { + it('should exist', function() { + expect(angular.module('horizon.dashboard.fault_management')).toBeDefined(); + }); + }); + +})(); diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/fault_management.scss b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/fault_management.scss new file mode 100644 index 00000000..3f8aa832 --- /dev/null +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/fault_management.scss @@ -0,0 +1 @@ +@import "events_suppression/events_suppression"; diff --git a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/js/horizon.alarmbanner.js b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/js/horizon.alarmbanner.js index 3e00ff4a..d06a15e0 100755 --- a/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/js/horizon.alarmbanner.js +++ b/starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/js/horizon.alarmbanner.js @@ -1,3 +1,10 @@ +/** + * Copyright (c) 2019 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + /* Core functionality related to alam-banner. */ horizon.alarmbanner = { @@ -6,7 +13,7 @@ horizon.alarmbanner = { var $old = $(location).attr('pathname'); var $url = $(location).attr('href'); - $url = $url.replace($old, "/admin/fault_management/banner"); + $url = $url.replace($old, "/admin/active_alarms/banner"); horizon.ajax.queue({ url: $url, @@ -49,7 +56,7 @@ horizon.alarmbanner = { }, onclick: function() { - var $fm = "/admin/fault_management"; + var $fm = "/admin/active_alarms"; var $dc = "/dc_admin/"; var $cur = document.location.href; var $path = document.location.pathname;