Commit eaf0ebfc authored by Dimitri Savineau's avatar Dimitri Savineau Committed by Guillaume Abrioux
Browse files

library: add ceph_mgr_module module



This adds ceph_mgr_module ansible module for replacing the command module
usage with the ceph mgr module enable/disable commands.
Signed-off-by: default avatarDimitri Savineau <dsavinea@redhat.com>
parent c610a1b4
......@@ -184,8 +184,13 @@
fsid: "{{ (current_fsid.stdout | from_json).fsid }}"
- name: enable cephadm mgr module
command: "{{ container_exec_cmd | default('') }} ceph --cluster {{ cluster }} mgr module enable cephadm"
changed_when: false
ceph_mgr_module:
name: cephadm
cluster: "{{ cluster }}"
state: enable
environment:
CEPH_CONTAINER_IMAGE: "{{ ceph_docker_registry + '/' + ceph_docker_image + ':' + ceph_docker_image_tag if containerized_deployment | bool else None }}"
CEPH_CONTAINER_BINARY: "{{ container_binary }}"
run_once: true
delegate_to: '{{ groups[mon_group_name][0] }}'
......
# Copyright 2020, Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from ansible.module_utils.basic import AnsibleModule
try:
from ansible.module_utils.ca_common import exit_module, generate_ceph_cmd, is_containerized
except ImportError:
from module_utils.ca_common import exit_module, generate_ceph_cmd, is_containerized
import datetime
ANSIBLE_METADATA = {
'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'
}
DOCUMENTATION = '''
---
module: ceph_mgr_module
short_description: Manage Ceph MGR module
version_added: "2.8"
description:
- Manage Ceph MGR module
options:
name:
description:
- name of the ceph MGR module.
required: true
cluster:
description:
- The ceph cluster name.
required: false
default: ceph
state:
description:
- If 'enable' is used, the module enables the MGR module.
If 'absent' is used, the module disables the MGR module.
required: false
choices: ['enable', 'disable']
default: enable
author:
- Dimitri Savineau <dsavinea@redhat.com>
'''
EXAMPLES = '''
- name: enable dashboard mgr module
ceph_mgr_module:
name: dashboard
state: enable
- name: disable multiple mgr modules
ceph_mgr_module:
name: '{{ item }}'
state: disable
loop:
- 'dashboard'
- 'prometheus'
'''
RETURN = '''# '''
def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(type='str', required=True),
cluster=dict(type='str', required=False, default='ceph'),
state=dict(type='str', required=False, default='enable', choices=['enable', 'disable']),
),
supports_check_mode=True,
)
name = module.params.get('name')
cluster = module.params.get('cluster')
state = module.params.get('state')
startd = datetime.datetime.now()
container_image = is_containerized()
cmd = generate_ceph_cmd(['mgr', 'module'], [state, name], cluster=cluster, container_image=container_image)
if module.check_mode:
exit_module(
module=module,
out='',
rc=0,
cmd=cmd,
err='',
startd=startd,
changed=False
)
else:
rc, out, err = module.run_command(cmd)
if out == "module '{}' is already enabled".format(name):
changed = False
else:
changed = True
exit_module(
module=module,
out=out,
rc=rc,
cmd=cmd,
err=err,
startd=startd,
changed=changed
)
if __name__ == '__main__':
main()
......@@ -110,16 +110,26 @@
dashboard_backend: '{{ item }}'
- name: disable mgr dashboard module (restart)
command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} mgr module disable dashboard"
ceph_mgr_module:
name: dashboard
cluster: "{{ cluster }}"
state: disable
environment:
CEPH_CONTAINER_IMAGE: "{{ ceph_docker_registry + '/' + ceph_docker_image + ':' + ceph_docker_image_tag if containerized_deployment | bool else None }}"
CEPH_CONTAINER_BINARY: "{{ container_binary }}"
delegate_to: "{{ groups[mon_group_name][0] }}"
run_once: true
changed_when: false
- name: enable mgr dashboard module (restart)
command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} mgr module enable dashboard"
ceph_mgr_module:
name: dashboard
cluster: "{{ cluster }}"
state: enable
environment:
CEPH_CONTAINER_IMAGE: "{{ ceph_docker_registry + '/' + ceph_docker_image + ':' + ceph_docker_image_tag if containerized_deployment | bool else None }}"
CEPH_CONTAINER_BINARY: "{{ container_binary }}"
delegate_to: "{{ groups[mon_group_name][0] }}"
run_once: true
changed_when: false
- name: create dashboard admin user
ceph_dashboard_user:
......@@ -270,13 +280,23 @@
when: ip_version == 'ipv6'
- name: disable mgr dashboard module (restart)
command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} mgr module disable dashboard"
changed_when: false
ceph_mgr_module:
name: dashboard
cluster: "{{ cluster }}"
state: disable
environment:
CEPH_CONTAINER_IMAGE: "{{ ceph_docker_registry + '/' + ceph_docker_image + ':' + ceph_docker_image_tag if containerized_deployment | bool else None }}"
CEPH_CONTAINER_BINARY: "{{ container_binary }}"
delegate_to: "{{ groups[mon_group_name][0] }}"
run_once: true
- name: enable mgr dashboard module (restart)
command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} mgr module enable dashboard"
changed_when: false
ceph_mgr_module:
name: dashboard
cluster: "{{ cluster }}"
state: enable
environment:
CEPH_CONTAINER_IMAGE: "{{ ceph_docker_registry + '/' + ceph_docker_image + ':' + ceph_docker_image_tag if containerized_deployment | bool else None }}"
CEPH_CONTAINER_BINARY: "{{ container_binary }}"
delegate_to: "{{ groups[mon_group_name][0] }}"
run_once: true
......@@ -32,13 +32,25 @@
_disabled_ceph_mgr_modules: "{% if _ceph_mgr_modules.disabled_modules | length == 0 %}[]{% elif _ceph_mgr_modules.disabled_modules[0] | type_debug != 'dict' %}{{ _ceph_mgr_modules['disabled_modules'] }}{% else %}{{ _ceph_mgr_modules['disabled_modules'] | map(attribute='name') | list }}{% endif %}"
- name: disable ceph mgr enabled modules
command: "{{ hostvars[groups[mon_group_name][0]]['container_exec_cmd'] | default('') }} ceph --cluster {{ cluster }} mgr module disable {{ item }}"
ceph_mgr_module:
name: "{{ item }}"
cluster: "{{ cluster }}"
state: disable
environment:
CEPH_CONTAINER_IMAGE: "{{ ceph_docker_registry + '/' + ceph_docker_image + ':' + ceph_docker_image_tag if containerized_deployment | bool else None }}"
CEPH_CONTAINER_BINARY: "{{ container_binary }}"
with_items: "{{ _ceph_mgr_modules.get('enabled_modules', []) }}"
delegate_to: "{{ groups[mon_group_name][0] }}"
when: item not in ceph_mgr_modules
- name: add modules to ceph-mgr
command: "{{ hostvars[groups[mon_group_name][0]]['container_exec_cmd'] | default('') }} ceph --cluster {{ cluster }} mgr module enable {{ item }}"
ceph_mgr_module:
name: "{{ item }}"
cluster: "{{ cluster }}"
state: enable
environment:
CEPH_CONTAINER_IMAGE: "{{ ceph_docker_registry + '/' + ceph_docker_image + ':' + ceph_docker_image_tag if containerized_deployment | bool else None }}"
CEPH_CONTAINER_BINARY: "{{ container_binary }}"
with_items: "{{ ceph_mgr_modules }}"
delegate_to: "{{ groups[mon_group_name][0] }}"
when: (item in _disabled_ceph_mgr_modules or _disabled_ceph_mgr_modules == [])
from mock.mock import patch
import os
import pytest
import ca_test_common
import ceph_mgr_module
fake_cluster = 'ceph'
fake_container_binary = 'podman'
fake_container_image = 'quay.ceph.io/ceph/daemon:latest'
fake_module = 'noup'
fake_user = 'client.admin'
fake_keyring = '/etc/ceph/{}.{}.keyring'.format(fake_cluster, fake_user)
class TestCephMgrModuleModule(object):
@patch('ansible.module_utils.basic.AnsibleModule.fail_json')
def test_without_parameters(self, m_fail_json):
ca_test_common.set_module_args({})
m_fail_json.side_effect = ca_test_common.fail_json
with pytest.raises(ca_test_common.AnsibleFailJson) as result:
ceph_mgr_module.main()
result = result.value.args[0]
assert result['msg'] == 'missing required arguments: name'
@patch('ansible.module_utils.basic.AnsibleModule.exit_json')
def test_with_check_mode(self, m_exit_json):
ca_test_common.set_module_args({
'name': fake_module,
'_ansible_check_mode': True
})
m_exit_json.side_effect = ca_test_common.exit_json
with pytest.raises(ca_test_common.AnsibleExitJson) as result:
ceph_mgr_module.main()
result = result.value.args[0]
assert not result['changed']
assert result['cmd'] == ['ceph', '-n', fake_user, '-k', fake_keyring, '--cluster', fake_cluster, 'mgr', 'module', 'enable', fake_module]
assert result['rc'] == 0
assert not result['stdout']
assert not result['stderr']
@patch('ansible.module_utils.basic.AnsibleModule.exit_json')
@patch('ansible.module_utils.basic.AnsibleModule.run_command')
def test_with_failure(self, m_run_command, m_exit_json):
ca_test_common.set_module_args({
'name': fake_module
})
m_exit_json.side_effect = ca_test_common.exit_json
stdout = ''
stderr = 'Error ENOENT: all mgr daemons do not support module \'{}\', pass --force to force enablement'.format(fake_module)
rc = 2
m_run_command.return_value = rc, stdout, stderr
with pytest.raises(ca_test_common.AnsibleExitJson) as result:
ceph_mgr_module.main()
result = result.value.args[0]
assert result['changed']
assert result['cmd'] == ['ceph', '-n', fake_user, '-k', fake_keyring, '--cluster', fake_cluster, 'mgr', 'module', 'enable', fake_module]
assert result['rc'] == rc
assert result['stderr'] == stderr
@patch('ansible.module_utils.basic.AnsibleModule.exit_json')
@patch('ansible.module_utils.basic.AnsibleModule.run_command')
def test_enable_module(self, m_run_command, m_exit_json):
ca_test_common.set_module_args({
'name': fake_module,
})
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_mgr_module.main()
result = result.value.args[0]
assert result['changed']
assert result['cmd'] == ['ceph', '-n', fake_user, '-k', fake_keyring, '--cluster', fake_cluster, 'mgr', 'module', 'enable', fake_module]
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')
def test_already_enable_module(self, m_run_command, m_exit_json):
ca_test_common.set_module_args({
'name': fake_module,
})
m_exit_json.side_effect = ca_test_common.exit_json
stdout = 'module \'{}\' is already enabled'.format(fake_module)
stderr = ''
rc = 0
m_run_command.return_value = rc, stdout, stderr
with pytest.raises(ca_test_common.AnsibleExitJson) as result:
ceph_mgr_module.main()
result = result.value.args[0]
assert not result['changed']
assert result['cmd'] == ['ceph', '-n', fake_user, '-k', fake_keyring, '--cluster', fake_cluster, 'mgr', 'module', 'enable', fake_module]
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')
def test_disable_module(self, m_run_command, m_exit_json):
ca_test_common.set_module_args({
'name': fake_module,
'state': 'disable'
})
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_mgr_module.main()
result = result.value.args[0]
assert result['changed']
assert result['cmd'] == ['ceph', '-n', fake_user, '-k', fake_keyring, '--cluster', fake_cluster, 'mgr', 'module', 'disable', fake_module]
assert result['rc'] == rc
assert result['stderr'] == stderr
assert result['stdout'] == stdout
@patch.dict(os.environ, {'CEPH_CONTAINER_BINARY': fake_container_binary})
@patch.dict(os.environ, {'CEPH_CONTAINER_IMAGE': fake_container_image})
@patch('ansible.module_utils.basic.AnsibleModule.exit_json')
@patch('ansible.module_utils.basic.AnsibleModule.run_command')
def test_with_container(self, m_run_command, m_exit_json):
ca_test_common.set_module_args({
'name': fake_module,
})
m_exit_json.side_effect = ca_test_common.exit_json
stdout = ''
stderr = '{} is set'.format(fake_module)
rc = 0
m_run_command.return_value = rc, stdout, stderr
with pytest.raises(ca_test_common.AnsibleExitJson) as result:
ceph_mgr_module.main()
result = result.value.args[0]
assert result['changed']
assert result['cmd'] == [fake_container_binary, 'run', '--rm', '--net=host',
'-v', '/etc/ceph:/etc/ceph:z',
'-v', '/var/lib/ceph/:/var/lib/ceph/:z',
'-v', '/var/log/ceph/:/var/log/ceph/:z',
'--entrypoint=ceph', fake_container_image,
'-n', fake_user, '-k', fake_keyring,
'--cluster', fake_cluster, 'mgr', 'module', 'enable', fake_module]
assert result['rc'] == rc
assert result['stderr'] == stderr
assert result['stdout'] == stdout
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment