From 0f57d0e1dc1ca62992ba8d2c606a46a22b5b955e Mon Sep 17 00:00:00 2001 From: Kristine Bujold Date: Tue, 22 Jan 2019 10:55:04 -0500 Subject: [PATCH] Refactor the FM panel to leverage AngularJS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The FM panel which contains 3 tabs is now replaced with a new panel group called “Fault Management” under Admin which contains an “Active Alarms”, “Events” and “Events Suppression” panel. The suppression buttons are gone, filters replace the need for the suppression buttons. Paging is done automatically in AngularJS the and ‘Default Limit' button is also gone. The Alarm Summary Banner was removed from the FM panels as it is already displayed in the header banner. The “Related Alarms” tab under the “Provider Network Topology“ panel was refactored to still uses Django’s alarms table. Other related FM Django code that is no longer used has been removed. Refactored some DC Cloud panels as well. Story: 2004818 Task: 28984 Change-Id: I7fdece26118dc066cf93001189767f78bfe2caf7 Signed-off-by: Kristine Bujold --- starlingx-dashboard/centos/build_srpm.data | 2 +- .../starlingx_dashboard/api/fm.py | 11 +- .../starlingx_dashboard/api/rest/fm.py | 84 ++++- .../__init__.py | 0 .../panel.py | 21 +- .../dashboards/admin/active_alarms/urls.py | 29 ++ .../dashboards/admin/active_alarms/views.py | 76 +++++ .../dashboards/admin/events/__init__.py | 0 .../dashboards/admin/events/panel.py | 41 +++ .../dashboards/admin/events/urls.py | 25 ++ .../admin/events_suppression/__init__.py | 0 .../admin/events_suppression/panel.py | 41 +++ .../admin/events_suppression/urls.py | 25 ++ .../admin/fault_management/tables.py | 280 ---------------- .../dashboards/admin/fault_management/tabs.py | 309 ------------------ .../fault_management/_active_alarms.html | 26 -- .../fault_management/_detail_history.html | 58 ---- .../fault_management/_detail_log.html | 50 --- .../fault_management/_detail_overview.html | 52 --- .../templates/fault_management/_summary.html | 5 - .../templates/fault_management/index.html | 29 -- .../dashboards/admin/fault_management/urls.py | 35 -- .../admin/fault_management/views.py | 175 ---------- .../dashboards/admin/host_topology/tables.py | 49 ++- .../table/central_table.controller.js | 4 +- .../table/subcloud_table.controller.js | 4 +- .../static/dashboard/dc_admin/fm.service.js | 48 --- .../enabled/_1001_starlingx.py | 6 + ...ingx_admin_fault_management_panel_group.py | 18 + ...gx_admin_fault_management_alarms_panel.py} | 8 +- ...ngx_admin_fault_management_events_panel.py | 9 + ...ult_management_events_suppression_panel.py | 10 + .../app/core/fault_management/fm.service.js | 116 +++++++ .../active_alarms/active_alarms.module.js | 194 +++++++++++ .../active_alarms.module.spec.js | 30 ++ .../active_alarms/active_alarms.service.js | 136 ++++++++ .../active_alarms.service.spec.js | 59 ++++ .../active_alarms/details/details.module.js | 64 ++++ .../active_alarms/details/drawer.html | 5 + .../details/overview.controller.js | 44 +++ .../active_alarms/details/overview.html | 17 + .../fault_management/active_alarms/panel.html | 6 + .../events/details/details.module.js | 64 ++++ .../events/details/drawer.html | 5 + .../events/details/overview.controller.js | 48 +++ .../events/details/overview.html | 17 + .../fault_management/events/events.module.js | 208 ++++++++++++ .../events/events.module.spec.js | 30 ++ .../fault_management/events/events.service.js | 157 +++++++++ .../events/events.service.spec.js | 60 ++++ .../fault_management/events/panel.html | 6 + .../actions/actions.module.js | 76 +++++ .../actions/suppress_event.service.js | 88 +++++ .../actions/unsuppress_event.service.js | 88 +++++ .../events_suppression.module.js | 131 ++++++++ .../events_suppression.module.spec.js | 30 ++ .../events_suppression.scss | 4 + .../events_suppression.service.js | 78 +++++ .../events_suppression.service.spec.js | 60 ++++ .../events_suppression/panel.html | 6 + .../fault_management.module.js | 48 +++ .../fault_management.module.spec.js | 30 ++ .../fault_management/fault_management.scss | 1 + .../static/js/horizon.alarmbanner.js | 11 +- 64 files changed, 2348 insertions(+), 1099 deletions(-) rename starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/{fault_management => active_alarms}/__init__.py (100%) mode change 100755 => 100644 rename starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/{fault_management => active_alarms}/panel.py (71%) mode change 100755 => 100644 create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/active_alarms/urls.py create mode 100755 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/active_alarms/views.py create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/events/__init__.py create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/events/panel.py create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/events/urls.py create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/events_suppression/__init__.py create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/events_suppression/panel.py create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/events_suppression/urls.py delete mode 100755 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/tables.py delete mode 100755 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/tabs.py delete mode 100755 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/templates/fault_management/_active_alarms.html delete mode 100755 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/templates/fault_management/_detail_history.html delete mode 100755 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/templates/fault_management/_detail_log.html delete mode 100755 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/templates/fault_management/_detail_overview.html delete mode 100755 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/templates/fault_management/_summary.html delete mode 100755 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/templates/fault_management/index.html delete mode 100755 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/urls.py delete mode 100755 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/admin/fault_management/views.py delete mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/dashboards/dc_admin/static/dashboard/dc_admin/fm.service.js create mode 100755 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/enabled/_1001_starlingx.py create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/enabled/_2400_starlingx_admin_fault_management_panel_group.py rename starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/enabled/{_2032_starlingx_admin_fault_management_panel.py => _2401_starlingx_admin_fault_management_alarms_panel.py} (75%) mode change 100755 => 100644 create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/enabled/_2402_starlingx_admin_fault_management_events_panel.py create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/enabled/_2403_starlingx_admin_fault_management_events_suppression_panel.py create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/app/core/fault_management/fm.service.js create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/active_alarms.module.js create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/active_alarms.module.spec.js create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/active_alarms.service.js create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/active_alarms.service.spec.js create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/details/details.module.js create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/details/drawer.html create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/details/overview.controller.js create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/details/overview.html create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/active_alarms/panel.html create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/details/details.module.js create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/details/drawer.html create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/details/overview.controller.js create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/details/overview.html create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/events.module.js create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/events.module.spec.js create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/events.service.js create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/events.service.spec.js create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events/panel.html create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/actions/actions.module.js create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/actions/suppress_event.service.js create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/actions/unsuppress_event.service.js create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/events_suppression.module.js create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/events_suppression.module.spec.js create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/events_suppression.scss create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/events_suppression.service.js create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/events_suppression.service.spec.js create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/events_suppression/panel.html create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/fault_management.module.js create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/fault_management.module.spec.js create mode 100644 starlingx-dashboard/starlingx-dashboard/starlingx_dashboard/static/dashboard/fault_management/fault_management.scss 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;