Add support for specifying playbook labels as Ansible variables

By declaring the "ara_playbook_labels" list Ansible variable, the
callback picks them up and sends them to the API.
The API then ensures the label is created and associates it with
the playbook.

Change-Id: Ibe5c36ce005f0a7ce99b38c57439a6dc2277228a
This commit is contained in:
David Moreau Simard 2019-05-17 12:44:13 -04:00
parent 0b9c17132e
commit 9b00abd786
5 changed files with 54 additions and 12 deletions

View File

@ -73,3 +73,16 @@ class FileContentField(serializers.CharField):
sha1=sha1, defaults={"sha1": sha1, "contents": zlib.compress(contents)}
)
return content_file
class CreatableSlugRelatedField(serializers.SlugRelatedField):
"""
A SlugRelatedField that supports get_or_create.
Used for creating or retrieving labels by name.
"""
def to_internal_value(self, data):
try:
return self.get_queryset().get_or_create(**{self.slug_field: data})[0]
except (TypeError, ValueError):
self.fail("invalid")

View File

@ -351,18 +351,9 @@ class PlaybookSerializer(DurationSerializer):
fields = "__all__"
arguments = ara_fields.CompressedObjectField(default=ara_fields.EMPTY_DICT)
labels = LabelSerializer(many=True, default=[])
def create(self, validated_data):
# First create the playbook without the labels
labels = validated_data.pop("labels")
playbook = models.Playbook.objects.create(**validated_data)
# Now associate the labels to the playbook
for label in labels:
playbook.labels.add(models.Label.objects.create(**label))
return playbook
labels = ara_fields.CreatableSlugRelatedField(
many=True, slug_field="name", queryset=models.Label.objects.all(), required=False
)
class PlaySerializer(DurationSerializer):

View File

@ -82,6 +82,18 @@ class PlaybookTestCase(APITestCase):
self.assertEqual(1, models.Playbook.objects.count())
self.assertEqual(request.data["status"], "running")
def test_create_playbook_with_labels(self):
self.assertEqual(0, models.Playbook.objects.count())
labels = ["test-label", "another-test-label"]
request = self.client.post(
"/api/v1/playbooks",
{"ansible_version": "2.4.0", "status": "running", "path": "/path/playbook.yml", "labels": labels},
)
self.assertEqual(201, request.status_code)
self.assertEqual(1, models.Playbook.objects.count())
self.assertEqual(request.data["status"], "running")
self.assertEqual(request.data["labels"], labels)
def test_partial_update_playbook(self):
playbook = factories.PlaybookFactory()
self.assertNotEqual("completed", playbook.status)
@ -133,4 +145,13 @@ class PlaybookTestCase(APITestCase):
request = self.client.get("/api/v1/playbooks/%s" % playbook.id)
self.assertEqual(request.data["duration"], datetime.timedelta(0, 3600))
def test_patch_playbook_labels(self):
playbook = factories.PlaybookFactory()
labels = ["test-label", "another-test-label"]
self.assertNotEqual(playbook.labels, labels)
request = self.client.patch("/api/v1/playbooks/%s" % playbook.id, {"labels": labels})
self.assertEqual(200, request.status_code)
playbook_updated = models.Playbook.objects.get(id=playbook.id)
self.assertEqual([label.name for label in playbook_updated.labels.all()], labels)
# TODO: Add tests for incrementally updating files

View File

@ -183,6 +183,8 @@ class CallbackModule(CallbackBase):
play_vars = play._variable_manager.get_vars(play=play)["vars"]
if "ara_playbook_name" in play_vars:
self._set_playbook_name(name=play_vars["ara_playbook_name"])
if "ara_playbook_labels" in play_vars:
self._set_playbook_labels(labels=play_vars["ara_playbook_labels"])
# Record all the files involved in the play
for path in play._loader._FILE_CACHE.keys():
@ -281,6 +283,10 @@ class CallbackModule(CallbackBase):
if self.playbook["name"] != name:
self.playbook = self.client.patch("/api/v1/playbooks/%s" % self.playbook["id"], name=name)
def _set_playbook_labels(self, labels):
if self.playbook["labels"] != labels:
self.playbook = self.client.patch("/api/v1/playbooks/%s" % self.playbook["id"], labels=labels)
def _get_or_create_file(self, path):
self.log.debug("Getting or creating file: %s" % path)
# Note: The get_or_create is handled through the serializer of the API server.

View File

@ -21,6 +21,9 @@
gather_facts: no
vars:
ara_playbook_name: Smoke tests
ara_playbook_labels:
- integration tests
- smoke
tasks:
- name: ARA Integration test
debug:
@ -33,6 +36,10 @@
- name: Add a host with non-ascii characters
hosts: localhost
gather_facts: no
vars:
ara_playbook_labels:
- integration tests
- smoke
tasks:
- name: Add a host with non-ascii character
add_host:
@ -46,6 +53,10 @@
- name: Play with non-ascii characters - ä, ö, ü
hosts: höstñämë
gather_facts: yes
vars:
ara_playbook_labels:
- integration tests
- smoke
tasks:
- name: Task with non-ascii characters - ä, ö, ü
debug: