# Copyright 2016 FUJITSU LIMITED # # 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. from django.utils.translation import ugettext_lazy as _ # noqa from django.views.decorators.debug import sensitive_variables from horizon import exceptions from horizon import forms from horizon.utils import memoized from horizon import workflows from monitoring.alarmdefs import constants from monitoring.alarmdefs import forms as ad_forms from monitoring import api class SetAlarmNotificationsAction(workflows.Action): notifications = ad_forms.NotificationField( label=_('Notifications'), required=False, widget=ad_forms.NotificationCreateWidget(), help_text=_('Notification methods. ' 'Notifications can be sent when an alarm ' 'state transition occurs.')) alarm_actions = ad_forms.NotificationField( label=_("Alarm Actions"), required=False, widget=forms.MultipleHiddenInput() ) ok_actions = ad_forms.NotificationField( label=_("OK Actions"), required=False, widget=forms.MultipleHiddenInput() ) undetermined_actions = ad_forms.NotificationField( label=_("Undetermined Actions"), required=False, widget=forms.MultipleHiddenInput() ) class Meta(object): name = _('Notifications') help_text_template = ("monitoring/alarmdefs/" "_create_ad_notification_help.html") def __init__(self, request, context, *args, **kwargs): super(SetAlarmNotificationsAction, self).__init__( request, context, *args, **kwargs ) try: notifications = ad_forms._get_notifications(request) self.fields['notifications'].choices = notifications except Exception as e: exceptions.handle(request, _('Unable to retrieve notifications: %s') % e) _SEVERITY_CHOICES = [("LOW", _("Low")), ("MEDIUM", _("Medium")), ("HIGH", _("High")), ("CRITICAL", _("Critical"))] class SetAlarmDefinitionAction(workflows.Action): name = forms.CharField(label=_('Name'), required=True, max_length=250, help_text=_('An unique name of the alarm.')) description = forms.CharField(label=_('Description'), required=False, help_text=_('A description of an alarm.')) severity = forms.ChoiceField(label=_('Severity'), choices=_SEVERITY_CHOICES, initial=_SEVERITY_CHOICES[0], widget=forms.SelectWidget, required=False, help_text=_('Severity of an alarm. Must be ' 'either LOW, MEDIUM, HIGH ' 'or CRITICAL. Default is LOW.')) class Meta(object): name = _('Details') help_text_template = ("monitoring/alarmdefs/" "_create_ad_details_help.html") def clean(self): cleaned_data = super(SetAlarmDefinitionAction, self).clean() alarm_def_name = cleaned_data.get('name', '').strip() if not alarm_def_name: return is_name_valid = self._is_alarm_def_name_unique_validator( alarm_def_name) if not is_name_valid: self.add_error('name', _('Alarm definition with %s name already exists') % alarm_def_name) def _is_alarm_def_name_unique_validator(self, value): try: ret = self._get_alarm_def_by_name(value) return not (ret and len(ret)) except Exception: exceptions.handle(request=self.request, message=_('Failed to validate name'), ignore=True) return True @memoized.memoized_method def _get_alarm_def_by_name(self, value): return api.monitor.alarmdef_get_by_name(self.request, value) class SetAlarmDefinitionExpressionAction(workflows.Action): expression = ad_forms.ExpressionField(label=_("Expression"), required=True, widget=ad_forms.ExpressionWidget(''), help_text=_( 'An alarm expression.')) match_by = forms.CharField(label=_('Match by'), required=False, widget=ad_forms.MatchByWidget(''), help_text=_('The metric dimensions used ' 'to create unique alarms.')) class Meta(object): name = _('Expression') help_text_template = ("monitoring/alarmdefs/" "_create_ad_expression_help.html") def __init__(self, request, context, *args, **kwargs): super(SetAlarmDefinitionExpressionAction, self).__init__(request, context, *args, **kwargs) try: self.fields['expression'].metrics = ad_forms._get_metrics(request) except Exception: exceptions.handle(request, _('Unable to retrieve metrics')) class SetDetailsStep(workflows.Step): action_class = SetAlarmDefinitionAction contributes = ('name', 'description', 'severity') template_name = 'monitoring/alarmdefs/workflow_step.html' class SetExpressionStep(workflows.Step): action_class = SetAlarmDefinitionExpressionAction contributes = ('expression', 'match_by') template_name = 'monitoring/alarmdefs/workflow_step.html' def contribute(self, data, context): context = (super(SetExpressionStep, self) .contribute(data, context)) if 'expression' in data and data['expression']: context['expression'] = data['expression'].strip() if 'match_by' in data and data['match_by']: context['match_by'] = context['match_by'].split(',') else: context['match_by'] = [] return context class SetNotificationsStep(workflows.Step): action_class = SetAlarmNotificationsAction contributes = ('alarm_actions', 'ok_actions', 'undetermined_actions') template_name = 'monitoring/alarmdefs/workflow_step.html' class AlarmDefinitionWorkflow(workflows.Workflow): slug = 'create_alarm_definition' name = _('Create Alarm Definition') finalize_button_name = _('Create Alarm Definition') success_message = _('Alarm definition %s has been created') failure_message = _('Unable to create alarm definition %s') success_url = constants.URL_PREFIX + 'index' wizard = True default_steps = ( SetDetailsStep, SetExpressionStep, SetNotificationsStep ) def format_status_message(self, message): name = self.context.get('name', _('Unknown name')) return message % name @sensitive_variables('alarm_actions', 'ok_actions', 'undetermined_actions') def handle(self, request, context): try: api.monitor.alarmdef_create( request, name=context['name'], expression=context['expression'], description=context['description'], severity=context['severity'], match_by=context['match_by'], alarm_actions=context['alarm_actions'], ok_actions=context['ok_actions'], undetermined_actions=context['undetermined_actions'], ) except Exception as e: exceptions.handle(request, e, escalate=True) return False return True