getRDSConnection returns the connection string with IAM for AWS RDS. refs: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.Connecting.Go.html https://repost.aws/knowledge-center/rds-mysql-access-denied
(ctx context.Context, connCfg db.ConnectionConfig)
| 196 | // https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.Connecting.Go.html |
| 197 | // https://repost.aws/knowledge-center/rds-mysql-access-denied |
| 198 | func (d *Driver) getRDSConnection(ctx context.Context, connCfg db.ConnectionConfig) (string, error) { |
| 199 | dbEndpoint := fmt.Sprintf("%s:%s", connCfg.DataSource.Host, connCfg.DataSource.Port) |
| 200 | cfg, err := util.GetAWSConnectionConfig(ctx, connCfg) |
| 201 | if err != nil { |
| 202 | return "", errors.Wrap(err, "load aws config failed") |
| 203 | } |
| 204 | |
| 205 | // Handle cross-account role assumption if configured |
| 206 | if err := util.AssumeRoleIfNeeded(ctx, &cfg, connCfg.ConnectionContext, connCfg.DataSource.GetAwsCredential()); err != nil { |
| 207 | return "", err |
| 208 | } |
| 209 | |
| 210 | authenticationToken, err := auth.BuildAuthToken( |
| 211 | ctx, dbEndpoint, connCfg.DataSource.GetRegion(), connCfg.DataSource.Username, cfg.Credentials) |
| 212 | if err != nil { |
| 213 | return "", errors.Wrap(err, "failed to create authentication token") |
| 214 | } |
| 215 | |
| 216 | // Get RDS CA certificate pool |
| 217 | rootCertPool, err := getRDSCertPool(ctx) |
| 218 | if err != nil { |
| 219 | return "", errors.Wrap(err, "failed to get RDS cert pool") |
| 220 | } |
| 221 | |
| 222 | // Create TLS config with unique name for this connection |
| 223 | tlsKey := uuid.NewString() |
| 224 | |
| 225 | var tlsConfig *tls.Config |
| 226 | if connCfg.DataSource.GetVerifyTlsCertificate() { |
| 227 | // Secure config with certificate verification |
| 228 | tlsConfig = &tls.Config{ |
| 229 | RootCAs: rootCertPool, |
| 230 | InsecureSkipVerify: true, // We use custom verification |
| 231 | } |
| 232 | tlsConfig.VerifyPeerCertificate = util.CreateCertificateVerifier(rootCertPool, connCfg.DataSource.Host) |
| 233 | } else { |
| 234 | // Backward compatible config without verification |
| 235 | tlsConfig = &tls.Config{ |
| 236 | RootCAs: rootCertPool, |
| 237 | InsecureSkipVerify: true, |
| 238 | } |
| 239 | } |
| 240 | |
| 241 | // Register the TLS config with unique name |
| 242 | if err := mysql.RegisterTLSConfig(tlsKey, tlsConfig); err != nil { |
| 243 | return "", errors.Wrap(err, "failed to register RDS TLS config") |
| 244 | } |
| 245 | |
| 246 | // Clean up the TLS config after connection |
| 247 | d.openCleanUp = append(d.openCleanUp, func() { mysql.DeregisterTLSConfig(tlsKey) }) |
| 248 | |
| 249 | return fmt.Sprintf("%s:%s@tcp(%s)/%s?tls=%s&allowCleartextPasswords=true&multiStatements=true&maxAllowedPacket=0", |
| 250 | connCfg.DataSource.Username, authenticationToken, dbEndpoint, connCfg.ConnectionContext.DatabaseName, tlsKey, |
| 251 | ), nil |
| 252 | } |
| 253 | |
| 254 | func getCloudSQLConnection(ctx context.Context, connCfg db.ConnectionConfig) (string, error) { |
| 255 | d, err := util.GetGCPConnectionConfig(ctx, connCfg) |
no test coverage detected