mirror of
https://github.com/ansible/awx.git
synced 2026-05-10 19:07:36 -02:30
Include in the API the count of hosts used by an organization
This commit is contained in:
@@ -29,7 +29,7 @@ from awx.main.models.ha import (
|
|||||||
)
|
)
|
||||||
from awx.main.models.organization import Team
|
from awx.main.models.organization import Team
|
||||||
from awx.main.models.projects import Project
|
from awx.main.models.projects import Project
|
||||||
from awx.main.models.inventory import Inventory
|
from awx.main.models.inventory import Inventory, Host
|
||||||
from awx.main.models.jobs import JobTemplate
|
from awx.main.models.jobs import JobTemplate
|
||||||
from awx.conf.license import (
|
from awx.conf.license import (
|
||||||
feature_enabled,
|
feature_enabled,
|
||||||
@@ -235,6 +235,8 @@ class OrganizationCountsMixin(object):
|
|||||||
db_results['projects'] = project_qs\
|
db_results['projects'] = project_qs\
|
||||||
.values('organization').annotate(Count('organization')).order_by('organization')
|
.values('organization').annotate(Count('organization')).order_by('organization')
|
||||||
|
|
||||||
|
db_results['hosts'] = Host.objects.active_counts_by_org()
|
||||||
|
|
||||||
# Other members and admins of organization are always viewable
|
# Other members and admins of organization are always viewable
|
||||||
db_results['users'] = org_qs.annotate(
|
db_results['users'] = org_qs.annotate(
|
||||||
users=Count('member_role__members', distinct=True),
|
users=Count('member_role__members', distinct=True),
|
||||||
@@ -246,7 +248,7 @@ class OrganizationCountsMixin(object):
|
|||||||
org_id = org['id']
|
org_id = org['id']
|
||||||
count_context[org_id] = {
|
count_context[org_id] = {
|
||||||
'inventories': 0, 'teams': 0, 'users': 0, 'job_templates': 0,
|
'inventories': 0, 'teams': 0, 'users': 0, 'job_templates': 0,
|
||||||
'admins': 0, 'projects': 0}
|
'admins': 0, 'projects': 0, 'hosts': 0}
|
||||||
|
|
||||||
for res, count_qs in db_results.items():
|
for res, count_qs in db_results.items():
|
||||||
if res == 'job_templates_project':
|
if res == 'job_templates_project':
|
||||||
@@ -255,6 +257,8 @@ class OrganizationCountsMixin(object):
|
|||||||
org_reference = JT_inventory_reference
|
org_reference = JT_inventory_reference
|
||||||
elif res == 'users':
|
elif res == 'users':
|
||||||
org_reference = 'id'
|
org_reference = 'id'
|
||||||
|
elif res == 'hosts':
|
||||||
|
org_reference = 'inventory__organization'
|
||||||
else:
|
else:
|
||||||
org_reference = 'organization'
|
org_reference = 'organization'
|
||||||
for entry in count_qs:
|
for entry in count_qs:
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ from awx.conf.license import (
|
|||||||
from awx.main.models import (
|
from awx.main.models import (
|
||||||
ActivityStream,
|
ActivityStream,
|
||||||
Inventory,
|
Inventory,
|
||||||
|
Host,
|
||||||
Project,
|
Project,
|
||||||
JobTemplate,
|
JobTemplate,
|
||||||
WorkflowJobTemplate,
|
WorkflowJobTemplate,
|
||||||
@@ -119,6 +120,7 @@ class OrganizationDetail(RelatedJobsPreventDeleteMixin, RetrieveUpdateDestroyAPI
|
|||||||
organization__id=org_id).count()
|
organization__id=org_id).count()
|
||||||
org_counts['job_templates'] = JobTemplate.accessible_objects(**access_kwargs).filter(
|
org_counts['job_templates'] = JobTemplate.accessible_objects(**access_kwargs).filter(
|
||||||
project__organization__id=org_id).count()
|
project__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'] = {}
|
||||||
full_context['related_field_counts'][org_id] = org_counts
|
full_context['related_field_counts'][org_id] = org_counts
|
||||||
|
|||||||
@@ -29,6 +29,34 @@ class HostManager(models.Manager):
|
|||||||
"""
|
"""
|
||||||
return self.order_by().exclude(inventory_sources__source='tower').values('name').distinct().count()
|
return self.order_by().exclude(inventory_sources__source='tower').values('name').distinct().count()
|
||||||
|
|
||||||
|
def org_active_count(self, org_id):
|
||||||
|
"""Return count of active, unique hosts used by an organization.
|
||||||
|
Construction of query involves:
|
||||||
|
- remove any ordering specified in model's Meta
|
||||||
|
- Exclude hosts sourced from another Tower
|
||||||
|
- Consider only hosts where the canonical inventory is owned by the organization
|
||||||
|
- Restrict the query to only return the name column
|
||||||
|
- Only consider results that are unique
|
||||||
|
- Return the count of this query
|
||||||
|
"""
|
||||||
|
return self.order_by().exclude(
|
||||||
|
inventory_sources__source='tower'
|
||||||
|
).filter(inventory__organization=org_id).values('name').distinct().count()
|
||||||
|
|
||||||
|
def active_counts_by_org(self):
|
||||||
|
"""Return the counts of active, unique hosts for each organization.
|
||||||
|
Construction of query involves:
|
||||||
|
- remove any ordering specified in model's Meta
|
||||||
|
- Exclude hosts sourced from another Tower
|
||||||
|
- Consider only hosts where the canonical inventory is owned by each organization
|
||||||
|
- Restrict the query to only count distinct names
|
||||||
|
- Return the counts
|
||||||
|
"""
|
||||||
|
return self.order_by().exclude(
|
||||||
|
inventory_sources__source='tower'
|
||||||
|
).values('inventory__organization').annotate(
|
||||||
|
inventory__organization__count=models.Count('name', distinct=True))
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
"""When the parent instance of the host query set has a `kind=smart` and a `host_filter`
|
"""When the parent instance of the host query set has a `kind=smart` and a `host_filter`
|
||||||
set. Use the `host_filter` to generate the queryset for the hosts.
|
set. Use the `host_filter` to generate the queryset for the hosts.
|
||||||
|
|||||||
Reference in New Issue
Block a user