Skip to content

Commit

Permalink
Renaming databases (#43)
Browse files Browse the repository at this point in the history
* clickhouse_db: new arguments added

* Add integration tests
  • Loading branch information
aleksvagachev authored Feb 26, 2024
1 parent e9f1f47 commit 9af667a
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 5 deletions.
4 changes: 4 additions & 0 deletions changelogs/fragments/2-clickhouse_db.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
minor_changes:
- clickhouse_db - added the ability to rename databases.
- clickhouse_db - add the ``cluster`` argument to execute commands on all cluster hosts.
- clickhouse_db - add the ``target`` argument to rename the database.
73 changes: 68 additions & 5 deletions plugins/modules/clickhouse_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
author:
- Andrew Klychkov (@Andersson007)
- Aleksandr Vagachev (@aleksvagachev)
extends_documentation_fragment:
- community.clickhouse.client_inst_opts
Expand All @@ -36,8 +37,9 @@
- Database state.
- If C(present), will create the database if not exists.
- If C(absent), will drop the database if exists.
- If C(rename), will rename the database if exists.
type: str
choices: ['present', 'absent']
choices: ['present', 'absent', 'rename']
default: 'present'
name:
description:
Expand All @@ -48,6 +50,17 @@
description:
- Database engine. Once set, cannot be changed.
type: str
cluster:
description:
- Run the command on all cluster hosts.
- If the cluster is not configured, the command will crash with an error.
type: str
version_added: '0.4.0'
target:
description:
- Name for renaming the database.
type: str
version_added: '0.4.0'
comment:
description:
- Database comment. Once set, cannot be changed.
Expand Down Expand Up @@ -75,6 +88,22 @@
login_password: my_password
name: test_db
state: absent
# Rename the database test_db to prod_db.
# If the database test_db exists, it will be renamed to prod_db.
# If the database test_db does not exist and the prod_db database exists,
# the module will report that nothing has changed.
# If both the databases exist, an error will be raised.
- name: Rename database
community.clickhouse.clickhouse_db:
login_host: localhost
login_user: alice
login_db: foo
login_password: my_password
name: test_db
target: prod_db
cluster: test_cluster
state: rename
'''

RETURN = r'''
Expand Down Expand Up @@ -102,10 +131,11 @@


class ClickHouseDB():
def __init__(self, module, client, name):
def __init__(self, module, client, name, cluster):
self.module = module
self.client = client
self.name = name
self.cluster = cluster
self.srv_version = get_server_version(self.module, self.client)
# Set default values, then update
self.exists = False
Expand Down Expand Up @@ -141,6 +171,9 @@ def create(self, engine, comment):
if engine:
query += " ENGINE = %s" % engine

if self.cluster:
query += " ON CLUSTER %s" % self.cluster

if comment:
query += " COMMENT '%s'" % comment

Expand Down Expand Up @@ -174,8 +207,23 @@ def update(self, engine, comment):

return False

def rename(self, target):
query = "RENAME DATABASE %s TO %s" % (self.name, target)
if self.cluster:
query += " ON CLUSTER %s" % self.cluster

executed_statements.append(query)

if not self.module.check_mode:
execute_query(self.module, self.client, query)

return True

def drop(self):
query = "DROP DATABASE %s" % self.name
if self.cluster:
query += " ON CLUSTER %s" % self.cluster

executed_statements.append(query)

if not self.module.check_mode:
Expand All @@ -191,9 +239,11 @@ def main():
# and invoke here to return a dict with those arguments
argument_spec = client_common_argument_spec()
argument_spec.update(
state=dict(type='str', choices=['present', 'absent'], default='present'),
state=dict(type='str', choices=['present', 'absent', 'rename'], default='present'),
name=dict(type='str', required=True),
engine=dict(type='str', default=None),
cluster=dict(type='str', default=None),
target=dict(type='str', default=None),
comment=dict(type='str', default=None),
)

Expand All @@ -213,6 +263,8 @@ def main():
state = module.params['state']
name = module.params['name']
engine = module.params['engine']
cluster = module.params['cluster']
target = module.params['target']
comment = module.params['comment']

# Will fail if no driver informing the user
Expand All @@ -223,7 +275,7 @@ def main():

# Do the job
changed = False
database = ClickHouseDB(module, client, name)
database = ClickHouseDB(module, client, name, cluster)

if comment and database.srv_version['year'] < 22:
msg = ('The module supports the comment feature for ClickHouse '
Expand All @@ -237,7 +289,18 @@ def main():
else:
# If database exists
changed = database.update(engine, comment)

elif state == 'rename':
if database.exists:
changed = database.rename(target)
else:
target_db = ClickHouseDB(module, client, target, cluster)
if target_db.exists:
changed = False
msg = "There is nothing to rename"
module.warn(msg)
else:
msg = "The %s and %s databases do not exist" % (name, target)
module.fail_json(msg=msg)
else:
# If state is absent
if database.exists:
Expand Down
68 changes: 68 additions & 0 deletions tests/integration/targets/clickhouse_db/tasks/initial.yml
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,74 @@
- result is not changed
- result.executed_statements == []

# Test rename database
- name: Create database for renaming
register: result
community.clickhouse.clickhouse_db:
name: test_rename_db

- name: Rename database
register: result
community.clickhouse.clickhouse_db:
name: test_rename_db
target: dev_db
state: rename

- name: Check ret values
ansible.builtin.assert:
that:
- result is changed
- result.executed_statements == ["RENAME DATABASE test_rename_db TO dev_db"]

# Test
- name: Rename database in check mode
register: result
check_mode: true
community.clickhouse.clickhouse_db:
state: rename
name: dev_db
target: test_rename_db

- name: Check ret values
ansible.builtin.assert:
that:
- result is changed
- result.executed_statements == ["RENAME DATABASE dev_db TO test_rename_db"]

# Test rename database if there is nothing to rename
- name: Rename database if there is nothing to rename
register: result
community.clickhouse.clickhouse_db:
name: test_rename_db
target: dev_db
state: rename

- name: Check ret values
ansible.builtin.assert:
that:
- result is not changed
- result.executed_statements == []
- result.warnings != []

# Test rename database if both databases exist
- name: Create database for renaming
register: result
community.clickhouse.clickhouse_db:
name: test_rename_db

- name: Rename database if both databases exist
register: result
community.clickhouse.clickhouse_db:
name: test_rename_db
target: dev_db
state: rename
ignore_errors: true

- name: Check ret values
ansible.builtin.assert:
that:
- result is failed

# Get srv version for the following block
- name: Get server version
register: server_info
Expand Down

0 comments on commit 9af667a

Please sign in to comment.