From a55d429dfb950901cea0e4d0d2b2139f7dd3d7a3 Mon Sep 17 00:00:00 2001 From: Andrew Klychkov Date: Thu, 7 Mar 2024 10:47:57 +0100 Subject: [PATCH] clickhouse_user: add update_password argument --- plugins/modules/clickhouse_user.py | 45 ++++++++++++++++++- .../targets/clickhouse_user/tasks/initial.yml | 31 ++++++++++++- 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/plugins/modules/clickhouse_user.py b/plugins/modules/clickhouse_user.py index 54195cd..bb81e2e 100644 --- a/plugins/modules/clickhouse_user.py +++ b/plugins/modules/clickhouse_user.py @@ -26,9 +26,11 @@ author: - Aleksandr Vagachev (@aleksvagachev) + - Andrew Klychkov (@Andersson007) extends_documentation_fragment: - community.clickhouse.client_inst_opts + version_added: '0.4.0' options: @@ -61,6 +63,18 @@ - Run the command on all cluster hosts. - If the cluster is not configured, the command will crash with an error. type: str + update_password: + description: + - If C(on_create), will set the password only for newly created users. + If the user already exists, a C(password) value will be ignored. + - If C(always), will always update the password. + This option is not idempotent and will update the password even + if it is the same in the database. If in future ClickHouse will allow + to retrieve password hashes and other necessary details, this behavior + will be changed. + type: str + choices: [always, on_create] + default: on_create ''' EXAMPLES = r''' @@ -74,6 +88,16 @@ password: qwerty type_password: sha256_password +- name: If user exists, update password + community.clickhouse.clickhouse_user: + login_host: localhost + login_user: alice + login_db: foo + login_password: my_password + name: test_user + password: qwerty123 + update_password: always + - name: Create user community.clickhouse.clickhouse_user: login_host: localhost @@ -164,6 +188,23 @@ def create(self): return True + def update(self, update_password): + if update_password == 'on_create': + return False + + # If update_password is always + # TODO: When ClickHouse will allow to retrieve password hashes, + # make this idempotent, i.e. execute this only if the passwords don't match + query = ("ALTER USER %s IDENTIFIED WITH %s " + "BY '%s'") % (self.name, self.type_password, self.password) + + executed_statements.append(query) + + if not self.module.check_mode: + execute_query(self.module, self.client, query) + + return True + def drop(self): query = "DROP USER %s" % self.name if self.cluster: @@ -185,6 +226,7 @@ def main(): password=dict(type='str', default=None, no_log=True), type_password=dict(type='str', default='sha256_password', no_log=True), cluster=dict(type='str', default=None), + update_password=dict(type='str', choices=['always', 'on_create'], default='on_create'), ) # Instantiate an object of module class @@ -205,6 +247,7 @@ def main(): password = module.params["password"] type_password = module.params["type_password"] cluster = module.params['cluster'] + update_password = module.params['update_password'] # Will fail if no driver informing the user check_clickhouse_driver(module) @@ -222,7 +265,7 @@ def main(): changed = user.create() else: # If user exists - pass + changed = user.update(update_password) else: # If state is absent if user.user_exists: diff --git a/tests/integration/targets/clickhouse_user/tasks/initial.yml b/tests/integration/targets/clickhouse_user/tasks/initial.yml index d1981e0..48895a5 100644 --- a/tests/integration/targets/clickhouse_user/tasks/initial.yml +++ b/tests/integration/targets/clickhouse_user/tasks/initial.yml @@ -10,12 +10,13 @@ community.clickhouse.clickhouse_user: state: present name: test_user + password: querty - name: Test 1 - Check ret values in ansible.builtin.assert: that: - result is changed - - result.executed_statements == ['CREATE USER test_user'] + - result.executed_statements == ["CREATE USER test_user IDENTIFIED WITH ******** BY '********'"] - name: Test 1 - Check the actual state register: result @@ -95,3 +96,31 @@ that: - result is not changed - result.executed_statements == [] + + +# test 6 +- name: Create test_user + register: result + community.clickhouse.clickhouse_user: + state: present + name: test_user + password: querty + +- name: Test 6 - Create test_user again with update_password always + register: result + community.clickhouse.clickhouse_user: + state: present + name: test_user + password: querty + update_password: always + +- name: Test 6 - Check result + ansible.builtin.assert: + that: + - result is changed + - result.executed_statements == ["ALTER USER test_user IDENTIFIED WITH ******** BY '********'"] + +- name: Drop test_user + community.clickhouse.clickhouse_user: + state: absent + name: test_user