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 <module>
    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.
This commit is contained in:
Lorin Hochstein 2012-09-07 16:24:00 -04:00
parent 0709c48f64
commit b3b01bb7a3

View file

@ -71,7 +71,7 @@ def user_delete(cursor, user):
cursor.execute("ROLLBACK TO SAVEPOINT ansible_pgsql_user_delete") cursor.execute("ROLLBACK TO SAVEPOINT ansible_pgsql_user_delete")
cursor.execute("RELEASE SAVEPOINT ansible_pgsql_user_delete") cursor.execute("RELEASE SAVEPOINT ansible_pgsql_user_delete")
return False return False
cursor.execute("RELEASE SAVEPOINT ansible_pgsql_user_delete") cursor.execute("RELEASE SAVEPOINT ansible_pgsql_user_delete")
return True return True
@ -89,7 +89,7 @@ def get_table_privileges(cursor, user, table):
WHERE grantee=%s AND table_name=%s AND table_schema=%s''' WHERE grantee=%s AND table_name=%s AND table_schema=%s'''
cursor.execute(query, (user, table, schema)) cursor.execute(query, (user, table, schema))
return set([x[0] for x in cursor.fetchall()]) return set([x[0] for x in cursor.fetchall()])
def grant_table_privilege(cursor, user, table, priv): def grant_table_privilege(cursor, user, table, priv):
prev_priv = get_table_privileges(cursor, user, table) 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' query = 'SELECT datacl FROM pg_database WHERE datname = %s'
cursor.execute(query, (db,)) cursor.execute(query, (db,))
datacl = cursor.fetchone()[0] datacl = cursor.fetchone()[0]
if datacl is None:
return []
r = re.search('%s=(C?T?c?)/[a-z]+\,?' % user, datacl) r = re.search('%s=(C?T?c?)/[a-z]+\,?' % user, datacl)
if r is None: if r is None:
return [] return []
@ -204,9 +206,9 @@ def parse_privs(privs, db):
type_ = 'table' type_ = 'table'
name, privileges = token.split(':', 1) name, privileges = token.split(':', 1)
priv_set = set(x.strip() for x in privileges.split(',')) priv_set = set(x.strip() for x in privileges.split(','))
o_privs[type_][name] = priv_set o_privs[type_][name] = priv_set
return o_privs return o_privs
# =========================================== # ===========================================
@ -240,8 +242,8 @@ def main():
if not postgresqldb_found: if not postgresqldb_found:
module.fail_json(msg="the python psycopg2 module is required") 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 # check which values are empty and don't include in the **kw
# dictionary # dictionary
params_map = { params_map = {
@ -249,16 +251,16 @@ def main():
"login_user":"user", "login_user":"user",
"login_password":"password", "login_password":"password",
"port":"port", "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 != "" ) if k in params_map and v != "" )
try: try:
db_connection = psycopg2.connect(**kw) db_connection = psycopg2.connect(**kw)
cursor = db_connection.cursor() cursor = db_connection.cursor()
except Exception, e: except Exception, e:
module.fail_json(msg="unable to connect to database: %s" % e) module.fail_json(msg="unable to connect to database: %s" % e)
kw = dict(user=user) kw = dict(user=user)
changed = False changed = False
user_removed = False user_removed = False