Refactor Notification's naming

Notifier -> NotificationTemplate
notifier -> notification_template
This commit is contained in:
Matthew Jones
2016-05-05 13:53:46 -04:00
parent 675b596fb0
commit 5895b3a343
22 changed files with 324 additions and 303 deletions

View File

@@ -16,7 +16,7 @@ from rest_framework.relations import RelatedField
from rest_framework.request import clone_request from rest_framework.request import clone_request
# Ansible Tower # Ansible Tower
from awx.main.models import InventorySource, Notifier from awx.main.models import InventorySource, NotificationTemplate
class Metadata(metadata.SimpleMetadata): class Metadata(metadata.SimpleMetadata):
@@ -91,7 +91,7 @@ class Metadata(metadata.SimpleMetadata):
# Special handling of notification configuration where the required properties # Special handling of notification configuration where the required properties
# are conditional on the type selected. # are conditional on the type selected.
if field.field_name == 'notification_configuration': if field.field_name == 'notification_configuration':
for (notification_type_name, notification_tr_name, notification_type_class) in Notifier.NOTIFICATION_TYPES: for (notification_type_name, notification_tr_name, notification_type_class) in NotificationTemplate.NOTIFICATION_TYPES:
field_info[notification_type_name] = notification_type_class.init_parameters field_info[notification_type_name] = notification_type_class.init_parameters
# Update type of fields returned... # Update type of fields returned...

View File

@@ -800,10 +800,10 @@ class OrganizationSerializer(BaseSerializer):
teams = reverse('api:organization_teams_list', args=(obj.pk,)), teams = reverse('api:organization_teams_list', args=(obj.pk,)),
credentials = reverse('api:organization_credential_list', args=(obj.pk,)), credentials = reverse('api:organization_credential_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,)), notification_templates = reverse('api:organization_notification_templates_list', args=(obj.pk,)),
notifiers_any = reverse('api:organization_notifiers_any_list', args=(obj.pk,)), notification_templates_any = reverse('api:organization_notification_templates_any_list', args=(obj.pk,)),
notifiers_success = reverse('api:organization_notifiers_success_list', args=(obj.pk,)), notification_templates_success = reverse('api:organization_notification_templates_success_list', args=(obj.pk,)),
notifiers_error = reverse('api:organization_notifiers_error_list', args=(obj.pk,)), notification_templates_error = reverse('api:organization_notification_templates_error_list', args=(obj.pk,)),
access_list = reverse('api:organization_access_list', args=(obj.pk,)), access_list = reverse('api:organization_access_list', args=(obj.pk,)),
)) ))
return res return res
@@ -885,9 +885,9 @@ class ProjectSerializer(UnifiedJobTemplateSerializer, ProjectOptionsSerializer):
project_updates = reverse('api:project_updates_list', args=(obj.pk,)), project_updates = reverse('api:project_updates_list', args=(obj.pk,)),
schedules = reverse('api:project_schedules_list', args=(obj.pk,)), schedules = reverse('api:project_schedules_list', args=(obj.pk,)),
activity_stream = reverse('api:project_activity_stream_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,)), notification_templates_any = reverse('api:project_notification_templates_any_list', args=(obj.pk,)),
notifiers_success = reverse('api:project_notifiers_success_list', args=(obj.pk,)), notification_templates_success = reverse('api:project_notification_templates_success_list', args=(obj.pk,)),
notifiers_error = reverse('api:project_notifiers_error_list', args=(obj.pk,)), notification_templates_error = reverse('api:project_notification_templates_error_list', args=(obj.pk,)),
access_list = reverse('api:project_access_list', args=(obj.pk,)), access_list = reverse('api:project_access_list', args=(obj.pk,)),
)) ))
if obj.organization: if obj.organization:
@@ -1347,9 +1347,9 @@ class InventorySourceSerializer(UnifiedJobTemplateSerializer, InventorySourceOpt
activity_stream = reverse('api:inventory_activity_stream_list', args=(obj.pk,)), activity_stream = reverse('api:inventory_activity_stream_list', args=(obj.pk,)),
hosts = reverse('api:inventory_source_hosts_list', args=(obj.pk,)), hosts = reverse('api:inventory_source_hosts_list', args=(obj.pk,)),
groups = reverse('api:inventory_source_groups_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,)), notification_templates_any = reverse('api:inventory_source_notification_templates_any_list', args=(obj.pk,)),
notifiers_success = reverse('api:inventory_source_notifiers_success_list', args=(obj.pk,)), notification_templates_success = reverse('api:inventory_source_notification_templates_success_list', args=(obj.pk,)),
notifiers_error = reverse('api:inventory_source_notifiers_error_list', args=(obj.pk,)), notification_templates_error = reverse('api:inventory_source_notification_templates_error_list', args=(obj.pk,)),
)) ))
if obj.inventory: if obj.inventory:
res['inventory'] = reverse('api:inventory_detail', args=(obj.inventory.pk,)) res['inventory'] = reverse('api:inventory_detail', args=(obj.inventory.pk,))
@@ -1730,9 +1730,9 @@ class JobTemplateSerializer(UnifiedJobTemplateSerializer, JobOptionsSerializer):
schedules = reverse('api:job_template_schedules_list', args=(obj.pk,)), schedules = reverse('api:job_template_schedules_list', args=(obj.pk,)),
activity_stream = reverse('api:job_template_activity_stream_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,)), launch = reverse('api:job_template_launch', args=(obj.pk,)),
notifiers_any = reverse('api:job_template_notifiers_any_list', args=(obj.pk,)), notification_templates_any = reverse('api:job_template_notification_templates_any_list', args=(obj.pk,)),
notifiers_success = reverse('api:job_template_notifiers_success_list', args=(obj.pk,)), notification_templates_success = reverse('api:job_template_notification_templates_success_list', args=(obj.pk,)),
notifiers_error = reverse('api:job_template_notifiers_error_list', args=(obj.pk,)), notification_templates_error = reverse('api:job_template_notification_templates_error_list', args=(obj.pk,)),
access_list = reverse('api:job_template_access_list', args=(obj.pk,)), access_list = reverse('api:job_template_access_list', args=(obj.pk,)),
survey_spec = reverse('api:job_template_survey_spec', args=(obj.pk,)), survey_spec = reverse('api:job_template_survey_spec', args=(obj.pk,)),
labels = reverse('api:job_template_label_list', args=(obj.pk,)), labels = reverse('api:job_template_label_list', args=(obj.pk,)),
@@ -2028,9 +2028,9 @@ class SystemJobTemplateSerializer(UnifiedJobTemplateSerializer):
jobs = reverse('api:system_job_template_jobs_list', args=(obj.pk,)), jobs = reverse('api:system_job_template_jobs_list', args=(obj.pk,)),
schedules = reverse('api:system_job_template_schedules_list', args=(obj.pk,)), schedules = reverse('api:system_job_template_schedules_list', args=(obj.pk,)),
launch = reverse('api:system_job_template_launch', args=(obj.pk,)), launch = reverse('api:system_job_template_launch', args=(obj.pk,)),
notifiers_any = reverse('api:system_job_template_notifiers_any_list', args=(obj.pk,)), notification_templates_any = reverse('api:system_job_template_notification_templates_any_list', args=(obj.pk,)),
notifiers_success = reverse('api:system_job_template_notifiers_success_list', args=(obj.pk,)), notification_templates_success = reverse('api:system_job_template_notification_templates_success_list', args=(obj.pk,)),
notifiers_error = reverse('api:system_job_template_notifiers_error_list', args=(obj.pk,)), notification_templates_error = reverse('api:system_job_template_notification_templates_error_list', args=(obj.pk,)),
)) ))
return res return res
@@ -2286,10 +2286,10 @@ class JobLaunchSerializer(BaseSerializer):
obj.credential = JT_credential obj.credential = JT_credential
return attrs return attrs
class NotifierSerializer(BaseSerializer): class NotificationTemplateSerializer(BaseSerializer):
class Meta: class Meta:
model = Notifier model = NotificationTemplate
fields = ('*', 'organization', 'notification_type', 'notification_configuration') fields = ('*', 'organization', 'notification_type', 'notification_configuration')
type_map = {"string": (str, unicode), type_map = {"string": (str, unicode),
@@ -2300,7 +2300,7 @@ class NotifierSerializer(BaseSerializer):
"object": (dict, OrderedDict)} "object": (dict, OrderedDict)}
def to_representation(self, obj): def to_representation(self, obj):
ret = super(NotifierSerializer, self).to_representation(obj) ret = super(NotificationTemplateSerializer, self).to_representation(obj)
for field in obj.notification_class.init_parameters: for field in obj.notification_class.init_parameters:
if field in ret['notification_configuration'] and \ if field in ret['notification_configuration'] and \
force_text(ret['notification_configuration'][field]).startswith('$encrypted$'): force_text(ret['notification_configuration'][field]).startswith('$encrypted$'):
@@ -2308,10 +2308,10 @@ class NotifierSerializer(BaseSerializer):
return ret return ret
def get_related(self, obj): def get_related(self, obj):
res = super(NotifierSerializer, self).get_related(obj) res = super(NotificationTemplateSerializer, self).get_related(obj)
res.update(dict( res.update(dict(
test = reverse('api:notifier_test', args=(obj.pk,)), test = reverse('api:notification_template_test', args=(obj.pk,)),
notifications = reverse('api:notifier_notification_list', args=(obj.pk,)), notifications = reverse('api:notification_template_notification_list', args=(obj.pk,)),
)) ))
if obj.organization: if obj.organization:
res['organization'] = reverse('api:organization_detail', args=(obj.organization.pk,)) res['organization'] = reverse('api:organization_detail', args=(obj.organization.pk,))
@@ -2321,12 +2321,12 @@ class NotifierSerializer(BaseSerializer):
return [{'id': x.id, 'status': x.status, 'created': x.created} for x in obj.notifications.all().order_by('-created')[:5]] return [{'id': x.id, 'status': x.status, 'created': x.created} for x in obj.notifications.all().order_by('-created')[:5]]
def get_summary_fields(self, obj): def get_summary_fields(self, obj):
d = super(NotifierSerializer, self).get_summary_fields(obj) d = super(NotificationTemplateSerializer, self).get_summary_fields(obj)
d['recent_notifications'] = self._recent_notifications(obj) d['recent_notifications'] = self._recent_notifications(obj)
return d return d
def validate(self, attrs): def validate(self, attrs):
notification_class = Notifier.CLASS_FOR_NOTIFICATION_TYPE[attrs['notification_type']] notification_class = NotificationTemplate.CLASS_FOR_NOTIFICATION_TYPE[attrs['notification_type']]
missing_fields = [] missing_fields = []
incorrect_type_fields = [] incorrect_type_fields = []
if 'notification_configuration' not in attrs: if 'notification_configuration' not in attrs:
@@ -2362,13 +2362,13 @@ class NotificationSerializer(BaseSerializer):
class Meta: class Meta:
model = Notification model = Notification
fields = ('*', '-name', '-description', 'notifier', 'error', 'status', 'notifications_sent', fields = ('*', '-name', '-description', 'notification_template', 'error', 'status', 'notifications_sent',
'notification_type', 'recipients', 'subject') 'notification_type', 'recipients', 'subject')
def get_related(self, obj): def get_related(self, obj):
res = super(NotificationSerializer, self).get_related(obj) res = super(NotificationSerializer, self).get_related(obj)
res.update(dict( res.update(dict(
notifier = reverse('api:notifier_detail', args=(obj.notifier.pk,)), notification_template = reverse('api:notification_template_detail', args=(obj.notification_template.pk,)),
)) ))
return res return res

View File

@@ -21,10 +21,10 @@ organization_urls = patterns('awx.api.views',
url(r'^(?P<pk>[0-9]+)/teams/$', 'organization_teams_list'), url(r'^(?P<pk>[0-9]+)/teams/$', 'organization_teams_list'),
url(r'^(?P<pk>[0-9]+)/credentials/$', 'organization_credential_list'), url(r'^(?P<pk>[0-9]+)/credentials/$', 'organization_credential_list'),
url(r'^(?P<pk>[0-9]+)/activity_stream/$', 'organization_activity_stream_list'), url(r'^(?P<pk>[0-9]+)/activity_stream/$', 'organization_activity_stream_list'),
url(r'^(?P<pk>[0-9]+)/notifiers/$', 'organization_notifiers_list'), url(r'^(?P<pk>[0-9]+)/notification_templates/$', 'organization_notification_templates_list'),
url(r'^(?P<pk>[0-9]+)/notifiers_any/$', 'organization_notifiers_any_list'), url(r'^(?P<pk>[0-9]+)/notification_templates_any/$', 'organization_notification_templates_any_list'),
url(r'^(?P<pk>[0-9]+)/notifiers_error/$', 'organization_notifiers_error_list'), url(r'^(?P<pk>[0-9]+)/notification_templates_error/$', 'organization_notification_templates_error_list'),
url(r'^(?P<pk>[0-9]+)/notifiers_success/$', 'organization_notifiers_success_list'), url(r'^(?P<pk>[0-9]+)/notification_templates_success/$', 'organization_notification_templates_success_list'),
url(r'^(?P<pk>[0-9]+)/access_list/$', 'organization_access_list'), url(r'^(?P<pk>[0-9]+)/access_list/$', 'organization_access_list'),
) )
@@ -50,9 +50,9 @@ project_urls = patterns('awx.api.views',
url(r'^(?P<pk>[0-9]+)/project_updates/$', 'project_updates_list'), url(r'^(?P<pk>[0-9]+)/project_updates/$', 'project_updates_list'),
url(r'^(?P<pk>[0-9]+)/activity_stream/$', 'project_activity_stream_list'), url(r'^(?P<pk>[0-9]+)/activity_stream/$', 'project_activity_stream_list'),
url(r'^(?P<pk>[0-9]+)/schedules/$', 'project_schedules_list'), url(r'^(?P<pk>[0-9]+)/schedules/$', 'project_schedules_list'),
url(r'^(?P<pk>[0-9]+)/notifiers_any/$', 'project_notifiers_any_list'), url(r'^(?P<pk>[0-9]+)/notification_templates_any/$', 'project_notification_templates_any_list'),
url(r'^(?P<pk>[0-9]+)/notifiers_error/$', 'project_notifiers_error_list'), url(r'^(?P<pk>[0-9]+)/notification_templates_error/$', 'project_notification_templates_error_list'),
url(r'^(?P<pk>[0-9]+)/notifiers_success/$', 'project_notifiers_success_list'), url(r'^(?P<pk>[0-9]+)/notification_templates_success/$', 'project_notification_templates_success_list'),
url(r'^(?P<pk>[0-9]+)/access_list/$', 'project_access_list'), url(r'^(?P<pk>[0-9]+)/access_list/$', 'project_access_list'),
) )
@@ -135,9 +135,9 @@ inventory_source_urls = patterns('awx.api.views',
url(r'^(?P<pk>[0-9]+)/schedules/$', 'inventory_source_schedules_list'), url(r'^(?P<pk>[0-9]+)/schedules/$', 'inventory_source_schedules_list'),
url(r'^(?P<pk>[0-9]+)/groups/$', 'inventory_source_groups_list'), url(r'^(?P<pk>[0-9]+)/groups/$', 'inventory_source_groups_list'),
url(r'^(?P<pk>[0-9]+)/hosts/$', 'inventory_source_hosts_list'), url(r'^(?P<pk>[0-9]+)/hosts/$', 'inventory_source_hosts_list'),
url(r'^(?P<pk>[0-9]+)/notifiers_any/$', 'inventory_source_notifiers_any_list'), url(r'^(?P<pk>[0-9]+)/notification_templates_any/$', 'inventory_source_notification_templates_any_list'),
url(r'^(?P<pk>[0-9]+)/notifiers_error/$', 'inventory_source_notifiers_error_list'), url(r'^(?P<pk>[0-9]+)/notification_templates_error/$', 'inventory_source_notification_templates_error_list'),
url(r'^(?P<pk>[0-9]+)/notifiers_success/$', 'inventory_source_notifiers_success_list'), url(r'^(?P<pk>[0-9]+)/notification_templates_success/$', 'inventory_source_notification_templates_success_list'),
) )
inventory_update_urls = patterns('awx.api.views', inventory_update_urls = patterns('awx.api.views',
@@ -178,9 +178,9 @@ job_template_urls = patterns('awx.api.views',
url(r'^(?P<pk>[0-9]+)/schedules/$', 'job_template_schedules_list'), url(r'^(?P<pk>[0-9]+)/schedules/$', 'job_template_schedules_list'),
url(r'^(?P<pk>[0-9]+)/survey_spec/$', 'job_template_survey_spec'), url(r'^(?P<pk>[0-9]+)/survey_spec/$', 'job_template_survey_spec'),
url(r'^(?P<pk>[0-9]+)/activity_stream/$', 'job_template_activity_stream_list'), url(r'^(?P<pk>[0-9]+)/activity_stream/$', 'job_template_activity_stream_list'),
url(r'^(?P<pk>[0-9]+)/notifiers_any/$', 'job_template_notifiers_any_list'), url(r'^(?P<pk>[0-9]+)/notification_templates_any/$', 'job_template_notification_templates_any_list'),
url(r'^(?P<pk>[0-9]+)/notifiers_error/$', 'job_template_notifiers_error_list'), url(r'^(?P<pk>[0-9]+)/notification_templates_error/$', 'job_template_notification_templates_error_list'),
url(r'^(?P<pk>[0-9]+)/notifiers_success/$', 'job_template_notifiers_success_list'), url(r'^(?P<pk>[0-9]+)/notification_templates_success/$', 'job_template_notification_templates_success_list'),
url(r'^(?P<pk>[0-9]+)/access_list/$', 'job_template_access_list'), url(r'^(?P<pk>[0-9]+)/access_list/$', 'job_template_access_list'),
url(r'^(?P<pk>[0-9]+)/labels/$', 'job_template_label_list'), url(r'^(?P<pk>[0-9]+)/labels/$', 'job_template_label_list'),
) )
@@ -233,9 +233,9 @@ system_job_template_urls = patterns('awx.api.views',
url(r'^(?P<pk>[0-9]+)/launch/$', 'system_job_template_launch'), url(r'^(?P<pk>[0-9]+)/launch/$', 'system_job_template_launch'),
url(r'^(?P<pk>[0-9]+)/jobs/$', 'system_job_template_jobs_list'), url(r'^(?P<pk>[0-9]+)/jobs/$', 'system_job_template_jobs_list'),
url(r'^(?P<pk>[0-9]+)/schedules/$', 'system_job_template_schedules_list'), url(r'^(?P<pk>[0-9]+)/schedules/$', 'system_job_template_schedules_list'),
url(r'^(?P<pk>[0-9]+)/notifiers_any/$', 'system_job_template_notifiers_any_list'), url(r'^(?P<pk>[0-9]+)/notification_templates_any/$', 'system_job_template_notification_templates_any_list'),
url(r'^(?P<pk>[0-9]+)/notifiers_error/$', 'system_job_template_notifiers_error_list'), url(r'^(?P<pk>[0-9]+)/notification_templates_error/$', 'system_job_template_notification_templates_error_list'),
url(r'^(?P<pk>[0-9]+)/notifiers_success/$', 'system_job_template_notifiers_success_list'), url(r'^(?P<pk>[0-9]+)/notification_templates_success/$', 'system_job_template_notification_templates_success_list'),
) )
system_job_urls = patterns('awx.api.views', system_job_urls = patterns('awx.api.views',
@@ -245,11 +245,11 @@ system_job_urls = patterns('awx.api.views',
url(r'^(?P<pk>[0-9]+)/notifications/$', 'system_job_notifications_list'), url(r'^(?P<pk>[0-9]+)/notifications/$', 'system_job_notifications_list'),
) )
notifier_urls = patterns('awx.api.views', notification_template_urls = patterns('awx.api.views',
url(r'^$', 'notifier_list'), url(r'^$', 'notification_template_list'),
url(r'^(?P<pk>[0-9]+)/$', 'notifier_detail'), url(r'^(?P<pk>[0-9]+)/$', 'notification_template_detail'),
url(r'^(?P<pk>[0-9]+)/test/$', 'notifier_test'), url(r'^(?P<pk>[0-9]+)/test/$', 'notification_template_test'),
url(r'^(?P<pk>[0-9]+)/notifications/$', 'notifier_notification_list'), url(r'^(?P<pk>[0-9]+)/notifications/$', 'notification_template_notification_list'),
) )
notification_urls = patterns('awx.api.views', notification_urls = patterns('awx.api.views',
@@ -310,7 +310,7 @@ v1_urls = patterns('awx.api.views',
url(r'^ad_hoc_command_events/', include(ad_hoc_command_event_urls)), url(r'^ad_hoc_command_events/', include(ad_hoc_command_event_urls)),
url(r'^system_job_templates/', include(system_job_template_urls)), url(r'^system_job_templates/', include(system_job_template_urls)),
url(r'^system_jobs/', include(system_job_urls)), url(r'^system_jobs/', include(system_job_urls)),
url(r'^notifiers/', include(notifier_urls)), url(r'^notification_templates/', include(notification_template_urls)),
url(r'^notifications/', include(notification_urls)), url(r'^notifications/', include(notification_urls)),
url(r'^labels/', include(label_urls)), url(r'^labels/', include(label_urls)),
url(r'^unified_job_templates/$','unified_job_template_list'), url(r'^unified_job_templates/$','unified_job_template_list'),

View File

@@ -140,7 +140,7 @@ class ApiV1RootView(APIView):
data['system_jobs'] = reverse('api:system_job_list') data['system_jobs'] = reverse('api:system_job_list')
data['schedules'] = reverse('api:schedule_list') data['schedules'] = reverse('api:schedule_list')
data['roles'] = reverse('api:role_list') data['roles'] = reverse('api:role_list')
data['notifiers'] = reverse('api:notifier_list') data['notification_templates'] = reverse('api:notification_template_list')
data['notifications'] = reverse('api:notification_list') data['notifications'] = reverse('api:notification_list')
data['labels'] = reverse('api:label_list') data['labels'] = reverse('api:label_list')
data['unified_job_templates'] = reverse('api:unified_job_template_list') data['unified_job_templates'] = reverse('api:unified_job_template_list')
@@ -764,34 +764,34 @@ class OrganizationActivityStreamList(SubListAPIView):
# Okay, let it through. # Okay, let it through.
return super(OrganizationActivityStreamList, self).get(request, *args, **kwargs) return super(OrganizationActivityStreamList, self).get(request, *args, **kwargs)
class OrganizationNotifiersList(SubListCreateAttachDetachAPIView): class OrganizationNotificationTemplatesList(SubListCreateAttachDetachAPIView):
model = Notifier model = NotificationTemplate
serializer_class = NotifierSerializer serializer_class = NotificationTemplateSerializer
parent_model = Organization parent_model = Organization
relationship = 'notifiers' relationship = 'notification_templates'
parent_key = 'organization' parent_key = 'organization'
class OrganizationNotifiersAnyList(SubListCreateAttachDetachAPIView): class OrganizationNotificationTemplatesAnyList(SubListCreateAttachDetachAPIView):
model = Notifier model = NotificationTemplate
serializer_class = NotifierSerializer serializer_class = NotificationTemplateSerializer
parent_model = Organization parent_model = Organization
relationship = 'notifiers_any' relationship = 'notification_templates_any'
class OrganizationNotifiersErrorList(SubListCreateAttachDetachAPIView): class OrganizationNotificationTemplatesErrorList(SubListCreateAttachDetachAPIView):
model = Notifier model = NotificationTemplate
serializer_class = NotifierSerializer serializer_class = NotificationTemplateSerializer
parent_model = Organization parent_model = Organization
relationship = 'notifiers_error' relationship = 'notification_templates_error'
class OrganizationNotifiersSuccessList(SubListCreateAttachDetachAPIView): class OrganizationNotificationTemplatesSuccessList(SubListCreateAttachDetachAPIView):
model = Notifier model = NotificationTemplate
serializer_class = NotifierSerializer serializer_class = NotificationTemplateSerializer
parent_model = Organization parent_model = Organization
relationship = 'notifiers_success' relationship = 'notification_templates_success'
class OrganizationAccessList(ResourceAccessList): class OrganizationAccessList(ResourceAccessList):
@@ -981,26 +981,26 @@ class ProjectActivityStreamList(SubListAPIView):
return qs.filter(project=parent) return qs.filter(project=parent)
return qs.filter(Q(project=parent) | Q(credential__in=parent.credential)) return qs.filter(Q(project=parent) | Q(credential__in=parent.credential))
class ProjectNotifiersAnyList(SubListCreateAttachDetachAPIView): class ProjectNotificationTemplatesAnyList(SubListCreateAttachDetachAPIView):
model = Notifier model = NotificationTemplate
serializer_class = NotifierSerializer serializer_class = NotificationTemplateSerializer
parent_model = Project parent_model = Project
relationship = 'notifiers_any' relationship = 'notification_templates_any'
class ProjectNotifiersErrorList(SubListCreateAttachDetachAPIView): class ProjectNotificationTemplatesErrorList(SubListCreateAttachDetachAPIView):
model = Notifier model = NotificationTemplate
serializer_class = NotifierSerializer serializer_class = NotificationTemplateSerializer
parent_model = Project parent_model = Project
relationship = 'notifiers_error' relationship = 'notification_templates_error'
class ProjectNotifiersSuccessList(SubListCreateAttachDetachAPIView): class ProjectNotificationTemplatesSuccessList(SubListCreateAttachDetachAPIView):
model = Notifier model = NotificationTemplate
serializer_class = NotifierSerializer serializer_class = NotificationTemplateSerializer
parent_model = Project parent_model = Project
relationship = 'notifiers_success' relationship = 'notification_templates_success'
class ProjectUpdatesList(SubListAPIView): class ProjectUpdatesList(SubListAPIView):
@@ -1991,26 +1991,26 @@ class InventorySourceActivityStreamList(SubListAPIView):
# Okay, let it through. # Okay, let it through.
return super(InventorySourceActivityStreamList, self).get(request, *args, **kwargs) return super(InventorySourceActivityStreamList, self).get(request, *args, **kwargs)
class InventorySourceNotifiersAnyList(SubListCreateAttachDetachAPIView): class InventorySourceNotificationTemplatesAnyList(SubListCreateAttachDetachAPIView):
model = Notifier model = NotificationTemplate
serializer_class = NotifierSerializer serializer_class = NotificationTemplateSerializer
parent_model = InventorySource parent_model = InventorySource
relationship = 'notifiers_any' relationship = 'notification_templates_any'
class InventorySourceNotifiersErrorList(SubListCreateAttachDetachAPIView): class InventorySourceNotificationTemplatesErrorList(SubListCreateAttachDetachAPIView):
model = Notifier model = NotificationTemplate
serializer_class = NotifierSerializer serializer_class = NotificationTemplateSerializer
parent_model = InventorySource parent_model = InventorySource
relationship = 'notifiers_error' relationship = 'notification_templates_error'
class InventorySourceNotifiersSuccessList(SubListCreateAttachDetachAPIView): class InventorySourceNotificationTemplatesSuccessList(SubListCreateAttachDetachAPIView):
model = Notifier model = NotificationTemplate
serializer_class = NotifierSerializer serializer_class = NotificationTemplateSerializer
parent_model = InventorySource parent_model = InventorySource
relationship = 'notifiers_success' relationship = 'notification_templates_success'
class InventorySourceHostsList(SubListAPIView): class InventorySourceHostsList(SubListAPIView):
@@ -2270,26 +2270,26 @@ class JobTemplateActivityStreamList(SubListAPIView):
# Okay, let it through. # Okay, let it through.
return super(JobTemplateActivityStreamList, self).get(request, *args, **kwargs) return super(JobTemplateActivityStreamList, self).get(request, *args, **kwargs)
class JobTemplateNotifiersAnyList(SubListCreateAttachDetachAPIView): class JobTemplateNotificationTemplatesAnyList(SubListCreateAttachDetachAPIView):
model = Notifier model = NotificationTemplate
serializer_class = NotifierSerializer serializer_class = NotificationTemplateSerializer
parent_model = JobTemplate parent_model = JobTemplate
relationship = 'notifiers_any' relationship = 'notification_templates_any'
class JobTemplateNotifiersErrorList(SubListCreateAttachDetachAPIView): class JobTemplateNotificationTemplatesErrorList(SubListCreateAttachDetachAPIView):
model = Notifier model = NotificationTemplate
serializer_class = NotifierSerializer serializer_class = NotificationTemplateSerializer
parent_model = JobTemplate parent_model = JobTemplate
relationship = 'notifiers_error' relationship = 'notification_templates_error'
class JobTemplateNotifiersSuccessList(SubListCreateAttachDetachAPIView): class JobTemplateNotificationTemplatesSuccessList(SubListCreateAttachDetachAPIView):
model = Notifier model = NotificationTemplate
serializer_class = NotifierSerializer serializer_class = NotificationTemplateSerializer
parent_model = JobTemplate parent_model = JobTemplate
relationship = 'notifiers_success' relationship = 'notification_templates_success'
class JobTemplateLabelList(SubListCreateAttachDetachAPIView, DeleteLastUnattachLabelMixin): class JobTemplateLabelList(SubListCreateAttachDetachAPIView, DeleteLastUnattachLabelMixin):
@@ -2526,26 +2526,26 @@ class SystemJobTemplateJobsList(SubListAPIView):
relationship = 'jobs' relationship = 'jobs'
parent_key = 'system_job_template' parent_key = 'system_job_template'
class SystemJobTemplateNotifiersAnyList(SubListCreateAttachDetachAPIView): class SystemJobTemplateNotificationTemplatesAnyList(SubListCreateAttachDetachAPIView):
model = Notifier model = NotificationTemplate
serializer_class = NotifierSerializer serializer_class = NotificationTemplateSerializer
parent_model = SystemJobTemplate parent_model = SystemJobTemplate
relationship = 'notifiers_any' relationship = 'notification_templates_any'
class SystemJobTemplateNotifiersErrorList(SubListCreateAttachDetachAPIView): class SystemJobTemplateNotificationTemplatesErrorList(SubListCreateAttachDetachAPIView):
model = Notifier model = NotificationTemplate
serializer_class = NotifierSerializer serializer_class = NotificationTemplateSerializer
parent_model = SystemJobTemplate parent_model = SystemJobTemplate
relationship = 'notifiers_error' relationship = 'notification_templates_error'
class SystemJobTemplateNotifiersSuccessList(SubListCreateAttachDetachAPIView): class SystemJobTemplateNotificationTemplatesSuccessList(SubListCreateAttachDetachAPIView):
model = Notifier model = NotificationTemplate
serializer_class = NotifierSerializer serializer_class = NotificationTemplateSerializer
parent_model = SystemJobTemplate parent_model = SystemJobTemplate
relationship = 'notifiers_success' relationship = 'notification_templates_success'
class JobList(ListCreateAPIView): class JobList(ListCreateAPIView):
@@ -3335,22 +3335,22 @@ class AdHocCommandStdout(UnifiedJobStdout):
model = AdHocCommand model = AdHocCommand
new_in_220 = True new_in_220 = True
class NotifierList(ListCreateAPIView): class NotificationTemplateList(ListCreateAPIView):
model = Notifier model = NotificationTemplate
serializer_class = NotifierSerializer serializer_class = NotificationTemplateSerializer
new_in_300 = True new_in_300 = True
class NotifierDetail(RetrieveUpdateDestroyAPIView): class NotificationTemplateDetail(RetrieveUpdateDestroyAPIView):
model = Notifier model = NotificationTemplate
serializer_class = NotifierSerializer serializer_class = NotificationTemplateSerializer
new_in_300 = True new_in_300 = True
class NotifierTest(GenericAPIView): class NotificationTemplateTest(GenericAPIView):
view_name = 'Notifier Test' view_name = 'NotificationTemplate Test'
model = Notifier model = NotificationTemplate
serializer_class = EmptySerializer serializer_class = EmptySerializer
new_in_300 = True new_in_300 = True
@@ -3367,13 +3367,13 @@ class NotifierTest(GenericAPIView):
headers=headers, headers=headers,
status=status.HTTP_202_ACCEPTED) status=status.HTTP_202_ACCEPTED)
class NotifierNotificationList(SubListAPIView): class NotificationTemplateNotificationList(SubListAPIView):
model = Notification model = Notification
serializer_class = NotificationSerializer serializer_class = NotificationSerializer
parent_model = Notifier parent_model = NotificationTemplate
relationship = 'notifications' relationship = 'notifications'
parent_key = 'notifier' parent_key = 'notification_template'
class NotificationList(ListAPIView): class NotificationList(ListAPIView):

View File

@@ -1204,11 +1204,11 @@ class ScheduleAccess(BaseAccess):
else: else:
return False return False
class NotifierAccess(BaseAccess): class NotificationTemplateAccess(BaseAccess):
''' '''
I can see/use a notifier if I have permission to I can see/use a notification_template if I have permission to
''' '''
model = Notifier model = NotificationTemplate
def get_queryset(self): def get_queryset(self):
qs = self.model.objects.all() qs = self.model.objects.all()
@@ -1257,13 +1257,13 @@ class NotificationAccess(BaseAccess):
qs = self.model.objects.all() qs = self.model.objects.all()
if self.user.is_superuser: if self.user.is_superuser:
return qs return qs
return self.model.objects.filter(notifier__organization__in=Organization.accessible_objects(self.user, 'admin_role')) return self.model.objects.filter(notification_template__organization__in=Organization.accessible_objects(self.user, 'admin_role'))
def can_read(self, obj): def can_read(self, obj):
return self.user.can_access(Notifier, 'read', obj.notifier) return self.user.can_access(NotificationTemplate, 'read', obj.notification_template)
def can_delete(self, obj): def can_delete(self, obj):
return self.user.can_access(Notifier, 'delete', obj.notifier) return self.user.can_access(NotificationTemplate, 'delete', obj.notification_template)
class LabelAccess(BaseAccess): class LabelAccess(BaseAccess):
''' '''
@@ -1483,6 +1483,6 @@ register_access(ActivityStream, ActivityStreamAccess)
register_access(CustomInventoryScript, CustomInventoryScriptAccess) register_access(CustomInventoryScript, CustomInventoryScriptAccess)
register_access(TowerSettings, TowerSettingsAccess) register_access(TowerSettings, TowerSettingsAccess)
register_access(Role, RoleAccess) register_access(Role, RoleAccess)
register_access(Notifier, NotifierAccess) register_access(NotificationTemplate, NotificationTemplateAccess)
register_access(Notification, NotificationAccess) register_access(Notification, NotificationAccess)
register_access(Label, LabelAccess) register_access(Label, LabelAccess)

View File

@@ -36,7 +36,7 @@ class Migration(migrations.Migration):
}, },
), ),
migrations.CreateModel( migrations.CreateModel(
name='Notifier', name='NotificationTemplate',
fields=[ fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('created', models.DateTimeField(default=None, editable=False)), ('created', models.DateTimeField(default=None, editable=False)),
@@ -46,16 +46,16 @@ class Migration(migrations.Migration):
('name', models.CharField(unique=True, max_length=512)), ('name', models.CharField(unique=True, max_length=512)),
('notification_type', models.CharField(max_length=32, choices=[(b'email', 'Email'), (b'slack', 'Slack'), (b'twilio', 'Twilio'), (b'pagerduty', 'Pagerduty'), (b'hipchat', 'HipChat'), (b'webhook', 'Webhook'), (b'irc', 'IRC')])), ('notification_type', models.CharField(max_length=32, choices=[(b'email', 'Email'), (b'slack', 'Slack'), (b'twilio', 'Twilio'), (b'pagerduty', 'Pagerduty'), (b'hipchat', 'HipChat'), (b'webhook', 'Webhook'), (b'irc', 'IRC')])),
('notification_configuration', jsonfield.fields.JSONField(default=dict)), ('notification_configuration', jsonfield.fields.JSONField(default=dict)),
('created_by', models.ForeignKey(related_name="{u'class': 'notifier', u'app_label': 'main'}(class)s_created+", on_delete=django.db.models.deletion.SET_NULL, default=None, editable=False, to=settings.AUTH_USER_MODEL, null=True)), ('created_by', models.ForeignKey(related_name="{u'class': 'notification_template', u'app_label': 'main'}(class)s_created+", on_delete=django.db.models.deletion.SET_NULL, default=None, editable=False, to=settings.AUTH_USER_MODEL, null=True)),
('modified_by', models.ForeignKey(related_name="{u'class': 'notifier', u'app_label': 'main'}(class)s_modified+", on_delete=django.db.models.deletion.SET_NULL, default=None, editable=False, to=settings.AUTH_USER_MODEL, null=True)), ('modified_by', models.ForeignKey(related_name="{u'class': 'notification_template', u'app_label': 'main'}(class)s_modified+", on_delete=django.db.models.deletion.SET_NULL, default=None, editable=False, to=settings.AUTH_USER_MODEL, null=True)),
('organization', models.ForeignKey(related_name='notifiers', on_delete=django.db.models.deletion.SET_NULL, to='main.Organization', null=True)), ('organization', models.ForeignKey(related_name='notification_templates', on_delete=django.db.models.deletion.SET_NULL, to='main.Organization', null=True)),
('tags', taggit.managers.TaggableManager(to='taggit.Tag', through='taggit.TaggedItem', blank=True, help_text='A comma-separated list of tags.', verbose_name='Tags')), ('tags', taggit.managers.TaggableManager(to='taggit.Tag', through='taggit.TaggedItem', blank=True, help_text='A comma-separated list of tags.', verbose_name='Tags')),
], ],
), ),
migrations.AddField( migrations.AddField(
model_name='notification', model_name='notification',
name='notifier', name='notification_template',
field=models.ForeignKey(related_name='notifications', editable=False, to='main.Notifier'), field=models.ForeignKey(related_name='notifications', editable=False, to='main.NotificationTemplate'),
), ),
migrations.AddField( migrations.AddField(
model_name='activitystream', model_name='activitystream',
@@ -64,23 +64,23 @@ class Migration(migrations.Migration):
), ),
migrations.AddField( migrations.AddField(
model_name='activitystream', model_name='activitystream',
name='notifier', name='notification_template',
field=models.ManyToManyField(to='main.Notifier', blank=True), field=models.ManyToManyField(to='main.NotificationTemplate', blank=True),
), ),
migrations.AddField( migrations.AddField(
model_name='organization', model_name='organization',
name='notifiers_any', name='notification_templates_any',
field=models.ManyToManyField(related_name='organization_notifiers_for_any', to='main.Notifier', blank=True), field=models.ManyToManyField(related_name='organization_notification_templates_for_any', to='main.NotificationTemplate', blank=True),
), ),
migrations.AddField( migrations.AddField(
model_name='organization', model_name='organization',
name='notifiers_error', name='notification_templates_error',
field=models.ManyToManyField(related_name='organization_notifiers_for_errors', to='main.Notifier', blank=True), field=models.ManyToManyField(related_name='organization_notification_templates_for_errors', to='main.NotificationTemplate', blank=True),
), ),
migrations.AddField( migrations.AddField(
model_name='organization', model_name='organization',
name='notifiers_success', name='notification_templates_success',
field=models.ManyToManyField(related_name='organization_notifiers_for_success', to='main.Notifier', blank=True), field=models.ManyToManyField(related_name='organization_notification_templates_for_success', to='main.NotificationTemplate', blank=True),
), ),
migrations.AddField( migrations.AddField(
model_name='unifiedjob', model_name='unifiedjob',
@@ -89,17 +89,17 @@ class Migration(migrations.Migration):
), ),
migrations.AddField( migrations.AddField(
model_name='unifiedjobtemplate', model_name='unifiedjobtemplate',
name='notifiers_any', name='notification_templates_any',
field=models.ManyToManyField(related_name='unifiedjobtemplate_notifiers_for_any', to='main.Notifier', blank=True), field=models.ManyToManyField(related_name='unifiedjobtemplate_notification_templates_for_any', to='main.NotificationTemplate', blank=True),
), ),
migrations.AddField( migrations.AddField(
model_name='unifiedjobtemplate', model_name='unifiedjobtemplate',
name='notifiers_error', name='notification_templates_error',
field=models.ManyToManyField(related_name='unifiedjobtemplate_notifiers_for_errors', to='main.Notifier', blank=True), field=models.ManyToManyField(related_name='unifiedjobtemplate_notification_templates_for_errors', to='main.NotificationTemplate', blank=True),
), ),
migrations.AddField( migrations.AddField(
model_name='unifiedjobtemplate', model_name='unifiedjobtemplate',
name='notifiers_success', name='notification_templates_success',
field=models.ManyToManyField(related_name='unifiedjobtemplate_notifiers_for_success', to='main.Notifier', blank=True), field=models.ManyToManyField(related_name='unifiedjobtemplate_notification_templates_for_success', to='main.NotificationTemplate', blank=True),
), ),
] ]

View File

@@ -71,7 +71,7 @@ def cleanup_deleted(apps, schema_editor):
apps.get_model('main', 'Group'), apps.get_model('main', 'Group'),
apps.get_model('main', 'Host'), apps.get_model('main', 'Host'),
apps.get_model('main', 'Inventory'), apps.get_model('main', 'Inventory'),
apps.get_model('main', 'Notifier'), apps.get_model('main', 'NotificationTemplate'),
apps.get_model('main', 'Organization'), apps.get_model('main', 'Organization'),
apps.get_model('main', 'Permission'), apps.get_model('main', 'Permission'),
apps.get_model('main', 'Schedule'), apps.get_model('main', 'Schedule'),

View File

@@ -79,7 +79,7 @@ activity_stream_registrar.connect(AdHocCommand)
activity_stream_registrar.connect(Schedule) activity_stream_registrar.connect(Schedule)
activity_stream_registrar.connect(CustomInventoryScript) activity_stream_registrar.connect(CustomInventoryScript)
activity_stream_registrar.connect(TowerSettings) activity_stream_registrar.connect(TowerSettings)
activity_stream_registrar.connect(Notifier) activity_stream_registrar.connect(NotificationTemplate)
activity_stream_registrar.connect(Notification) activity_stream_registrar.connect(Notification)
activity_stream_registrar.connect(Label) activity_stream_registrar.connect(Label)
activity_stream_registrar.connect(User) activity_stream_registrar.connect(User)

View File

@@ -53,7 +53,7 @@ class ActivityStream(models.Model):
ad_hoc_command = models.ManyToManyField("AdHocCommand", blank=True) ad_hoc_command = models.ManyToManyField("AdHocCommand", blank=True)
schedule = models.ManyToManyField("Schedule", blank=True) schedule = models.ManyToManyField("Schedule", blank=True)
custom_inventory_script = models.ManyToManyField("CustomInventoryScript", blank=True) custom_inventory_script = models.ManyToManyField("CustomInventoryScript", blank=True)
notifier = models.ManyToManyField("Notifier", blank=True) notification_template = models.ManyToManyField("NotificationTemplate", blank=True)
notification = models.ManyToManyField("Notification", blank=True) notification = models.ManyToManyField("Notification", blank=True)
label = models.ManyToManyField("Label", blank=True) label = models.ManyToManyField("Label", blank=True)
role = models.ManyToManyField("Role", blank=True) role = models.ManyToManyField("Role", blank=True)

View File

@@ -319,20 +319,20 @@ class NotificationFieldsModel(BaseModel):
class Meta: class Meta:
abstract = True abstract = True
notifiers_error = models.ManyToManyField( notification_templates_error = models.ManyToManyField(
"Notifier", "NotificationTemplate",
blank=True, blank=True,
related_name='%(class)s_notifiers_for_errors' related_name='%(class)s_notification_templates_for_errors'
) )
notifiers_success = models.ManyToManyField( notification_templates_success = models.ManyToManyField(
"Notifier", "NotificationTemplate",
blank=True, blank=True,
related_name='%(class)s_notifiers_for_success' related_name='%(class)s_notification_templates_for_success'
) )
notifiers_any = models.ManyToManyField( notification_templates_any = models.ManyToManyField(
"Notifier", "NotificationTemplate",
blank=True, blank=True,
related_name='%(class)s_notifiers_for_any' related_name='%(class)s_notification_templates_for_any'
) )

View File

@@ -25,7 +25,7 @@ from awx.main.models.base import * # noqa
from awx.main.models.jobs import Job from awx.main.models.jobs import Job
from awx.main.models.unified_jobs import * # noqa from awx.main.models.unified_jobs import * # noqa
from awx.main.models.mixins import ResourceMixin from awx.main.models.mixins import ResourceMixin
from awx.main.models.notifications import Notifier from awx.main.models.notifications import NotificationTemplate
from awx.main.utils import _inventory_updates from awx.main.utils import _inventory_updates
from awx.main.conf import tower_settings from awx.main.conf import tower_settings
@@ -1183,12 +1183,17 @@ class InventorySource(UnifiedJobTemplate, InventorySourceOptions):
return False return False
@property @property
def notifiers(self): def notification_templates(self):
base_notifiers = Notifier.objects base_notification_templates = NotificationTemplate.objects
error_notifiers = list(base_notifiers.filter(organization_notifiers_for_errors=self.inventory.organization)) error_notification_templates = list(base_notification_templates
success_notifiers = list(base_notifiers.filter(organization_notifiers_for_success=self.inventory.organization)) .filter(organization_notification_templates_for_errors=self.inventory.organization))
any_notifiers = list(base_notifiers.filter(organization_notifiers_for_any=self.inventory.organization)) success_notification_templates = list(base_notification_templates
return dict(error=error_notifiers, success=success_notifiers, any=any_notifiers) .filter(organization_notification_templates_for_success=self.inventory.organization))
any_notification_templates = list(base_notification_templates
.filter(organization_notification_templates_for_any=self.inventory.organization))
return dict(error=error_notification_templates,
success=success_notification_templates,
any=any_notification_templates)
def clean_source(self): def clean_source(self):
source = self.source source = self.source

View File

@@ -23,7 +23,7 @@ from jsonfield import JSONField
from awx.main.constants import CLOUD_PROVIDERS from awx.main.constants import CLOUD_PROVIDERS
from awx.main.models.base import * # noqa from awx.main.models.base import * # noqa
from awx.main.models.unified_jobs import * # noqa from awx.main.models.unified_jobs import * # noqa
from awx.main.models.notifications import Notifier from awx.main.models.notifications import NotificationTemplate
from awx.main.utils import decrypt_field, ignore_inventory_computed_fields from awx.main.utils import decrypt_field, ignore_inventory_computed_fields
from awx.main.utils import emit_websocket_notification from awx.main.utils import emit_websocket_notification
from awx.main.redact import PlainTextCleaner from awx.main.redact import PlainTextCleaner
@@ -441,20 +441,20 @@ class JobTemplate(UnifiedJobTemplate, JobOptions, ResourceMixin):
return self.can_start_without_user_input() return self.can_start_without_user_input()
@property @property
def notifiers(self): def notification_templates(self):
# Return all notifiers defined on the Job Template, on the Project, and on the Organization for each trigger type # Return all notification_templates defined on the Job Template, on the Project, and on the Organization for each trigger type
# TODO: Currently there is no org fk on project so this will need to be added once that is # TODO: Currently there is no org fk on project so this will need to be added once that is
# available after the rbac pr # available after the rbac pr
base_notifiers = Notifier.objects base_notification_templates = NotificationTemplate.objects
error_notifiers = list(base_notifiers.filter(unifiedjobtemplate_notifiers_for_errors__in=[self, self.project])) error_notification_templates = list(base_notification_templates.filter(unifiedjobtemplate_notification_templates_for_errors__in=[self, self.project]))
success_notifiers = list(base_notifiers.filter(unifiedjobtemplate_notifiers_for_success__in=[self, self.project])) success_notification_templates = list(base_notification_templates.filter(unifiedjobtemplate_notification_templates_for_success__in=[self, self.project]))
any_notifiers = list(base_notifiers.filter(unifiedjobtemplate_notifiers_for_any__in=[self, self.project])) any_notification_templates = list(base_notification_templates.filter(unifiedjobtemplate_notification_templates_for_any__in=[self, self.project]))
# Get Organization Notifiers # Get Organization NotificationTemplates
if self.project is not None and self.project.organization is not None: if self.project is not None and self.project.organization is not None:
error_notifiers = set(error_notifiers + list(base_notifiers.filter(organization_notifiers_for_errors=self.project.organization))) error_notification_templates = set(error_notification_templates + list(base_notification_templates.filter(organization_notification_templates_for_errors=self.project.organization)))
success_notifiers = set(success_notifiers + list(base_notifiers.filter(organization_notifiers_for_success=self.project.organization))) success_notification_templates = set(success_notification_templates + list(base_notification_templates.filter(organization_notification_templates_for_success=self.project.organization)))
any_notifiers = set(any_notifiers + list(base_notifiers.filter(organization_notifiers_for_any=self.project.organization))) any_notification_templates = set(any_notification_templates + list(base_notification_templates.filter(organization_notification_templates_for_any=self.project.organization)))
return dict(error=list(error_notifiers), success=list(success_notifiers), any=list(any_notifiers)) return dict(error=list(error_notification_templates), success=list(success_notification_templates), any=list(any_notification_templates))
class Job(UnifiedJob, JobOptions): class Job(UnifiedJob, JobOptions):
''' '''
@@ -1204,13 +1204,18 @@ class SystemJobTemplate(UnifiedJobTemplate, SystemJobOptions):
return False return False
@property @property
def notifiers(self): def notification_templates(self):
# TODO: Go through RBAC instead of calling all(). Need to account for orphaned Notifiers # TODO: Go through RBAC instead of calling all(). Need to account for orphaned NotificationTemplates
base_notifiers = Notifier.objects.all() base_notification_templates = NotificationTemplate.objects.all()
error_notifiers = list(base_notifiers.filter(unifiedjobtemplate_notifiers_for_errors__in=[self])) error_notification_templates = list(base_notification_templates
success_notifiers = list(base_notifiers.filter(unifiedjobtemplate_notifiers_for_success__in=[self])) .filter(unifiedjobtemplate_notification_templates_for_errors__in=[self]))
any_notifiers = list(base_notifiers.filter(unifiedjobtemplate_notifiers_for_any__in=[self])) success_notification_templates = list(base_notification_templates
return dict(error=list(error_notifiers), success=list(success_notifiers), any=list(any_notifiers)) .filter(unifiedjobtemplate_notification_templates_for_success__in=[self]))
any_notification_templates = list(base_notification_templates
.filter(unifiedjobtemplate_notification_templates_for_any__in=[self]))
return dict(error=list(error_notification_templates),
success=list(success_notification_templates),
any=list(any_notification_templates))
class SystemJob(UnifiedJob, SystemJobOptions): class SystemJob(UnifiedJob, SystemJobOptions):

View File

@@ -24,9 +24,9 @@ from jsonfield import JSONField
logger = logging.getLogger('awx.main.models.notifications') logger = logging.getLogger('awx.main.models.notifications')
__all__ = ['Notifier', 'Notification'] __all__ = ['NotificationTemplate', 'Notification']
class Notifier(CommonModel): class NotificationTemplate(CommonModel):
NOTIFICATION_TYPES = [('email', _('Email'), CustomEmailBackend), NOTIFICATION_TYPES = [('email', _('Email'), CustomEmailBackend),
('slack', _('Slack'), SlackBackend), ('slack', _('Slack'), SlackBackend),
@@ -46,7 +46,7 @@ class Notifier(CommonModel):
blank=False, blank=False,
null=True, null=True,
on_delete=models.SET_NULL, on_delete=models.SET_NULL,
related_name='notifiers', related_name='notification_templates',
) )
notification_type = models.CharField( notification_type = models.CharField(
@@ -57,7 +57,7 @@ class Notifier(CommonModel):
notification_configuration = JSONField(blank=False) notification_configuration = JSONField(blank=False)
def get_absolute_url(self): def get_absolute_url(self):
return reverse('api:notifier_detail', args=(self.pk,)) return reverse('api:notification_template_detail', args=(self.pk,))
@property @property
def notification_class(self): def notification_class(self):
@@ -79,7 +79,7 @@ class Notifier(CommonModel):
self.notification_configuration[field] = encrypted self.notification_configuration[field] = encrypted
if 'notification_configuration' not in update_fields: if 'notification_configuration' not in update_fields:
update_fields.append('notification_configuration') update_fields.append('notification_configuration')
super(Notifier, self).save(*args, **kwargs) super(NotificationTemplate, self).save(*args, **kwargs)
if new_instance: if new_instance:
update_fields = [] update_fields = []
for field in filter(lambda x: self.notification_class.init_parameters[x]['type'] == "password", for field in filter(lambda x: self.notification_class.init_parameters[x]['type'] == "password",
@@ -95,7 +95,7 @@ class Notifier(CommonModel):
return self.notification_configuration[self.notification_class.recipient_parameter] return self.notification_configuration[self.notification_class.recipient_parameter]
def generate_notification(self, subject, message): def generate_notification(self, subject, message):
notification = Notification(notifier=self, notification = Notification(notification_template=self,
notification_type=self.notification_type, notification_type=self.notification_type,
recipients=smart_str(self.recipients), recipients=smart_str(self.recipients),
subject=subject, subject=subject,
@@ -119,7 +119,7 @@ class Notifier(CommonModel):
class Notification(CreatedModifiedModel): class Notification(CreatedModifiedModel):
''' '''
A notification event emitted when a Notifier is run A notification event emitted when a NotificationTemplate is run
''' '''
NOTIFICATION_STATE_CHOICES = [ NOTIFICATION_STATE_CHOICES = [
@@ -132,8 +132,8 @@ class Notification(CreatedModifiedModel):
app_label = 'main' app_label = 'main'
ordering = ('pk',) ordering = ('pk',)
notifier = models.ForeignKey( notification_template = models.ForeignKey(
'Notifier', 'NotificationTemplate',
related_name='notifications', related_name='notifications',
on_delete=models.CASCADE, on_delete=models.CASCADE,
editable=False editable=False
@@ -155,7 +155,7 @@ class Notification(CreatedModifiedModel):
) )
notification_type = models.CharField( notification_type = models.CharField(
max_length = 32, max_length = 32,
choices=Notifier.NOTIFICATION_TYPE_CHOICES, choices=NotificationTemplate.NOTIFICATION_TYPE_CHOICES,
) )
recipients = models.TextField( recipients = models.TextField(
blank=True, blank=True,

View File

@@ -20,7 +20,7 @@ from django.utils.timezone import now, make_aware, get_default_timezone
from awx.lib.compat import slugify from awx.lib.compat import slugify
from awx.main.models.base import * # noqa from awx.main.models.base import * # noqa
from awx.main.models.jobs import Job from awx.main.models.jobs import Job
from awx.main.models.notifications import Notifier from awx.main.models.notifications import NotificationTemplate
from awx.main.models.unified_jobs import * # noqa from awx.main.models.unified_jobs import * # noqa
from awx.main.models.mixins import ResourceMixin from awx.main.models.mixins import ResourceMixin
from awx.main.utils import update_scm_url from awx.main.utils import update_scm_url
@@ -346,17 +346,28 @@ class Project(UnifiedJobTemplate, ProjectOptions, ResourceMixin):
return False return False
@property @property
def notifiers(self): def notification_templates(self):
base_notifiers = Notifier.objects base_notification_templates = NotificationTemplate.objects
error_notifiers = list(base_notifiers.filter(unifiedjobtemplate_notifiers_for_errors=self)) error_notification_templates = list(base_notification_templates
success_notifiers = list(base_notifiers.filter(unifiedjobtemplate_notifiers_for_success=self)) .filter(unifiedjobtemplate_notification_templates_for_errors=self))
any_notifiers = list(base_notifiers.filter(unifiedjobtemplate_notifiers_for_any=self)) success_notification_templates = list(base_notification_templates
# Get Organization Notifiers .filter(unifiedjobtemplate_notification_templates_for_success=self))
any_notification_templates = list(base_notification_templates
.filter(unifiedjobtemplate_notification_templates_for_any=self))
# Get Organization NotificationTemplates
if self.organization is not None: if self.organization is not None:
error_notifiers = set(error_notifiers + list(base_notifiers.filter(organization_notifiers_for_errors=self.organization))) error_notification_templates = set(error_notification_templates +
success_notifiers = set(success_notifiers + list(base_notifiers.filter(organization_notifiers_for_success=self.organization))) list(base_notification_templates
any_notifiers = set(any_notifiers + list(base_notifiers.filter(organization_notifiers_for_any=self.organization))) .filter(organization_notification_templates_for_errors=self.organization)))
return dict(error=list(error_notifiers), success=list(success_notifiers), any=list(any_notifiers)) success_notification_templates = set(success_notification_templates +
list(base_notification_templates
.filter(organization_notification_templates_for_success=self.organization)))
any_notification_templates = set(any_notification_templates +
list(base_notification_templates
.filter(organization_notification_templates_for_any=self.organization)))
return dict(error=list(error_notification_templates),
success=list(success_notification_templates),
any=list(any_notification_templates))
def get_absolute_url(self): def get_absolute_url(self):
return reverse('api:project_detail', args=(self.pk,)) return reverse('api:project_detail', args=(self.pk,))

View File

@@ -293,12 +293,12 @@ class UnifiedJobTemplate(PolymorphicModel, CommonModelNameNotUnique, Notificatio
return kwargs # Override if needed in subclass. return kwargs # Override if needed in subclass.
@property @property
def notifiers(self): def notification_templates(self):
''' '''
Return notifiers relevant to this Unified Job Template Return notification_templates relevant to this Unified Job Template
''' '''
# NOTE: Derived classes should implement # NOTE: Derived classes should implement
return Notifier.objects.none() return NotificationTemplate.objects.none()
def create_unified_job(self, **kwargs): def create_unified_job(self, **kwargs):
''' '''

View File

@@ -307,7 +307,7 @@ model_serializer_mapping = {
Job: JobSerializer, Job: JobSerializer,
AdHocCommand: AdHocCommandSerializer, AdHocCommand: AdHocCommandSerializer,
TowerSettings: TowerSettingsSerializer, TowerSettings: TowerSettingsSerializer,
Notifier: NotifierSerializer, NotificationTemplate: NotificationTemplateSerializer,
Notification: NotificationSerializer, Notification: NotificationSerializer,
} }

View File

@@ -77,7 +77,7 @@ def send_notifications(notification_list, job_id=None):
for notification_id in notification_list: for notification_id in notification_list:
notification = Notification.objects.get(id=notification_id) notification = Notification.objects.get(id=notification_id)
try: try:
sent = notification.notifier.send(notification.subject, notification.body) sent = notification.notification_template.send(notification.subject, notification.body)
notification.status = "successful" notification.status = "successful"
notification.notifications_sent = sent notification.notifications_sent = sent
except Exception as e: except Exception as e:
@@ -181,27 +181,27 @@ def handle_work_success(self, result, task_actual):
if task_actual['type'] == 'project_update': if task_actual['type'] == 'project_update':
instance = ProjectUpdate.objects.get(id=task_actual['id']) instance = ProjectUpdate.objects.get(id=task_actual['id'])
instance_name = instance.name instance_name = instance.name
notifiers = instance.project.notifiers notification_templates = instance.project.notification_templates
friendly_name = "Project Update" friendly_name = "Project Update"
elif task_actual['type'] == 'inventory_update': elif task_actual['type'] == 'inventory_update':
instance = InventoryUpdate.objects.get(id=task_actual['id']) instance = InventoryUpdate.objects.get(id=task_actual['id'])
instance_name = instance.name instance_name = instance.name
notifiers = instance.inventory_source.notifiers notification_templates = instance.inventory_source.notification_templates
friendly_name = "Inventory Update" friendly_name = "Inventory Update"
elif task_actual['type'] == 'job': elif task_actual['type'] == 'job':
instance = Job.objects.get(id=task_actual['id']) instance = Job.objects.get(id=task_actual['id'])
instance_name = instance.job_template.name instance_name = instance.job_template.name
notifiers = instance.job_template.notifiers notification_templates = instance.job_template.notification_templates
friendly_name = "Job" friendly_name = "Job"
elif task_actual['type'] == 'ad_hoc_command': elif task_actual['type'] == 'ad_hoc_command':
instance = AdHocCommand.objects.get(id=task_actual['id']) instance = AdHocCommand.objects.get(id=task_actual['id'])
instance_name = instance.module_name instance_name = instance.module_name
notifiers = [] # TODO: Ad-hoc commands need to notify someone notification_templates = [] # TODO: Ad-hoc commands need to notify someone
friendly_name = "AdHoc Command" friendly_name = "AdHoc Command"
elif task_actual['type'] == 'system_job': elif task_actual['type'] == 'system_job':
instance = SystemJob.objects.get(id=task_actual['id']) instance = SystemJob.objects.get(id=task_actual['id'])
instance_name = instance.system_job_template.name instance_name = instance.system_job_template.name
notifiers = instance.system_job_template.notifiers notification_templates = instance.system_job_template.notification_templates
friendly_name = "System Job" friendly_name = "System Job"
else: else:
return return
@@ -212,7 +212,7 @@ def handle_work_success(self, result, task_actual):
notification_body['url']) notification_body['url'])
notification_body['friendly_name'] = friendly_name notification_body['friendly_name'] = friendly_name
send_notifications.delay([n.generate_notification(notification_subject, notification_body).id send_notifications.delay([n.generate_notification(notification_subject, notification_body).id
for n in set(notifiers.get('success', []) + notifiers.get('any', []))], for n in set(notification_templates.get('success', []) + notification_templates.get('any', []))],
job_id=task_actual['id']) job_id=task_actual['id'])
@task(bind=True) @task(bind=True)
@@ -229,27 +229,27 @@ def handle_work_error(self, task_id, subtasks=None):
if each_task['type'] == 'project_update': if each_task['type'] == 'project_update':
instance = ProjectUpdate.objects.get(id=each_task['id']) instance = ProjectUpdate.objects.get(id=each_task['id'])
instance_name = instance.name instance_name = instance.name
notifiers = instance.project.notifiers notification_templates = instance.project.notification_templates
friendly_name = "Project Update" friendly_name = "Project Update"
elif each_task['type'] == 'inventory_update': elif each_task['type'] == 'inventory_update':
instance = InventoryUpdate.objects.get(id=each_task['id']) instance = InventoryUpdate.objects.get(id=each_task['id'])
instance_name = instance.name instance_name = instance.name
notifiers = instance.inventory_source.notifiers notification_templates = instance.inventory_source.notification_templates
friendly_name = "Inventory Update" friendly_name = "Inventory Update"
elif each_task['type'] == 'job': elif each_task['type'] == 'job':
instance = Job.objects.get(id=each_task['id']) instance = Job.objects.get(id=each_task['id'])
instance_name = instance.job_template.name instance_name = instance.job_template.name
notifiers = instance.job_template.notifiers notification_templates = instance.job_template.notification_templates
friendly_name = "Job" friendly_name = "Job"
elif each_task['type'] == 'ad_hoc_command': elif each_task['type'] == 'ad_hoc_command':
instance = AdHocCommand.objects.get(id=each_task['id']) instance = AdHocCommand.objects.get(id=each_task['id'])
instance_name = instance.module_name instance_name = instance.module_name
notifiers = [] notification_templates = []
friendly_name = "AdHoc Command" friendly_name = "AdHoc Command"
elif each_task['type'] == 'system_job': elif each_task['type'] == 'system_job':
instance = SystemJob.objects.get(id=each_task['id']) instance = SystemJob.objects.get(id=each_task['id'])
instance_name = instance.system_job_template.name instance_name = instance.system_job_template.name
notifiers = instance.system_job_template.notifiers notification_templates = instance.system_job_template.notification_templates
friendly_name = "System Job" friendly_name = "System Job"
else: else:
# Unknown task type # Unknown task type
@@ -274,7 +274,7 @@ def handle_work_error(self, task_id, subtasks=None):
notification_body['url']) notification_body['url'])
notification_body['friendly_name'] = first_task_friendly_name notification_body['friendly_name'] = first_task_friendly_name
send_notifications.delay([n.generate_notification(notification_subject, notification_body).id send_notifications.delay([n.generate_notification(notification_subject, notification_body).id
for n in set(notifiers.get('error', []) + notifiers.get('any', []))], for n in set(notification_templates.get('error', []) + notification_templates.get('any', []))],
job_id=first_task_id) job_id=first_task_id)

View File

@@ -36,7 +36,7 @@ from awx.main.models.organization import (
Team, Team,
) )
from awx.main.models.notifications import Notifier from awx.main.models.notifications import NotificationTemplate
''' '''
Disable all django model signals. Disable all django model signals.
@@ -186,8 +186,8 @@ def label(organization):
return organization.labels.create(name="test-label", description="test-label-desc") return organization.labels.create(name="test-label", description="test-label-desc")
@pytest.fixture @pytest.fixture
def notifier(organization): def notification_template(organization):
return Notifier.objects.create(name='test-notifier', return NotificationTemplate.objects.create(name='test-notification_template',
organization=organization, organization=organization,
notification_type="webhook", notification_type="webhook",
notification_configuration=dict(url="http://localhost", notification_configuration=dict(url="http://localhost",
@@ -270,18 +270,18 @@ def permissions():
} }
@pytest.fixture @pytest.fixture
def notifier_factory(organization): def notification_template_factory(organization):
def n(name="test-notifier"): def n(name="test-notification_template"):
try: try:
notifier = Notifier.objects.get(name=name) notification_template = NotificationTemplate.objects.get(name=name)
except Notifier.DoesNotExist: except NotificationTemplate.DoesNotExist:
notifier = Notifier(name=name, notification_template = NotificationTemplate(name=name,
organization=organization, organization=organization,
notification_type="webhook", notification_type="webhook",
notification_configuration=dict(url="http://localhost", notification_configuration=dict(url="http://localhost",
headers={"Test": "Header"})) headers={"Test": "Header"}))
notifier.save() notification_template.save()
return notifier return notification_template
return n return n
@pytest.fixture @pytest.fixture

View File

@@ -1,15 +1,15 @@
import mock import mock
import pytest import pytest
from awx.main.models.notifications import Notifier from awx.main.models.notifications import NotificationTemplate
from awx.main.models.inventory import Inventory, Group from awx.main.models.inventory import Inventory, Group
from awx.main.models.jobs import JobTemplate from awx.main.models.jobs import JobTemplate
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
@pytest.mark.django_db @pytest.mark.django_db
def test_get_notifier_list(get, user, notifier): def test_get_notification_template_list(get, user, notification_template):
url = reverse('api:notifier_list') url = reverse('api:notification_template_list')
response = get(url, user('admin', True)) response = get(url, user('admin', True))
assert response.status_code == 200 assert response.status_code == 200
assert len(response.data['results']) == 1 assert len(response.data['results']) == 1
@@ -17,7 +17,7 @@ def test_get_notifier_list(get, user, notifier):
@pytest.mark.django_db @pytest.mark.django_db
def test_basic_parameterization(get, post, user, organization): def test_basic_parameterization(get, post, user, organization):
u = user('admin-poster', True) u = user('admin-poster', True)
url = reverse('api:notifier_list') url = reverse('api:notification_template_list')
response = post(url, response = post(url,
dict(name="test-webhook", dict(name="test-webhook",
description="test webhook", description="test webhook",
@@ -27,7 +27,7 @@ def test_basic_parameterization(get, post, user, organization):
headers={"Test": "Header"})), headers={"Test": "Header"})),
u) u)
assert response.status_code == 201 assert response.status_code == 201
url = reverse('api:notifier_detail', args=(response.data['id'],)) url = reverse('api:notification_template_detail', args=(response.data['id'],))
response = get(url, u) response = get(url, u)
assert 'related' in response.data assert 'related' in response.data
assert 'organization' in response.data['related'] assert 'organization' in response.data['related']
@@ -44,7 +44,7 @@ def test_encrypted_subfields(get, post, user, organization):
assert self.account_token == "shouldhide" assert self.account_token == "shouldhide"
return 1 return 1
u = user('admin-poster', True) u = user('admin-poster', True)
url = reverse('api:notifier_list') url = reverse('api:notification_template_list')
response = post(url, response = post(url,
dict(name="test-twilio", dict(name="test-twilio",
description="test twilio", description="test twilio",
@@ -56,18 +56,18 @@ def test_encrypted_subfields(get, post, user, organization):
to_numbers=["9998887777"])), to_numbers=["9998887777"])),
u) u)
assert response.status_code == 201 assert response.status_code == 201
notifier_actual = Notifier.objects.get(id=response.data['id']) notification_template_actual = NotificationTemplate.objects.get(id=response.data['id'])
url = reverse('api:notifier_detail', args=(response.data['id'],)) url = reverse('api:notification_template_detail', args=(response.data['id'],))
response = get(url, u) response = get(url, u)
assert response.data['notification_configuration']['account_token'] == "$encrypted$" assert response.data['notification_configuration']['account_token'] == "$encrypted$"
with mock.patch.object(notifier_actual.notification_class, "send_messages", assert_send): with mock.patch.object(notification_template_actual.notification_class, "send_messages", assert_send):
notifier_actual.send("Test", {'body': "Test"}) notification_template_actual.send("Test", {'body': "Test"})
@pytest.mark.django_db @pytest.mark.django_db
def test_inherited_notifiers(get, post, user, organization, project): def test_inherited_notification_templates(get, post, user, organization, project):
u = user('admin-poster', True) u = user('admin-poster', True)
url = reverse('api:notifier_list') url = reverse('api:notification_template_list')
notifiers = [] notification_templates = []
for nfiers in xrange(3): for nfiers in xrange(3):
response = post(url, response = post(url,
dict(name="test-webhook-{}".format(nfiers), dict(name="test-webhook-{}".format(nfiers),
@@ -78,29 +78,29 @@ def test_inherited_notifiers(get, post, user, organization, project):
headers={"Test": "Header"})), headers={"Test": "Header"})),
u) u)
assert response.status_code == 201 assert response.status_code == 201
notifiers.append(response.data['id']) notification_templates.append(response.data['id'])
i = Inventory.objects.create(name='test', organization=organization) i = Inventory.objects.create(name='test', organization=organization)
i.save() i.save()
g = Group.objects.create(name='test', inventory=i) g = Group.objects.create(name='test', inventory=i)
g.save() g.save()
jt = JobTemplate.objects.create(name='test', inventory=i, project=project, playbook='debug.yml') jt = JobTemplate.objects.create(name='test', inventory=i, project=project, playbook='debug.yml')
jt.save() jt.save()
url = reverse('api:organization_notifiers_any_list', args=(organization.id,)) url = reverse('api:organization_notification_templates_any_list', args=(organization.id,))
response = post(url, dict(id=notifiers[0]), u) response = post(url, dict(id=notification_templates[0]), u)
assert response.status_code == 204 assert response.status_code == 204
url = reverse('api:project_notifiers_any_list', args=(project.id,)) url = reverse('api:project_notification_templates_any_list', args=(project.id,))
response = post(url, dict(id=notifiers[1]), u) response = post(url, dict(id=notification_templates[1]), u)
assert response.status_code == 204 assert response.status_code == 204
url = reverse('api:job_template_notifiers_any_list', args=(jt.id,)) url = reverse('api:job_template_notification_templates_any_list', args=(jt.id,))
response = post(url, dict(id=notifiers[2]), u) response = post(url, dict(id=notification_templates[2]), u)
assert response.status_code == 204 assert response.status_code == 204
assert len(jt.notifiers['any']) == 3 assert len(jt.notification_templates['any']) == 3
assert len(project.notifiers['any']) == 2 assert len(project.notification_templates['any']) == 2
assert len(g.inventory_source.notifiers['any']) == 1 assert len(g.inventory_source.notification_templates['any']) == 1
@pytest.mark.django_db @pytest.mark.django_db
def test_notifier_merging(get, post, user, organization, project, notifier): def test_notification_template_merging(get, post, user, organization, project, notification_template):
user('admin-poster', True) user('admin-poster', True)
organization.notifiers_any.add(notifier) organization.notification_templates_any.add(notification_template)
project.notifiers_any.add(notifier) project.notification_templates_any.add(notification_template)
assert len(project.notifiers['any']) == 1 assert len(project.notification_templates['any']) == 1

View File

@@ -1,36 +1,36 @@
import pytest import pytest
from awx.main.access import NotifierAccess from awx.main.access import NotificationTemplateAccess
@pytest.mark.django_db @pytest.mark.django_db
def test_notifier_get_queryset_orgmember(notifier, user): def test_notification_template_get_queryset_orgmember(notification_template, user):
access = NotifierAccess(user('user', False)) access = NotificationTemplateAccess(user('user', False))
notifier.organization.member_role.members.add(user('user', False)) notification_template.organization.member_role.members.add(user('user', False))
assert access.get_queryset().count() == 0 assert access.get_queryset().count() == 0
@pytest.mark.django_db @pytest.mark.django_db
def test_notifier_get_queryset_nonorgmember(notifier, user): def test_notification_template_get_queryset_nonorgmember(notification_template, user):
access = NotifierAccess(user('user', False)) access = NotificationTemplateAccess(user('user', False))
assert access.get_queryset().count() == 0 assert access.get_queryset().count() == 0
@pytest.mark.django_db @pytest.mark.django_db
def test_notifier_get_queryset_su(notifier, user): def test_notification_template_get_queryset_su(notification_template, user):
access = NotifierAccess(user('user', True)) access = NotificationTemplateAccess(user('user', True))
assert access.get_queryset().count() == 1 assert access.get_queryset().count() == 1
@pytest.mark.django_db @pytest.mark.django_db
def test_notifier_get_queryset_orgadmin(notifier, user): def test_notification_template_get_queryset_orgadmin(notification_template, user):
access = NotifierAccess(user('admin', False)) access = NotificationTemplateAccess(user('admin', False))
notifier.organization.admin_role.members.add(user('admin', False)) notification_template.organization.admin_role.members.add(user('admin', False))
assert access.get_queryset().count() == 1 assert access.get_queryset().count() == 1
@pytest.mark.django_db @pytest.mark.django_db
def test_notifier_access_superuser(notifier, user, notifier_factory): def test_notification_template_access_superuser(notification_template, user, notification_template_factory):
access = NotifierAccess(user('admin', True)) access = NotificationTemplateAccess(user('admin', True))
assert access.can_read(notifier) assert access.can_read(notification_template)
assert access.can_change(notifier, None) assert access.can_change(notification_template, None)
assert access.can_delete(notifier) assert access.can_delete(notification_template)
nf = notifier_factory("test-orphaned") nf = notification_template_factory("test-orphaned")
nf.organization = None nf.organization = None
nf.save() nf.save()
assert access.can_read(nf) assert access.can_read(nf)
@@ -38,20 +38,20 @@ def test_notifier_access_superuser(notifier, user, notifier_factory):
assert access.can_delete(nf) assert access.can_delete(nf)
@pytest.mark.django_db @pytest.mark.django_db
def test_notifier_access_admin(notifier, user, organization_factory, notifier_factory): def test_notification_template_access_admin(notification_template, user, organization_factory, notification_template_factory):
adm = user('admin', False) adm = user('admin', False)
other_org = organization_factory('other') other_org = organization_factory('other')
present_org = organization_factory('present') present_org = organization_factory('present')
notifier.organization.admin_role.members.add(adm) notification_template.organization.admin_role.members.add(adm)
present_org.admin_role.members.add(adm) present_org.admin_role.members.add(adm)
access = NotifierAccess(user('admin', False)) access = NotificationTemplateAccess(user('admin', False))
assert not access.can_change(notifier, {'organization': other_org.id}) assert not access.can_change(notification_template, {'organization': other_org.id})
assert access.can_read(notifier) assert access.can_read(notification_template)
assert access.can_change(notifier, None) assert access.can_change(notification_template, None)
assert access.can_change(notifier, {'organization': present_org.id}) assert access.can_change(notification_template, {'organization': present_org.id})
assert access.can_delete(notifier) assert access.can_delete(notification_template)
nf = notifier_factory("test-orphaned") nf = notification_template_factory("test-orphaned")
nf.organization = None nf.organization = None
nf.save() nf.save()
assert not access.can_read(nf) assert not access.can_read(nf)
@@ -59,10 +59,10 @@ def test_notifier_access_admin(notifier, user, organization_factory, notifier_fa
assert not access.can_delete(nf) assert not access.can_delete(nf)
@pytest.mark.django_db @pytest.mark.django_db
def test_notifier_access_org_user(notifier, user): def test_notification_template_access_org_user(notification_template, user):
u = user('normal', False) u = user('normal', False)
notifier.organization.member_role.members.add(u) notification_template.organization.member_role.members.add(u)
access = NotifierAccess(user('normal', False)) access = NotificationTemplateAccess(user('normal', False))
assert not access.can_read(notifier) assert not access.can_read(notification_template)
assert not access.can_change(notifier, None) assert not access.can_change(notification_template, None)
assert not access.can_delete(notifier) assert not access.can_delete(notification_template)

View File

@@ -61,9 +61,9 @@ class TestJobTemplateSerializerGetRelated(GetRelatedMixin):
'schedules', 'schedules',
'activity_stream', 'activity_stream',
'launch', 'launch',
'notifiers_any', 'notification_templates_any',
'notifiers_success', 'notification_templates_success',
'notifiers_error', 'notification_templates_error',
'survey_spec', 'survey_spec',
'labels', 'labels',
'callback', 'callback',

View File

@@ -37,7 +37,7 @@ class TestApiV1RootView:
'system_job_templates', 'system_job_templates',
'system_jobs', 'system_jobs',
'schedules', 'schedules',
'notifiers', 'notification_templates',
'notifications', 'notifications',
'labels', 'labels',
'unified_job_templates', 'unified_job_templates',