secrets/database: Add usePrivateIP field for cloudsql postgresql instances (#26828)

* add usePrivateIP params to determine if to use private ip dial option

Signed-off-by: aviv guiser <avivguiser@gmail.com>

* fix the connection_producer.go in mysql plugin

Signed-off-by: aviv guiser <avivguiser@gmail.com>

* Update sdk/database/helper/connutil/sql.go

Co-authored-by: Robert <17119716+robmonte@users.noreply.github.com>

---------

Signed-off-by: aviv guiser <avivguiser@gmail.com>
Signed-off-by: AvivGuiser <aviv.guiser@placer.ai>
Co-authored-by: Robert <17119716+robmonte@users.noreply.github.com>
This commit is contained in:
AvivGuiser
2024-06-25 22:17:13 +03:00
committed by GitHub
parent bf878c4248
commit 3372a9b4db
6 changed files with 18 additions and 5 deletions

3
changelog/26828.txt Normal file
View File

@@ -0,0 +1,3 @@
```release-note:improvement
secrets/database: Add support for GCP CloudSQL private IP's.
```

View File

@@ -322,7 +322,7 @@ func (c *mySQLConnectionProducer) rewriteProtocolForGCP(inDSN string) (string, e
} }
func registerDriverMySQL(driverName, credentials string) (cleanup func() error, err error) { func registerDriverMySQL(driverName, credentials string) (cleanup func() error, err error) {
opts, err := connutil.GetCloudSQLAuthOptions(credentials) opts, err := connutil.GetCloudSQLAuthOptions(credentials, false)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -27,13 +27,13 @@ func (c *SQLConnectionProducer) getCloudSQLDriverType() (string, error) {
return driverType, nil return driverType, nil
} }
func (c *SQLConnectionProducer) registerDrivers(driverName string, credentials string) (func() error, error) { func (c *SQLConnectionProducer) registerDrivers(driverName string, credentials string, usePrivateIP bool) (func() error, error) {
typ, err := c.getCloudSQLDriverType() typ, err := c.getCloudSQLDriverType()
if err != nil { if err != nil {
return nil, err return nil, err
} }
opts, err := GetCloudSQLAuthOptions(credentials) opts, err := GetCloudSQLAuthOptions(credentials, usePrivateIP)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -49,13 +49,17 @@ func (c *SQLConnectionProducer) registerDrivers(driverName string, credentials s
// GetCloudSQLAuthOptions takes a credentials JSON and returns // GetCloudSQLAuthOptions takes a credentials JSON and returns
// a set of GCP CloudSQL options - always WithIAMAUthN, and then the appropriate file/JSON option. // a set of GCP CloudSQL options - always WithIAMAUthN, and then the appropriate file/JSON option.
func GetCloudSQLAuthOptions(credentials string) ([]cloudsqlconn.Option, error) { func GetCloudSQLAuthOptions(credentials string, usePrivateIP bool) ([]cloudsqlconn.Option, error) {
opts := []cloudsqlconn.Option{cloudsqlconn.WithIAMAuthN()} opts := []cloudsqlconn.Option{cloudsqlconn.WithIAMAuthN()}
if credentials != "" { if credentials != "" {
opts = append(opts, cloudsqlconn.WithCredentialsJSON([]byte(credentials))) opts = append(opts, cloudsqlconn.WithCredentialsJSON([]byte(credentials)))
} }
if usePrivateIP {
opts = append(opts, cloudsqlconn.WithDefaultDialOptions(cloudsqlconn.WithPrivateIP()))
}
return opts, nil return opts, nil
} }

View File

@@ -40,6 +40,7 @@ type SQLConnectionProducer struct {
AuthType string `json:"auth_type" mapstructure:"auth_type" structs:"auth_type"` AuthType string `json:"auth_type" mapstructure:"auth_type" structs:"auth_type"`
ServiceAccountJSON string `json:"service_account_json" mapstructure:"service_account_json" structs:"service_account_json"` ServiceAccountJSON string `json:"service_account_json" mapstructure:"service_account_json" structs:"service_account_json"`
DisableEscaping bool `json:"disable_escaping" mapstructure:"disable_escaping" structs:"disable_escaping"` DisableEscaping bool `json:"disable_escaping" mapstructure:"disable_escaping" structs:"disable_escaping"`
usePrivateIP bool `json:"use_private_ip" mapstructure:"use_private_ip" structs:"use_private_ip"`
// cloud options here - cloudDriverName is globally unique, but only needs to be retained for the lifetime // cloud options here - cloudDriverName is globally unique, but only needs to be retained for the lifetime
// of driver registration, not across plugin restarts. // of driver registration, not across plugin restarts.
@@ -140,7 +141,7 @@ func (c *SQLConnectionProducer) Init(ctx context.Context, conf map[string]interf
// however, the driver might store a credentials file, in which case the state stored by the driver is in // however, the driver might store a credentials file, in which case the state stored by the driver is in
// fact critical to the proper function of the connection. So it needs to be registered here inside the // fact critical to the proper function of the connection. So it needs to be registered here inside the
// ConnectionProducer init. // ConnectionProducer init.
dialerCleanup, err := c.registerDrivers(c.cloudDriverName, c.ServiceAccountJSON) dialerCleanup, err := c.registerDrivers(c.cloudDriverName, c.ServiceAccountJSON, c.usePrivateIP)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -58,6 +58,9 @@ has a number of parameters to further configure a connection.
- `service_account_json` `(string: "")` - JSON encoded credentials for a GCP Service Account to use - `service_account_json` `(string: "")` - JSON encoded credentials for a GCP Service Account to use
for IAM authentication. Requires `auth_type` to be `gcp_iam`. for IAM authentication. Requires `auth_type` to be `gcp_iam`.
- `use_private_ip` `(boolean: false)` - Enables the option to connect to CloudSQL Instances with Private IP.
Requires `auth_type` to be `gcp_iam`.
- `username_template` `(string)` - [Template](/vault/docs/concepts/username-templating) describing how - `username_template` `(string)` - [Template](/vault/docs/concepts/username-templating) describing how
dynamic usernames are generated. dynamic usernames are generated.

View File

@@ -128,6 +128,7 @@ ALTER USER "<YOUR DB USERNAME>" WITH CREATEROLE;
plugin_name="postgresql-database-plugin" \ plugin_name="postgresql-database-plugin" \
allowed_roles="my-role" \ allowed_roles="my-role" \
connection_url="host=project:us-west1:mydb user=test-user@project.iam dbname=postgres sslmode=disable" \ connection_url="host=project:us-west1:mydb user=test-user@project.iam dbname=postgres sslmode=disable" \
use_private_ip="false" \
auth_type="gcp_iam" auth_type="gcp_iam"
``` ```
@@ -139,6 +140,7 @@ ALTER USER "<YOUR DB USERNAME>" WITH CREATEROLE;
plugin_name="postgresql-database-plugin" \ plugin_name="postgresql-database-plugin" \
allowed_roles="my-role" \ allowed_roles="my-role" \
connection_url="host=project:region:instance user=test-user@project.iam dbname=postgres sslmode=disable" \ connection_url="host=project:region:instance user=test-user@project.iam dbname=postgres sslmode=disable" \
use_private_ip="false" \
auth_type="gcp_iam" \ auth_type="gcp_iam" \
service_account_json="@my_credentials.json" service_account_json="@my_credentials.json"
``` ```