From 57dc4fbea2488391d9e1dc931488c7484b064be1 Mon Sep 17 00:00:00 2001
From: Jinn Koriech <jinn@fivecool.net>
Date: Tue, 31 Dec 2013 18:23:45 +0000
Subject: [PATCH] postgresql_user module: Gracefully handle ALTER ROLE on
 read-only postgres servers.

---
 database/postgresql_user | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/database/postgresql_user b/database/postgresql_user
index 7897ecac72f..e739a23cd4b 100644
--- a/database/postgresql_user
+++ b/database/postgresql_user
@@ -173,7 +173,7 @@ def user_add(cursor, user, password, role_attr_flags,  encrypted, expires):
     cursor.execute(query)
     return True
 
-def user_alter(cursor, user, password, role_attr_flags, encrypted, expires):
+def user_alter(cursor, module, user, password, role_attr_flags, encrypted, expires):
     """Change user password and/or attributes. Return True if changed, False otherwise."""
     changed = False
 
@@ -203,7 +203,17 @@ def user_alter(cursor, user, password, role_attr_flags, encrypted, expires):
         if expires is not None:
             alter = alter + " VALID UNTIL '%(expires)s'" % { "exipres": expires }
 
-        cursor.execute(alter)
+        try:
+            cursor.execute(alter)
+        except psycopg2.InternalError, e:
+            if e.pgcode == '25006':
+                # Handle errors due to read-only transactions indicated by pgcode 25006
+                # ERROR:  cannot execute ALTER ROLE in a read-only transaction
+                changed = False
+                module.fail_json(msg=e.pgerror)
+                return changed
+            else:
+                raise psycopg2.InternalError, e
 
         # Grab new role attributes.
         cursor.execute(select, {"user": user})
@@ -455,7 +465,7 @@ def main():
 
     if state == "present":
         if user_exists(cursor, user):
-            changed = user_alter(cursor, user, password, role_attr_flags, encrypted, expires)
+            changed = user_alter(cursor, module, user, password, role_attr_flags, encrypted, expires)
         else:
             changed = user_add(cursor, user, password, role_attr_flags, encrypted, expires)
         changed = grant_privileges(cursor, user, privs) or changed