253 lines
7.1 KiB
Python
253 lines
7.1 KiB
Python
# Copyright (c) 2018 Red Hat, Inc.
|
|
# All Rights Reserved.
|
|
|
|
# Python
|
|
import logging
|
|
|
|
# Django
|
|
from django.db.models import Count
|
|
from django.contrib.contenttypes.models import ContentType
|
|
from django.utils.translation import ugettext_lazy as _
|
|
|
|
# AWX
|
|
from awx.main.models import (
|
|
ActivityStream,
|
|
Inventory,
|
|
Host,
|
|
Project,
|
|
JobTemplate,
|
|
WorkflowJobTemplate,
|
|
Organization,
|
|
NotificationTemplate,
|
|
Role,
|
|
User,
|
|
Team,
|
|
InstanceGroup,
|
|
Credential
|
|
)
|
|
from awx.api.generics import (
|
|
ListCreateAPIView,
|
|
RetrieveUpdateDestroyAPIView,
|
|
SubListAPIView,
|
|
SubListCreateAttachDetachAPIView,
|
|
SubListAttachDetachAPIView,
|
|
SubListCreateAPIView,
|
|
ResourceAccessList,
|
|
BaseUsersList,
|
|
)
|
|
|
|
from awx.api.serializers import (
|
|
OrganizationSerializer,
|
|
InventorySerializer,
|
|
UserSerializer,
|
|
TeamSerializer,
|
|
ActivityStreamSerializer,
|
|
RoleSerializer,
|
|
NotificationTemplateSerializer,
|
|
InstanceGroupSerializer,
|
|
ProjectSerializer, JobTemplateSerializer, WorkflowJobTemplateSerializer,
|
|
CredentialSerializer
|
|
)
|
|
from awx.api.views.mixin import (
|
|
RelatedJobsPreventDeleteMixin,
|
|
OrganizationCountsMixin,
|
|
)
|
|
|
|
logger = logging.getLogger('awx.api.views.organization')
|
|
|
|
|
|
class OrganizationList(OrganizationCountsMixin, ListCreateAPIView):
|
|
|
|
model = Organization
|
|
serializer_class = OrganizationSerializer
|
|
|
|
def get_queryset(self):
|
|
qs = Organization.accessible_objects(self.request.user, 'read_role')
|
|
qs = qs.select_related('admin_role', 'auditor_role', 'member_role', 'read_role')
|
|
qs = qs.prefetch_related('created_by', 'modified_by')
|
|
return qs
|
|
|
|
|
|
class OrganizationDetail(RelatedJobsPreventDeleteMixin, RetrieveUpdateDestroyAPIView):
|
|
|
|
model = Organization
|
|
serializer_class = OrganizationSerializer
|
|
|
|
def get_serializer_context(self, *args, **kwargs):
|
|
full_context = super(OrganizationDetail, self).get_serializer_context(*args, **kwargs)
|
|
|
|
if not hasattr(self, 'kwargs') or 'pk' not in self.kwargs:
|
|
return full_context
|
|
org_id = int(self.kwargs['pk'])
|
|
|
|
org_counts = {}
|
|
access_kwargs = {'accessor': self.request.user, 'role_field': 'read_role'}
|
|
direct_counts = Organization.objects.filter(id=org_id).annotate(
|
|
users=Count('member_role__members', distinct=True),
|
|
admins=Count('admin_role__members', distinct=True)
|
|
).values('users', 'admins')
|
|
|
|
if not direct_counts:
|
|
return full_context
|
|
|
|
org_counts = direct_counts[0]
|
|
org_counts['inventories'] = Inventory.accessible_objects(**access_kwargs).filter(
|
|
organization__id=org_id).count()
|
|
org_counts['teams'] = Team.accessible_objects(**access_kwargs).filter(
|
|
organization__id=org_id).count()
|
|
org_counts['projects'] = Project.accessible_objects(**access_kwargs).filter(
|
|
organization__id=org_id).count()
|
|
org_counts['job_templates'] = JobTemplate.accessible_objects(**access_kwargs).filter(
|
|
organization__id=org_id).count()
|
|
org_counts['hosts'] = Host.objects.org_active_count(org_id)
|
|
|
|
full_context['related_field_counts'] = {}
|
|
full_context['related_field_counts'][org_id] = org_counts
|
|
|
|
return full_context
|
|
|
|
|
|
class OrganizationInventoriesList(SubListAPIView):
|
|
|
|
model = Inventory
|
|
serializer_class = InventorySerializer
|
|
parent_model = Organization
|
|
relationship = 'inventories'
|
|
|
|
|
|
class OrganizationUsersList(BaseUsersList):
|
|
|
|
model = User
|
|
serializer_class = UserSerializer
|
|
parent_model = Organization
|
|
relationship = 'member_role.members'
|
|
ordering = ('username',)
|
|
|
|
|
|
class OrganizationAdminsList(BaseUsersList):
|
|
|
|
model = User
|
|
serializer_class = UserSerializer
|
|
parent_model = Organization
|
|
relationship = 'admin_role.members'
|
|
ordering = ('username',)
|
|
|
|
|
|
class OrganizationProjectsList(SubListCreateAPIView):
|
|
|
|
model = Project
|
|
serializer_class = ProjectSerializer
|
|
parent_model = Organization
|
|
parent_key = 'organization'
|
|
|
|
|
|
class OrganizationJobTemplatesList(SubListCreateAPIView):
|
|
|
|
model = JobTemplate
|
|
serializer_class = JobTemplateSerializer
|
|
parent_model = Organization
|
|
parent_key = 'organization'
|
|
|
|
|
|
class OrganizationWorkflowJobTemplatesList(SubListCreateAPIView):
|
|
|
|
model = WorkflowJobTemplate
|
|
serializer_class = WorkflowJobTemplateSerializer
|
|
parent_model = Organization
|
|
parent_key = 'organization'
|
|
|
|
|
|
class OrganizationTeamsList(SubListCreateAttachDetachAPIView):
|
|
|
|
model = Team
|
|
serializer_class = TeamSerializer
|
|
parent_model = Organization
|
|
relationship = 'teams'
|
|
parent_key = 'organization'
|
|
|
|
|
|
class OrganizationActivityStreamList(SubListAPIView):
|
|
|
|
model = ActivityStream
|
|
serializer_class = ActivityStreamSerializer
|
|
parent_model = Organization
|
|
relationship = 'activitystream_set'
|
|
search_fields = ('changes',)
|
|
|
|
|
|
class OrganizationNotificationTemplatesList(SubListCreateAttachDetachAPIView):
|
|
|
|
model = NotificationTemplate
|
|
serializer_class = NotificationTemplateSerializer
|
|
parent_model = Organization
|
|
relationship = 'notification_templates'
|
|
parent_key = 'organization'
|
|
|
|
|
|
class OrganizationNotificationTemplatesAnyList(SubListCreateAttachDetachAPIView):
|
|
|
|
model = NotificationTemplate
|
|
serializer_class = NotificationTemplateSerializer
|
|
parent_model = Organization
|
|
|
|
|
|
class OrganizationNotificationTemplatesStartedList(OrganizationNotificationTemplatesAnyList):
|
|
|
|
relationship = 'notification_templates_started'
|
|
|
|
|
|
class OrganizationNotificationTemplatesErrorList(OrganizationNotificationTemplatesAnyList):
|
|
|
|
relationship = 'notification_templates_error'
|
|
|
|
|
|
class OrganizationNotificationTemplatesSuccessList(OrganizationNotificationTemplatesAnyList):
|
|
|
|
relationship = 'notification_templates_success'
|
|
|
|
|
|
class OrganizationNotificationTemplatesApprovalList(OrganizationNotificationTemplatesAnyList):
|
|
|
|
relationship = 'notification_templates_approvals'
|
|
|
|
|
|
class OrganizationInstanceGroupsList(SubListAttachDetachAPIView):
|
|
|
|
model = InstanceGroup
|
|
serializer_class = InstanceGroupSerializer
|
|
parent_model = Organization
|
|
relationship = 'instance_groups'
|
|
|
|
|
|
class OrganizationGalaxyCredentialsList(SubListAttachDetachAPIView):
|
|
|
|
model = Credential
|
|
serializer_class = CredentialSerializer
|
|
parent_model = Organization
|
|
relationship = 'galaxy_credentials'
|
|
|
|
def is_valid_relation(self, parent, sub, created=False):
|
|
if sub.kind != 'galaxy_api_token':
|
|
return {'msg': _(
|
|
f"Credential must be a Galaxy credential, not {sub.credential_type.name}."
|
|
)}
|
|
|
|
|
|
class OrganizationAccessList(ResourceAccessList):
|
|
|
|
model = User # needs to be User for AccessLists's
|
|
parent_model = Organization
|
|
|
|
|
|
class OrganizationObjectRolesList(SubListAPIView):
|
|
|
|
model = Role
|
|
serializer_class = RoleSerializer
|
|
parent_model = Organization
|
|
search_fields = ('role_field', 'content_type__model',)
|
|
|
|
def get_queryset(self):
|
|
po = self.get_parent_object()
|
|
content_type = ContentType.objects.get_for_model(self.parent_model)
|
|
return Role.objects.filter(content_type=content_type, object_id=po.pk)
|