From 01e4e1bb424e0e586e6c934347b5523618d4d191 Mon Sep 17 00:00:00 2001 From: Andrey Klychkov Date: Fri, 15 Nov 2019 10:07:56 +0300 Subject: [PATCH] postgres.py: add query_params (#64661) * postgres.py: add query_params * postgres.py: add query_params, add changelog --- ...64661-postgres_py_add_query_params_arg.yml | 3 ++ lib/ansible/module_utils/postgres.py | 30 ++++++++++++++++--- .../database/postgresql/postgresql_idx.py | 11 +++---- 3 files changed, 35 insertions(+), 9 deletions(-) create mode 100644 changelogs/fragments/64661-postgres_py_add_query_params_arg.yml diff --git a/changelogs/fragments/64661-postgres_py_add_query_params_arg.yml b/changelogs/fragments/64661-postgres_py_add_query_params_arg.yml new file mode 100644 index 00000000000..28e43bd87b1 --- /dev/null +++ b/changelogs/fragments/64661-postgres_py_add_query_params_arg.yml @@ -0,0 +1,3 @@ +bugfixes: +- postgres.py - add a new keyword argument ``query_params`` (https://github.com/ansible/ansible/pull/64661). +- postgresql_idx.py - use the ``query_params`` arg of exec_sql function (https://github.com/ansible/ansible/pull/64661). diff --git a/lib/ansible/module_utils/postgres.py b/lib/ansible/module_utils/postgres.py index cf7ca3d3d35..81808a16a1a 100644 --- a/lib/ansible/module_utils/postgres.py +++ b/lib/ansible/module_utils/postgres.py @@ -122,7 +122,7 @@ def connect_to_db(module, conn_params, autocommit=False, fail_on_conn=True): return db_connection -def exec_sql(obj, query, ddl=False, add_to_executed=True): +def exec_sql(obj, query, query_params=None, ddl=False, add_to_executed=True, dont_exec=False): """Execute SQL. Auxiliary function for PostgreSQL user classes. @@ -130,21 +130,43 @@ def exec_sql(obj, query, ddl=False, add_to_executed=True): Returns a query result if possible or True/False if ddl=True arg was passed. It necessary for statements that don't return any result (like DDL queries). - Arguments: + Args: obj (obj) -- must be an object of a user class. The object must have module (AnsibleModule class object) and cursor (psycopg cursor object) attributes query (str) -- SQL query to execute + + Kwargs: + query_params (dict or tuple) -- Query parameters to prevent SQL injections, + could be a dict or tuple ddl (bool) -- must return True or False instead of rows (typical for DDL queries) (default False) add_to_executed (bool) -- append the query to obj.executed_queries attribute + dont_exec (bool) -- used with add_to_executed=True to generate a query, add it + to obj.executed_queries list and return True (default False) """ - try: - obj.cursor.execute(query) + if dont_exec: + # This is usually needed to return queries in check_mode + # without execution + query = obj.cursor.mogrify(query, query_params) if add_to_executed: obj.executed_queries.append(query) + return True + + try: + if query_params is not None: + obj.cursor.execute(query, query_params) + else: + obj.cursor.execute(query) + + if add_to_executed: + if query_params is not None: + obj.executed_queries.append(obj.cursor.mogrify(query, query_params)) + else: + obj.executed_queries.append(query) + if not ddl: res = obj.cursor.fetchall() return res diff --git a/lib/ansible/modules/database/postgresql/postgresql_idx.py b/lib/ansible/modules/database/postgresql/postgresql_idx.py index 6a76ad2eda6..1b42981e771 100644 --- a/lib/ansible/modules/database/postgresql/postgresql_idx.py +++ b/lib/ansible/modules/database/postgresql/postgresql_idx.py @@ -334,10 +334,11 @@ class Index(object): Return index statistics dictionary if index exists, otherwise False. """ query = ("SELECT * FROM pg_stat_user_indexes " - "WHERE indexrelname = '%s' " - "AND schemaname = '%s'" % (self.name, self.schema)) + "WHERE indexrelname = %(name)s " + "AND schemaname = %(schema)s") - result = exec_sql(self, query, add_to_executed=False) + result = exec_sql(self, query, query_params={'name': self.name, 'schema': self.schema}, + add_to_executed=False) if result: return [dict(row) for row in result] else: @@ -355,9 +356,9 @@ class Index(object): "ON i.indexname = c.relname " "JOIN pg_catalog.pg_index AS pi " "ON c.oid = pi.indexrelid " - "WHERE i.indexname = '%s'" % self.name) + "WHERE i.indexname = %(name)s") - res = exec_sql(self, query, add_to_executed=False) + res = exec_sql(self, query, query_params={'name': self.name}, add_to_executed=False) if res: self.exists = True self.info = dict(