]> git.apps.os.sepia.ceph.com Git - ceph-ansible.git/commitdiff
library/ceph_key: add output format parameter
authorDimitri Savineau <dsavinea@redhat.com>
Fri, 23 Oct 2020 18:50:52 +0000 (14:50 -0400)
committerGuillaume Abrioux <gabrioux@redhat.com>
Mon, 2 Nov 2020 16:17:29 +0000 (17:17 +0100)
The ceph_key module currently only supports the json output for the
info state.
When using this state on an entity then we something want the output
as:
  - plain for copying it to another node.
  - json in order to get only a subset information of the entity (like
the key or caps).

This patch adds the output_format parameter which uses json as a
default value for backward compatibility. It removes the internal and
hardcoded variable also called output_format.
In addition of json and plain outputs, there's also xml and yaml
values available.

Signed-off-by: Dimitri Savineau <dsavinea@redhat.com>
library/ceph_key.py
tests/library/test_ceph_key.py

index 92a5a2528da97d341f4c7114cb447aad3def8b36..2be37ed84a8a3c2e7b005d6f8ad276d01e8a6b23 100644 (file)
@@ -103,6 +103,12 @@ options:
             This command can ONLY run from a monitor node.
         required: false
         default: false
+    output_format:
+        description:
+            - The key output format when retrieving the information of an
+            entity.
+        required: false
+        default: json
 '''
 
 EXAMPLES = '''
@@ -163,6 +169,13 @@ caps:
     name: "my_key""
     state: info
 
+- name: info cephx admin key (plain)
+  ceph_key:
+    name: client.admin
+    output_format: plain
+    state: info
+  register: client_admin_key
+
 - name: list cephx keys
   ceph_key:
     state: list
@@ -512,7 +525,8 @@ def run_module():
         import_key=dict(type='bool', required=False, default=True),
         dest=dict(type='str', required=False, default='/etc/ceph/'),
         user=dict(type='str', required=False, default='client.admin'),
-        user_key=dict(type='str', required=False, default=None)
+        user_key=dict(type='str', required=False, default=None),
+        output_format=dict(type='str', required=False, default='json', choices=['json', 'plain', 'xml', 'yaml'])
     )
 
     module = AnsibleModule(
@@ -533,6 +547,7 @@ def run_module():
     dest = module.params.get('dest')
     user = module.params.get('user')
     user_key = module.params.get('user_key')
+    output_format = module.params.get('output_format')
 
     changed = False
 
@@ -568,8 +583,6 @@ def run_module():
     else:
         user_key_path = user_key
 
-    output_format = "json"
-
     if (state in ["present", "update"]):
         # if dest is not a directory, the user wants to change the file's name
         # (e,g: /etc/ceph/ceph.mgr.ceph-mon2.keyring)
index 56eb891851b58898a116e8a4f85c363f31d2345c..87c7ccac1daff1a5e0828bac257f2d41f1070790 100644 (file)
@@ -25,10 +25,18 @@ class AnsibleExitJson(Exception):
     pass
 
 
+class AnsibleFailJson(Exception):
+    pass
+
+
 def exit_json(*args, **kwargs):
     raise AnsibleExitJson(kwargs)
 
 
+def fail_json(*args, **kwargs):
+    raise AnsibleFailJson(kwargs)
+
+
 @mock.patch.dict(os.environ, {'CEPH_CONTAINER_BINARY': 'docker'})
 class TestCephKeyModule(object):
 
@@ -373,27 +381,27 @@ class TestCephKeyModule(object):
             fake_cluster, fake_user, fake_user_key, fake_name, fake_container_image)
         assert result == expected_command_list
 
-    def test_info_key_non_container(self):
+    @pytest.mark.parametrize('output_format', ['json', 'plain', 'xml', 'yaml'])
+    def test_info_key_non_container(self, output_format):
         fake_user = 'client.admin'
         fake_user_key = '/etc/ceph/fake.client.admin.keyring'
         fake_cluster = "fake"
         fake_name = "client.fake"
         fake_user = "fake-user"
-        fake_output_format = "json"
         expected_command_list = [
             ['ceph', '-n', fake_user, '-k', fake_user_key, '--cluster', fake_cluster, 'auth',
-                'get', fake_name, '-f', 'json'],
+                'get', fake_name, '-f', output_format],
         ]
         result = ceph_key.info_key(
-            fake_cluster, fake_name, fake_user, fake_user_key, fake_output_format)
+            fake_cluster, fake_name, fake_user, fake_user_key, output_format)
         assert result == expected_command_list
 
-    def test_info_key_container(self):
+    @pytest.mark.parametrize('output_format', ['json', 'plain', 'xml', 'yaml'])
+    def test_info_key_container_json(self, output_format):
         fake_cluster = "fake"
         fake_name = "client.fake"
         fake_user = 'client.admin'
         fake_user_key = '/etc/ceph/fake.client.admin.keyring'
-        fake_output_format = "json"
         fake_container_image = "quay.ceph.io/ceph-ci/daemon:latest-luminous"
         expected_command_list = [['docker',   # noqa E128
                                   'run',
@@ -408,9 +416,9 @@ class TestCephKeyModule(object):
                                   '-k', fake_user_key,
                                   '--cluster', fake_cluster,
                                   'auth', 'get', fake_name,
-                                  '-f', 'json']]
+                                  '-f', output_format]]
         result = ceph_key.info_key(
-            fake_cluster, fake_name, fake_user, fake_user_key, fake_output_format, fake_container_image)  # noqa E501
+            fake_cluster, fake_name, fake_user, fake_user_key, output_format, fake_container_image)  # noqa E501
         assert result == expected_command_list
 
     def test_list_key_non_container(self):
@@ -552,14 +560,16 @@ class TestCephKeyModule(object):
 
     @mock.patch('ansible.module_utils.basic.AnsibleModule.exit_json')
     @mock.patch('ceph_key.exec_commands')
-    def test_state_info(self, m_exec_commands, m_exit_json):
+    @pytest.mark.parametrize('output_format', ['json', 'plain', 'xml', 'yaml'])
+    def test_state_info(self, m_exec_commands, m_exit_json, output_format):
         set_module_args({"state": "info",
                          "cluster": "ceph",
-                         "name": "client.admin"}
+                         "name": "client.admin",
+                         "output_format": output_format}
                         )
         m_exit_json.side_effect = exit_json
         m_exec_commands.return_value = (0,
-                                        ['ceph', 'auth', 'get', 'client.admin', '-f', 'json'],
+                                        ['ceph', 'auth', 'get', 'client.admin', '-f', output_format],
                                         '[{"entity":"client.admin","key":"AQC1tw5fF156GhAAoJCvHGX/jl/k7/N4VZm8iQ==","caps":{"mds":"allow *","mgr":"allow *","mon":"allow *","osd":"allow *"}}]',  # noqa: E501
                                         'exported keyring for client.admin')
 
@@ -568,6 +578,23 @@ class TestCephKeyModule(object):
 
         result = result.value.args[0]
         assert not result['changed']
+        assert result['cmd'] == ['ceph', 'auth', 'get', 'client.admin', '-f', output_format]
         assert result['stdout'] == '[{"entity":"client.admin","key":"AQC1tw5fF156GhAAoJCvHGX/jl/k7/N4VZm8iQ==","caps":{"mds":"allow *","mgr":"allow *","mon":"allow *","osd":"allow *"}}]'  # noqa: E501
         assert result['stderr'] == 'exported keyring for client.admin'
         assert result['rc'] == 0
+
+    @mock.patch('ansible.module_utils.basic.AnsibleModule.fail_json')
+    def test_state_info_invalid_format(self, m_fail_json):
+        invalid_format = 'txt'
+        set_module_args({"state": "info",
+                         "cluster": "ceph",
+                         "name": "client.admin",
+                         "output_format": invalid_format}
+                        )
+        m_fail_json.side_effect = fail_json
+
+        with pytest.raises(AnsibleFailJson) as result:
+            ceph_key.run_module()
+
+        result = result.value.args[0]
+        assert result['msg'] == 'value of output_format must be one of: json, plain, xml, yaml, got: {}'.format(invalid_format)