Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,12 @@ function test() {
if [[ "$(uname -s)" == "Darwin" ]]; then
echo "macOS detected. Setting up IP aliases for tests."
echo "You may be prompted for your password to run sudo."
sudo ifconfig lo0 alias 127.0.0.2 up
sudo ifconfig lo0 alias 127.0.0.3 up
if ! ifconfig lo0 | grep -q 127.0.0.2 ; then
sudo ifconfig lo0 alias 127.0.0.2 up
fi
if ! ifconfig lo0 | grep -q 127.0.0.3 ; then
sudo ifconfig lo0 alias 127.0.0.3 up
fi
fi
$mvn_cmd -P coverage test
}
Expand Down Expand Up @@ -93,7 +97,7 @@ function write_e2e_env(){
secret_vars=(
MYSQL_CONNECTION_NAME=MYSQL_CONNECTION_NAME
MYSQL_USER=MYSQL_USER
MYSQL_USER_IAM=MYSQL_USER_IAM_GO
IMPERSONATED_USER=IMPERSONATED_USER
MYSQL_PASS=MYSQL_PASS
MYSQL_DB=MYSQL_DB
MYSQL_MCP_CONNECTION_NAME=MYSQL_MCP_CONNECTION_NAME
Expand All @@ -107,8 +111,8 @@ function write_e2e_env(){
POSTGRES_CAS_PASS=POSTGRES_CAS_PASS
POSTGRES_CUSTOMER_CAS_CONNECTION_NAME=POSTGRES_CUSTOMER_CAS_CONNECTION_NAME
POSTGRES_CUSTOMER_CAS_PASS=POSTGRES_CUSTOMER_CAS_PASS
POSTGRES_CUSTOMER_CAS_DOMAIN_NAME=POSTGRES_CUSTOMER_CAS_DOMAIN_NAME
POSTGRES_CUSTOMER_CAS_INVALID_DOMAIN_NAME=POSTGRES_CUSTOMER_CAS_INVALID_DOMAIN_NAME
POSTGRES_CUSTOMER_CAS_PASS_VALID_DOMAIN_NAME=POSTGRES_CUSTOMER_CAS_DOMAIN_NAME
POSTGRES_CUSTOMER_CAS_PASS_INVALID_DOMAIN_NAME=POSTGRES_CUSTOMER_CAS_INVALID_DOMAIN_NAME
POSTGRES_MCP_CONNECTION_NAME=POSTGRES_MCP_CONNECTION_NAME
POSTGRES_MCP_PASS=POSTGRES_MCP_PASS
SQLSERVER_CONNECTION_NAME=SQLSERVER_CONNECTION_NAME
Expand All @@ -133,6 +137,10 @@ function write_e2e_env(){
val=$(gcloud secrets versions access latest --project "$TEST_PROJECT" --secret="$secret_name")
echo "export $env_var_name='$val'"
done

echo "export MYSQL_IAM_USER='$(whoami)'"
echo "export POSTGRES_IAM_USER='$(whoami)@google.com'"

} > "$outfile"

}
Expand Down
41 changes: 40 additions & 1 deletion core/src/main/java/com/google/cloud/sql/core/Connector.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,12 @@
import com.google.common.util.concurrent.ListeningScheduledExecutorService;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyPair;
import java.util.List;
import java.util.Timer;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
Expand All @@ -52,6 +55,7 @@ class Connector {
private final ConnectorConfig config;

private final InstanceConnectionNameResolver instanceNameResolver;
private final DnsResolver dnsResolver;
private final Timer instanceNameResolverTimer;
private final ProtocolHandler mdxProtocolHandler;

Expand All @@ -65,9 +69,9 @@ class Connector {
long refreshTimeoutMs,
int serverProxyPort,
InstanceConnectionNameResolver instanceNameResolver,
DnsResolver dnsResolver,
ProtocolHandler mdxProtocolHandler) {
this.config = config;

this.adminApi =
connectionInfoRepositoryFactory.create(instanceCredentialFactory.create(), config);
this.instanceCredentialFactory = instanceCredentialFactory;
Expand All @@ -76,6 +80,7 @@ class Connector {
this.minRefreshDelayMs = minRefreshDelayMs;
this.serverProxyPort = serverProxyPort;
this.instanceNameResolver = instanceNameResolver;
this.dnsResolver = dnsResolver;
this.instanceNameResolverTimer = new Timer("InstanceNameResolverTimer", true);
this.mdxProtocolHandler = mdxProtocolHandler;
}
Expand Down Expand Up @@ -125,6 +130,40 @@ Socket connect(ConnectionConfig config, long timeoutMs) throws IOException {
try {
ConnectionMetadata metadata = instance.getConnectionMetadata(timeoutMs);
String instanceIp = metadata.getPreferredIpAddress();

// If a domain name was used to connect, resolve it to an IP address
if (!Strings.isNullOrEmpty(instance.getConfig().getDomainName())) {
try {
List<InetAddress> addrs = dnsResolver.resolveHost(instance.getConfig().getDomainName());
if (addrs != null && !addrs.isEmpty()) {
logger.debug(
String.format(
"[%s] custom DNS name %s resolved to %s, using it to connect",
instance.getConfig().getCloudSqlInstance(),
instance.getConfig().getDomainName(),
addrs.get(0).getHostAddress()));
instanceIp = addrs.get(0).getHostAddress();
} else {
logger.debug(
String.format(
"[%s] custom DNS name %s resolved but returned no entries, using %s from"
+ " instance metadata",
instance.getConfig().getCloudSqlInstance(),
instance.getConfig().getDomainName(),
instanceIp));
}
} catch (UnknownHostException e) {
logger.debug(
String.format(
"[%s] custom DNS name %s did not resolve to an IP address: %s, using %s from"
+ " instance metadata",
instance.getConfig().getCloudSqlInstance(),
instance.getConfig().getDomainName(),
e.getMessage(),
instanceIp));
}
}

logger.debug(String.format("[%s] Connecting to instance.", instanceIp));

SSLSocket socket = (SSLSocket) metadata.getSslContext().getSocketFactory().createSocket();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,15 @@

package com.google.cloud.sql.core;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import javax.naming.NameNotFoundException;
import org.xbill.DNS.ARecord;
import org.xbill.DNS.Lookup;
import org.xbill.DNS.Record;
import org.xbill.DNS.SimpleResolver;
Expand Down Expand Up @@ -105,4 +109,44 @@ public Collection<String> resolveTxt(String domainName) throws NameNotFoundExcep
throw new RuntimeException("Invalid domain name format: " + domainName, e);
}
}

/**
* Resolve an A record.
*
* @param hostName the hostname to look up
* @return the resolved IP addresses
* @throws UnknownHostException if no records are found.
*/
@Override
public List<InetAddress> resolveHost(String hostName) throws UnknownHostException {
Comment on lines +120 to +121
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: add comment description

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

try {
Lookup lookup = new Lookup(hostName, Type.A);
if (this.resolver != null) {
lookup.setResolver(this.resolver);
}
lookup.run();

int resultCode = lookup.getResult();
if (resultCode == Lookup.HOST_NOT_FOUND) {
throw new UnknownHostException("DNS record not found for " + hostName);
}
if (resultCode != Lookup.SUCCESSFUL) {
throw new UnknownHostException(
"DNS lookup failed for " + hostName + ": " + lookup.getErrorString());
}

Record[] records = lookup.getAnswers();
if (records == null || records.length == 0) {
return Collections.emptyList();
}

return Arrays.stream(records)
.map(r -> (ARecord) r)
.map(ARecord::getAddress)
.collect(Collectors.toList());

} catch (TextParseException e) {
throw new UnknownHostException("Invalid domain name format: " + hostName);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,15 @@

package com.google.cloud.sql.core;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Collection;
import java.util.List;
import javax.naming.NameNotFoundException;

/** Wraps the Java DNS API. */
interface DnsResolver {
Collection<String> resolveTxt(String domainName) throws NameNotFoundException;

List<InetAddress> resolveHost(String hostName) throws UnknownHostException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ private Connector createConnector(ConnectorConfig config) {
connectTimeoutMs,
serverProxyPort,
new DnsInstanceConnectionNameResolver(new DnsJavaResolver()),
new DnsJavaResolver(),
this.mdxProtocolHandler);
}

Expand Down
Loading
Loading