Skip to content

Commit ead20c1

Browse files
authored
Merge pull request #1151 from brendandburns/kubectl
Add support for KubectlCopy.
2 parents 3057ef2 + a230b1e commit ead20c1

File tree

3 files changed

+148
-1
lines changed

3 files changed

+148
-1
lines changed

examples/src/main/java/io/kubernetes/client/examples/KubectlExample.java

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
package io.kubernetes.client.examples;
1414

1515
import static io.kubernetes.client.extended.kubectl.Kubectl.apiResources;
16+
import static io.kubernetes.client.extended.kubectl.Kubectl.copy;
1617
import static io.kubernetes.client.extended.kubectl.Kubectl.exec;
1718
import static io.kubernetes.client.extended.kubectl.Kubectl.label;
1819
import static io.kubernetes.client.extended.kubectl.Kubectl.log;
@@ -43,7 +44,7 @@
4344
* A Java equivalent for the kubectl command line tool. Not nearly as complete.
4445
*
4546
* <p>Easiest way to run this: mvn exec:java
46-
* -Dexec.mainClass="io.kubernetes.client.examples.KubectlExample"
47+
* -Dexec.mainClass="io.kubernetes.client.examples.KubectlExample" -Dexec.args="log some-pod"
4748
*
4849
* <p>From inside $REPO_DIR/examples
4950
*/
@@ -87,6 +88,37 @@ public static void main(String[] args)
8788
String name = null;
8889

8990
switch (verb) {
91+
case "cp":
92+
String from = args[1];
93+
String to = args[2];
94+
if (from.indexOf(":") != -1) {
95+
String[] parts = from.split(":");
96+
name = parts[0];
97+
from = parts[1];
98+
copy(client)
99+
.namespace(ns)
100+
.name(name)
101+
.container(cli.getOptionValue("c", ""))
102+
.fromPod(from)
103+
.to(to)
104+
.execute();
105+
} else if (to.indexOf(":") != -1) {
106+
String[] parts = to.split(":");
107+
name = parts[0];
108+
to = parts[1];
109+
copy(client)
110+
.namespace(ns)
111+
.name(name)
112+
.container(cli.getOptionValue("c", ""))
113+
.from(from)
114+
.toPod(to)
115+
.execute();
116+
} else {
117+
System.err.println("Missing pod name for copy.");
118+
System.exit(-1);
119+
}
120+
System.out.println("Copied " + from + " -> " + to);
121+
System.exit(0);
90122
case "portforward":
91123
name = args[1];
92124
KubectlPortForward forward = portforward(client).name(name).namespace(ns);

extended/src/main/java/io/kubernetes/client/extended/kubectl/Kubectl.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,25 @@
2323
*/
2424
public class Kubectl {
2525

26+
/**
27+
* Equivalence for `kubectl cp`.
28+
*
29+
* @return the kubectl copy
30+
*/
31+
public static KubectlCopy copy() {
32+
return copy(Configuration.getDefaultApiClient());
33+
}
34+
35+
/**
36+
* Equivalence for `kubectl cp`.
37+
*
38+
* @param apiClient the api client instance
39+
* @return the kubectl copy
40+
*/
41+
public static KubectlCopy copy(ApiClient apiClient) {
42+
return new KubectlCopy(apiClient);
43+
}
44+
2645
/**
2746
* Equivalence for `kubectl label`.
2847
*
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*
2+
Copyright 2020 The Kubernetes Authors.
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
http://www.apache.org/licenses/LICENSE-2.0
7+
Unless required by applicable law or agreed to in writing, software
8+
distributed under the License is distributed on an "AS IS" BASIS,
9+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
package io.kubernetes.client.extended.kubectl;
14+
15+
import static com.google.common.base.Strings.isNullOrEmpty;
16+
17+
import io.kubernetes.client.Copy;
18+
import io.kubernetes.client.extended.kubectl.exception.KubectlException;
19+
import io.kubernetes.client.openapi.ApiClient;
20+
import io.kubernetes.client.openapi.ApiException;
21+
import io.kubernetes.client.openapi.models.V1Pod;
22+
import io.kubernetes.client.util.exception.CopyNotSupportedException;
23+
import java.io.IOException;
24+
import java.nio.file.Paths;
25+
26+
public class KubectlCopy extends Kubectl.ResourceAndContainerBuilder<V1Pod, KubectlCopy>
27+
implements Kubectl.Executable<Boolean> {
28+
private String from;
29+
private String to;
30+
private Boolean toPod;
31+
private boolean dir;
32+
33+
KubectlCopy(ApiClient client) {
34+
super(client, V1Pod.class);
35+
this.toPod = null;
36+
}
37+
38+
public KubectlCopy directory() {
39+
this.dir = true;
40+
return this;
41+
}
42+
43+
public KubectlCopy from(String file) {
44+
this.from = file;
45+
return this;
46+
}
47+
48+
public KubectlCopy fromPod(String fileInPod) {
49+
this.from = fileInPod;
50+
this.toPod = false;
51+
return this;
52+
}
53+
54+
public KubectlCopy to(String file) {
55+
this.to = file;
56+
return this;
57+
}
58+
59+
public KubectlCopy toPod(String fileInPod) {
60+
this.to = fileInPod;
61+
this.toPod = true;
62+
return this;
63+
}
64+
65+
@Override
66+
public Boolean execute() throws KubectlException {
67+
validate();
68+
Copy cp = new Copy(apiClient);
69+
try {
70+
if (toPod) {
71+
cp.copyFileToPod(namespace, name, container, Paths.get(from), Paths.get(to));
72+
} else {
73+
if (this.dir) {
74+
cp.copyDirectoryFromPod(namespace, name, container, from, Paths.get(to));
75+
} else {
76+
cp.copyFileFromPod(namespace, name, container, from, Paths.get(to));
77+
}
78+
}
79+
return true;
80+
} catch (ApiException | IOException | CopyNotSupportedException ex) {
81+
throw new KubectlException(ex);
82+
}
83+
}
84+
85+
private void validate() throws KubectlException {
86+
if (toPod == null) {
87+
throw new KubectlException("You must specify either from or to a pod");
88+
}
89+
if (isNullOrEmpty(from)) {
90+
throw new KubectlException("From file missing");
91+
}
92+
if (isNullOrEmpty(to)) {
93+
throw new KubectlException("To file missing");
94+
}
95+
}
96+
}

0 commit comments

Comments
 (0)