]> git.apps.os.sepia.ceph.com Git - ceph-ansible.git/commitdiff
ceph_osd_flag: support setting noout flag at osd or bucket level
authorGuillaume Abrioux <gabrioux@redhat.com>
Wed, 16 Dec 2020 08:47:36 +0000 (09:47 +0100)
committerGuillaume Abrioux <gabrioux@redhat.com>
Wed, 6 Jul 2022 01:38:35 +0000 (03:38 +0200)
Currently `ceph_osd_flag` module only supports setting `noout` flag at
the cluster level.
Ceph supports setting this flag at the osd or the bucket level so let's
implement this support in `ceph_osd_flag` module.

Signed-off-by: Guillaume Abrioux <gabrioux@redhat.com>
library/ceph_osd_flag.py
tests/library/test_ceph_osd_flag.py

index 1e6fe961192714f48d401125c13fa9f76c73f5d0..311ee253cceac3c3660a5661af10e4fdeaff3971 100644 (file)
@@ -45,8 +45,25 @@ options:
         description:
             - name of the ceph OSD flag.
         required: true
-        choices: ['noup', 'nodown', 'noout', 'nobackfill', 'norebalance',
-                 'norecover', 'noscrub', 'nodeep-scrub']
+        choices: ['noup', 'nodown', 'noout', 'nobackfill', 'norebalance', 'norecover', 'noscrub', 'nodeep-scrub']
+    level:
+        description:
+            - This is applicable only when 'name' is 'noout'.
+              This flag can be applied at several levels:
+              1/ at the whole cluster level
+              2/ at the bucket level
+              3/ at the osd.X level
+        required: false
+        choices: ['osd', 'bucket', 'cluster']
+        default: 'cluster'
+    osd:
+        description:
+            - pass the osd when 'level' is 'osd'
+        required: false
+    bucket:
+        description:
+            - pass the bucket name when 'level' is 'bucket'
+        required: false
     cluster:
         description:
             - The ceph cluster name.
@@ -75,6 +92,19 @@ EXAMPLES = '''
   loop:
     - 'noup'
     - 'norebalance'
+
+- name: set noup flag on osd.123
+  ceph_osd_flag:
+    name: noup
+    level: osd
+    osd: osd.123
+
+- name: unset noup flag on bucket 'host-456'
+  ceph_osd_flag:
+    state: absent
+    name: noup
+    level: bucket
+    bucket: host-456
 '''
 
 RETURN = '''#  '''
@@ -84,13 +114,23 @@ def main():
     module = AnsibleModule(
         argument_spec=dict(
             name=dict(type='str', required=True, choices=['noup', 'nodown', 'noout', 'nobackfill', 'norebalance', 'norecover', 'noscrub', 'nodeep-scrub']),  # noqa: E501
+            level=dict(type='str', required=False, default='cluster', choices=['cluster', 'bucket', 'osd']),
+            osd=dict(type='str', required=False),
+            bucket=dict(type='str', required=False),
             cluster=dict(type='str', required=False, default='ceph'),
             state=dict(type='str', required=False, default='present', choices=['present', 'absent']),  # noqa: E501
         ),
         supports_check_mode=True,
+        required_if=[
+            ['level', 'osd', ['osd']],
+            ['level', 'bucket', ['bucket']]
+            ]
     )
 
     name = module.params.get('name')
+    level = module.params.get('level')
+    osd = module.params.get('osd')
+    bucket = module.params.get('bucket')
     cluster = module.params.get('cluster')
     state = module.params.get('state')
 
@@ -98,10 +138,20 @@ def main():
 
     container_image = is_containerized()
 
-    if state == 'present':
-        cmd = generate_ceph_cmd(['osd', 'set'], [name], cluster=cluster, container_image=container_image)  # noqa: E501
+    osd_sub_cmd = ['osd']
+    if name == 'noout' and level in ['osd', 'bucket']:
+        if level == 'osd':
+            action = ['add-noout'] if state == 'present' else ['rm-noout']
+            name = osd
+        if level == 'bucket':
+            action = ['set-group', 'noout'] if state == 'present' else ['unset-group', 'noout']
+            name = bucket
+        osd_sub_cmd.extend(action)
+
     else:
-        cmd = generate_ceph_cmd(['osd', 'unset'], [name], cluster=cluster, container_image=container_image)  # noqa: E501
+        osd_sub_cmd.extend(['set']) if state == 'present' else osd_sub_cmd.extend(['unset'])
+
+    cmd = generate_ceph_cmd(osd_sub_cmd, [name], cluster=cluster, container_image=container_image)
 
     if module.check_mode:
         exit_module(
index 5f99f1e2f7778dad9c5d5f2646e62b213d7b7b2d..93b84274f1f2e126364b90baafe9d60831678007 100644 (file)
@@ -154,3 +154,80 @@ class TestCephOSDFlagModule(object):
         assert result['rc'] == rc
         assert result['stderr'] == stderr
         assert result['stdout'] == stdout
+
+    @patch('ansible.module_utils.basic.AnsibleModule.exit_json')
+    @patch('ansible.module_utils.basic.AnsibleModule.run_command')
+    @pytest.mark.parametrize('state', ['present', 'absent'])
+    def test_flag_noout_osd_level(self, m_run_command, m_exit_json, state):
+        ca_test_common.set_module_args({
+            'name': 'noout',
+            'state': state,
+            'level': 'osd',
+            'osd': 'osd.123'
+        })
+        m_exit_json.side_effect = ca_test_common.exit_json
+        stdout = ''
+        stderr = ''
+        rc = 0
+        m_run_command.return_value = rc, stdout, stderr
+
+        with pytest.raises(ca_test_common.AnsibleExitJson) as result:
+            ceph_osd_flag.main()
+
+        result = result.value.args[0]
+
+        assert result['cmd'] == ['ceph', '-n', 'client.admin', '-k', '/etc/ceph/ceph.client.admin.keyring',
+                                 '--cluster', 'ceph', 'osd', 'add-noout' if state == 'present' else 'rm-noout', 'osd.123']
+        assert result['rc'] == rc
+        assert result['stderr'] == ''
+        assert result['stdout'] == ''
+
+    @patch('ansible.module_utils.basic.AnsibleModule.exit_json')
+    @patch('ansible.module_utils.basic.AnsibleModule.run_command')
+    @pytest.mark.parametrize('state', ['present', 'absent'])
+    def test_flag_noout_bucket_level(self, m_run_command, m_exit_json, state):
+        ca_test_common.set_module_args({
+            'name': 'noout',
+            'state': state,
+            'level': 'bucket',
+            'bucket': 'my_osd_host_123'
+        })
+        m_exit_json.side_effect = ca_test_common.exit_json
+        stdout = ''
+        stderr = ''
+        rc = 0
+        m_run_command.return_value = rc, stdout, stderr
+
+        with pytest.raises(ca_test_common.AnsibleExitJson) as result:
+            ceph_osd_flag.main()
+
+        result = result.value.args[0]
+        assert result['cmd'] == ['ceph', '-n', 'client.admin', '-k', '/etc/ceph/ceph.client.admin.keyring',
+                                 '--cluster', 'ceph', 'osd', 'set-group' if state == 'present' else 'unset-group', 'noout', 'my_osd_host_123']
+        assert result['rc'] == rc
+        assert result['stderr'] == ''
+        assert result['stdout'] == ''
+
+    @patch('ansible.module_utils.basic.AnsibleModule.exit_json')
+    @patch('ansible.module_utils.basic.AnsibleModule.run_command')
+    @pytest.mark.parametrize('state', ['present', 'absent'])
+    def test_flag_noout_cluster_level(self, m_run_command, m_exit_json, state):
+        ca_test_common.set_module_args({
+            'name': 'noout',
+            'state': state
+        })
+        m_exit_json.side_effect = ca_test_common.exit_json
+        stdout = ''
+        stderr = ''
+        rc = 0
+        m_run_command.return_value = rc, stdout, stderr
+
+        with pytest.raises(ca_test_common.AnsibleExitJson) as result:
+            ceph_osd_flag.main()
+
+        result = result.value.args[0]
+        assert result['cmd'] == ['ceph', '-n', 'client.admin', '-k', '/etc/ceph/ceph.client.admin.keyring',
+                                 '--cluster', 'ceph', 'osd', 'set' if state == 'present' else 'unset', 'noout']
+        assert result['rc'] == rc
+        assert result['stderr'] == ''
+        assert result['stdout'] == ''