From b3b01bb7a361121b4bc36170ca2d9b8cdb64aa20 Mon Sep 17 00:00:00 2001 From: Lorin Hochstein Date: Fri, 7 Sep 2012 16:24:00 -0400 Subject: [PATCH] Fix postgresql_user bug If I create a database from scratch and assign permissions by doing: - name: ensure database is created action: postgresql_db db=$dbname - name: ensure django user has access action: postgresql_user db=$dbname user=$dbuser priv=ALL password=$dbpassword Then it fails with the error: File "/tmp/ansible-1347048449.32-29998829936529/postgresql_user", line 565, in main() File "/tmp/ansible-1347048449.32-29998829936529/postgresql_user", line 273, in main changed = grant_privileges(cursor, user, privs) or changed File "/tmp/ansible-1347048449.32-29998829936529/postgresql_user", line 174, in grant_privileges changed = grant_func(cursor, user, name, privilege)\ File "/tmp/ansible-1347048449.32-29998829936529/postgresql_user", line 132, in grant_database_privilege prev_priv = get_database_privileges(cursor, user, db) File "/tmp/ansible-1347048449.32-29998829936529/postgresql_user", line 118, in get_database_privileges r = re.search('%s=(C?T?c?)/[a-z]+\,?' % user, datacl) File "/usr/lib/python2.7/re.py", line 142, in search return _compile(pattern, flags).search(string) TypeError: expected string or buffer This fix fixes the problem by not executing the regex if the db query on pg_database returns None. --- library/postgresql_user | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/library/postgresql_user b/library/postgresql_user index 6104fd8d008..8f85988770d 100755 --- a/library/postgresql_user +++ b/library/postgresql_user @@ -71,7 +71,7 @@ def user_delete(cursor, user): cursor.execute("ROLLBACK TO SAVEPOINT ansible_pgsql_user_delete") cursor.execute("RELEASE SAVEPOINT ansible_pgsql_user_delete") return False - + cursor.execute("RELEASE SAVEPOINT ansible_pgsql_user_delete") return True @@ -89,7 +89,7 @@ def get_table_privileges(cursor, user, table): WHERE grantee=%s AND table_name=%s AND table_schema=%s''' cursor.execute(query, (user, table, schema)) return set([x[0] for x in cursor.fetchall()]) - + def grant_table_privilege(cursor, user, table, priv): prev_priv = get_table_privileges(cursor, user, table) @@ -115,6 +115,8 @@ def get_database_privileges(cursor, user, db): query = 'SELECT datacl FROM pg_database WHERE datname = %s' cursor.execute(query, (db,)) datacl = cursor.fetchone()[0] + if datacl is None: + return [] r = re.search('%s=(C?T?c?)/[a-z]+\,?' % user, datacl) if r is None: return [] @@ -204,9 +206,9 @@ def parse_privs(privs, db): type_ = 'table' name, privileges = token.split(':', 1) priv_set = set(x.strip() for x in privileges.split(',')) - + o_privs[type_][name] = priv_set - + return o_privs # =========================================== @@ -240,8 +242,8 @@ def main(): if not postgresqldb_found: module.fail_json(msg="the python psycopg2 module is required") - - # To use defaults values, keyword arguments must be absent, so + + # To use defaults values, keyword arguments must be absent, so # check which values are empty and don't include in the **kw # dictionary params_map = { @@ -249,16 +251,16 @@ def main(): "login_user":"user", "login_password":"password", "port":"port", - "db":"database" + "db":"database" } - kw = dict( (params_map[k], v) for (k, v) in module.params.iteritems() + kw = dict( (params_map[k], v) for (k, v) in module.params.iteritems() if k in params_map and v != "" ) try: db_connection = psycopg2.connect(**kw) cursor = db_connection.cursor() except Exception, e: module.fail_json(msg="unable to connect to database: %s" % e) - + kw = dict(user=user) changed = False user_removed = False