Skip to content

Commit

Permalink
fix fabric8io#5033: allow port-forward to work with other clients
Browse files Browse the repository at this point in the history
  • Loading branch information
shawkins committed Apr 6, 2023
1 parent e2a85ad commit 527dc34
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* Fix #4985: triggering the immediate cleanup of the okhttp idle task
* fix #5002: Jetty response completion accounts for header processing
* Fix #5009: addressing issue with serialization of wrapped polymophic types
* Fix #5033: port forwarding for clients other than okhttp needs to specify the subprotocol

#### Improvements
* Fix #4434: Update CronJobIT to use `batch/v1` CronJob instead
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ public PortForward forward(URL resourceBaseUrl, int port, final ReadableByteChan
CompletableFuture<WebSocket> socket = client
.newWebSocketBuilder()
.uri(URI.create(URLUtils.join(resourceBaseUrl.toString(), "portforward?ports=" + port)))
.subprotocol("v4.channel.k8s.io")
.buildAsync(listener);

socket.whenComplete((w, t) -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,8 @@ public void onMessage(WebSocket webSocket, ByteBuffer buffer) {
closeBothWays(webSocket, 1002, PROTOCOL_ERROR);
} else if (channel == 1) {
// Error channel
// TODO: read the error
KubernetesClientException e = new KubernetesClientException(
String.format("Received an error from the remote socket"));
String.format("Received an error from the remote socket %s", ExecWebSocketListener.toString(buffer)));
serverThrowables.add(e);
logger.debug("Server error", e);
closeForwarder();
Expand Down
42 changes: 42 additions & 0 deletions kubernetes-itests/src/test/java/io/fabric8/kubernetes/PodIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@
import io.fabric8.kubernetes.api.model.PodList;
import io.fabric8.kubernetes.api.model.Status;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.LocalPortForward;
import io.fabric8.kubernetes.client.dsl.ExecListener;
import io.fabric8.kubernetes.client.dsl.ExecWatch;
import io.fabric8.kubernetes.client.dsl.LogWatch;
import io.fabric8.kubernetes.client.dsl.PodResource;
import io.fabric8.kubernetes.client.utils.IOHelpers;
import io.fabric8.kubernetes.client.utils.InputStreamPumper;
import org.awaitility.Awaitility;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.junit.jupiter.params.ParameterizedTest;
Expand All @@ -44,6 +46,10 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.SocketException;
import java.net.URL;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
Expand Down Expand Up @@ -444,4 +450,40 @@ void listFromServer() {
assertEquals(pod1.getMetadata().getName(), fromServerPod.getMetadata().getName());
}

@Test
void portForward() throws IOException, InterruptedException {
client.pods().withName("nginx").waitUntilReady(POD_READY_WAIT_IN_MILLIS, TimeUnit.SECONDS);
LocalPortForward portForward = client.pods().withName("nginx").portForward(80);
boolean failed = false;
try (SocketChannel channel = SocketChannel.open()) {

int localPort = portForward.getLocalPort();

URL url = new URL("http://localhost:" + localPort);

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

InputStream content = (InputStream) conn.getContent();

// make sure we got data, should be the welcome page
assertTrue(content.read() != -1);

content.close();
} catch (SocketException e) {
failed = true;
} finally {
portForward.close();
}

if (failed) {
// not all kube versions nor runtimes can to port forwarding - the nodes need socat installed
portForward.getServerThrowables().stream()
.filter(t -> !t.getMessage().contains("unable to do port forwarding: socat not found")).findFirst()
.ifPresent(Assertions::fail);
} else {
assertThat(portForward.getServerThrowables()).isEmpty();
}
assertThat(portForward.getClientThrowables()).isEmpty();
}

}
11 changes: 11 additions & 0 deletions kubernetes-itests/src/test/resources/pod-it.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,14 @@ spec:
command: ["timeout", "-s", "SIGKILL", "36000", "sh", "-i"]
stdin: true
tty: true
---
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80

0 comments on commit 527dc34

Please sign in to comment.