diff --git a/lib/ansible/modules/database/postgresql/postgresql_schema.py b/lib/ansible/modules/database/postgresql/postgresql_schema.py index a3f7c2e842..355beaa1af 100644 --- a/lib/ansible/modules/database/postgresql/postgresql_schema.py +++ b/lib/ansible/modules/database/postgresql/postgresql_schema.py @@ -54,13 +54,31 @@ options: - The schema state. default: present choices: [ "present", "absent" ] + ssl_mode: + description: + - Determines whether or with what priority a secure SSL TCP/IP connection + will be negotiated with the server. + - See U(https://www.postgresql.org/docs/current/static/libpq-ssl.html) for + more information on the modes. + - Default of C(prefer) matches libpq default. + default: prefer + choices: ["disable", "allow", "prefer", "require", "verify-ca", "verify-full"] + version_added: '2.8' + ssl_rootcert: + description: + - Specifies the name of a file containing SSL certificate authority (CA) + certificate(s). If the file exists, the server's certificate will be + verified to be signed by one of these authorities. + version_added: '2.8' notes: - This module uses I(psycopg2), a Python PostgreSQL database adapter. You must ensure that psycopg2 is installed on the host before using this module. If the remote host is the PostgreSQL server (which is the default case), then PostgreSQL must also be installed on the remote host. For Ubuntu-based systems, install the C(postgresql), C(libpq-dev), and C(python-psycopg2) packages on the remote host before using this module. requirements: [ psycopg2 ] -author: Flavien Chantelot (@Dorn-) +author: + - Flavien Chantelot (@Dorn-) + - Thomas O'Donnell (@andytom) ''' EXAMPLES = ''' @@ -95,6 +113,7 @@ else: from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.database import SQLParseError, pg_quote_identifier +from ansible.module_utils.six import iteritems from ansible.module_utils._text import to_native @@ -182,6 +201,9 @@ def main(): owner=dict(default=""), database=dict(default="postgres"), state=dict(default="present", choices=["absent", "present"]), + ssl_mode=dict(default='prefer', choices=[ + 'disable', 'allow', 'prefer', 'require', 'verify-ca', 'verify-full']), + ssl_rootcert=dict(default=None), ), supports_check_mode=True ) @@ -192,7 +214,7 @@ def main(): schema = module.params["schema"] owner = module.params["owner"] state = module.params["state"] - database = module.params["database"] + sslrootcert = module.params["ssl_rootcert"] changed = False # To use defaults values, keyword arguments must be absent, so @@ -202,18 +224,25 @@ def main(): "login_host": "host", "login_user": "user", "login_password": "password", - "port": "port" + "port": "port", + "database": "database", + "ssl_mode": "sslmode", + "ssl_rootcert": "sslrootcert" } - kw = dict((params_map[k], v) for (k, v) in module.params.items() - if k in params_map and v != '') + kw = dict((params_map[k], v) for (k, v) in iteritems(module.params) + if k in params_map and v != "" and v is not None) # If a login_unix_socket is specified, incorporate it here. is_localhost = "host" not in kw or kw["host"] == "" or kw["host"] == "localhost" if is_localhost and module.params["login_unix_socket"] != "": kw["host"] = module.params["login_unix_socket"] + if psycopg2.__version__ < '2.4.3' and sslrootcert is not None: + module.fail_json( + msg='psycopg2 must be at least 2.4.3 in order to user the ssl_rootcert parameter') + try: - db_connection = psycopg2.connect(database=database, **kw) + db_connection = psycopg2.connect(**kw) # Enable autocommit so we can create databases if psycopg2.__version__ >= '2.4.2': db_connection.autocommit = True @@ -223,6 +252,13 @@ def main(): .ISOLATION_LEVEL_AUTOCOMMIT) cursor = db_connection.cursor( cursor_factory=psycopg2.extras.DictCursor) + + except TypeError as e: + if 'sslrootcert' in e.args[0]: + module.fail_json( + msg='Postgresql server must be at least version 8.4 to support sslrootcert') + module.fail_json(msg="unable to connect to database: %s" % to_native(e), exception=traceback.format_exc()) + except Exception as e: module.fail_json(msg="unable to connect to database: %s" % to_native(e), exception=traceback.format_exc())