Add canary service to GKE (#2594)

This commit is contained in:
Lai Jiang
2024-10-22 17:12:00 +00:00
committed by GitHub
parent 4d96e5a6b1
commit a9ba770bfa
20 changed files with 368 additions and 49 deletions
@@ -261,6 +261,13 @@ public abstract class ProtocolModuleTest {
return Suppliers.ofInstance("fake.test.id.token");
}
@Singleton
@Provides
@Named("canary")
static boolean provideIsCanary() {
return false;
}
@Singleton
@Provides
static LoggingHandler provideLoggingHandler() {
@@ -25,7 +25,6 @@ import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpMessage;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpMessage;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpRequest;
@@ -53,6 +52,22 @@ public final class TestUtils {
return request;
}
public static FullHttpRequest makeHttpPostRequest(
String content, String host, String path, boolean canary) {
ByteBuf buf = Unpooled.wrappedBuffer(content.getBytes(US_ASCII));
FullHttpRequest request =
new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, path, buf);
request
.headers()
.set("user-agent", "Proxy")
.set("host", host)
.setInt("content-length", buf.readableBytes());
if (canary) {
request.headers().set("canary", "true");
}
return request;
}
public static FullHttpRequest makeHttpGetRequest(String host, String path) {
FullHttpRequest request =
new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, path);
@@ -74,16 +89,46 @@ public final class TestUtils {
}
public static FullHttpRequest makeWhoisHttpRequest(
String content, String host, String path, String idToken) throws IOException {
FullHttpRequest request = makeHttpPostRequest(content, host, path);
String content, String host, String path, boolean canary, String idToken) throws IOException {
FullHttpRequest request = makeHttpPostRequest(content, host, path, canary);
request
.headers()
.set("authorization", "Bearer " + idToken)
.set(HttpHeaderNames.CONTENT_TYPE, "text/plain")
.set("content-type", "text/plain")
.set("accept", "text/plain");
return request;
}
public static FullHttpRequest makeWhoisHttpRequest(
String content, String host, String path, String idToken) throws IOException {
return makeWhoisHttpRequest(content, host, path, false, idToken);
}
public static FullHttpRequest makeEppHttpRequest(
String content,
String host,
String path,
boolean canary,
String idToken,
String sslClientCertificateHash,
String clientAddress,
Cookie... cookies)
throws IOException {
FullHttpRequest request = makeHttpPostRequest(content, host, path, canary);
request
.headers()
.set("authorization", "Bearer " + idToken)
.set("content-type", "application/epp+xml")
.set("accept", "application/epp+xml")
.set(ProxyHttpHeaders.CERTIFICATE_HASH, sslClientCertificateHash)
.set(ProxyHttpHeaders.IP_ADDRESS, clientAddress)
.set(ProxyHttpHeaders.FALLBACK_IP_ADDRESS, clientAddress);
if (cookies.length != 0) {
request.headers().set("cookie", ClientCookieEncoder.STRICT.encode(cookies));
}
return request;
}
public static FullHttpRequest makeEppHttpRequest(
String content,
String host,
@@ -93,31 +138,20 @@ public final class TestUtils {
String clientAddress,
Cookie... cookies)
throws IOException {
FullHttpRequest request = makeHttpPostRequest(content, host, path);
request
.headers()
.set("authorization", "Bearer " + idToken)
.set(HttpHeaderNames.CONTENT_TYPE, "application/epp+xml")
.set("accept", "application/epp+xml")
.set(ProxyHttpHeaders.CERTIFICATE_HASH, sslClientCertificateHash)
.set(ProxyHttpHeaders.IP_ADDRESS, clientAddress)
.set(ProxyHttpHeaders.FALLBACK_IP_ADDRESS, clientAddress);
if (cookies.length != 0) {
request.headers().set("cookie", ClientCookieEncoder.STRICT.encode(cookies));
}
return request;
return makeEppHttpRequest(
content, host, path, false, idToken, sslClientCertificateHash, clientAddress, cookies);
}
public static FullHttpResponse makeWhoisHttpResponse(String content, HttpResponseStatus status) {
FullHttpResponse response = makeHttpResponse(content, status);
response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain");
response.headers().set("content-type", "text/plain");
return response;
}
public static FullHttpResponse makeEppHttpResponse(
String content, HttpResponseStatus status, Cookie... cookies) {
FullHttpResponse response = makeHttpResponse(content, status);
response.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/epp+xml");
response.headers().set("content-type", "application/epp+xml");
for (Cookie cookie : cookies) {
response.headers().add("set-cookie", ServerCookieEncoder.STRICT.encode(cookie));
}
@@ -54,11 +54,11 @@ class EppServiceHandlerTest {
private static final String HELLO =
"""
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<hello/>
</epp>
""";
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<hello/>
</epp>
""";
private static final String RELAY_HOST = "registry.example.tld";
private static final String RELAY_PATH = "/epp";
@@ -71,7 +71,8 @@ class EppServiceHandlerTest {
private final FrontendMetrics metrics = mock(FrontendMetrics.class);
private final EppServiceHandler eppServiceHandler =
new EppServiceHandler(RELAY_HOST, RELAY_PATH, () -> ID_TOKEN, HELLO.getBytes(UTF_8), metrics);
new EppServiceHandler(
RELAY_HOST, RELAY_PATH, false, () -> ID_TOKEN, HELLO.getBytes(UTF_8), metrics);
private EmbeddedChannel channel;
@@ -146,7 +147,7 @@ class EppServiceHandlerTest {
// Set up the second channel.
EppServiceHandler eppServiceHandler2 =
new EppServiceHandler(
RELAY_HOST, RELAY_PATH, () -> ID_TOKEN, HELLO.getBytes(UTF_8), metrics);
RELAY_HOST, RELAY_PATH, false, () -> ID_TOKEN, HELLO.getBytes(UTF_8), metrics);
EmbeddedChannel channel2 = setUpNewChannel(eppServiceHandler2);
setHandshakeSuccess(channel2, clientCertificate);
@@ -166,7 +167,7 @@ class EppServiceHandlerTest {
// Set up the second channel.
EppServiceHandler eppServiceHandler2 =
new EppServiceHandler(
RELAY_HOST, RELAY_PATH, () -> ID_TOKEN, HELLO.getBytes(UTF_8), metrics);
RELAY_HOST, RELAY_PATH, false, () -> ID_TOKEN, HELLO.getBytes(UTF_8), metrics);
EmbeddedChannel channel2 = setUpNewChannel(eppServiceHandler2);
X509Certificate clientCertificate2 = SelfSignedCaCertificate.create().cert();
setHandshakeSuccess(channel2, clientCertificate2);
@@ -214,6 +215,33 @@ class EppServiceHandlerTest {
assertThat(channel.isActive()).isTrue();
}
@Test
void testSuccess_sendRequestToNextHandler_canary() throws Exception {
EppServiceHandler eppServiceHandler2 =
new EppServiceHandler(
RELAY_HOST, RELAY_PATH, true, () -> ID_TOKEN, HELLO.getBytes(UTF_8), metrics);
channel = setUpNewChannel(eppServiceHandler2);
setHandshakeSuccess();
// First inbound message is hello.
channel.readInbound();
String content = "<epp>stuff</epp>";
channel.writeInbound(Unpooled.wrappedBuffer(content.getBytes(UTF_8)));
FullHttpRequest request = channel.readInbound();
assertThat(request)
.isEqualTo(
TestUtils.makeEppHttpRequest(
content,
RELAY_HOST,
RELAY_PATH,
true,
ID_TOKEN,
getCertificateHash(clientCertificate),
CLIENT_ADDRESS));
// Nothing further to pass to the next handler.
assertThat((Object) channel.readInbound()).isNull();
assertThat(channel.isActive()).isTrue();
}
@Test
void testSuccess_sendResponseToNextHandler() throws Exception {
setHandshakeSuccess();
@@ -50,7 +50,7 @@ class WhoisServiceHandlerTest {
private final FrontendMetrics metrics = mock(FrontendMetrics.class);
private final WhoisServiceHandler whoisServiceHandler =
new WhoisServiceHandler(RELAY_HOST, RELAY_PATH, () -> ID_TOKEN, metrics);
new WhoisServiceHandler(RELAY_HOST, RELAY_PATH, false, () -> ID_TOKEN, metrics);
private EmbeddedChannel channel;
@BeforeEach
@@ -74,7 +74,7 @@ class WhoisServiceHandlerTest {
// Setup second channel.
WhoisServiceHandler whoisServiceHandler2 =
new WhoisServiceHandler(RELAY_HOST, RELAY_PATH, () -> ID_TOKEN, metrics);
new WhoisServiceHandler(RELAY_HOST, RELAY_PATH, false, () -> ID_TOKEN, metrics);
EmbeddedChannel channel2 =
// We need a new channel id so that it has a different hash code.
// This only is needed for EmbeddedChannel because it has a dummy hash code implementation.
@@ -98,6 +98,23 @@ class WhoisServiceHandlerTest {
assertThat(channel.isActive()).isTrue();
}
@Test
void testSuccess_fireInboundHttpRequest_canary() throws Exception {
WhoisServiceHandler whoisServiceHandler2 =
new WhoisServiceHandler(RELAY_HOST, RELAY_PATH, true, () -> ID_TOKEN, metrics);
channel = new EmbeddedChannel(whoisServiceHandler2);
ByteBuf inputBuffer = Unpooled.wrappedBuffer(QUERY_CONTENT.getBytes(US_ASCII));
FullHttpRequest expectedRequest =
makeWhoisHttpRequest(QUERY_CONTENT, RELAY_HOST, RELAY_PATH, true, ID_TOKEN);
// Input data passed to next handler
assertThat(channel.writeInbound(inputBuffer)).isTrue();
FullHttpRequest inputRequest = channel.readInbound();
assertThat(inputRequest).isEqualTo(expectedRequest);
// The channel is still open, and nothing else is to be read from it.
assertThat((Object) channel.readInbound()).isNull();
assertThat(channel.isActive()).isTrue();
}
@Test
void testSuccess_parseOutboundHttpResponse() {
String outputString = "line1\r\nline2\r\n";