From 4c0071916dea9031721bcb84cf87c202e269a424 Mon Sep 17 00:00:00 2001 From: Artem Goncharov Date: Fri, 2 Aug 2019 17:42:23 +0200 Subject: [PATCH] Enable ansible module test for keypair to check return data With a change in cloud layer to use proxy/resource layer for keypair Ansible got borked and is not capable in resolving data we return it back. Add test for it searching for the cause. Investigation resulted in the fact, that when invoked by Ansible native implementation of the Resoure.items was not suddifient under Py3, while under Py2 it is fine. An attempt to integrate all invoked functions into SDK from Ansible has not brought any success. Change-Id: I60dec9ba26176efc5b8ad8378b0ef414754a857c --- openstack/resource.py | 16 ++++++++++++++++ .../tests/ansible/roles/keypair/tasks/main.yml | 8 ++++++++ openstack/tests/unit/test_resource.py | 18 ++++++++++++++++++ tox.ini | 2 +- 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/openstack/resource.py b/openstack/resource.py index f3d776464..a6ab26d06 100644 --- a/openstack/resource.py +++ b/openstack/resource.py @@ -630,6 +630,22 @@ class Resource(dict): # remotes or "unknown" return self._attributes() + def items(self): + # This method is critically required for Ansible "jsonify" + # NOTE(gtema) For some reason when running from SDK itself the native + # implementation of the method is absolutely sifficient, when called + # from Ansible - the values are often empty. Even integrating all + # Ansible internal methods did not help to find the root cause. Another + # fact is that under Py2 everything is fine, while under Py3 it fails. + # There is currently no direct test for Ansible-SDK issue. It is tested + # implicitely in the keypair role for ansible module, where an assert + # verifies presence of attributes. + res = [] + for attr in self._attributes(): + # Append key, value tuple to result list + res.append((attr, self[attr])) + return res + def _update(self, **attrs): """Given attributes, update them on this instance diff --git a/openstack/tests/ansible/roles/keypair/tasks/main.yml b/openstack/tests/ansible/roles/keypair/tasks/main.yml index 53a856e2f..636bf1aca 100644 --- a/openstack/tests/ansible/roles/keypair/tasks/main.yml +++ b/openstack/tests/ansible/roles/keypair/tasks/main.yml @@ -4,6 +4,14 @@ cloud: "{{ cloud }}" name: "{{ keypair_name }}" state: present + register: + keypair + +# This assert verifies that Ansible is capable serializing data returned by SDK +- name: Ensure private key is returned + assert: + that: + - keypair.key.public_key is defined and keypair.key.public_key - name: Delete keypair (non-existing) os_keypair: diff --git a/openstack/tests/unit/test_resource.py b/openstack/tests/unit/test_resource.py index d51a2b560..d435a89ae 100644 --- a/openstack/tests/unit/test_resource.py +++ b/openstack/tests/unit/test_resource.py @@ -896,6 +896,24 @@ class TestResource(base.TestCase): actual = json.dumps(res, sort_keys=True) self.assertEqual(expected, actual) + def test_items(self): + class Test(resource.Resource): + foo = resource.Body('foo') + bar = resource.Body('bar') + foot = resource.Body('foot') + + data = { + 'foo': 'bar', + 'bar': 'foo\n', + 'foot': 'a:b:c:d' + } + + res = Test(**data) + for k, v in res.items(): + expected = data.get(k) + if expected: + self.assertEqual(v, expected) + def test_access_by_aka(self): class Test(resource.Resource): foo = resource.Header('foo_remote', aka='foo_alias') diff --git a/tox.ini b/tox.ini index aab8ea678..5322f1012 100644 --- a/tox.ini +++ b/tox.ini @@ -69,7 +69,7 @@ commands = [testenv:ansible] # Need to pass some env vars for the Ansible playbooks -basepython = {env:OPENSTACKSDK_TOX_PYTHON:python2} +basepython = {env:OPENSTACKSDK_TOX_PYTHON:python3} passenv = HOME USER ANSIBLE_VAR_* deps = {[testenv]deps}