]> git.apps.os.sepia.ceph.com Git - ceph-ansible.git/commitdiff
dashboard: manage password backward compatibility
authorDimitri Savineau <dsavinea@redhat.com>
Mon, 11 Jan 2021 16:48:53 +0000 (11:48 -0500)
committerDimitri Savineau <savineau.dimitri@gmail.com>
Mon, 18 Jan 2021 19:46:53 +0000 (14:46 -0500)
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>
library/ceph_dashboard_user.py
roles/ceph-dashboard/tasks/configure_dashboard.yml
tests/library/test_ceph_dashboard_user.py

index 95b486ddb5263c00d289c17f96ddde3f8e6f7bcb..39d80606225b2fa34c1f2e4ce38a665ca65b25de 100644 (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
 
index fd2bb1a7315c7099f214efdb1a42995660a00d8c..b4f6ce37b8fb9bdfd75aeae05ff8ce7d5da1fe7b 100644 (file)
   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:
   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"
         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 -"
         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'] }}"
       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 -"
       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"
index b8d15101eeeac7e133a22bf9f45f3704f04724c9..aa6118bbe25260aeb96e568fdf3f1749b3ab40ef 100644 (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