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)}
|
||||
)
|
||||
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__"
|
||||
|
||||
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):
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user