mirror of
https://github.com/ansible/awx.git
synced 2026-01-20 06:01:25 -03:30
Added queries that calculate counts for organization resources
This commit is contained in:
parent
a1c843e9f6
commit
765dcd3318
@ -798,6 +798,14 @@ class OrganizationSerializer(BaseSerializer):
|
||||
))
|
||||
return res
|
||||
|
||||
def get_summary_fields(self, obj):
|
||||
summary_dict = super(OrganizationSerializer, self).get_summary_fields(obj)
|
||||
counts_dict = self.context.get('counts', None)
|
||||
if counts_dict is not None and summary_dict is not None:
|
||||
print 'counts_dict: ' + str(counts_dict)
|
||||
summary_dict['counts'] = counts_dict[obj.id]
|
||||
return summary_dict
|
||||
|
||||
|
||||
class ProjectOptionsSerializer(BaseSerializer):
|
||||
|
||||
|
||||
@ -596,6 +596,15 @@ class OrganizationList(ListCreateAPIView):
|
||||
model = Organization
|
||||
serializer_class = OrganizationSerializer
|
||||
|
||||
# @paginated
|
||||
# def get(self, *args, **kwargs):
|
||||
# # self.paginated_params = {'limit': limit, 'offset': offset, 'ordering': ordering}
|
||||
# limit = kwargs.pop('limit')
|
||||
# offset = kwargs.pop('offset')
|
||||
# ordering = kwargs.pop('ordering')
|
||||
# # qs[offset:offset + limit]
|
||||
# return (super(OrganizationList, self).get(*args, **kwargs), 5, None)
|
||||
|
||||
def create(self, request, *args, **kwargs):
|
||||
"""Create a new organzation.
|
||||
|
||||
@ -614,6 +623,75 @@ class OrganizationList(ListCreateAPIView):
|
||||
# Okay, create the organization as usual.
|
||||
return super(OrganizationList, self).create(request, *args, **kwargs)
|
||||
|
||||
def get_serializer_context(self, *args, **kwargs):
|
||||
full_context = super(OrganizationList, self).get_serializer_context(*args, **kwargs)
|
||||
|
||||
if self.request is None:
|
||||
return full_context
|
||||
|
||||
db_results = {}
|
||||
org_qs = self.request.user.get_queryset(self.model)
|
||||
org_id_list = org_qs.values('id')
|
||||
if len(org_id_list) == 0:
|
||||
return full_context
|
||||
|
||||
# Produce counts of Foreign Key relationships
|
||||
db_results['inventories'] = self.request.user.get_queryset(Inventory)\
|
||||
.values('organization').annotate(Count('organization')).order_by('organization')
|
||||
|
||||
db_results['teams'] = self.request.user.get_queryset(Team)\
|
||||
.values('organization').annotate(Count('organization')).order_by('organization')
|
||||
|
||||
JT_reference = 'inventory__organization'
|
||||
db_JT_results = self.request.user.get_queryset(JobTemplate)\
|
||||
.values(JT_reference).annotate(Count(JT_reference)).\
|
||||
order_by(JT_reference)
|
||||
|
||||
# Produce counts of m2m relationships
|
||||
project_qs = self.request.user.get_queryset(Project)
|
||||
db_results['projects'] = Organization.projects.through.objects\
|
||||
.filter(
|
||||
project_id__in=project_qs.values_list('pk', flat=True),
|
||||
organization_id__in=org_qs.values_list('pk', flat=True))\
|
||||
.values('organization')\
|
||||
.annotate(Count('organization')).order_by('organization')
|
||||
|
||||
# TODO: When RBAC branch merges, change these to role relation
|
||||
user_qs = self.request.user.get_queryset(User)
|
||||
db_results['users'] = Organization.users.through.objects\
|
||||
.filter(
|
||||
user_id__in=user_qs.values_list('pk', flat=True),
|
||||
organization_id__in=org_qs.values_list('pk', flat=True))\
|
||||
.values('organization')\
|
||||
.annotate(Count('organization')).order_by('organization')
|
||||
|
||||
db_results['admins'] = Organization.admins.through.objects\
|
||||
.filter(
|
||||
user_id__in=user_qs.values_list('pk', flat=True),
|
||||
organization_id__in=org_qs.values_list('pk', flat=True))\
|
||||
.values('organization')\
|
||||
.annotate(Count('organization')).order_by('organization')
|
||||
|
||||
count_context = {}
|
||||
for org in org_id_list:
|
||||
org_id = org['id']
|
||||
count_context[org_id] = {'inventories': 0, 'teams': 0, 'users': 0,
|
||||
'job_templates': 0, 'admins': 0,
|
||||
'projects': 0}
|
||||
|
||||
for res in db_results:
|
||||
for entry in db_results[res]:
|
||||
org_id = entry['organization']
|
||||
count_context[org_id][res] = entry['organization__count']
|
||||
|
||||
for entry in db_JT_results:
|
||||
org_id = entry[JT_reference]
|
||||
count_context[org_id]['job_templates'] = entry['%s__count' % JT_reference]
|
||||
|
||||
full_context['counts'] = count_context
|
||||
|
||||
return full_context
|
||||
|
||||
class OrganizationDetail(RetrieveUpdateDestroyAPIView):
|
||||
|
||||
model = Organization
|
||||
|
||||
54
awx/main/tests/functional/api/test_organization_counts.py
Normal file
54
awx/main/tests/functional/api/test_organization_counts.py
Normal file
@ -0,0 +1,54 @@
|
||||
import pytest
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
@pytest.fixture
|
||||
def resourced_organization(organization, project, user):
|
||||
admin_user = user('test-admin', True)
|
||||
member_user = user('org-member')
|
||||
|
||||
# Associate one resource of every type with the organization
|
||||
organization.users.add(member_user)
|
||||
organization.admins.add(admin_user)
|
||||
organization.projects.add(project)
|
||||
organization.teams.create(name='org-team')
|
||||
inventory = organization.inventories.create(name="associated-inv")
|
||||
inventory.jobtemplates.create(name="test-jt",
|
||||
description="test-job-template-desc",
|
||||
project=project,
|
||||
playbook="test_playbook.yml")
|
||||
|
||||
return organization
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_org_counts_admin(resourced_organization, user, get):
|
||||
# Check that all types of resources are counted by a superuser
|
||||
external_admin = user('admin', True)
|
||||
response = get(reverse('api:organization_list', args=[]), external_admin)
|
||||
counts = response.data['results'][0]['summary_fields']['counts']
|
||||
|
||||
assert counts == {
|
||||
'users': 1,
|
||||
'admins': 1,
|
||||
'job_templates': 1,
|
||||
'projects': 1,
|
||||
'inventories': 1,
|
||||
'teams': 1
|
||||
}
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_org_counts_member(resourced_organization, get):
|
||||
# Check that a non-admin user can only see the full project and
|
||||
# user count, consistent with the RBAC rules
|
||||
member_user = resourced_organization.users.get(username='org-member')
|
||||
response = get(reverse('api:organization_list', args=[]), member_user)
|
||||
counts = response.data['results'][0]['summary_fields']['counts']
|
||||
|
||||
assert counts == {
|
||||
'users': 1, # User can see themselves
|
||||
'admins': 0,
|
||||
'job_templates': 0,
|
||||
'projects': 1, # Projects are shared with all the organization
|
||||
'inventories': 0,
|
||||
'teams': 0
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user