monasca-ui/monitoring/alarmdefs/workflows.py

229 lines
8.5 KiB
Python

# 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 # noqa
from horizon import exceptions
from horizon import forms
from horizon import workflows
from horizon.utils import memoized
from monitoring import api
from monitoring.alarmdefs import constants
from monitoring.alarmdefs import forms as ad_forms
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