Exemple #1
0
    def test_ensure_req_libs_ca_cert(self, m_ansible_module, m_psycopg2, monkeypatch):
        """
        Test with module.params['ca_cert'], psycopg2 version is suitable.
        """
        m_ansible_module.params['ca_cert'] = True
        monkeypatch.setattr(pg, 'HAS_PSYCOPG2', True)
        monkeypatch.setattr(pg, 'psycopg2', m_psycopg2)

        pg.ensure_required_libs(m_ansible_module)
        assert m_ansible_module.err_msg == ''
Exemple #2
0
    def test_ensure_req_libs_ca_cert_low_psycopg2_ver(self, m_ansible_module, m_psycopg2, monkeypatch):
        """
        Test with module.params['ca_cert'], psycopg2 version is wrong.
        """
        m_ansible_module.params['ca_cert'] = True
        monkeypatch.setattr(pg, 'HAS_PSYCOPG2', True)
        # Set wrong psycopg2 version number:
        psycopg2 = m_psycopg2
        psycopg2.__version__ = '2.4.2'
        monkeypatch.setattr(pg, 'psycopg2', psycopg2)

        pg.ensure_required_libs(m_ansible_module)
        assert 'psycopg2 must be at least 2.4.3' in m_ansible_module.err_msg
def main():
    argument_spec = pgutils.postgres_common_argument_spec()
    argument_spec.update(
        db=dict(type='str', required=True, aliases=['name']),
        owner=dict(type='str', default=''),
        template=dict(type='str', default=''),
        encoding=dict(type='str', default=''),
        lc_collate=dict(type='str', default=''),
        lc_ctype=dict(type='str', default=''),
        state=dict(type='str',
                   default='present',
                   choices=['absent', 'dump', 'present', 'restore']),
        target=dict(type='path', default=''),
        target_opts=dict(type='str', default=''),
        maintenance_db=dict(type='str', default="postgres"),
        session_role=dict(type='str'),
        conn_limit=dict(type='str', default=''),
        tablespace=dict(type='path', default=''),
        dump_extra_args=dict(type='str', default=None),
        trust_input=dict(type='bool', default=True),
    )

    module = AnsibleModule(argument_spec=argument_spec,
                           supports_check_mode=True)

    db = module.params["db"]
    owner = module.params["owner"]
    template = module.params["template"]
    encoding = module.params["encoding"]
    lc_collate = module.params["lc_collate"]
    lc_ctype = module.params["lc_ctype"]
    target = module.params["target"]
    target_opts = module.params["target_opts"]
    state = module.params["state"]
    changed = False
    maintenance_db = module.params['maintenance_db']
    session_role = module.params["session_role"]
    conn_limit = module.params['conn_limit']
    tablespace = module.params['tablespace']
    dump_extra_args = module.params['dump_extra_args']
    trust_input = module.params['trust_input']

    # Check input
    if not trust_input:
        # Check input for potentially dangerous elements:
        check_input(module, owner, conn_limit, encoding, db, template,
                    tablespace, session_role)

    raw_connection = state in ("dump", "restore")

    if not raw_connection:
        pgutils.ensure_required_libs(module)

    # 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 = {
        "login_host": "host",
        "login_user": "******",
        "login_password": "******",
        "port": "port",
        "ssl_mode": "sslmode",
        "ca_cert": "sslrootcert"
    }
    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 target == "":
        target = "{0}/{1}.sql".format(os.getcwd(), db)
        target = os.path.expanduser(target)

    if not raw_connection:
        try:
            db_connection = psycopg2.connect(database=maintenance_db, **kw)

            # Enable autocommit so we can create databases
            if psycopg2.__version__ >= '2.4.2':
                db_connection.autocommit = True
            else:
                db_connection.set_isolation_level(
                    psycopg2.extensions.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. Exception: {0}'
                    .format(to_native(e)),
                    exception=traceback.format_exc())
            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())

        if session_role:
            try:
                cursor.execute('SET ROLE "%s"' % session_role)
            except Exception as e:
                module.fail_json(msg="Could not switch role: %s" %
                                 to_native(e),
                                 exception=traceback.format_exc())

    try:
        if module.check_mode:
            if state == "absent":
                changed = db_exists(cursor, db)
            elif state == "present":
                changed = not db_matches(cursor, db, owner, template, encoding,
                                         lc_collate, lc_ctype, conn_limit,
                                         tablespace)
            module.exit_json(changed=changed,
                             db=db,
                             executed_commands=executed_commands)

        if state == "absent":
            try:
                changed = db_delete(cursor, db)
            except SQLParseError as e:
                module.fail_json(msg=to_native(e),
                                 exception=traceback.format_exc())

        elif state == "present":
            try:
                changed = db_create(cursor, db, owner, template, encoding,
                                    lc_collate, lc_ctype, conn_limit,
                                    tablespace)
            except SQLParseError as e:
                module.fail_json(msg=to_native(e),
                                 exception=traceback.format_exc())

        elif state in ("dump", "restore"):
            method = state == "dump" and db_dump or db_restore
            try:
                if state == 'dump':
                    rc, stdout, stderr, cmd = method(module, target,
                                                     target_opts, db,
                                                     dump_extra_args, **kw)
                else:
                    rc, stdout, stderr, cmd = method(module, target,
                                                     target_opts, db, **kw)

                if rc != 0:
                    module.fail_json(msg=stderr, stdout=stdout, rc=rc, cmd=cmd)
                else:
                    module.exit_json(changed=True,
                                     msg=stdout,
                                     stderr=stderr,
                                     rc=rc,
                                     cmd=cmd,
                                     executed_commands=executed_commands)
            except SQLParseError as e:
                module.fail_json(msg=to_native(e),
                                 exception=traceback.format_exc())

    except NotSupportedError as e:
        module.fail_json(msg=to_native(e), exception=traceback.format_exc())
    except SystemExit:
        # Avoid catching this on Python 2.4
        raise
    except Exception as e:
        module.fail_json(msg="Database query failed: %s" % to_native(e),
                         exception=traceback.format_exc())

    module.exit_json(changed=changed,
                     db=db,
                     executed_commands=executed_commands)
    def test_ensure_req_libs_has_psycopg2(self, m_ansible_module, monkeypatch):
        """Test ensure_required_libs() with psycopg2 is not None."""
        monkeypatch.setattr(pg, 'HAS_PSYCOPG2', True)

        pg.ensure_required_libs(m_ansible_module)
        assert m_ansible_module.err_msg == ''
 def test_ensure_req_libs_has_not_psycopg2(self, m_ansible_module):
     """Test ensure_required_libs() with psycopg2 is None."""
     # HAS_PSYCOPG2 is False by default
     pg.ensure_required_libs(m_ansible_module)
     assert 'Failed to import the required Python library (psycopg2)' in m_ansible_module.err_msg