dashboard: manage password backward compatibility

The ceph dashboard changed the way the password are provided via the
CLI.
This breaks the backward compatibility when using a recent ceph-ansible
version with ceph release without that feature.
This patch adds tasks for legacy workflow (ceph release without that
feature) in both ceph-dashboard role and ceph_dashboard_user module.

Signed-off-by: Dimitri Savineau <dsavinea@redhat.com>
pull/6210/head
Dimitri Savineau 2021-01-11 11:48:53 -05:00 committed by Dimitri Savineau
parent fb03dfda30
commit fdda54eeb4
3 changed files with 149 additions and 26 deletions

View File

@ -61,7 +61,11 @@ options:
- roles of the Ceph Dashboard user.
required: false
default: []
interactive:
description:
- use password from file or stdin
required: false
default: True
author:
- Dimitri Savineau <dsavinea@redhat.com>
'''
@ -187,10 +191,15 @@ def create_user(module, container_image=None):
cluster = module.params.get('cluster')
name = module.params.get('name')
interactive = module.params.get('interactive')
args = ['ac-user-create', '-i', '-', name]
if interactive:
args = ['ac-user-create', '-i', '-', name]
else:
password = module.params.get('password')
args = ['ac-user-create', name, password]
cmd = generate_ceph_cmd(cluster=cluster, args=args, container_image=container_image, interactive=True)
cmd = generate_ceph_cmd(cluster=cluster, args=args, container_image=container_image, interactive=interactive)
return cmd
@ -220,10 +229,15 @@ def set_password(module, container_image=None):
cluster = module.params.get('cluster')
name = module.params.get('name')
interactive = module.params.get('interactive')
args = ['ac-user-set-password', '-i', '-', name]
if interactive:
args = ['ac-user-set-password', '-i', '-', name]
else:
password = module.params.get('password')
args = ['ac-user-set-password', name, password]
cmd = generate_ceph_cmd(cluster=cluster, args=args, container_image=container_image, interactive=True)
cmd = generate_ceph_cmd(cluster=cluster, args=args, container_image=container_image, interactive=interactive)
return cmd
@ -285,6 +299,7 @@ def run_module():
required=False,
choices=['administrator', 'read-only', 'block-manager', 'rgw-manager', 'cluster-manager', 'pool-manager', 'cephfs-manager'],
default=[]),
interactive=dict(type='bool', required=False, default=True),
)
module = AnsibleModule(
@ -298,6 +313,7 @@ def run_module():
state = module.params.get('state')
roles = module.params.get('roles')
password = module.params.get('password')
interactive = module.params.get('interactive')
if module.check_mode:
module.exit_json(
@ -318,6 +334,9 @@ def run_module():
if state == "present":
rc, cmd, out, err = exec_commands(module, get_user(module, container_image=container_image))
stdin = password
if not interactive:
stdin = None
if rc == 0:
user = json.loads(out)
user['roles'].sort()
@ -325,9 +344,9 @@ def run_module():
if user['roles'] != roles:
rc, cmd, out, err = exec_commands(module, set_roles(module, container_image=container_image))
changed = True
rc, cmd, out, err = exec_commands(module, set_password(module, container_image=container_image), stdin=password)
rc, cmd, out, err = exec_commands(module, set_password(module, container_image=container_image), stdin=stdin)
else:
rc, cmd, out, err = exec_commands(module, create_user(module, container_image=container_image), stdin=password)
rc, cmd, out, err = exec_commands(module, create_user(module, container_image=container_image), stdin=stdin)
rc, cmd, out, err = exec_commands(module, set_roles(module, container_image=container_image))
changed = True

View File

@ -125,12 +125,26 @@
run_once: true
changed_when: false
- name: check dashboard password in file option command
command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} dashboard ac-user-set-password"
delegate_to: "{{ groups[mon_group_name][0] }}"
run_once: true
changed_when: false
failed_when: false
register: dashboard_password_in_file_option
- name: set_fact dashboard_password_from_stdin
set_fact:
dashboard_password_from_stdin: "{{ ' -i ' in dashboard_password_in_file_option.stderr }}"
run_once: true
- name: create dashboard admin user
ceph_dashboard_user:
name: "{{ dashboard_admin_user }}"
cluster: "{{ cluster }}"
password: "{{ dashboard_admin_password }}"
roles: ["{{ 'read-only' if dashboard_admin_user_ro | bool else 'administrator' }}"]
interactive: "{{ dashboard_password_from_stdin }}"
run_once: true
delegate_to: "{{ groups[mon_group_name][0] }}"
environment:
@ -151,6 +165,14 @@
delegate_to: "{{ groups[mon_group_name][0] }}"
run_once: true
changed_when: false
when: dashboard_password_from_stdin | bool
- name: set grafana api password (legacy)
command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} dashboard set-grafana-api-password {{ grafana_admin_password }}"
delegate_to: "{{ groups[mon_group_name][0] }}"
run_once: true
changed_when: false
when: not dashboard_password_from_stdin | bool
- name: disable ssl verification for grafana
command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} dashboard set-grafana-api-ssl-verify False"
@ -218,6 +240,13 @@
stdin_add_newline: no
delegate_to: "{{ groups[mon_group_name][0] }}"
changed_when: false
when: dashboard_password_from_stdin | bool
- name: set the rgw access key (legacy)
command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} dashboard set-rgw-api-access-key {{ rgw_access_key }}"
delegate_to: "{{ groups[mon_group_name][0] }}"
changed_when: false
when: not dashboard_password_from_stdin | bool
- name: set the rgw secret key
command: "{{ ceph_cmd }} --cluster {{ cluster }} dashboard set-rgw-api-secret-key -i -"
@ -226,6 +255,13 @@
stdin_add_newline: no
delegate_to: "{{ groups[mon_group_name][0] }}"
changed_when: false
when: dashboard_password_from_stdin | bool
- name: set the rgw secret key (legacy)
command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} dashboard set-rgw-api-secret-key {{ rgw_secret_key }}"
delegate_to: "{{ groups[mon_group_name][0] }}"
changed_when: false
when: not dashboard_password_from_stdin | bool
- name: set the rgw host
command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} dashboard set-rgw-api-host {{ hostvars[groups[rgw_group_name][0]]['rgw_instances'][0]['radosgw_address'] }}"
@ -276,7 +312,18 @@
changed_when: false
delegate_to: "{{ groups[mon_group_name][0] }}"
with_items: "{{ groups[iscsi_gw_group_name] }}"
when: ip_version == 'ipv4'
when:
- ip_version == 'ipv4'
- dashboard_password_from_stdin | bool
- name: add iscsi gateways - ipv4 (legacy)
command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} dashboard iscsi-gateway-add {{ 'https' if hostvars[item]['api_secure'] | default(false) | bool else 'http' }}://{{ hostvars[item]['api_user'] | default('admin') }}:{{ hostvars[item]['api_password'] | default('admin') }}@{{ hostvars[item]['ansible_all_ipv4_addresses'] | ips_in_ranges(public_network.split(',')) | first }}:{{ hostvars[item]['api_port'] | default(5000) }}"
changed_when: false
delegate_to: "{{ groups[mon_group_name][0] }}"
with_items: "{{ groups[iscsi_gw_group_name] }}"
when:
- ip_version == 'ipv4'
- not dashboard_password_from_stdin | bool
- name: add iscsi gateways - ipv6
command: "{{ ceph_cmd }} --cluster {{ cluster }} dashboard iscsi-gateway-add -i -"
@ -286,7 +333,18 @@
changed_when: false
delegate_to: "{{ groups[mon_group_name][0] }}"
with_items: "{{ groups[iscsi_gw_group_name] }}"
when: ip_version == 'ipv6'
when:
- ip_version == 'ipv6'
- dashboard_password_from_stdin | bool
- name: add iscsi gateways - ipv6 (legacy)
command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} dashboard iscsi-gateway-add {{ 'https' if hostvars[item]['api_secure'] | default(false) | bool else 'http' }}://{{ hostvars[item]['api_user'] | default('admin') }}:{{ hostvars[item]['api_password'] | default('admin') }}@{{ hostvars[item]['ansible_all_ipv6_addresses'] | ips_in_ranges(public_network.split(',')) | last | ipwrap }}:{{ hostvars[item]['api_port'] | default(5000) }}"
changed_when: false
delegate_to: "{{ groups[mon_group_name][0] }}"
with_items: "{{ groups[iscsi_gw_group_name] }}"
when:
- ip_version == 'ipv6'
- not dashboard_password_from_stdin | bool
- name: disable mgr dashboard module (restart)
command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} mgr module disable dashboard"

View File

@ -91,26 +91,41 @@ class TestCephDashboardUserModule(object):
])
assert ceph_dashboard_user.generate_ceph_cmd(self.fake_cluster, [], image) == expected_cmd
def test_create_user(self):
@pytest.mark.parametrize('interactive', [True, False])
def test_create_user(self, interactive):
self.fake_params.update({'interactive': interactive})
self.fake_module.params = self.fake_params
expected_cmd = [
self.fake_binary,
'--cluster', self.fake_cluster,
'dashboard', 'ac-user-create',
'-i', '-',
self.fake_user
'dashboard', 'ac-user-create'
]
if interactive:
expected_cmd.extend([
'-i', '-',
self.fake_user
])
else:
expected_cmd.extend([
self.fake_user,
self.fake_password
])
assert ceph_dashboard_user.create_user(self.fake_module) == expected_cmd
@patch.dict(os.environ, {'CEPH_CONTAINER_BINARY': fake_container_binary})
@patch.dict(os.environ, {'CEPH_CONTAINER_IMAGE': fake_container_image})
def test_create_user_container(self):
@pytest.mark.parametrize('interactive', [True, False])
def test_create_user_container(self, interactive):
self.fake_params.update({'interactive': interactive})
self.fake_module.params = self.fake_params
expected_cmd = [
fake_container_binary,
'run',
'--interactive',
]
if interactive:
expected_cmd.append('--interactive')
expected_cmd.extend([
'--rm',
'--net=host',
'-v', '/etc/ceph:/etc/ceph:z',
@ -120,9 +135,17 @@ class TestCephDashboardUserModule(object):
fake_container_image,
'--cluster', self.fake_cluster,
'dashboard', 'ac-user-create',
'-i', '-',
self.fake_user
]
])
if interactive:
expected_cmd.extend([
'-i', '-',
self.fake_user
])
else:
expected_cmd.extend([
self.fake_user,
self.fake_password
])
assert ceph_dashboard_user.create_user(self.fake_module, container_image=fake_container_image) == expected_cmd
@ -138,26 +161,41 @@ class TestCephDashboardUserModule(object):
assert ceph_dashboard_user.set_roles(self.fake_module) == expected_cmd
def test_set_password(self):
@pytest.mark.parametrize('interactive', [True, False])
def test_set_password(self, interactive):
self.fake_params.update({'interactive': interactive})
self.fake_module.params = self.fake_params
expected_cmd = [
self.fake_binary,
'--cluster', self.fake_cluster,
'dashboard', 'ac-user-set-password',
'-i', '-',
self.fake_user
]
if interactive:
expected_cmd.extend([
'-i', '-',
self.fake_user
])
else:
expected_cmd.extend([
self.fake_user,
self.fake_password
])
assert ceph_dashboard_user.set_password(self.fake_module) == expected_cmd
@patch.dict(os.environ, {'CEPH_CONTAINER_BINARY': fake_container_binary})
@patch.dict(os.environ, {'CEPH_CONTAINER_IMAGE': fake_container_image})
def test_set_password_container(self):
@pytest.mark.parametrize('interactive', [True, False])
def test_set_password_container(self, interactive):
self.fake_params.update({'interactive': interactive})
self.fake_module.params = self.fake_params
expected_cmd = [
fake_container_binary,
'run',
'--interactive',
]
if interactive:
expected_cmd.append('--interactive')
expected_cmd.extend([
'--rm',
'--net=host',
'-v', '/etc/ceph:/etc/ceph:z',
@ -167,9 +205,17 @@ class TestCephDashboardUserModule(object):
fake_container_image,
'--cluster', self.fake_cluster,
'dashboard', 'ac-user-set-password',
'-i', '-',
self.fake_user
]
])
if interactive:
expected_cmd.extend([
'-i', '-',
self.fake_user
])
else:
expected_cmd.extend([
self.fake_user,
self.fake_password
])
assert ceph_dashboard_user.set_password(self.fake_module, container_image=fake_container_image) == expected_cmd