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:
parent
0b9c17132e
commit
9b00abd786
@ -73,3 +73,16 @@ class FileContentField(serializers.CharField):
|
|||||||
sha1=sha1, defaults={"sha1": sha1, "contents": zlib.compress(contents)}
|
sha1=sha1, defaults={"sha1": sha1, "contents": zlib.compress(contents)}
|
||||||
)
|
)
|
||||||
return content_file
|
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")
|
||||||
|
@ -351,18 +351,9 @@ class PlaybookSerializer(DurationSerializer):
|
|||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
|
|
||||||
arguments = ara_fields.CompressedObjectField(default=ara_fields.EMPTY_DICT)
|
arguments = ara_fields.CompressedObjectField(default=ara_fields.EMPTY_DICT)
|
||||||
labels = LabelSerializer(many=True, default=[])
|
labels = ara_fields.CreatableSlugRelatedField(
|
||||||
|
many=True, slug_field="name", queryset=models.Label.objects.all(), required=False
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
class PlaySerializer(DurationSerializer):
|
class PlaySerializer(DurationSerializer):
|
||||||
|
@ -82,6 +82,18 @@ class PlaybookTestCase(APITestCase):
|
|||||||
self.assertEqual(1, models.Playbook.objects.count())
|
self.assertEqual(1, models.Playbook.objects.count())
|
||||||
self.assertEqual(request.data["status"], "running")
|
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):
|
def test_partial_update_playbook(self):
|
||||||
playbook = factories.PlaybookFactory()
|
playbook = factories.PlaybookFactory()
|
||||||
self.assertNotEqual("completed", playbook.status)
|
self.assertNotEqual("completed", playbook.status)
|
||||||
@ -133,4 +145,13 @@ class PlaybookTestCase(APITestCase):
|
|||||||
request = self.client.get("/api/v1/playbooks/%s" % playbook.id)
|
request = self.client.get("/api/v1/playbooks/%s" % playbook.id)
|
||||||
self.assertEqual(request.data["duration"], datetime.timedelta(0, 3600))
|
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
|
# TODO: Add tests for incrementally updating files
|
||||||
|
@ -183,6 +183,8 @@ class CallbackModule(CallbackBase):
|
|||||||
play_vars = play._variable_manager.get_vars(play=play)["vars"]
|
play_vars = play._variable_manager.get_vars(play=play)["vars"]
|
||||||
if "ara_playbook_name" in play_vars:
|
if "ara_playbook_name" in play_vars:
|
||||||
self._set_playbook_name(name=play_vars["ara_playbook_name"])
|
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
|
# Record all the files involved in the play
|
||||||
for path in play._loader._FILE_CACHE.keys():
|
for path in play._loader._FILE_CACHE.keys():
|
||||||
@ -281,6 +283,10 @@ class CallbackModule(CallbackBase):
|
|||||||
if self.playbook["name"] != name:
|
if self.playbook["name"] != name:
|
||||||
self.playbook = self.client.patch("/api/v1/playbooks/%s" % self.playbook["id"], 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):
|
def _get_or_create_file(self, path):
|
||||||
self.log.debug("Getting or creating file: %s" % path)
|
self.log.debug("Getting or creating file: %s" % path)
|
||||||
# Note: The get_or_create is handled through the serializer of the API server.
|
# Note: The get_or_create is handled through the serializer of the API server.
|
||||||
|
@ -21,6 +21,9 @@
|
|||||||
gather_facts: no
|
gather_facts: no
|
||||||
vars:
|
vars:
|
||||||
ara_playbook_name: Smoke tests
|
ara_playbook_name: Smoke tests
|
||||||
|
ara_playbook_labels:
|
||||||
|
- integration tests
|
||||||
|
- smoke
|
||||||
tasks:
|
tasks:
|
||||||
- name: ARA Integration test
|
- name: ARA Integration test
|
||||||
debug:
|
debug:
|
||||||
@ -33,6 +36,10 @@
|
|||||||
- name: Add a host with non-ascii characters
|
- name: Add a host with non-ascii characters
|
||||||
hosts: localhost
|
hosts: localhost
|
||||||
gather_facts: no
|
gather_facts: no
|
||||||
|
vars:
|
||||||
|
ara_playbook_labels:
|
||||||
|
- integration tests
|
||||||
|
- smoke
|
||||||
tasks:
|
tasks:
|
||||||
- name: Add a host with non-ascii character
|
- name: Add a host with non-ascii character
|
||||||
add_host:
|
add_host:
|
||||||
@ -46,6 +53,10 @@
|
|||||||
- name: Play with non-ascii characters - ä, ö, ü
|
- name: Play with non-ascii characters - ä, ö, ü
|
||||||
hosts: höstñämë
|
hosts: höstñämë
|
||||||
gather_facts: yes
|
gather_facts: yes
|
||||||
|
vars:
|
||||||
|
ara_playbook_labels:
|
||||||
|
- integration tests
|
||||||
|
- smoke
|
||||||
tasks:
|
tasks:
|
||||||
- name: Task with non-ascii characters - ä, ö, ü
|
- name: Task with non-ascii characters - ä, ö, ü
|
||||||
debug:
|
debug:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user