mirror of
https://github.com/ZwareBear/awx.git
synced 2026-05-14 15:58:38 -05:00
Merge branch 'notifications_work' into devel
* notifications_work: (23 commits) Updates to notification unit tests after @wwitzel3's feedback Fix some notifications issues and write some tests Add notification system documentation Clean up flake8 related issues Fixing up some unicode issues Implement tower ui view url on models Sanity check and force proper types in admin check Proper type for in check Adding migration and base notification type Add a periodic administrative notification Refactor message generator Support notification password field encryption Notification configuration type checking Refactor NotificationTemplate to Notifier Implement irc notification backend Add webhook notification backend Pagerduty and Hipchat backends plus some cleanup Notification serializers, views, and tasks Implement notification serializer and validations Notification endpoints and url expositions ...
This commit is contained in:
+92
-1
@@ -481,6 +481,8 @@ class BaseSerializer(serializers.ModelSerializer):
|
||||
class EmptySerializer(serializers.Serializer):
|
||||
pass
|
||||
|
||||
class EmptySerializer(serializers.Serializer):
|
||||
pass
|
||||
|
||||
class BaseFactSerializer(DocumentSerializer):
|
||||
|
||||
@@ -794,7 +796,11 @@ class OrganizationSerializer(BaseSerializer):
|
||||
users = reverse('api:organization_users_list', args=(obj.pk,)),
|
||||
admins = reverse('api:organization_admins_list', args=(obj.pk,)),
|
||||
teams = reverse('api:organization_teams_list', args=(obj.pk,)),
|
||||
activity_stream = reverse('api:organization_activity_stream_list', args=(obj.pk,))
|
||||
activity_stream = reverse('api:organization_activity_stream_list', args=(obj.pk,)),
|
||||
notifiers = reverse('api:organization_notifiers_list', args=(obj.pk,)),
|
||||
notifiers_any = reverse('api:organization_notifiers_any_list', args=(obj.pk,)),
|
||||
notifiers_success = reverse('api:organization_notifiers_success_list', args=(obj.pk,)),
|
||||
notifiers_error = reverse('api:organization_notifiers_error_list', args=(obj.pk,)),
|
||||
))
|
||||
return res
|
||||
|
||||
@@ -864,6 +870,9 @@ class ProjectSerializer(UnifiedJobTemplateSerializer, ProjectOptionsSerializer):
|
||||
project_updates = reverse('api:project_updates_list', args=(obj.pk,)),
|
||||
schedules = reverse('api:project_schedules_list', args=(obj.pk,)),
|
||||
activity_stream = reverse('api:project_activity_stream_list', args=(obj.pk,)),
|
||||
notifiers_any = reverse('api:project_notifiers_any_list', args=(obj.pk,)),
|
||||
notifiers_success = reverse('api:project_notifiers_success_list', args=(obj.pk,)),
|
||||
notifiers_error = reverse('api:project_notifiers_error_list', args=(obj.pk,)),
|
||||
))
|
||||
# Backwards compatibility.
|
||||
if obj.current_update:
|
||||
@@ -909,6 +918,7 @@ class ProjectUpdateSerializer(UnifiedJobSerializer, ProjectOptionsSerializer):
|
||||
res.update(dict(
|
||||
project = reverse('api:project_detail', args=(obj.project.pk,)),
|
||||
cancel = reverse('api:project_update_cancel', args=(obj.pk,)),
|
||||
notifications = reverse('api:project_update_notifications_list', args=(obj.pk,)),
|
||||
))
|
||||
return res
|
||||
|
||||
@@ -1316,6 +1326,9 @@ class InventorySourceSerializer(UnifiedJobTemplateSerializer, InventorySourceOpt
|
||||
activity_stream = reverse('api:inventory_activity_stream_list', args=(obj.pk,)),
|
||||
hosts = reverse('api:inventory_source_hosts_list', args=(obj.pk,)),
|
||||
groups = reverse('api:inventory_source_groups_list', args=(obj.pk,)),
|
||||
notifiers_any = reverse('api:inventory_source_notifiers_any_list', args=(obj.pk,)),
|
||||
notifiers_success = reverse('api:inventory_source_notifiers_success_list', args=(obj.pk,)),
|
||||
notifiers_error = reverse('api:inventory_source_notifiers_error_list', args=(obj.pk,)),
|
||||
))
|
||||
if obj.inventory and obj.inventory.active:
|
||||
res['inventory'] = reverse('api:inventory_detail', args=(obj.inventory.pk,))
|
||||
@@ -1360,6 +1373,7 @@ class InventoryUpdateSerializer(UnifiedJobSerializer, InventorySourceOptionsSeri
|
||||
res.update(dict(
|
||||
inventory_source = reverse('api:inventory_source_detail', args=(obj.inventory_source.pk,)),
|
||||
cancel = reverse('api:inventory_update_cancel', args=(obj.pk,)),
|
||||
notifications = reverse('api:inventory_update_notifications_list', args=(obj.pk,)),
|
||||
))
|
||||
return res
|
||||
|
||||
@@ -1575,6 +1589,9 @@ class JobTemplateSerializer(UnifiedJobTemplateSerializer, JobOptionsSerializer):
|
||||
schedules = reverse('api:job_template_schedules_list', args=(obj.pk,)),
|
||||
activity_stream = reverse('api:job_template_activity_stream_list', args=(obj.pk,)),
|
||||
launch = reverse('api:job_template_launch', args=(obj.pk,)),
|
||||
notifiers_any = reverse('api:job_template_notifiers_any_list', args=(obj.pk,)),
|
||||
notifiers_success = reverse('api:job_template_notifiers_success_list', args=(obj.pk,)),
|
||||
notifiers_error = reverse('api:job_template_notifiers_error_list', args=(obj.pk,)),
|
||||
))
|
||||
if obj.host_config_key:
|
||||
res['callback'] = reverse('api:job_template_callback', args=(obj.pk,))
|
||||
@@ -1629,6 +1646,7 @@ class JobSerializer(UnifiedJobSerializer, JobOptionsSerializer):
|
||||
job_tasks = reverse('api:job_job_tasks_list', args=(obj.pk,)),
|
||||
job_host_summaries = reverse('api:job_job_host_summaries_list', args=(obj.pk,)),
|
||||
activity_stream = reverse('api:job_activity_stream_list', args=(obj.pk,)),
|
||||
notifications = reverse('api:job_notifications_list', args=(obj.pk,)),
|
||||
))
|
||||
if obj.job_template and obj.job_template.active:
|
||||
res['job_template'] = reverse('api:job_template_detail',
|
||||
@@ -2044,6 +2062,79 @@ class JobLaunchSerializer(BaseSerializer):
|
||||
attrs = super(JobLaunchSerializer, self).validate(attrs)
|
||||
return attrs
|
||||
|
||||
class NotifierSerializer(BaseSerializer):
|
||||
|
||||
class Meta:
|
||||
model = Notifier
|
||||
fields = ('*', 'organization', 'notification_type', 'notification_configuration')
|
||||
|
||||
type_map = {"string": (str, unicode),
|
||||
"int": (int,),
|
||||
"bool": (bool,),
|
||||
"list": (list,),
|
||||
"password": (str, unicode),
|
||||
"object": (dict,)}
|
||||
|
||||
def to_representation(self, obj):
|
||||
ret = super(NotifierSerializer, self).to_representation(obj)
|
||||
for field in obj.notification_class.init_parameters:
|
||||
if field in ret['notification_configuration'] and \
|
||||
force_text(ret['notification_configuration'][field]).startswith('$encrypted$'):
|
||||
ret['notification_configuration'][field] = '$encrypted$'
|
||||
return ret
|
||||
|
||||
def get_related(self, obj):
|
||||
res = super(NotifierSerializer, self).get_related(obj)
|
||||
res.update(dict(
|
||||
test = reverse('api:notifier_test', args=(obj.pk,)),
|
||||
notifications = reverse('api:notifier_notification_list', args=(obj.pk,)),
|
||||
))
|
||||
if obj.organization and obj.organization.active:
|
||||
res['organization'] = reverse('api:organization_detail', args=(obj.organization.pk,))
|
||||
return res
|
||||
|
||||
def validate(self, attrs):
|
||||
notification_class = Notifier.CLASS_FOR_NOTIFICATION_TYPE[attrs['notification_type']]
|
||||
missing_fields = []
|
||||
incorrect_type_fields = []
|
||||
if 'notification_configuration' not in attrs:
|
||||
return attrs
|
||||
for field in notification_class.init_parameters:
|
||||
if field not in attrs['notification_configuration']:
|
||||
missing_fields.append(field)
|
||||
continue
|
||||
field_val = attrs['notification_configuration'][field]
|
||||
field_type = notification_class.init_parameters[field]['type']
|
||||
expected_types = self.type_map[field_type]
|
||||
if not type(field_val) in expected_types:
|
||||
incorrect_type_fields.append((field, field_type))
|
||||
continue
|
||||
if field_type == "password" and field_val.startswith('$encrypted$'):
|
||||
missing_fields.append(field)
|
||||
error_list = []
|
||||
if missing_fields:
|
||||
error_list.append("Missing required fields for Notification Configuration: {}".format(missing_fields))
|
||||
if incorrect_type_fields:
|
||||
for type_field_error in incorrect_type_fields:
|
||||
error_list.append("Configuration field '{}' incorrect type, expected {}".format(type_field_error[0],
|
||||
type_field_error[1]))
|
||||
if error_list:
|
||||
raise serializers.ValidationError(error_list)
|
||||
return attrs
|
||||
|
||||
class NotificationSerializer(BaseSerializer):
|
||||
|
||||
class Meta:
|
||||
model = Notification
|
||||
fields = ('*', '-name', '-description', 'notifier', 'error', 'status', 'notifications_sent',
|
||||
'notification_type', 'recipients', 'subject')
|
||||
|
||||
def get_related(self, obj):
|
||||
res = super(NotificationSerializer, self).get_related(obj)
|
||||
res.update(dict(
|
||||
notifier = reverse('api:notifier_detail', args=(obj.notifier.pk,)),
|
||||
))
|
||||
return res
|
||||
|
||||
class ScheduleSerializer(BaseSerializer):
|
||||
|
||||
|
||||
Reference in New Issue
Block a user