2017-06-20 2 views
2

Ich habe eine AWS RDS Instanz von PostgreSQL, in denen ich brauche eine SQL Anweisung innerhalb einer Funktion dblink_connect(text) und dblink_exec(text) während angemeldet mit der postgres Rolle auszuführen (die ich erstellt).RDS PostgreSQL vermeiden bei der Verwendung von dblink_connect()

CREATE OR REPLACE FUNCTION application.create_tenant_schemas(first integer, last integer) RETURNS void AS 
DECLARE 
    tenant VARCHAR; 
    sql VARCHAR; 
BEGIN 
    FOR index IN first..last LOOP 
    tenant := 'tenant_' || to_char(index, 'FM00000'); 

    sql := 'CREATE SCHEMA ' || quote_ident(tenant); 
    RAISE NOTICE '%', sql; 

    PERFORM dblink_connect('dbname=application user=postgres'); 
    PERFORM dblink_exec(sql); 
    PERFORM dblink_disconnect(); 

    END LOOP; 
END; 
$BODY$ 
LANGUAGE plpgsql; 

Die dblink_exec() erzeugt folgende Fehlermeldungen:

[2F003] ERROR: password is required 
Detail: Non-superusers must provide a password in the connection string. 
Where: SQL statement "SELECT dblink_connect('dbname=application user=postgres')" 

ich eine answer gefunden, die mit dblink_connect_u(text) vorgeschlagen. Als ich das versucht habe ich folgende Fehlermeldungen:

[42501] ERROR: permission denied for function dblink_connect_u 
Where: SQL statement "SELECT dblink_connect_u('dbname=application user=postgres')" 

Auf AWS wie kann ich den Benutzer geben, die die RDS-Instanz Erlaubnis erstellt auszuführen Funktion dblink_connect_u()? Ich habe versucht, die folgenden ohne Erfolg:

GRANT EXECUTE ON FUNCTION dblink_connect_u(text) TO postgres; 
GRANT EXECUTE ON FUNCTION dblink_connect_u(text, text) TO postgres; 

Es scheint, mein postgres Benutzer muss superuser Berechtigungen, auf die ich anscheinend nicht auf AWS haben.

Ich spielte auch mit %APPDATA%\postgresql\pgpass.conf (unter Windows), um das Passwort für dblink_connect(text)dblink_connect(text) aber dblink_connect(text) offenbar ignoriert diese Datei.

konnte ich ein hart codiert die Passwort-String verwenden dblink_connect(text) rufen Sie wie folgt vor:

PERFORM "pascal"."dblink_connect_u"('dbname=pascal user=postgres password=secret'); 

... schließlich, dies aufgrund der harten Codierung des Passworts keine akzeptable Lösung.

Hat jemand einen Vorschlag, wie man RDS PostgreSQL entweder zur Verwendung der Passwort-Datei oder erlauben Sie mir GRANT EXECUTE ON FUNCTION dblink_connect_u(text) oder gibt es eine andere Alternative, die ich nicht gefunden habe?

UPDATE

Links zu PostgreSQL-Dokumentation für den Versuch, eine Fremddaten Wrapper/Server, in dem das Passwort für den Benutzer speichern einrichten, die dblink_connect(text)

CREATE SERVER

CREATE FOREIGN DATA WRAPPER

ist die Ausführung

CREATE USER MAPPING

FAZIT

CREATE SERVER "password_server" FOREIGN DATA WRAPPER "dblink_fdw" 
OPTIONS (dbname 'application'); 

CREATE USER MAPPING FOR "postgres" 
SERVER "password_server" 
OPTIONS (user 'postgres', password 'pa55VV0&d'); 

... andere Quelldatei ...

CREATE OR REPLACE FUNCTION application.create_tenant_schemas(first integer, last integer) RETURNS VOID AS $$ 
DECLARE 
    tenant VARCHAR; 
    sql VARCHAR; 
BEGIN 
    FOR index IN first..last LOOP 
    tenant := 'tenant_' || to_char(index, 'FM00000'); 

    sql := 'CREATE SCHEMA ' || quote_ident(tenant); 
    RAISE NOTICE '%', sql; 

    PERFORM "dblink_connect"('password_server'); 
    PERFORM "dblink_exec"(sql); 
    PERFORM "dblink_disconnect"(); 
    END LOOP; 
END; 
$BODY$ 
LANGUAGE plpgsql; 

Antwort

2

Sie können Benutzerzuordnung erstellen:

  1. create server application_srv foreign data wrapper dblink_fdw OPTIONS (...;
  2. create user mapping FOR app_user SERVER application_srv OPTIONS (user 'user_to_connect', password 'password goes here');
  3. Verwendung application_srv in dblink Verbindungsname:

.

t# select * from dblink('application_srv','select max(t) from t') as t(m timestamp(0)); 
      m 
--------------------- 
2017-06-13 11:41:05 
(1 row) 

jetzt wird das Passwort in Klartext pg_user_mappings (pg_user_mapping sollte für jedermann im RDS nicht wählbar) angezeigt werden, aber der eigentliche Pass wird nur rds_superuser

+0

Nette Idee angezeigt. Leider scheint es, dass, um den 'CREATE SERVER'-Befehl auszuführen, ich einen' FOREIGN DATA WRAPPER' definiere und den 'FOREIGN DATA WRAPPER' definiere, muss ich Superuser-Privilegien haben, die mich dahin zurückbringen, wo ich angefangen habe ... – Neoheurist

+0

Nein - ich habe diese Lösung von meiner Mautbox gegeben. So mache ich es auf RDS. Bitte offenbaren die Aussage und den Fehler –

+0

Mein Fehler. Ich musste die Erweiterung 'dblink' in der Datenbank installieren, in der ich den' FOREIGN DATA WRAPPER' hinzufügen wollte - ich experimentierte in einer Datenbank, in der die Erweiterung 'dblink' nicht installiert war ... – Neoheurist

Verwandte Themen