Skip to content

Commit

Permalink
clickhouse_db: add comment argument (#41)
Browse files Browse the repository at this point in the history
* clickhouse_db: add comment argument
  • Loading branch information
Andersson007 authored Feb 22, 2024
1 parent c23126d commit e9f1f47
Show file tree
Hide file tree
Showing 5 changed files with 178 additions and 48 deletions.
2 changes: 2 additions & 0 deletions changelogs/fragments/1-clickhouse_db.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
minor_changes:
- clickhouse_db - add the ``comment`` argument to set a comment on databases.
31 changes: 31 additions & 0 deletions plugins/module_utils/clickhouse.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,34 @@ def execute_query(module, client, query, execute_kwargs=None):
module.fail_json(msg="Failed to execute query: %s" % to_native(e))

return result


def get_server_version(module, client):
"""Get server version.
Returns a dictionary with server version.
"""
result = execute_query(module, client, "SELECT version()")

if result == PRIV_ERR_CODE:
return {PRIV_ERR_CODE: "Not enough privileges"}

raw = result[0][0]
split_raw = raw.split('.')

version = {}
version["raw"] = raw

version["year"] = int(split_raw[0])
version["feature"] = int(split_raw[1])
version["maintenance"] = int(split_raw[2])

if '-' in split_raw[3]:
tmp = split_raw[3].split('-')
version["build"] = int(tmp[0])
version["type"] = tmp[1]
else:
version["build"] = int(split_raw[3])
version["type"] = None

return version
70 changes: 55 additions & 15 deletions plugins/modules/clickhouse_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,13 @@
required: true
engine:
description:
- Database engine.
- Database engine. Once set, cannot be changed.
type: str
comment:
description:
- Database comment. Once set, cannot be changed.
type: str
version_added: '0.4.0'
'''

EXAMPLES = r'''
Expand All @@ -60,6 +65,7 @@
name: test_db
engine: Memory
state: present
comment: Test DB
- name: Drop database
community.clickhouse.clickhouse_db:
Expand All @@ -85,9 +91,10 @@
from ansible_collections.community.clickhouse.plugins.module_utils.clickhouse import (
check_clickhouse_driver,
client_common_argument_spec,
get_main_conn_kwargs,
execute_query,
connect_to_db_via_client,
execute_query,
get_main_conn_kwargs,
get_server_version,
)


Expand All @@ -99,37 +106,55 @@ def __init__(self, module, client, name):
self.module = module
self.client = client
self.name = name
self.exists, self.engine = self.__populate_info()
self.srv_version = get_server_version(self.module, self.client)
# Set default values, then update
self.exists = False
self.engine = None
self.comment = None
self.__populate_info()

def __populate_info(self):
query = "SELECT engine FROM system.databases WHERE name = %(name)s"
# TODO: If anyone can determine the version when the comment feature
# was added to database more precisely, you're welcome to adjust it here
if self.srv_version['year'] >= 22:
# The comment is not supported in all versions
query = ("SELECT engine, comment "
"FROM system.databases "
"WHERE name = %(name)s")
else:
query = "SELECT engine FROM system.databases WHERE name = %(name)s"

# Will move this function to the lib later and reuse
exec_kwargs = {'params': {'name': self.name}}
result = execute_query(self.module, self.client, query, exec_kwargs)

# Assume the DB does not exist by default
exists = False
engine = None
if result:
# If exists
exists = True
engine = result[0][0]
self.exists = True
self.engine = result[0][0]
if self.srv_version['year'] >= 22:
self.comment = result[0][1]

return exists, engine

def create(self, engine):
def create(self, engine, comment):
query = "CREATE DATABASE %s" % self.name
if engine:
query += " ENGINE = %s" % engine

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

executed_statements.append(query)

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

return True

def update(self, engine):
def update(self, engine, comment):
# IMPORTANT: In case in future any items here can change
# please add check_mode handling

# There's no way to change the engine
# so just inform the users they have to recreate
# the DB in order to change them
Expand All @@ -140,6 +165,13 @@ def update(self, engine):
"in order to change it." % (engine, self.engine))
self.module.warn(msg)

if comment and comment != self.comment:
msg = ("The provided comment '%s' is different from "
"the current one '%s'. It is NOT possible to "
"change it. The recreation of the database is required "
"in order to change it." % (comment, self.comment))
self.module.warn(msg)

return False

def drop(self):
Expand All @@ -162,6 +194,7 @@ def main():
state=dict(type='str', choices=['present', 'absent'], default='present'),
name=dict(type='str', required=True),
engine=dict(type='str', default=None),
comment=dict(type='str', default=None),
)

# Instantiate an object of module class
Expand All @@ -180,6 +213,7 @@ def main():
state = module.params['state']
name = module.params['name']
engine = module.params['engine']
comment = module.params['comment']

# Will fail if no driver informing the user
check_clickhouse_driver(module)
Expand All @@ -191,12 +225,18 @@ def main():
changed = False
database = ClickHouseDB(module, client, name)

if comment and database.srv_version['year'] < 22:
msg = ('The module supports the comment feature for ClickHouse '
'versions equal to or higher than 22.*. Ignored.')
module.warn(msg)
comment = None

if state == 'present':
if not database.exists:
changed = database.create(engine)
changed = database.create(engine, comment)
else:
# If database exists
changed = database.update(engine)
changed = database.update(engine, comment)

else:
# If state is absent
Expand Down
36 changes: 3 additions & 33 deletions plugins/modules/clickhouse_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,12 @@

from ansible_collections.community.clickhouse.plugins.module_utils.clickhouse import (
check_clickhouse_driver,
version_clickhouse_driver,
client_common_argument_spec,
get_main_conn_kwargs,
connect_to_db_via_client,
execute_query,
get_main_conn_kwargs,
get_server_version,
version_clickhouse_driver,
)


Expand Down Expand Up @@ -488,37 +489,6 @@ def get_quotas(module, client):
return quota_info


def get_server_version(module, client):
"""Get server version.
Returns a dictionary with server version.
"""
result = execute_query(module, client, "SELECT version()")

if result == PRIV_ERR_CODE:
return {PRIV_ERR_CODE: "Not enough privileges"}

raw = result[0][0]
split_raw = raw.split('.')

version = {}
version["raw"] = raw

version["year"] = int(split_raw[0])
version["feature"] = int(split_raw[1])
version["maintenance"] = int(split_raw[2])

if '-' in split_raw[3]:
tmp = split_raw[3].split('-')
version["build"] = int(tmp[0])
version["type"] = tmp[1]
else:
version["build"] = int(split_raw[3])
version["type"] = None

return version


def get_driver(module, client):
"""Gets driver information.
Expand Down
87 changes: 87 additions & 0 deletions tests/integration/targets/clickhouse_db/tasks/initial.yml
Original file line number Diff line number Diff line change
Expand Up @@ -222,3 +222,90 @@
that:
- result is not changed
- result.executed_statements == []

# Get srv version for the following block
- name: Get server version
register: server_info
community.clickhouse.clickhouse_info:
limit: version

- name: Test comment
when: server_info['version']['year'] >= 22
block:

# Test
- name: Create database in check mode with comment
register: result
check_mode: true
community.clickhouse.clickhouse_db:
state: present
name: test_db
comment: Test DB

- name: Check ret values
ansible.builtin.assert:
that:
- result is changed
- result.executed_statements == ["CREATE DATABASE test_db COMMENT 'Test DB'"]

# Test
- name: Create database with comment real mode
register: result
community.clickhouse.clickhouse_db:
state: present
name: test_db
comment: Test DB

- name: Check ret values
ansible.builtin.assert:
that:
- result is changed
- result.executed_statements == ["CREATE DATABASE test_db COMMENT 'Test DB'"]

- name: Check the actual state
register: result
community.clickhouse.clickhouse_client:
execute: "SELECT comment FROM system.databases WHERE name = 'test_db'"

- name: Check the DB is there
ansible.builtin.assert:
that:
- result.result == [['Test DB']]

# Test
# The change is not possible. It'll just show a warning and ignore
- name: Create database with another comment real mode
register: result
community.clickhouse.clickhouse_db:
state: present
name: test_db
comment: Test DB 1

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

- name: Check the actual state
register: result
community.clickhouse.clickhouse_client:
execute: "SELECT comment FROM system.databases WHERE name = 'test_db'"

- name: Check the DB is there
ansible.builtin.assert:
that:
- result.result == [['Test DB']]

# Test
- name: Drop DB with comment
register: result
community.clickhouse.clickhouse_db:
state: absent
name: test_db
comment: Test DB

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

0 comments on commit e9f1f47

Please sign in to comment.