2017-06-20 81 views
2

私は(そのI私はpostgres役割でログインdblink_connect(text)dblink_exec(text)しばらく使って関数内SQL文を実行する必要があるではPostgreSQLのAWS RDSインスタンスを持っています作成した)。PostgreSQLはRDS 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; 

dblink_exec()は、次のエラーメッセージが生成されます。

[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')" 

私は​​を使うことを提案answerを見つけました。私はこれを試したとき、私は次のエラーメッセージを得た:AWS上で

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

どのように私は機能dblink_connect_u()を実行するためのRDSインスタンスのアクセス許可を作成したユーザーを与えることができますか?私は成功せず、次を試してみました:

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

私のpostgresユーザーが、私は明らかにAWS上で持つことができない先のsuperuser権限が必要と思われます。

(Windowsの場合)を使用してdblink_connect(text)のパスワードを提供していますが、dblink_connect(text)は明らかにこのファイルを無視しています。

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

...最終的には、これが原因パスワードのハードコーディングに許容可能なソリューションではありません。次のように

私は dblink_connect(text)を呼び出すためにハードコードされたパスワード文字列を使用することができました。

RDS PostgreSQLを入手してパスワードファイルを使用する方法や、私にGRANT EXECUTE ON FUNCTION dblink_connect_u(text)を許可する方法の提案がありますか、それとも私が見逃した別の方法がありますか? dblink_connect(text)

CREATE SERVER

CREATE FOREIGN DATA WRAPPER

を実行していますユーザーのパスワードを格納するためにいる外国人のデータラッパ/サーバを設定しようとするためのPostgreSQLのドキュメントへ

UPDATE

リンク

CREATE USER MAPPING

結論

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'); 

...別のソース・ファイル...

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; 

答えて

2

あなたは、ユーザー・マッピングを作成することができます。

  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. 使用application_srv

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) 

は今、パスワードは(pg_user_mappingはRDSの誰のための選択ではないはずです)pg_user_mappingsでプレーンテキストを表示されますが、実際のパスはrds_superuser

+0

ナイスアイデアに表示されます。残念ながら、 'CREATE SERVER'コマンドを実行するために、私は' FOREIGN DATA WRAPPER'を定義する必要があり、 'FOREIGN DATA WRAPPER'を定義するためには、スーパーユーザー権限を持っていなければなりません。 – Neoheurist

+0

いいえ - 私はこのソリューションを私の通話箱から出しました。これが私がRDSでやる方法です。声明を開示してください。 –

+0

私の間違い。私は 'dlink'拡張子をデータベースにインストールする必要がありました。私は' FOREIGN DATA WRAPPER'を追加しようとしていました - 'dblink'拡張子がインストールされていないデータベースで実験していました... – Neoheurist

関連する問題