Beispiel #1
0
def ensure_db_relation_resources(rel):
    """Create the database resources needed for the relation."""

    master = rel.local

    if "password" not in master:
        return

    hookenv.log("Ensuring database {!r} and user {!r} exist for {}" "".format(master["database"], master["user"], rel))

    # First create the database, if it isn't already.
    postgresql.ensure_database(master["database"])

    # Next, connect to the database to create the rest in a transaction.
    con = postgresql.connect(database=master["database"])

    superuser, replication = _credential_types(rel)
    postgresql.ensure_user(
        con,
        master["user"],
        master["password"],
        superuser=superuser,
        replication=replication,
    )
    if not superuser:
        postgresql.ensure_user(con, master["schema_user"], master["schema_password"])

    # Grant specified privileges on the database to the user. This comes
    # from the PostgreSQL service configuration, as allowing the
    # relation to specify how much access it gets is insecure.
    config = hookenv.config()
    privs = set(filter(None, config["relation_database_privileges"].split(",")))
    postgresql.grant_database_privileges(con, master["user"], master["database"], privs)
    if not superuser:
        postgresql.grant_database_privileges(con, master["schema_user"], master["database"], privs)

    # Reset the roles granted to the user as requested.
    if "roles" in master:
        roles = filter(None, master.get("roles", "").split(","))
        postgresql.grant_user_roles(con, master["user"], roles)

    # Create requested extensions. We never drop extensions, as there
    # may be dependent objects.
    if "extensions" in master:
        extensions = list(filter(None, master.get("extensions", "").split(",")))
        # Convert to the (extension, schema) tuple expected by
        # postgresql.ensure_extensions
        for i in range(0, len(extensions)):
            m = re.search(r"^\s*([^(\s]+)\s*(?:\((\w+)\))?", extensions[i])
            if m is None:
                raise RuntimeError("Invalid extension {}".format(extensions[i]))
            extensions[i] = (m.group(1), m.group(2) or "public")
        postgresql.ensure_extensions(con, extensions)

    con.commit()  # Don't throw away our changes.
Beispiel #2
0
    def test_grant_database_privileges(self):
        con = MagicMock()
        cur = con.cursor()
        privs = ['privA', 'privB']
        postgresql.grant_database_privileges(con, 'a_Role', 'a_DB', privs)

        cur.execute.assert_has_calls([
            call(
                "GRANT %s ON DATABASE %s TO %s",
                (
                    postgresql.AsIs('privA'),  # Unquoted. Its a keyword.
                    postgresql.AsIs('"a_DB"'),
                    postgresql.AsIs('"a_Role"'))),
            call("GRANT %s ON DATABASE %s TO %s",
                 (postgresql.AsIs('privB'), postgresql.AsIs('"a_DB"'),
                  postgresql.AsIs('"a_Role"')))
        ])
Beispiel #3
0
def ensure_db_relation_resources(rel):
    """Create the database resources needed for the relation."""

    master = rel.local

    hookenv.log("Ensuring database {!r} and user {!r} exist for {}" "".format(master["database"], master["user"], rel))

    # First create the database, if it isn't already.
    postgresql.ensure_database(master["database"])

    # Next, connect to the database to create the rest in a transaction.
    con = postgresql.connect(database=master["database"])

    superuser, replication = _credential_types(rel)
    postgresql.ensure_user(con, master["user"], master["password"], superuser=superuser, replication=replication)
    if not superuser:
        postgresql.ensure_user(con, master["schema_user"], master["schema_password"])

    # Grant specified privileges on the database to the user. This comes
    # from the PostgreSQL service configuration, as allowing the
    # relation to specify how much access it gets is insecure.
    config = hookenv.config()
    privs = set(filter(None, config["relation_database_privileges"].split(",")))
    postgresql.grant_database_privileges(con, master["user"], master["database"], privs)
    if not superuser:
        postgresql.grant_database_privileges(con, master["schema_user"], master["database"], privs)

    # Reset the roles granted to the user as requested.
    if "roles" in master:
        roles = filter(None, master.get("roles", "").split(","))
        postgresql.grant_user_roles(con, master["user"], roles)

    # Create requested extensions. We never drop extensions, as there
    # may be dependent objects.
    if "extensions" in master:
        extensions = filter(None, master.get("extensions", "").split(","))
        postgresql.ensure_extensions(con, extensions)

    con.commit()  # Don't throw away our changes.
    def test_grant_database_privileges(self):
        con = MagicMock()
        cur = con.cursor()
        privs = ["privA", "privB"]
        postgresql.grant_database_privileges(con, "a_Role", "a_DB", privs)

        cur.execute.assert_has_calls(
            [
                call(
                    "GRANT %s ON DATABASE %s TO %s",
                    (
                        postgresql.AsIs("privA"),  # Unquoted. Its a keyword.
                        postgresql.AsIs('"a_DB"'),
                        postgresql.AsIs('"a_Role"'),
                    ),
                ),
                call(
                    "GRANT %s ON DATABASE %s TO %s",
                    (postgresql.AsIs("privB"), postgresql.AsIs('"a_DB"'), postgresql.AsIs('"a_Role"')),
                ),
            ]
        )