mirror of
https://github.com/ansible/awx.git
synced 2026-03-10 05:59:28 -02:30
Adds Inventory labels (#11558)
* Adds inventory labels end point * Adds label field to inventory form
This commit is contained in:
@@ -1643,7 +1643,25 @@ class BaseSerializerWithVariables(BaseSerializer):
|
||||
return vars_validate_or_raise(value)
|
||||
|
||||
|
||||
class InventorySerializer(BaseSerializerWithVariables):
|
||||
class LabelsListMixin(object):
|
||||
def _summary_field_labels(self, obj):
|
||||
label_list = [{'id': x.id, 'name': x.name} for x in obj.labels.all()[:10]]
|
||||
if has_model_field_prefetched(obj, 'labels'):
|
||||
label_ct = len(obj.labels.all())
|
||||
else:
|
||||
if len(label_list) < 10:
|
||||
label_ct = len(label_list)
|
||||
else:
|
||||
label_ct = obj.labels.count()
|
||||
return {'count': label_ct, 'results': label_list}
|
||||
|
||||
def get_summary_fields(self, obj):
|
||||
res = super(LabelsListMixin, self).get_summary_fields(obj)
|
||||
res['labels'] = self._summary_field_labels(obj)
|
||||
return res
|
||||
|
||||
|
||||
class InventorySerializer(LabelsListMixin, BaseSerializerWithVariables):
|
||||
show_capabilities = ['edit', 'delete', 'adhoc', 'copy']
|
||||
capabilities_prefetch = ['admin', 'adhoc', {'copy': 'organization.inventory_admin'}]
|
||||
|
||||
@@ -1684,6 +1702,7 @@ class InventorySerializer(BaseSerializerWithVariables):
|
||||
object_roles=self.reverse('api:inventory_object_roles_list', kwargs={'pk': obj.pk}),
|
||||
instance_groups=self.reverse('api:inventory_instance_groups_list', kwargs={'pk': obj.pk}),
|
||||
copy=self.reverse('api:inventory_copy', kwargs={'pk': obj.pk}),
|
||||
labels=self.reverse('api:inventory_label_list', kwargs={'pk': obj.pk}),
|
||||
)
|
||||
)
|
||||
if obj.organization:
|
||||
@@ -2753,24 +2772,6 @@ class OrganizationCredentialSerializerCreate(CredentialSerializerCreate):
|
||||
fields = ('*', '-user', '-team')
|
||||
|
||||
|
||||
class LabelsListMixin(object):
|
||||
def _summary_field_labels(self, obj):
|
||||
label_list = [{'id': x.id, 'name': x.name} for x in obj.labels.all()[:10]]
|
||||
if has_model_field_prefetched(obj, 'labels'):
|
||||
label_ct = len(obj.labels.all())
|
||||
else:
|
||||
if len(label_list) < 10:
|
||||
label_ct = len(label_list)
|
||||
else:
|
||||
label_ct = obj.labels.count()
|
||||
return {'count': label_ct, 'results': label_list}
|
||||
|
||||
def get_summary_fields(self, obj):
|
||||
res = super(LabelsListMixin, self).get_summary_fields(obj)
|
||||
res['labels'] = self._summary_field_labels(obj)
|
||||
return res
|
||||
|
||||
|
||||
class JobOptionsSerializer(LabelsListMixin, BaseSerializer):
|
||||
class Meta:
|
||||
fields = (
|
||||
|
||||
@@ -20,6 +20,7 @@ from awx.api.views import (
|
||||
InventoryAccessList,
|
||||
InventoryObjectRolesList,
|
||||
InventoryInstanceGroupsList,
|
||||
InventoryLabelList,
|
||||
InventoryCopy,
|
||||
)
|
||||
|
||||
@@ -41,6 +42,7 @@ urls = [
|
||||
url(r'^(?P<pk>[0-9]+)/access_list/$', InventoryAccessList.as_view(), name='inventory_access_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/object_roles/$', InventoryObjectRolesList.as_view(), name='inventory_object_roles_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/instance_groups/$', InventoryInstanceGroupsList.as_view(), name='inventory_instance_groups_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/labels/$', InventoryLabelList.as_view(), name='inventory_label_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/copy/$', InventoryCopy.as_view(), name='inventory_copy'),
|
||||
]
|
||||
|
||||
|
||||
@@ -157,6 +157,7 @@ from awx.api.views.inventory import ( # noqa
|
||||
InventoryAccessList,
|
||||
InventoryObjectRolesList,
|
||||
InventoryJobTemplateList,
|
||||
InventoryLabelList,
|
||||
InventoryCopy,
|
||||
)
|
||||
from awx.api.views.mesh_visualizer import MeshVisualizer # noqa
|
||||
|
||||
@@ -16,17 +16,21 @@ from rest_framework.response import Response
|
||||
from rest_framework import status
|
||||
|
||||
# AWX
|
||||
from awx.main.models import (
|
||||
ActivityStream,
|
||||
Inventory,
|
||||
JobTemplate,
|
||||
Role,
|
||||
User,
|
||||
InstanceGroup,
|
||||
InventoryUpdateEvent,
|
||||
InventoryUpdate,
|
||||
from awx.main.models import ActivityStream, Inventory, JobTemplate, Role, User, InstanceGroup, InventoryUpdateEvent, InventoryUpdate
|
||||
|
||||
from awx.main.models.label import Label
|
||||
|
||||
from awx.api.generics import (
|
||||
ListCreateAPIView,
|
||||
RetrieveUpdateDestroyAPIView,
|
||||
SubListAPIView,
|
||||
SubListAttachDetachAPIView,
|
||||
ResourceAccessList,
|
||||
CopyAPIView,
|
||||
DeleteLastUnattachLabelMixin,
|
||||
SubListCreateAttachDetachAPIView,
|
||||
)
|
||||
from awx.api.generics import ListCreateAPIView, RetrieveUpdateDestroyAPIView, SubListAPIView, SubListAttachDetachAPIView, ResourceAccessList, CopyAPIView
|
||||
|
||||
|
||||
from awx.api.serializers import (
|
||||
InventorySerializer,
|
||||
@@ -35,6 +39,7 @@ from awx.api.serializers import (
|
||||
InstanceGroupSerializer,
|
||||
InventoryUpdateEventSerializer,
|
||||
JobTemplateSerializer,
|
||||
LabelSerializer,
|
||||
)
|
||||
from awx.api.views.mixin import RelatedJobsPreventDeleteMixin, ControlledByScmMixin
|
||||
|
||||
@@ -152,6 +157,30 @@ class InventoryJobTemplateList(SubListAPIView):
|
||||
return qs.filter(inventory=parent)
|
||||
|
||||
|
||||
class InventoryLabelList(DeleteLastUnattachLabelMixin, SubListCreateAttachDetachAPIView, SubListAPIView):
|
||||
|
||||
model = Label
|
||||
serializer_class = LabelSerializer
|
||||
parent_model = Inventory
|
||||
relationship = 'labels'
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
# If a label already exists in the database, attach it instead of erroring out
|
||||
# that it already exists
|
||||
if 'id' not in request.data and 'name' in request.data and 'organization' in request.data:
|
||||
existing = Label.objects.filter(name=request.data['name'], organization_id=request.data['organization'])
|
||||
if existing.exists():
|
||||
existing = existing[0]
|
||||
request.data['id'] = existing.id
|
||||
del request.data['name']
|
||||
del request.data['organization']
|
||||
if Label.objects.filter(inventory_labels=self.kwargs['pk']).count() > 100:
|
||||
return Response(
|
||||
dict(msg=_('Maximum number of labels for {} reached.'.format(self.parent_model._meta.verbose_name_raw))), status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
return super(InventoryLabelList, self).post(request, *args, **kwargs)
|
||||
|
||||
|
||||
class InventoryCopy(CopyAPIView):
|
||||
|
||||
model = Inventory
|
||||
|
||||
Reference in New Issue
Block a user