AC-540 Add /api/v1/inventory_sources/ list. OPTIONS request now returns all fields under actions['GET'] and only writable fields under actions['PUT'] or actions['POST'].

This commit is contained in:
Chris Church 2013-10-09 15:44:19 -04:00
parent a74a7dd21e
commit 85a9f2f68a
3 changed files with 64 additions and 15 deletions

View File

@ -18,6 +18,7 @@ from rest_framework.authentication import get_authorization_header
from rest_framework.exceptions import PermissionDenied
from rest_framework import generics
from rest_framework.response import Response
from rest_framework.request import clone_request
from rest_framework import status
from rest_framework import views
@ -128,6 +129,47 @@ class GenericAPIView(generics.GenericAPIView, APIView):
})
return d
def metadata(self, request):
'''
Add field information for GET requests (so field names/labels are
available even when we can't POST/PUT).
'''
ret = super(GenericAPIView, self).metadata(request)
actions = ret.get('actions', {})
# Remove read only fields from PUT/POST data.
for method in ('POST', 'PUT'):
fields = actions.get(method, {})
for field, meta in fields.items():
if not isinstance(meta, dict):
continue
if meta.get('read_only', False):
fields.pop(field)
if 'GET' in self.allowed_methods:
cloned_request = clone_request(request, 'GET')
try:
# Test global permissions
self.check_permissions(cloned_request)
# Test object permissions
if hasattr(self, 'retrieve'):
try:
self.get_object()
except Http404:
# Http404 should be acceptable and the serializer
# metadata should be populated. Except this so the
# outer "else" clause of the try-except-else block
# will be executed.
pass
except (exceptions.APIException, PermissionDenied):
pass
else:
# If user has appropriate permissions for the view, include
# appropriate metadata about the fields that should be supplied.
serializer = self.get_serializer()
actions['GET'] = serializer.metadata()
if actions:
ret['actions'] = actions
return ret
class ListAPIView(generics.ListAPIView, GenericAPIView):
# Base class for a read-only list view.

View File

@ -91,6 +91,7 @@ group_urls = patterns('awx.main.views',
)
inventory_source_urls = patterns('awx.main.views',
url(r'^$', 'inventory_source_list'),
url(r'^(?P<pk>[0-9]+)/$', 'inventory_source_detail'),
url(r'^(?P<pk>[0-9]+)/update/$', 'inventory_source_update_view'),
url(r'^(?P<pk>[0-9]+)/inventory_updates/$', 'inventory_source_updates_list'),

View File

@ -81,21 +81,21 @@ class ApiV1RootView(APIView):
def get(self, request, format=None):
''' list top level resources '''
data = dict(
organizations = reverse('main:organization_list'),
users = reverse('main:user_list'),
projects = reverse('main:project_list'),
teams = reverse('main:team_list'),
credentials = reverse('main:credential_list'),
inventory = reverse('main:inventory_list'),
groups = reverse('main:group_list'),
hosts = reverse('main:host_list'),
job_templates = reverse('main:job_template_list'),
jobs = reverse('main:job_list'),
authtoken = reverse('main:auth_token_view'),
me = reverse('main:user_me_list'),
config = reverse('main:api_v1_config_view'),
)
data = SortedDict()
data['authtoken'] = reverse('main:auth_token_view')
data['config'] = reverse('main:api_v1_config_view')
data['me'] = reverse('main:user_me_list')
data['organizations'] = reverse('main:organization_list')
data['users'] = reverse('main:user_list')
data['projects'] = reverse('main:project_list')
data['teams'] = reverse('main:team_list')
data['credentials'] = reverse('main:credential_list')
data['inventory'] = reverse('main:inventory_list')
data['inventory_sources'] = reverse('main:inventory_source_list')
data['groups'] = reverse('main:group_list')
data['hosts'] = reverse('main:host_list')
data['job_templates'] = reverse('main:job_template_list')
data['jobs'] = reverse('main:job_list')
return Response(data)
class ApiV1ConfigView(APIView):
@ -717,6 +717,12 @@ class InventoryInventorySourcesList(SubListAPIView):
return qs.filter(Q(inventory__pk=parent.pk) |
Q(group__inventory__pk=parent.pk))
class InventorySourceList(ListAPIView):
model = InventorySource
serializer_class = InventorySourceSerializer
new_in_14 = True
class InventorySourceDetail(RetrieveUpdateAPIView):
model = InventorySource