postgresql 使用IAM从App Engine Standard连接到Postgres Cloud SQL是否超时?

2skhul33  于 2023-06-22  发布在  PostgreSQL
关注(0)|答案(2)|浏览(207)

在这里尝试示例代码:https://cloud.google.com/sql/docs/postgres/connect-app-engine-standard#connect-connectors...这里:https://cloud.google.com/sql/docs/postgres/iam-logins
...使用私有IP时连接超时(但使用示例名正确解析私有IP),与公有IP相同的代码(通过调整拨号器)说:
SASL身份验证失败(致命:用户““的密码身份验证失败(SQLSTATE 28P01)
通过我的客户端计算机上的云SQL代理连接IAM确实有效。由于这两个选项都不适用于App Engine Standard,并且日志显示没有有用的信息,是否有已知的解决方案或建议?
我用的是Go,这里的代码是“编辑过的”版本...

import (
    "database/sql"
    "fmt"
    "net"

    "cloud.google.com/go/cloudsqlconn"
    pgx "github.com/jackc/pgx/v4"
    pgxStdlib "github.com/jackc/pgx/v4/stdlib"
)

func test() {
    var dialOptions []cloudsqlconn.DialOption

    if usePrivateIP {
        dialOptions = append(dialOptions, cloudsqlconn.WithPrivateIP())
    }

    var dialer *cloudsqlconn.Dialer
    dialer, err := cloudsqlconn.NewDialer(
        context.Background(),
        cloudsqlconn.WithIAMAuthN(),
        cloudsqlconn.WithDefaultDialOptions(dialOptions...),
    )

    if err != nil {
        return
    }

    config, err =: pgx.ParseConfig(fmt.Sprintf(
        "user=%s password=%s database=%s",
        user,
        password,
        databaseName,
    ))

    if err != nil {
        return
    }

     config.DialFunc = func(ctx context.Context, _ string, _ string) (net.Conn, error) {
        return dialer.Dial(ctx, instanceName)
    }

    var db *sql.DB
    db, err := sql.Open("pgx", pgxStdlib.RegisterConnConfig(config))

    if err != nil {
        return
    }

    _ = db // should be live
}
jxct1oxe

jxct1oxe1#

私有IP可能超时,因为您需要配置无服务器VPC访问连接器以确保到数据库的网络路径。
当您尝试使用公共IP时,您确实连接到了数据库,但身份验证失败。这可能是因为您是作为独立的IAM主体而不是数据库用户运行App Engine应用程序。
以下是它的整体外观:

// password is intentionally blank
    dsn := fmt.Sprintf("user=%s password=\"\" dbname=%s sslmode=disable", postgresUserIAM, postgresDB)
    config, err := pgx.ParseConfig(dsn)
    if err != nil {
        t.Fatalf("failed to parse pgx config: %v", err)
    }
    d, err := cloudsqlconn.NewDialer(ctx, cloudsqlconn.WithIAMAuthN())
    if err != nil {
        t.Fatalf("failed to initiate Dialer: %v", err)
    }
    defer d.Close()
    config.DialFunc = func(ctx context.Context, network string, instance string) (net.Conn, error) {
        return d.Dial(ctx, postgresConnName)
    }

    conn, connErr := pgx.ConnectConfig(ctx, config)
    if connErr != nil {
        t.Fatalf("failed to connect: %s", connErr)
    }
    defer conn.Close(ctx)

    var now time.Time
    err = conn.QueryRow(context.Background(), "SELECT NOW()").Scan(&now)
    if err != nil {
        t.Fatalf("QueryRow failed: %s", err)
    }

看看我们是怎么把它接上去的。

j2qf4p5b

j2qf4p5b2#

您需要使用XX@appspot而不是完整的IAM服务帐户(XX@appspot.gserviceaccount.com)地址。
感谢@enocom在我们进行故障排除时在他的评论中强调了这一点,因为不清楚这些值是否可以从文档中互换,而客户端计算机的Cloud SQL Proxy可以为您做到这一点。

相关问题