Skip to content

Commit

Permalink
feat: Add all additional Cloud SQL Java Connector parameters to the s…
Browse files Browse the repository at this point in the history
…pring configuration.

This adds JDBC needed for lazy refresh, service account impersonation, universe domains, and alternate 
SQL Admin API endpoints to the JDBC configuration for a Cloud SQL JDBC connection. 

This is related to GoogleCloudPlatform/cloud-sql-jdbc-socket-factory#2065.
  • Loading branch information
hessjcg committed Oct 4, 2024
1 parent 05ad3ef commit a82e856
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 2 deletions.
7 changes: 7 additions & 0 deletions docs/src/main/asciidoc/sql.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,13 @@ Used to authenticate and authorize new connections to a Google Cloud SQL instanc
Used to authenticate and authorize new connections to a Google Cloud SQL instance. | No
| Default credentials provided by the Spring Framework on Google Cloud Core Starter
| `spring.cloud.gcp.sql.enableIamAuth` | Specifies whether to enable IAM database authentication (PostgreSQL only). | No | `False`
| `spring.cloud.gcp.sql.refreshStrategy` | The strategy used to refresh the Google Cloud SQL authentication tokens. Valid values: `background` - refresh credentials using a background thread, `lazy` - refresh credentials during connection attempts. | No | "background"
| `spring.cloud.gcp.sql.targetPrincipal` | The service account to impersonate when connecting to the database and database admin API. | No | (empty)
| `spring.cloud.gcp.sql.delegates` | A comma-separated list of service accounts delegates. | No | (empty)
| `spring.cloud.gcp.sql.universeDomain` | A universe domain for the TPC environment. | No | "googleapis.com"
| `spring.cloud.gcp.sql.adminRootUrl` | An alternate root url for the Cloud SQL admin API. | No | (empty)
| `spring.cloud.gcp.sql.adminServicePath` | An alternate path to the SQL Admin API endpoint. | No | (empty)
| `spring.cloud.gcp.sql.adminQuotaProject` | A project ID for quota and billing. | No | (empty)
|===

=== Troubleshooting tips
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@

package com.google.cloud.spring.autoconfigure.sql;

import java.net.URLEncoder;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

Expand Down Expand Up @@ -54,12 +58,49 @@ public String getJdbcUrl() {
this.properties.getDatabaseName(),
this.properties.getInstanceConnectionName());

// Build additional JDBC url parameters from the configuration.
Map<String, String> urlParams = new LinkedHashMap<>();
if (StringUtils.hasText(properties.getIpTypes())) {
jdbcUrl += "&ipTypes=" + properties.getIpTypes();
urlParams.put("ipTypes", properties.getIpTypes());
}

if (properties.isEnableIamAuth()) {
jdbcUrl += "&enableIamAuth=true&sslmode=disable";
urlParams.put("enableIamAuth", "true");
urlParams.put("sslmode", "disable");
}
if (StringUtils.hasText(properties.getTargetPrincipal())) {
urlParams.put("cloudSqlTargetPrincipal", properties.getTargetPrincipal());
}
if (StringUtils.hasText(properties.getDelegates())) {
urlParams.put("cloudSqlDelegates", properties.getDelegates());
}
if (StringUtils.hasText(properties.getAdminRootUrl())) {
urlParams.put("cloudSqlAdminRootUrl", properties.getAdminRootUrl());
}
if (StringUtils.hasText(properties.getAdminServicePath())) {
urlParams.put("cloudSqlAdminServicePath", properties.getAdminServicePath());
}
if (StringUtils.hasText(properties.getAdminQuotaProject())) {
urlParams.put("cloudSqlAdminQuotaProject", properties.getAdminQuotaProject());
}
if (StringUtils.hasText(properties.getUniverseDomain())) {
urlParams.put("cloudSqlUniverseDomain", properties.getUniverseDomain());
}
if (StringUtils.hasText(properties.getRefreshStrategy())) {
urlParams.put("cloudSqlRefreshStrategy", properties.getRefreshStrategy());
}

// Convert map to a string of url parameters
String urlParamsString =
urlParams.entrySet().stream()
.map(
entry ->
URLEncoder.encode(entry.getKey()) + "=" + URLEncoder.encode(entry.getValue()))
.collect(Collectors.joining("&"));

// Append url parameters to the JDBC URL.
if (StringUtils.hasText(urlParamsString)) {
jdbcUrl = jdbcUrl + "&" + urlParamsString;
}

return jdbcUrl;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,44 @@ public class GcpCloudSqlProperties {

/** Specifies whether to enable IAM database authentication (PostgreSQL only). */
private boolean enableIamAuth;
/**
* The target principal to use for service account impersonation. Corresponds to
* Cloud SQL Java Connector JDBC property cloudSqlTargetPrincipal
*/
private String targetPrincipal;

/**
* The chain of delegated service accounts to use for service account impersonation.
* Corresponds to Cloud SQL Java Connector JDBC property cloudSqlDelegates
*/
private String delegates;

/**
* The alternate admin root url for the Cloud SQL Admin API.
* Corresponds to Cloud SQL Java Connector JDBC property cloudSqlAdminRootUrl.
*/
private String adminRootUrl;
/**
* The alternate service path for the Cloud SQL Admin API
* Corresponds to Cloud SQL Java Connector JDBC property cloudSqlAdminServicePath.
*/
private String adminServicePath;
/**
* The quota project to use for API requests.
* Corresponds to Cloud SQL Java Connector JDBC property cloudSqlAdminQuotaProject
*/
private String adminQuotaProject;
/**
* The universe domain to use for API requests
* Corresponds to Cloud SQL Java Connector JDBC property cloudSqlUniverseDomain
*/
private String universeDomain;
/**
* The refresh strategy to use for API requests
* Corresponds to Cloud SQL Java Connector JDBC property cloudSqlRefreshStrategy
*/
private String refreshStrategy;


public String getDatabaseName() {
return this.databaseName;
Expand Down Expand Up @@ -76,4 +114,60 @@ public boolean isEnableIamAuth() {
public void setEnableIamAuth(boolean enableIamAuth) {
this.enableIamAuth = enableIamAuth;
}

public String getTargetPrincipal() {
return targetPrincipal;
}

public void setTargetPrincipal(String targetPrincipal) {
this.targetPrincipal = targetPrincipal;
}

public String getDelegates() {
return delegates;
}

public void setDelegates(String delegates) {
this.delegates = delegates;
}

public String getAdminRootUrl() {
return adminRootUrl;
}

public void setAdminRootUrl(String adminRootUrl) {
this.adminRootUrl = adminRootUrl;
}

public String getAdminServicePath() {
return adminServicePath;
}

public void setAdminServicePath(String adminServicePath) {
this.adminServicePath = adminServicePath;
}

public String getAdminQuotaProject() {
return adminQuotaProject;
}

public void setAdminQuotaProject(String adminQuotaProject) {
this.adminQuotaProject = adminQuotaProject;
}

public String getUniverseDomain() {
return universeDomain;
}

public void setUniverseDomain(String universeDomain) {
this.universeDomain = universeDomain;
}

public String getRefreshStrategy() {
return refreshStrategy;
}

public void setRefreshStrategy(String refreshStrategy) {
this.refreshStrategy = refreshStrategy;
}
}

0 comments on commit a82e856

Please sign in to comment.