Skip to content

Commit

Permalink
fix #3408: quote upload paths
Browse files Browse the repository at this point in the history
replaces #3496
  • Loading branch information
shawkins authored and manusa committed Oct 27, 2021
1 parent 7edfec4 commit 9c766ff
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -20,6 +20,7 @@
* Fix #3353: addressing extra quoting in quantity serialization
* Fix #3509: notify reader when something is written in ExecWebSocketListener
* Fix #3501: addressed NPE with default BuildConfig operations
* Fix #3408: quote pod upload file paths to support special chars

#### Improvements
* Fix #3448 added methods for getting specific version information - `KubernetesClient.getKubernetesVersion`, `OpenShiftClient.getOpenShiftV3Version`, and `OpenShiftClient.getOpenShiftV3Version`
Expand Down
Expand Up @@ -439,7 +439,7 @@ public void onClose(int code, String reason) {
e.printStackTrace();
}
}
}).exec("sh", "-c", "cat " + source + "|" + "base64");
}).exec("sh", "-c", String.format("cat %s | base64", PodUpload.shellQuote(source)));
return new org.apache.commons.codec.binary.Base64InputStream(in);
} catch (Exception e) {
throw KubernetesClientException.launderThrowable(e);
Expand Down
Expand Up @@ -75,7 +75,7 @@ private static boolean uploadFile(OkHttpClient client, PodOperationContext conte
final String file = context.getFile();
final String directory = file.substring(0, file.lastIndexOf('/'));
final String command = String.format(
"mkdir -p %s && base64 -d - > %s", directory, file);
"mkdir -p %s && base64 -d - > %s", shellQuote(directory), shellQuote(file));
final PodUploadWebSocketListener podUploadWebSocketListener = initWebSocket(
buildCommandUrl(command, context, operationSupport), client);
try (
Expand All @@ -88,13 +88,17 @@ private static boolean uploadFile(OkHttpClient client, PodOperationContext conte
return true;
}
}

public static String shellQuote(String value) {
return "'" + value.replaceAll("'", "'\\\\''") + "'";
}

private static boolean uploadDirectory(OkHttpClient client, PodOperationContext context,
OperationSupport operationSupport, Path pathToUpload)
throws IOException, InterruptedException {

final String command = String.format(
"mkdir -p %1$s && base64 -d - | tar -C %1$s -xzf -", context.getDir());
"mkdir -p %1$s && base64 -d - | tar -C %1$s -xzf -", shellQuote(context.getDir()));
final PodUploadWebSocketListener podUploadWebSocketListener = initWebSocket(
buildCommandUrl(command, context, operationSupport), client);
try (
Expand Down
Expand Up @@ -110,7 +110,7 @@ void testUploadFileHappyScenarioShouldUploadFile() throws Exception {
assertThat(result, equalTo(true));
verify(mockPathToUpload, atLeast(1)).toFile();
verify(mockClient, times(1)).newWebSocket(argThat(request -> {
assertThat(request.url().toString(), equalTo("https://openshift.com:8443/api/v1/namespaces/default/pods/mock-pod/exec?command=sh&command=-c&command=mkdir+-p+%2Fmock%2Fdir+%26%26+base64+-d+-+%3E+%2Fmock%2Fdir%2Ffile&stdin=true&stderr=true"));
assertThat(request.url().toString(), equalTo("https://openshift.com:8443/api/v1/namespaces/default/pods/mock-pod/exec?command=sh&command=-c&command=mkdir+-p+%27%2Fmock%2Fdir%27+%26%26+base64+-d+-+%3E+%27%2Fmock%2Fdir%2Ffile%27&stdin=true&stderr=true"));
return true;
}), any(PodUploadWebSocketListener.class));
verify(mockWebSocket, atLeast(1)).send(any(ByteString.class));
Expand Down Expand Up @@ -149,7 +149,7 @@ private void uploadDirectoryAndVerify(String resourcePath) throws IOException, I
assertThat(result, equalTo(true));
verify(mockPathToUpload, atLeast(1)).toFile();
verify(mockClient, times(1)).newWebSocket(argThat(request -> {
assertThat(request.url().toString(), equalTo("https://openshift.com:8443/api/v1/namespaces/default/pods/mock-pod/exec?command=sh&command=-c&command=mkdir+-p+%2Fmock%2Fdir+%26%26+base64+-d+-+%7C+tar+-C+%2Fmock%2Fdir+-xzf+-&stdin=true&stderr=true"));
assertThat(request.url().toString(), equalTo("https://openshift.com:8443/api/v1/namespaces/default/pods/mock-pod/exec?command=sh&command=-c&command=mkdir+-p+%27%2Fmock%2Fdir%27+%26%26+base64+-d+-+%7C+tar+-C+%27%2Fmock%2Fdir%27+-xzf+-&stdin=true&stderr=true"));
return true;
}), any(PodUploadWebSocketListener.class));
verify(mockWebSocket, atLeast(1)).send(any(ByteString.class));
Expand Down
14 changes: 7 additions & 7 deletions kubernetes-itests/src/test/java/io/fabric8/kubernetes/PodIT.java
Expand Up @@ -45,29 +45,24 @@

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static junit.framework.TestCase.assertNotNull;
import static org.assertj.core.api.Assertions.assertThat;
import static org.awaitility.Awaitility.await;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

@RunWith(ArquillianConditionalRunner.class)
@RequiresKubernetes
Expand Down Expand Up @@ -260,12 +255,17 @@ public void uploadFile() throws IOException {
final Path tmpFile = Files.createTempFile("PodIT", "toBeUploaded");
Files.write(tmpFile, Arrays.asList("I'm uploaded"));

assertUploaded(pod1, tmpFile, "/tmp/toBeUploaded");
assertUploaded(pod1, tmpFile, "/tmp/001_special_!@#\\$^&(.mp4");
}

private void assertUploaded(Pod pod1, final Path tmpFile, String filename) throws IOException {
PodResource<Pod> podResource = client.pods().inNamespace(session.getNamespace())
.withName(pod1.getMetadata().getName());

podResource.file("/tmp/toBeUploaded").upload(tmpFile);
podResource.file(filename).upload(tmpFile);

try (InputStream checkIs = podResource.file("/tmp/toBeUploaded").read();
try (InputStream checkIs = podResource.file(filename).read();
BufferedReader br = new BufferedReader(new InputStreamReader(checkIs, StandardCharsets.UTF_8))) {
String result = br.lines().collect(Collectors.joining(System.lineSeparator()));
assertEquals("I'm uploaded", result);
Expand Down

0 comments on commit 9c766ff

Please sign in to comment.