Fix POST /playbooks/:id/files

The Playbook is kind of special in the sense that it has it's own
(playbook) file but it's also very convenient to store references for
all the files relevant to a playbook execution in a single place.

This makes it so we are able to append files individually as they come
up in the various stages of the execution of a playbook.

Change-Id: I7bf8dcb8286adb702d0a884cdcfeea6ac419b417
This commit is contained in:
Guillaume Vincent 2018-03-22 16:58:47 +01:00 committed by David Moreau Simard
parent 61bd81226f
commit bacd61bade
No known key found for this signature in database
GPG Key ID: 33A07694CBB71ECC
3 changed files with 37 additions and 20 deletions

View File

@ -1,8 +1,7 @@
import datetime
from django.utils import timezone
import time
from rest_framework.test import APITestCase
from api import models, serializers
from api import models
from api.tests import factories
@ -26,23 +25,26 @@ class PlaybookFileTestCase(APITestCase):
def test_create_file_to_a_playbook(self):
playbook = factories.PlaybookFactory()
self.assertEqual(0, models.File.objects.all().count())
self.client.post('/api/v1/playbooks/%s/files' % playbook.id, {
'path': '/tmp/playbook.yml',
'content': '# playbook'
})
self.assertEqual(1, models.File.objects.all().count())
self.assertEqual(1, models.FileContent.objects.all().count())
def test_create_2_files_with_same_content(self):
playbook = factories.PlaybookFactory()
self.client.post('/api/v1/playbooks/%s/files' % playbook.id, {
'path': '/tmp/1/playbook.yml',
'content': '# playbook'
})
self.client.post('/api/v1/playbooks/%s/files' % playbook.id, {
'path': '/tmp/2/playbook.yml',
self.client.post('/api/v1/playbooks/%s/files/' % playbook.id, {
'path': '/tmp/playbook.yml',
'content': '# playbook'
})
self.assertEqual(2, models.File.objects.all().count())
self.assertEqual(1, models.FileContent.objects.all().count())
def test_create_2_files_with_same_content(self):
playbook = factories.PlaybookFactory()
number_playbooks = models.File.objects.all().count()
number_file_contents = models.FileContent.objects.all().count()
content = '# playbook %s' % time.time()
self.client.post('/api/v1/playbooks/%s/files/' % playbook.id, {
'path': '/tmp/1/playbook.yml',
'content': content
})
self.client.post('/api/v1/playbooks/%s/files/' % playbook.id, {
'path': '/tmp/2/playbook.yml',
'content': content
})
self.assertEqual(number_playbooks + 2, models.File.objects.all().count())
self.assertEqual(number_file_contents + 1, models.FileContent.objects.all().count())

View File

@ -23,6 +23,7 @@ urlpatterns = [
url(r'^$', views.api_root),
url(r'^playbooks/$', views.PlaybookList.as_view(), name='playbook-list'),
url(r'^playbooks/(?P<pk>[0-9]+)/$', views.PlaybookDetail.as_view(), name='playbook-detail'),
url(r'^playbooks/(?P<pk>[0-9]+)/files/$', views.PlaybookFilesDetail.as_view(), name='playbook-file-detail'),
url(r'^plays/$', views.PlayList.as_view(), name='play-list'),
url(r'^plays/(?P<pk>[0-9]+)/$', views.PlayDetail.as_view(), name='play-detail'),
url(r'^tasks/$', views.TaskList.as_view(), name='task-list'),

View File

@ -14,13 +14,13 @@
#
# You should have received a copy of the GNU General Public License
# along with ARA. If not, see <http://www.gnu.org/licenses/>.
from rest_framework.decorators import api_view
from rest_framework.decorators import api_view, detail_route
from rest_framework.response import Response
from rest_framework.reverse import reverse
from api import models, serializers
from rest_framework import generics
from rest_framework import generics, status
@api_view(['GET'])
@ -43,6 +43,20 @@ class PlaybookDetail(generics.RetrieveUpdateDestroyAPIView):
serializer_class = serializers.PlaybookSerializer
class PlaybookFilesDetail(generics.CreateAPIView):
queryset = models.Playbook.objects.all()
serializer_class = serializers.FileSerializer
def post(self, request, *args, **kwargs):
playbook = self.get_object()
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
playbook.files.add(serializer.data['id'])
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
class PlayList(generics.ListCreateAPIView):
queryset = models.Play.objects.all()
serializer_class = serializers.PlaySerializer