mirror of https://github.com/ceph/ceph-ansible.git
mon: refact initial keyring generation
adding monitor is no longer possible because we generate a new mon
keyring each time the playbook is run.
Fixes: #5864
Closes: https://bugzilla.redhat.com/show_bug.cgi?id=1902281
Signed-off-by: Guillaume Abrioux <gabrioux@redhat.com>
(cherry picked from commit 970c6a4ee6
)
4.2rc
v4.0.41
parent
f917bb015c
commit
d14723d5b4
|
@ -68,6 +68,9 @@
|
||||||
name: ceph-config
|
name: ceph-config
|
||||||
- import_role:
|
- import_role:
|
||||||
name: ceph-mon
|
name: ceph-mon
|
||||||
|
- import_role:
|
||||||
|
name: ceph-crash
|
||||||
|
when: containerized_deployment | bool
|
||||||
|
|
||||||
# update config files on OSD nodes
|
# update config files on OSD nodes
|
||||||
- hosts: osds
|
- hosts: osds
|
||||||
|
|
|
@ -70,8 +70,9 @@ options:
|
||||||
return a json output.
|
return a json output.
|
||||||
If 'info' is used, the module will return in a json format the
|
If 'info' is used, the module will return in a json format the
|
||||||
description of a given keyring.
|
description of a given keyring.
|
||||||
|
If 'generate_secret' is used, the module will simply output a cephx keyring.
|
||||||
required: false
|
required: false
|
||||||
choices: ['present', 'update', 'absent', 'list', 'info', 'fetch_initial_keys']
|
choices: ['present', 'update', 'absent', 'list', 'info', 'fetch_initial_keys', 'generate_secret']
|
||||||
default: present
|
default: present
|
||||||
caps:
|
caps:
|
||||||
description:
|
description:
|
||||||
|
@ -506,7 +507,8 @@ def run_module():
|
||||||
module_args = dict(
|
module_args = dict(
|
||||||
cluster=dict(type='str', required=False, default='ceph'),
|
cluster=dict(type='str', required=False, default='ceph'),
|
||||||
name=dict(type='str', required=False),
|
name=dict(type='str', required=False),
|
||||||
state=dict(type='str', required=False, default='present', choices=['present', 'update', 'absent', 'list', 'info', 'fetch_initial_keys']),
|
state=dict(type='str', required=False, default='present', choices=['present', 'update', 'absent',
|
||||||
|
'list', 'info', 'fetch_initial_keys', 'generate_secret']),
|
||||||
caps=dict(type='dict', required=False, default=None),
|
caps=dict(type='dict', required=False, default=None),
|
||||||
secret=dict(type='str', required=False, default=None, no_log=True),
|
secret=dict(type='str', required=False, default=None, no_log=True),
|
||||||
import_key=dict(type='bool', required=False, default=True),
|
import_key=dict(type='bool', required=False, default=True),
|
||||||
|
@ -692,9 +694,12 @@ def run_module():
|
||||||
file_args = module.load_file_common_arguments(module.params)
|
file_args = module.load_file_common_arguments(module.params)
|
||||||
file_args['path'] = key_path
|
file_args['path'] = key_path
|
||||||
module.set_fs_attributes_if_different(file_args, False)
|
module.set_fs_attributes_if_different(file_args, False)
|
||||||
else:
|
elif state == "generate_secret":
|
||||||
module.fail_json(
|
out = generate_secret().decode()
|
||||||
msg='State must either be "present" or "absent" or "list" or "info" or "fetch_initial_keys".', changed=False, rc=1) # noqa E501
|
cmd = ''
|
||||||
|
rc = 0
|
||||||
|
err = ''
|
||||||
|
changed = True
|
||||||
|
|
||||||
endd = datetime.datetime.now()
|
endd = datetime.datetime.now()
|
||||||
delta = endd - startd
|
delta = endd - startd
|
||||||
|
|
|
@ -1,31 +1,31 @@
|
||||||
---
|
---
|
||||||
- name: check if monitor initial keyring already exists
|
- name: check if monitor initial keyring already exists
|
||||||
command: >
|
ceph_key:
|
||||||
{{ _container_exec_cmd | default('') }} ceph --cluster {{ cluster }} --name mon. -k
|
name: mon.
|
||||||
/var/lib/ceph/mon/{{ cluster }}-{{ hostvars[groups[mon_group_name][0] if running_mon is undefined else running_mon]['ansible_hostname'] }}/keyring
|
cluster: "{{ cluster }}"
|
||||||
auth get-key mon.
|
user: mon.
|
||||||
|
user_key: "/var/lib/ceph/mon/{{ cluster }}-{{ hostvars[running_mon]['ansible_hostname'] }}/keyring"
|
||||||
|
state: info
|
||||||
|
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 }}"
|
||||||
register: initial_mon_key
|
register: initial_mon_key
|
||||||
run_once: True
|
run_once: True
|
||||||
delegate_to: "{{ groups[mon_group_name][0] if running_mon is undefined else running_mon }}"
|
delegate_to: "{{ running_mon }}"
|
||||||
when: ceph_current_status.fsid is defined
|
when: running_mon is defined
|
||||||
|
|
||||||
- name: generate monitor initial keyring
|
- name: generate monitor initial keyring
|
||||||
command: >
|
ceph_key:
|
||||||
{{ hostvars[groups[mon_group_name][0] if running_mon is undefined else running_mon]['discovered_interpreter_python'] }} -c "import os ; import struct ;
|
state: generate_secret
|
||||||
import time; import base64 ; key = os.urandom(16) ;
|
|
||||||
header = struct.pack('<hiih',1,int(time.time()),0,len(key)) ;
|
|
||||||
print(base64.b64encode(header + key).decode())"
|
|
||||||
register: monitor_keyring
|
register: monitor_keyring
|
||||||
run_once: True
|
delegate_to: localhost
|
||||||
delegate_to: "{{ groups[mon_group_name][0] if running_mon is undefined else running_mon }}"
|
run_once: true
|
||||||
when:
|
when:
|
||||||
- initial_mon_key.skipped is defined
|
- initial_mon_key.skipped is defined
|
||||||
- ceph_current_status.fsid is undefined
|
|
||||||
|
|
||||||
- name: get initial keyring when it already exists
|
- name: get initial keyring when it already exists
|
||||||
set_fact:
|
set_fact:
|
||||||
monitor_keyring: "{{ initial_mon_key.stdout if monitor_keyring.skipped is defined else monitor_keyring.stdout if initial_mon_key.skipped is defined }}"
|
monitor_keyring: "{{ (initial_mon_key.stdout | from_json)[0]['key'] if initial_mon_key is not skipped else monitor_keyring.stdout }}"
|
||||||
when: initial_mon_key is not skipped or monitor_keyring is not skipped
|
|
||||||
|
|
||||||
- name: create monitor initial keyring
|
- name: create monitor initial keyring
|
||||||
ceph_key:
|
ceph_key:
|
||||||
|
|
|
@ -571,3 +571,15 @@ class TestCephKeyModule(object):
|
||||||
assert result['stdout'] == '[{"entity":"client.admin","key":"AQC1tw5fF156GhAAoJCvHGX/jl/k7/N4VZm8iQ==","caps":{"mds":"allow *","mgr":"allow *","mon":"allow *","osd":"allow *"}}]' # noqa: E501
|
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['stderr'] == 'exported keyring for client.admin'
|
||||||
assert result['rc'] == 0
|
assert result['rc'] == 0
|
||||||
|
|
||||||
|
@mock.patch('ceph_key.generate_secret')
|
||||||
|
@mock.patch('ansible.module_utils.basic.AnsibleModule.exit_json')
|
||||||
|
def test_generate_key(self, m_exit_json, m_generate_secret):
|
||||||
|
fake_secret = b'AQDaLb1fAAAAABAAsIMKdGEKu+lGOyXnRfT0Hg=='
|
||||||
|
set_module_args({"state": "generate_secret"})
|
||||||
|
m_exit_json.side_effect = exit_json
|
||||||
|
m_generate_secret.return_value = fake_secret
|
||||||
|
|
||||||
|
with pytest.raises(AnsibleExitJson) as result:
|
||||||
|
ceph_key.run_module()
|
||||||
|
assert result.value.args[0]['stdout'] == fake_secret.decode()
|
||||||
|
|
Loading…
Reference in New Issue