diff --git a/examples/pom.xml b/examples/pom.xml index b51efabad1..72ed8a821f 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -72,6 +72,19 @@ + + com.coveo + fmt-maven-plugin + 2.2.0 + + + test + + check + + + + diff --git a/examples/src/main/java/io/kubernetes/client/examples/AttachExample.java b/examples/src/main/java/io/kubernetes/client/examples/AttachExample.java index e0cbaafd60..22ea714f59 100644 --- a/examples/src/main/java/io/kubernetes/client/examples/AttachExample.java +++ b/examples/src/main/java/io/kubernetes/client/examples/AttachExample.java @@ -12,67 +12,66 @@ */ package io.kubernetes.client.examples; +import com.google.common.io.ByteStreams; import io.kubernetes.client.ApiClient; import io.kubernetes.client.ApiException; -import io.kubernetes.client.Configuration; import io.kubernetes.client.Attach; -import io.kubernetes.client.apis.CoreV1Api; -import io.kubernetes.client.models.V1Pod; -import io.kubernetes.client.models.V1PodList; +import io.kubernetes.client.Configuration; import io.kubernetes.client.util.Config; - -import com.google.common.io.ByteStreams; - import java.io.BufferedReader; -import java.io.InputStreamReader; import java.io.IOException; +import java.io.InputStreamReader; import java.io.OutputStream; /** * A simple example of how to use the Java API - * - *

Easiest way to run this: - * mvn exec:java -Dexec.mainClass="io.kubernetes.client.examples.AttachExample" - * + * + *

Easiest way to run this: mvn exec:java + * -Dexec.mainClass="io.kubernetes.client.examples.AttachExample" + * *

From inside $REPO_DIR/examples */ public class AttachExample { - public static void main(String[] args) throws IOException, ApiException, InterruptedException { - ApiClient client = Config.defaultClient(); - Configuration.setDefaultApiClient(client); + public static void main(String[] args) throws IOException, ApiException, InterruptedException { + ApiClient client = Config.defaultClient(); + Configuration.setDefaultApiClient(client); - Attach attach = new Attach(); - final Attach.AttachResult result = attach.attach("default", "nginx-4217019353-k5sn9", true); + Attach attach = new Attach(); + final Attach.AttachResult result = attach.attach("default", "nginx-4217019353-k5sn9", true); - new Thread(new Runnable() { - public void run() { + new Thread( + new Runnable() { + public void run() { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); OutputStream output = result.getStandardInputStream(); try { - while (true) { - String line = in.readLine(); - output.write(line.getBytes()); - output.write('\n'); - output.flush(); - } + while (true) { + String line = in.readLine(); + output.write(line.getBytes()); + output.write('\n'); + output.flush(); + } } catch (IOException ex) { - ex.printStackTrace(); + ex.printStackTrace(); } - } - }).start(); + } + }) + .start(); - new Thread(new Runnable() { - public void run() { + new Thread( + new Runnable() { + public void run() { try { - ByteStreams.copy(result.getStandardOutputStream(), System.out); + ByteStreams.copy(result.getStandardOutputStream(), System.out); } catch (IOException ex) { - ex.printStackTrace(); + ex.printStackTrace(); } - } - }).start(); + } + }) + .start(); - Thread.sleep(10*1000); - result.close(); - System.exit(0); - } + Thread.sleep(10 * 1000); + result.close(); + System.exit(0); + } } diff --git a/examples/src/main/java/io/kubernetes/client/examples/Example.java b/examples/src/main/java/io/kubernetes/client/examples/Example.java index 196fa81529..3135c0c981 100644 --- a/examples/src/main/java/io/kubernetes/client/examples/Example.java +++ b/examples/src/main/java/io/kubernetes/client/examples/Example.java @@ -19,27 +19,26 @@ import io.kubernetes.client.models.V1Pod; import io.kubernetes.client.models.V1PodList; import io.kubernetes.client.util.Config; - import java.io.IOException; -import java.util.logging.Logger; /** * A simple example of how to use the Java API - * - *

Easiest way to run this: - * mvn exec:java -Dexec.mainClass="io.kubernetes.client.examples.Example" - * + * + *

Easiest way to run this: mvn exec:java + * -Dexec.mainClass="io.kubernetes.client.examples.Example" + * *

From inside $REPO_DIR/examples */ public class Example { - public static void main(String[] args) throws IOException, ApiException{ - ApiClient client = Config.defaultClient(); - Configuration.setDefaultApiClient(client); + public static void main(String[] args) throws IOException, ApiException { + ApiClient client = Config.defaultClient(); + Configuration.setDefaultApiClient(client); - CoreV1Api api = new CoreV1Api(); - V1PodList list = api.listPodForAllNamespaces(null, null, null, null, null, null, null, null, null); - for (V1Pod item : list.getItems()) { - System.out.println(item.getMetadata().getName()); - } + CoreV1Api api = new CoreV1Api(); + V1PodList list = + api.listPodForAllNamespaces(null, null, null, null, null, null, null, null, null); + for (V1Pod item : list.getItems()) { + System.out.println(item.getMetadata().getName()); } -} \ No newline at end of file + } +} diff --git a/examples/src/main/java/io/kubernetes/client/examples/ExecExample.java b/examples/src/main/java/io/kubernetes/client/examples/ExecExample.java index 637ed16fb4..aa1c584243 100644 --- a/examples/src/main/java/io/kubernetes/client/examples/ExecExample.java +++ b/examples/src/main/java/io/kubernetes/client/examples/ExecExample.java @@ -12,71 +12,68 @@ */ package io.kubernetes.client.examples; +import com.google.common.io.ByteStreams; import io.kubernetes.client.ApiClient; import io.kubernetes.client.ApiException; import io.kubernetes.client.Configuration; import io.kubernetes.client.Exec; -import io.kubernetes.client.apis.CoreV1Api; -import io.kubernetes.client.models.V1Pod; -import io.kubernetes.client.models.V1PodList; import io.kubernetes.client.util.Config; - -import com.google.common.io.ByteStreams; - -import java.io.BufferedReader; -import java.io.InputStreamReader; import java.io.IOException; -import java.io.OutputStream; /** * A simple example of how to use the Java API - * - *

Easiest way to run this: - * mvn exec:java -Dexec.mainClass="io.kubernetes.client.examples.Example" - * + * + *

Easiest way to run this: mvn exec:java + * -Dexec.mainClass="io.kubernetes.client.examples.Example" + * *

From inside $REPO_DIR/examples */ public class ExecExample { - public static void main(String[] args) throws IOException, ApiException, InterruptedException { - ApiClient client = Config.defaultClient(); - Configuration.setDefaultApiClient(client); + public static void main(String[] args) throws IOException, ApiException, InterruptedException { + ApiClient client = Config.defaultClient(); + Configuration.setDefaultApiClient(client); - Exec exec = new Exec(); - boolean tty = System.console() != null; -// final Process proc = exec.exec("default", "nginx-2371676037-czqx3", new String[] {"sh", "-c", "echo foo"}, true, tty); - final Process proc = exec.exec("default", "nginx-4217019353-k5sn9", new String[] {"sh"}, true, tty); + Exec exec = new Exec(); + boolean tty = System.console() != null; + // final Process proc = exec.exec("default", "nginx-2371676037-czqx3", new String[] + // {"sh", "-c", "echo foo"}, true, tty); + final Process proc = + exec.exec("default", "nginx-4217019353-k5sn9", new String[] {"sh"}, true, tty); - - new Thread(new Runnable() { - public void run() { + new Thread( + new Runnable() { + public void run() { try { - ByteStreams.copy(System.in, proc.getOutputStream()); + ByteStreams.copy(System.in, proc.getOutputStream()); } catch (IOException ex) { - ex.printStackTrace(); + ex.printStackTrace(); } - } - }).start(); + } + }) + .start(); - new Thread(new Runnable() { - public void run() { + new Thread( + new Runnable() { + public void run() { try { - ByteStreams.copy(proc.getInputStream(), System.out); + ByteStreams.copy(proc.getInputStream(), System.out); } catch (IOException ex) { - ex.printStackTrace(); + ex.printStackTrace(); } - } - }).start(); + } + }) + .start(); - proc.waitFor(); - try { - // Wait for buffers to flush. - Thread.sleep(2000); - } catch (InterruptedException ex) { - ex.printStackTrace(); - } + proc.waitFor(); + try { + // Wait for buffers to flush. + Thread.sleep(2000); + } catch (InterruptedException ex) { + ex.printStackTrace(); + } - proc.destroy(); + proc.destroy(); - System.exit(0); - } -} \ No newline at end of file + System.exit(0); + } +} diff --git a/examples/src/main/java/io/kubernetes/client/examples/LogsExample.java b/examples/src/main/java/io/kubernetes/client/examples/LogsExample.java index 119e8ae06f..5efbc56540 100644 --- a/examples/src/main/java/io/kubernetes/client/examples/LogsExample.java +++ b/examples/src/main/java/io/kubernetes/client/examples/LogsExample.java @@ -12,41 +12,39 @@ */ package io.kubernetes.client.examples; +import com.google.common.io.ByteStreams; import io.kubernetes.client.ApiClient; import io.kubernetes.client.ApiException; import io.kubernetes.client.Configuration; import io.kubernetes.client.PodLogs; import io.kubernetes.client.apis.CoreV1Api; import io.kubernetes.client.models.V1Pod; -import io.kubernetes.client.models.V1PodList; import io.kubernetes.client.util.Config; - -import com.google.common.io.ByteStreams; - -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; import java.io.IOException; -import java.io.OutputStream; +import java.io.InputStream; /** * A simple example of how to use the Java API - * - *

Easiest way to run this: - * mvn exec:java -Dexec.mainClass="io.kubernetes.client.examples.LogsExample" - * + * + *

Easiest way to run this: mvn exec:java + * -Dexec.mainClass="io.kubernetes.client.examples.LogsExample" + * *

From inside $REPO_DIR/examples */ public class LogsExample { - public static void main(String[] args) throws IOException, ApiException, InterruptedException { - ApiClient client = Config.defaultClient(); - Configuration.setDefaultApiClient(client); - CoreV1Api coreApi = new CoreV1Api(client); + public static void main(String[] args) throws IOException, ApiException, InterruptedException { + ApiClient client = Config.defaultClient(); + Configuration.setDefaultApiClient(client); + CoreV1Api coreApi = new CoreV1Api(client); - PodLogs logs = new PodLogs(); - V1Pod pod = coreApi.listNamespacedPod("default", "false", null, null, null, null, null, null, null, null).getItems().get(0); + PodLogs logs = new PodLogs(); + V1Pod pod = + coreApi + .listNamespacedPod("default", "false", null, null, null, null, null, null, null, null) + .getItems() + .get(0); - InputStream is = logs.streamNamespacedPodLog(pod); - ByteStreams.copy(is, System.out); - } + InputStream is = logs.streamNamespacedPodLog(pod); + ByteStreams.copy(is, System.out); + } } diff --git a/examples/src/main/java/io/kubernetes/client/examples/PortForwardExample.java b/examples/src/main/java/io/kubernetes/client/examples/PortForwardExample.java index 4f8ad1c575..28c910c286 100644 --- a/examples/src/main/java/io/kubernetes/client/examples/PortForwardExample.java +++ b/examples/src/main/java/io/kubernetes/client/examples/PortForwardExample.java @@ -12,82 +12,75 @@ */ package io.kubernetes.client.examples; +import com.google.common.io.ByteStreams; import io.kubernetes.client.ApiClient; import io.kubernetes.client.ApiException; import io.kubernetes.client.Configuration; import io.kubernetes.client.PortForward; -import io.kubernetes.client.apis.CoreV1Api; -import io.kubernetes.client.models.V1Pod; -import io.kubernetes.client.models.V1PodList; import io.kubernetes.client.util.Config; - -import com.google.common.io.ByteStreams; - -import java.io.BufferedReader; -import java.io.InputStreamReader; import java.io.IOException; -import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.List; - /** * A simple example of how to use the Java API - * - *

Easiest way to run this: - * mvn exec:java -Dexec.mainClass="io.kubernetes.client.examples.PortForwardExample" - * from inside $REPO_DIR/examples - * - *

Then: - * curl localhost:8080 - * from a different terminal (but be quick about it, the socket times out pretty fast...) - * + * + *

Easiest way to run this: mvn exec:java + * -Dexec.mainClass="io.kubernetes.client.examples.PortForwardExample" from inside + * $REPO_DIR/examples + * + *

Then: curl localhost:8080 from a different terminal (but be quick about it, the socket times + * out pretty fast...) */ public class PortForwardExample { - public static void main(String[] args) throws IOException, ApiException, InterruptedException { - ApiClient client = Config.defaultClient(); - Configuration.setDefaultApiClient(client); + public static void main(String[] args) throws IOException, ApiException, InterruptedException { + ApiClient client = Config.defaultClient(); + Configuration.setDefaultApiClient(client); - PortForward forward = new PortForward(); - List ports = new ArrayList<>(); - ports.add(8080); - ports.add(80); - final PortForward.PortForwardResult result = - forward.forward("default", "nginx-d5dc44cf7-x7475", ports); + PortForward forward = new PortForward(); + List ports = new ArrayList<>(); + ports.add(8080); + ports.add(80); + final PortForward.PortForwardResult result = + forward.forward("default", "nginx-d5dc44cf7-x7475", ports); - ServerSocket ss = new ServerSocket(8080); + ServerSocket ss = new ServerSocket(8080); - final Socket s = ss.accept(); - System.out.println("Connected!"); + final Socket s = ss.accept(); + System.out.println("Connected!"); - new Thread(new Runnable() { - public void run() { + new Thread( + new Runnable() { + public void run() { try { - ByteStreams.copy(result.getInputStream(80), s.getOutputStream()); + ByteStreams.copy(result.getInputStream(80), s.getOutputStream()); } catch (IOException ex) { - ex.printStackTrace(); + ex.printStackTrace(); } catch (Exception ex) { - ex.printStackTrace(); + ex.printStackTrace(); } - } - }).start(); + } + }) + .start(); - new Thread(new Runnable() { - public void run() { + new Thread( + new Runnable() { + public void run() { try { - ByteStreams.copy(s.getInputStream(), result.getOutboundStream(80)); + ByteStreams.copy(s.getInputStream(), result.getOutboundStream(80)); } catch (IOException ex) { - ex.printStackTrace(); + ex.printStackTrace(); } catch (Exception ex) { - ex.printStackTrace(); + ex.printStackTrace(); } - } - }).start(); + } + }) + .start(); - Thread.sleep(10 * 1000); + Thread.sleep(10 * 1000); - System.exit(0); - } + System.exit(0); + } } diff --git a/examples/src/main/java/io/kubernetes/client/examples/ProtoExample.java b/examples/src/main/java/io/kubernetes/client/examples/ProtoExample.java index 64d19b9b96..eaa9c8ef52 100644 --- a/examples/src/main/java/io/kubernetes/client/examples/ProtoExample.java +++ b/examples/src/main/java/io/kubernetes/client/examples/ProtoExample.java @@ -18,60 +18,52 @@ import io.kubernetes.client.ProtoClient; import io.kubernetes.client.ProtoClient.ObjectOrStatus; import io.kubernetes.client.proto.Meta.ObjectMeta; -import io.kubernetes.client.proto.Meta.Status; import io.kubernetes.client.proto.V1.Namespace; import io.kubernetes.client.proto.V1.NamespaceSpec; import io.kubernetes.client.proto.V1.Pod; import io.kubernetes.client.proto.V1.PodList; import io.kubernetes.client.util.Config; - import java.io.IOException; - /** * A simple example of how to use the Java API - * - *

Easiest way to run this: - * mvn exec:java -Dexec.mainClass="io.kubernetes.client.examples.ProtoExample" - * + * + *

Easiest way to run this: mvn exec:java + * -Dexec.mainClass="io.kubernetes.client.examples.ProtoExample" + * *

From inside $REPO_DIR/examples */ public class ProtoExample { - public static void main(String[] args) throws IOException, ApiException, InterruptedException { - ApiClient client = Config.defaultClient(); - Configuration.setDefaultApiClient(client); - - ProtoClient pc = new ProtoClient(client); - ObjectOrStatus list = pc.list(PodList.newBuilder(), "/api/v1/namespaces/default/pods"); + public static void main(String[] args) throws IOException, ApiException, InterruptedException { + ApiClient client = Config.defaultClient(); + Configuration.setDefaultApiClient(client); - if (list.object.getItemsCount() > 0) { - Pod p = list.object.getItems(0); - System.out.println(p); - } + ProtoClient pc = new ProtoClient(client); + ObjectOrStatus list = pc.list(PodList.newBuilder(), "/api/v1/namespaces/default/pods"); - Namespace namespace = Namespace.newBuilder() - .setMetadata(ObjectMeta.newBuilder() - .setName("test").build()) - .build(); - - ObjectOrStatus ns = pc.create(namespace, "/api/v1/namespaces", "v1", "Namespace"); - System.out.println(ns); - if (ns.object != null) { - namespace = ns.object.toBuilder() - .setSpec( - NamespaceSpec.newBuilder() - .addFinalizers("test") - .build() - ) - .build(); - // This is how you would update an object, but you can't actually - // update namespaces, so this returns a 405 - ns = pc.update(namespace, "/api/v1/namespaces/test", "v1", "Namespace"); - System.out.println(ns.status); - } + if (list.object.getItemsCount() > 0) { + Pod p = list.object.getItems(0); + System.out.println(p); + } - ns = pc.delete(Namespace.newBuilder(), "/api/v1/namespaces/test"); - System.out.println(ns); + Namespace namespace = + Namespace.newBuilder().setMetadata(ObjectMeta.newBuilder().setName("test").build()).build(); + ObjectOrStatus ns = pc.create(namespace, "/api/v1/namespaces", "v1", "Namespace"); + System.out.println(ns); + if (ns.object != null) { + namespace = + ns.object + .toBuilder() + .setSpec(NamespaceSpec.newBuilder().addFinalizers("test").build()) + .build(); + // This is how you would update an object, but you can't actually + // update namespaces, so this returns a 405 + ns = pc.update(namespace, "/api/v1/namespaces/test", "v1", "Namespace"); + System.out.println(ns.status); } + + ns = pc.delete(Namespace.newBuilder(), "/api/v1/namespaces/test"); + System.out.println(ns); + } } diff --git a/examples/src/main/java/io/kubernetes/client/examples/WatchExample.java b/examples/src/main/java/io/kubernetes/client/examples/WatchExample.java index fa9bccb42d..4b5afab4d0 100644 --- a/examples/src/main/java/io/kubernetes/client/examples/WatchExample.java +++ b/examples/src/main/java/io/kubernetes/client/examples/WatchExample.java @@ -20,28 +20,27 @@ import io.kubernetes.client.models.V1Namespace; import io.kubernetes.client.util.Config; import io.kubernetes.client.util.Watch; - import java.io.IOException; import java.util.concurrent.TimeUnit; -/** - * A simple example of how to use Watch API to watch changes in Namespace list. - */ +/** A simple example of how to use Watch API to watch changes in Namespace list. */ public class WatchExample { - public static void main(String[] args) throws IOException, ApiException{ - ApiClient client = Config.defaultClient(); - client.getHttpClient().setReadTimeout(60, TimeUnit.SECONDS); - Configuration.setDefaultApiClient(client); + public static void main(String[] args) throws IOException, ApiException { + ApiClient client = Config.defaultClient(); + client.getHttpClient().setReadTimeout(60, TimeUnit.SECONDS); + Configuration.setDefaultApiClient(client); - CoreV1Api api = new CoreV1Api(); + CoreV1Api api = new CoreV1Api(); - Watch watch = Watch.createWatch( - client, - api.listNamespaceCall(null, null, null, null, null, 5, null, null, Boolean.TRUE, null, null), - new TypeToken>(){}.getType()); + Watch watch = + Watch.createWatch( + client, + api.listNamespaceCall( + null, null, null, null, null, 5, null, null, Boolean.TRUE, null, null), + new TypeToken>() {}.getType()); - for (Watch.Response item : watch) { - System.out.printf("%s : %s%n", item.type, item.object.getMetadata().getName()); - } + for (Watch.Response item : watch) { + System.out.printf("%s : %s%n", item.type, item.object.getMetadata().getName()); } + } } diff --git a/examples/src/main/java/io/kubernetes/client/examples/WebSocketsExample.java b/examples/src/main/java/io/kubernetes/client/examples/WebSocketsExample.java index a7d4d5f0cb..39c0aee123 100644 --- a/examples/src/main/java/io/kubernetes/client/examples/WebSocketsExample.java +++ b/examples/src/main/java/io/kubernetes/client/examples/WebSocketsExample.java @@ -17,46 +17,48 @@ import io.kubernetes.client.ApiException; import io.kubernetes.client.util.Config; import io.kubernetes.client.util.WebSockets; - import java.io.BufferedReader; -import java.io.Closeable; import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; import java.io.Reader; /** - * This is a pretty low level, most people won't need to use WebSockets - * directly. + * This is a pretty low level, most people won't need to use WebSockets directly. * - * If you do need to run it, you can run: - * mvn exec:java \ - * -Dexec.mainClass=io.kubernetes.client.examples.WebSocketsExample \ - * -Dexec.args=/api/v1/namespaces/default/pods//attach?stdout=true + *

If you do need to run it, you can run: mvn exec:java \ + * -Dexec.mainClass=io.kubernetes.client.examples.WebSocketsExample \ + * -Dexec.args=/api/v1/namespaces/default/pods//attach?stdout=true * - * Note that you'd think 'watch' calls were WebSockets, but you'd be wrong, - * they're straight HTTP GET calls. + *

Note that you'd think 'watch' calls were WebSockets, but you'd be wrong, they're straight HTTP + * GET calls. */ public class WebSocketsExample { - public static void main(String... args) throws ApiException, IOException { - final ApiClient client = Config.defaultClient(); - WebSockets.stream(args[0], "GET", client, new WebSockets.SocketListener() { - public void open(String protocol, WebSocket socket) {} - public void close() { - // Trigger shutdown of the dispatcher's executor so this process can exit cleanly. - client.getHttpClient().getDispatcher().getExecutorService().shutdown(); - } - public void bytesMessage(InputStream is) {} - public void textMessage(Reader in) { - try { - BufferedReader reader = new BufferedReader(in); - for (String line = reader.readLine(); line != null; line = reader.readLine()) { - System.out.println(line); - } - } catch (IOException ex) { - ex.printStackTrace(); - } + public static void main(String... args) throws ApiException, IOException { + final ApiClient client = Config.defaultClient(); + WebSockets.stream( + args[0], + "GET", + client, + new WebSockets.SocketListener() { + public void open(String protocol, WebSocket socket) {} + + public void close() { + // Trigger shutdown of the dispatcher's executor so this process can exit cleanly. + client.getHttpClient().getDispatcher().getExecutorService().shutdown(); + } + + public void bytesMessage(InputStream is) {} + + public void textMessage(Reader in) { + try { + BufferedReader reader = new BufferedReader(in); + for (String line = reader.readLine(); line != null; line = reader.readLine()) { + System.out.println(line); + } + } catch (IOException ex) { + ex.printStackTrace(); } + } }); - } + } } diff --git a/target/checkout b/target/checkout deleted file mode 160000 index 02bb7ab2ee..0000000000 --- a/target/checkout +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 02bb7ab2ee7495b2a64148e9033b2cb9777f68e2 diff --git a/util/pom.xml b/util/pom.xml index f30e3ef6fd..bc8166f71f 100644 --- a/util/pom.xml +++ b/util/pom.xml @@ -103,6 +103,19 @@ pertest + + com.coveo + fmt-maven-plugin + 2.2.0 + + + test + + check + + + + diff --git a/util/src/main/java/io/kubernetes/client/Attach.java b/util/src/main/java/io/kubernetes/client/Attach.java index b09f21023a..05c251c443 100644 --- a/util/src/main/java/io/kubernetes/client/Attach.java +++ b/util/src/main/java/io/kubernetes/client/Attach.java @@ -13,153 +13,160 @@ package io.kubernetes.client; import io.kubernetes.client.models.V1Pod; -import io.kubernetes.client.util.WebSockets; import io.kubernetes.client.util.WebSocketStreamHandler; - -import java.io.InputStream; +import io.kubernetes.client.util.WebSockets; import java.io.IOException; +import java.io.InputStream; import java.io.OutputStream; public class Attach { - private ApiClient apiClient; - - /** - * Simple Attach API constructor, uses default configuration - */ - public Attach() { - this(Configuration.getDefaultApiClient()); + private ApiClient apiClient; + + /** Simple Attach API constructor, uses default configuration */ + public Attach() { + this(Configuration.getDefaultApiClient()); + } + + /** + * Attach API Constructor + * + * @param apiClient The api client to use. + */ + public Attach(ApiClient apiClient) { + this.apiClient = apiClient; + } + + /** + * Get the API client for these Attach operations. + * + * @return The API client that will be used. + */ + public ApiClient getApiClient() { + return apiClient; + } + + /** + * Set the API client for subsequent Attach operations. + * + * @param apiClient The new API client to use. + */ + public void setApiClient(ApiClient apiClient) { + this.apiClient = apiClient; + } + + private String makePath( + String namespace, String name, String container, boolean stdin, boolean tty) { + return "/api/v1/namespaces/" + + namespace + + "/pods/" + + name + + "/attach?" + + "stdin=" + + stdin + + "&tty=" + + tty + + (container != null ? "&container=" + container : ""); + } + + /** + * Attach to a running AttachResult in a container. If there are multiple containers in the pod, + * uses the first container in the Pod. + * + * @param namespace The namespace of the Pod + * @param name The name of the Pod + * @param stdin If true, pass a stdin stream into the container + */ + public AttachResult attach(String namespace, String name, boolean stdin) + throws ApiException, IOException { + return attach(namespace, name, null, stdin, false); + } + + /** + * Attach to a running AttachResult in a container. If there are multiple containers in the pod, + * uses the first container in the Pod. + * + * @param pod The pod where the command is run. + * @param stdin If true, pass a stdin stream into the container + */ + public AttachResult attach(V1Pod pod, boolean stdin) throws ApiException, IOException { + return attach(pod, stdin, false); + } + + /** + * Attach to a running AttachResult in a container. If there are multiple containers in the pod, + * uses the first container in the Pod. + * + * @param pod The pod where the command is run. + * @param stdin If true, pass a stdin stream into the container + * @param tty If true, stdin is a tty. + */ + public AttachResult attach(V1Pod pod, boolean stdin, boolean tty) + throws ApiException, IOException { + return attach(pod, null, stdin, tty); + } + + /** + * Attach to a running AttachResult in a container. If there are multiple containers in the pod, + * uses the first container in the Pod. + * + * @param pod The pod where the command is run. + * @param container The container in the Pod where the command is run. + * @param stdin If true, pass a stdin stream into the container. + * @param tty If true, stdin is a TTY (only applies if stdin is true) + */ + public AttachResult attach(V1Pod pod, String container, boolean stdin, boolean tty) + throws ApiException, IOException { + return attach( + pod.getMetadata().getNamespace(), pod.getMetadata().getName(), container, stdin, tty); + } + + /** + * Attach to a running AttachResult in a container. If there are multiple containers in the pod, + * uses the first container in the Pod. + * + * @param namespace The namespace of the Pod + * @param name The name of the Pod + * @param container The container in the Pod where the command is run. + * @param stdin If true, pass a stdin stream into the container. + * @param tty If true, stdin is a TTY (only applies if stdin is true) + */ + public AttachResult attach( + String namespace, String name, String container, boolean stdin, boolean tty) + throws ApiException, IOException { + String path = makePath(namespace, name, container, stdin, tty); + + WebSocketStreamHandler handler = new WebSocketStreamHandler(); + AttachResult result = new AttachResult(handler); + WebSockets.stream(path, "GET", apiClient, handler); + + return result; + } + + /** + * AttachResult contains the result of an Attach call, it includes streams for stdout stderr and + * stdin. + */ + public static class AttachResult implements java.io.Closeable { + private WebSocketStreamHandler handler; + + public AttachResult(WebSocketStreamHandler handler) throws IOException { + this.handler = handler; } - /** - * Attach API Constructor - * @param apiClient The api client to use. - */ - public Attach(ApiClient apiClient) { - this.apiClient = apiClient; + public OutputStream getStandardInputStream() { + return handler.getOutputStream(0); } - /** - * Get the API client for these Attach operations. - * @return The API client that will be used. - */ - public ApiClient getApiClient() { - return apiClient; + public InputStream getStandardOutputStream() throws IOException { + return handler.getInputStream(1); } - /** - * Set the API client for subsequent Attach operations. - * @param apiClient The new API client to use. - */ - public void setApiClient(ApiClient apiClient) { - this.apiClient = apiClient; + public InputStream getErrorStream() throws IOException { + return handler.getInputStream(2); } - private String makePath(String namespace, String name, String container, boolean stdin, boolean tty) { - return "/api/v1/namespaces/" + - namespace + - "/pods/" + - name + - "/attach?" + - "stdin=" + stdin + - "&tty=" + tty + - (container != null ? "&container=" + container : ""); - } - - /** - * Attach to a running AttachResult in a container. If there are multiple containers in the pod, uses - * the first container in the Pod. - * - * @param namespace The namespace of the Pod - * @param name The name of the Pod - * @param stdin If true, pass a stdin stream into the container - */ - public AttachResult attach(String namespace, String name, boolean stdin) throws ApiException, IOException { - return attach(namespace, name, null, stdin, false); - } - - /** - * Attach to a running AttachResult in a container. If there are multiple containers in the pod, uses - * the first container in the Pod. - * - * @param pod The pod where the command is run. - * @param stdin If true, pass a stdin stream into the container - */ - public AttachResult attach(V1Pod pod, boolean stdin) throws ApiException, IOException { - return attach(pod, stdin, false); - } - - - /** - * Attach to a running AttachResult in a container. If there are multiple containers in the pod, uses - * the first container in the Pod. - * - * @param pod The pod where the command is run. - * @param stdin If true, pass a stdin stream into the container - * @param tty If true, stdin is a tty. - */ - public AttachResult attach(V1Pod pod, boolean stdin, boolean tty) throws ApiException, IOException { - return attach(pod, null, stdin, tty); - } - - /** - * Attach to a running AttachResult in a container. If there are multiple containers in the pod, uses - * the first container in the Pod. - * - * @param pod The pod where the command is run. - * @param container The container in the Pod where the command is run. - * @param stdin If true, pass a stdin stream into the container. - * @param tty If true, stdin is a TTY (only applies if stdin is true) - */ - public AttachResult attach(V1Pod pod, String container, boolean stdin, boolean tty) throws ApiException, IOException { - return attach(pod.getMetadata().getNamespace(), pod.getMetadata().getName(), container, stdin, tty); - } - - /** - * Attach to a running AttachResult in a container. If there are multiple containers in the pod, uses - * the first container in the Pod. - * - * @param namespace The namespace of the Pod - * @param name The name of the Pod - * @param container The container in the Pod where the command is run. - * @param stdin If true, pass a stdin stream into the container. - * @param tty If true, stdin is a TTY (only applies if stdin is true) - */ - public AttachResult attach(String namespace, String name, String container, boolean stdin, boolean tty) throws ApiException, IOException { - String path = makePath(namespace, name, container, stdin, tty); - - WebSocketStreamHandler handler = new WebSocketStreamHandler(); - AttachResult result = new AttachResult(handler); - WebSockets.stream(path, "GET", apiClient, handler); - - return result; - } - - /** - * AttachResult contains the result of an Attach call, it includes streams for stdout - * stderr and stdin. - */ - public static class AttachResult implements java.io.Closeable { - private WebSocketStreamHandler handler; - - - public AttachResult(WebSocketStreamHandler handler) throws IOException { - this.handler = handler; - } - - public OutputStream getStandardInputStream() { - return handler.getOutputStream(0); - } - - public InputStream getStandardOutputStream() throws IOException { - return handler.getInputStream(1); - } - - public InputStream getErrorStream() throws IOException { - return handler.getInputStream(2); - } - - public void close() { - handler.close(); - } + public void close() { + handler.close(); } -} \ No newline at end of file + } +} diff --git a/util/src/main/java/io/kubernetes/client/Exec.java b/util/src/main/java/io/kubernetes/client/Exec.java index edb5dd2320..cf7af31260 100644 --- a/util/src/main/java/io/kubernetes/client/Exec.java +++ b/util/src/main/java/io/kubernetes/client/Exec.java @@ -15,185 +15,206 @@ import io.kubernetes.client.models.V1Pod; import io.kubernetes.client.util.WebSocketStreamHandler; import io.kubernetes.client.util.WebSockets; -import org.apache.commons.lang3.StringUtils; - -import java.io.InputStream; import java.io.IOException; +import java.io.InputStream; import java.io.OutputStream; +import org.apache.commons.lang3.StringUtils; public class Exec { - private ApiClient apiClient; - - /** - * Simple Exec API constructor, uses default configuration - */ - public Exec() { - this(Configuration.getDefaultApiClient()); - } - - /** - * Exec API Constructor - * @param apiClient The api client to use. - */ - public Exec(ApiClient apiClient) { - this.apiClient = apiClient; - } - - /** - * Get the API client for these exec operations. - * @return The API client that will be used. - */ - public ApiClient getApiClient() { - return apiClient; - } - - /** - * Set the API client for subsequent exec operations. - * @param apiClient The new API client to use. - */ - public void setApiClient(ApiClient apiClient) { - this.apiClient = apiClient; - } - - private String makePath(String namespace, String name, String[] command, String container, boolean stdin, boolean tty) { - String path = "/api/v1/namespaces/" + - namespace + - "/pods/" + - name + - "/exec?" + - "stdin=" + stdin + - "&tty=" + tty + - (container != null ? "&container=" + container : "") + - "&command=" + StringUtils.join(command, "&command="); - return path; - } - - /** - * Execute a command in a container. If there are multiple containers in the pod, uses - * the first container in the Pod. - * - * @param namespace The namespace of the Pod - * @param name The name of the Pod - * @param command The command to run - * @param stdin If true, pass a stdin stream into the container - */ - public Process exec(String namespace, String name, String[] command, boolean stdin) throws ApiException, IOException { - return exec(namespace, name, command, null, stdin, false); + private ApiClient apiClient; + + /** Simple Exec API constructor, uses default configuration */ + public Exec() { + this(Configuration.getDefaultApiClient()); + } + + /** + * Exec API Constructor + * + * @param apiClient The api client to use. + */ + public Exec(ApiClient apiClient) { + this.apiClient = apiClient; + } + + /** + * Get the API client for these exec operations. + * + * @return The API client that will be used. + */ + public ApiClient getApiClient() { + return apiClient; + } + + /** + * Set the API client for subsequent exec operations. + * + * @param apiClient The new API client to use. + */ + public void setApiClient(ApiClient apiClient) { + this.apiClient = apiClient; + } + + private String makePath( + String namespace, + String name, + String[] command, + String container, + boolean stdin, + boolean tty) { + String path = + "/api/v1/namespaces/" + + namespace + + "/pods/" + + name + + "/exec?" + + "stdin=" + + stdin + + "&tty=" + + tty + + (container != null ? "&container=" + container : "") + + "&command=" + + StringUtils.join(command, "&command="); + return path; + } + + /** + * Execute a command in a container. If there are multiple containers in the pod, uses the first + * container in the Pod. + * + * @param namespace The namespace of the Pod + * @param name The name of the Pod + * @param command The command to run + * @param stdin If true, pass a stdin stream into the container + */ + public Process exec(String namespace, String name, String[] command, boolean stdin) + throws ApiException, IOException { + return exec(namespace, name, command, null, stdin, false); + } + + /** + * Execute a command in a container. If there are multiple containers in the pod, uses the first + * container in the Pod. + * + * @param pod The pod where the command is run. + * @param command The command to run + * @param stdin If true, pass a stdin stream into the container + */ + public Process exec(V1Pod pod, String[] command, boolean stdin) throws ApiException, IOException { + return exec(pod, command, null, stdin, false); + } + + /** + * Execute a command in a container. If there are multiple containers in the pod, uses the first + * container in the Pod. + * + * @param namespace The namespace of the Pod + * @param name The name of the Pod + * @param command The command to run + * @param stdin If true, pass a stdin stream into the container + * @param tty If true, stdin is a tty. + */ + public Process exec(String namespace, String name, String[] command, boolean stdin, boolean tty) + throws ApiException, IOException { + return exec(namespace, name, command, null, stdin, tty); + } + + /** + * Execute a command in a container. If there are multiple containers in the pod, uses the first + * container in the Pod. + * + * @param pod The pod where the command is run. + * @param command The command to run + * @param stdin If true, pass a stdin stream into the container + * @param tty If true, stdin is a tty. + */ + public Process exec(V1Pod pod, String[] command, boolean stdin, boolean tty) + throws ApiException, IOException { + return exec(pod, command, null, stdin, tty); + } + + /** + * Execute a command in a container. If there are multiple containers in the pod, uses the first + * container in the Pod. + * + * @param pod The pod where the command is run. + * @param command The command to run + * @param container The container in the Pod where the command is run. + * @param stdin If true, pass a stdin stream into the container. + * @param tty If true, stdin is a TTY (only applies if stdin is true) + */ + public Process exec(V1Pod pod, String[] command, String container, boolean stdin, boolean tty) + throws ApiException, IOException { + return exec( + pod.getMetadata().getNamespace(), + pod.getMetadata().getName(), + command, + container, + stdin, + tty); + } + + /** + * Execute a command in a container. If there are multiple containers in the pod, uses the first + * container in the Pod. + * + * @param namespace The namespace of the Pod + * @param name The name of the Pod + * @param command The command to run + * @param container The container in the Pod where the command is run. + * @param stdin If true, pass a stdin stream into the container. + * @param tty If true, stdin is a TTY (only applies if stdin is true) + */ + public Process exec( + String namespace, String name, String[] command, String container, boolean stdin, boolean tty) + throws ApiException, IOException { + String path = makePath(namespace, name, command, container, stdin, tty); + + WebSocketStreamHandler handler = new WebSocketStreamHandler(); + ExecProcess exec = new ExecProcess(handler); + WebSockets.stream(path, "GET", apiClient, handler); + + return exec; + } + + private static class ExecProcess extends Process { + WebSocketStreamHandler streamHandler; + private int statusCode; + + public ExecProcess(WebSocketStreamHandler handler) throws IOException { + this.streamHandler = handler; + this.statusCode = -1; } - /** - * Execute a command in a container. If there are multiple containers in the pod, uses - * the first container in the Pod. - * - * @param pod The pod where the command is run. - * @param command The command to run - * @param stdin If true, pass a stdin stream into the container - */ - public Process exec(V1Pod pod, String[] command, boolean stdin) throws ApiException, IOException { - return exec(pod, command, null, stdin, false); + @Override + public OutputStream getOutputStream() { + return streamHandler.getOutputStream(0); } - /** - * Execute a command in a container. If there are multiple containers in the pod, uses - * the first container in the Pod. - * - * @param namespace The namespace of the Pod - * @param name The name of the Pod - * @param command The command to run - * @param stdin If true, pass a stdin stream into the container - * @param tty If true, stdin is a tty. - */ - public Process exec(String namespace, String name, String[] command, boolean stdin, boolean tty) throws ApiException, IOException { - return exec(namespace, name, command, null, stdin, tty); + @Override + public InputStream getInputStream() { + return streamHandler.getInputStream(1); } - /** - * Execute a command in a container. If there are multiple containers in the pod, uses - * the first container in the Pod. - * - * @param pod The pod where the command is run. - * @param command The command to run - * @param stdin If true, pass a stdin stream into the container - * @param tty If true, stdin is a tty. - */ - public Process exec(V1Pod pod, String[] command, boolean stdin, boolean tty) throws ApiException, IOException { - return exec(pod, command, null, stdin, tty); + @Override + public InputStream getErrorStream() { + return streamHandler.getInputStream(2); } - /** - * Execute a command in a container. If there are multiple containers in the pod, uses - * the first container in the Pod. - * - * @param pod The pod where the command is run. - * @param command The command to run - * @param container The container in the Pod where the command is run. - * @param stdin If true, pass a stdin stream into the container. - * @param tty If true, stdin is a TTY (only applies if stdin is true) - */ - public Process exec(V1Pod pod, String[] command, String container, boolean stdin, boolean tty) throws ApiException, IOException { - return exec(pod.getMetadata().getNamespace(), pod.getMetadata().getName(), command, container, stdin, tty); + @Override + public int waitFor() throws InterruptedException { + synchronized (this) { + this.wait(); + } + return statusCode; } - /** - * Execute a command in a container. If there are multiple containers in the pod, uses - * the first container in the Pod. - * - * @param namespace The namespace of the Pod - * @param name The name of the Pod - * @param command The command to run - * @param container The container in the Pod where the command is run. - * @param stdin If true, pass a stdin stream into the container. - * @param tty If true, stdin is a TTY (only applies if stdin is true) - */ - public Process exec(String namespace, String name, String[] command, String container, boolean stdin, boolean tty) throws ApiException, IOException { - String path = makePath(namespace, name, command, container, stdin, tty); - - WebSocketStreamHandler handler = new WebSocketStreamHandler(); - ExecProcess exec = new ExecProcess(handler); - WebSockets.stream(path, "GET", apiClient, handler); - - return exec; + public int exitValue() { + return statusCode; } - private static class ExecProcess extends Process { - WebSocketStreamHandler streamHandler; - private int statusCode; - - - public ExecProcess(WebSocketStreamHandler handler) throws IOException { - this.streamHandler = handler; - this.statusCode = -1; - } - - @Override - public OutputStream getOutputStream() { - return streamHandler.getOutputStream(0); - } - - @Override - public InputStream getInputStream() { - return streamHandler.getInputStream(1); - } - - @Override - public InputStream getErrorStream() { - return streamHandler.getInputStream(2); - } - - @Override - public int waitFor() throws InterruptedException { - synchronized(this) { - this.wait(); - } - return statusCode; - } - - public int exitValue() { - return statusCode; - } - - public void destroy() { - streamHandler.close(); - } + public void destroy() { + streamHandler.close(); } -} \ No newline at end of file + } +} diff --git a/util/src/main/java/io/kubernetes/client/PodLogs.java b/util/src/main/java/io/kubernetes/client/PodLogs.java index 8ac149597c..f696e5d6d5 100644 --- a/util/src/main/java/io/kubernetes/client/PodLogs.java +++ b/util/src/main/java/io/kubernetes/client/PodLogs.java @@ -12,65 +12,82 @@ */ package io.kubernetes.client; +import com.squareup.okhttp.Call; +import com.squareup.okhttp.Response; import io.kubernetes.client.apis.CoreV1Api; import io.kubernetes.client.models.V1Pod; - -import java.io.InputStream; import java.io.IOException; +import java.io.InputStream; -import com.squareup.okhttp.Call; -import com.squareup.okhttp.Response; - -/** - * Utility class offering streaming access to Pod logs. - */ +/** Utility class offering streaming access to Pod logs. */ public class PodLogs { - private ApiClient apiClient; - private CoreV1Api coreClient; + private ApiClient apiClient; + private CoreV1Api coreClient; - /** - * Simple PodLogs API constructor, uses default configuration - */ - public PodLogs() { - this(Configuration.getDefaultApiClient()); - } + /** Simple PodLogs API constructor, uses default configuration */ + public PodLogs() { + this(Configuration.getDefaultApiClient()); + } - /** - * PodLogs API Constructor - * @param apiClient The api client to use. - */ - public PodLogs(ApiClient apiClient) { - this.apiClient = apiClient; - this.coreClient = new CoreV1Api(apiClient); - } + /** + * PodLogs API Constructor + * + * @param apiClient The api client to use. + */ + public PodLogs(ApiClient apiClient) { + this.apiClient = apiClient; + this.coreClient = new CoreV1Api(apiClient); + } - /** - * Get the API client for these Logs operations. - * @return The API client that will be used. - */ - public ApiClient getApiClient() { - return apiClient; - } + /** + * Get the API client for these Logs operations. + * + * @return The API client that will be used. + */ + public ApiClient getApiClient() { + return apiClient; + } - public InputStream streamNamespacedPodLog(V1Pod pod) throws ApiException, IOException { - return streamNamespacedPodLog(pod.getMetadata().getNamespace(), pod.getMetadata().getName(), - pod.getSpec().getContainers().get(0).getName()); - } - - // Important note. You must close this stream or else you can leak connections. - public InputStream streamNamespacedPodLog(String namespace, String name, String container) throws ApiException, IOException { - return streamNamespacedPodLog(namespace, name, container, null, null, false); - } + public InputStream streamNamespacedPodLog(V1Pod pod) throws ApiException, IOException { + return streamNamespacedPodLog( + pod.getMetadata().getNamespace(), + pod.getMetadata().getName(), + pod.getSpec().getContainers().get(0).getName()); + } + // Important note. You must close this stream or else you can leak connections. + public InputStream streamNamespacedPodLog(String namespace, String name, String container) + throws ApiException, IOException { + return streamNamespacedPodLog(namespace, name, container, null, null, false); + } - // Important note. You must close this stream or else you can leak connections. - public InputStream streamNamespacedPodLog(String namespace, String name, String container, - Integer sinceSeconds, Integer tailLines, boolean timestamps) throws ApiException, IOException { - Call call = coreClient.readNamespacedPodLogCall(name, namespace, container, true, null, "false", false, sinceSeconds, tailLines, timestamps, null, null); - Response response = call.execute(); - if (!response.isSuccessful()) { - throw new ApiException("Logs request failed: " + response.code()); - } - return response.body().byteStream(); + // Important note. You must close this stream or else you can leak connections. + public InputStream streamNamespacedPodLog( + String namespace, + String name, + String container, + Integer sinceSeconds, + Integer tailLines, + boolean timestamps) + throws ApiException, IOException { + Call call = + coreClient.readNamespacedPodLogCall( + name, + namespace, + container, + true, + null, + "false", + false, + sinceSeconds, + tailLines, + timestamps, + null, + null); + Response response = call.execute(); + if (!response.isSuccessful()) { + throw new ApiException("Logs request failed: " + response.code()); } + return response.body().byteStream(); + } } diff --git a/util/src/main/java/io/kubernetes/client/PortForward.java b/util/src/main/java/io/kubernetes/client/PortForward.java index 4b01584bcd..81cc47a8c2 100644 --- a/util/src/main/java/io/kubernetes/client/PortForward.java +++ b/util/src/main/java/io/kubernetes/client/PortForward.java @@ -1,193 +1,190 @@ package io.kubernetes.client; -import io.kubernetes.client.Configuration; import io.kubernetes.client.models.V1Pod; -import io.kubernetes.client.util.WebSockets; import io.kubernetes.client.util.WebSocketStreamHandler; - -import java.io.InputStream; +import io.kubernetes.client.util.WebSockets; import java.io.IOException; +import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; /** - * Utility class for setting up port-forwarding connections. - * Uses the WebSockets API, not the SPDY API (which the Go client uses) - * - * The protocol is undocumented as far as I can tell, but the PR that added - * it is here: + * Utility class for setting up port-forwarding connections. Uses the WebSockets API, not the SPDY + * API (which the Go client uses) + * + *

The protocol is undocumented as far as I can tell, but the PR that added it is here: * https://github.com/kubernetes/kubernetes/pull/33684 - * - * And the protocol is: - * - * ws://server/api/v1/namespaces//pods//portforward?ports=80&ports=8080 - * - * I/O for first port (80) is on Channel 0 - * Err for first port (80) is on Channel 1 - * I/O for second port (8080) is on Channel 2 - * Err for second port (8080) is on Channel 3 - * - * - * The first two bytes of each output stream is the port that is being forwarded - * in little-endian format. + * + *

And the protocol is: + * + *

ws://server/api/v1/namespaces//pods//portforward?ports=80&ports=8080 + * + *

I/O for first port (80) is on Channel 0 Err for first port (80) is on Channel 1 I/O for second + * port (8080) is on Channel 2 Err for second port (8080) is on Channel 3 + * + *

The first two bytes of each output stream is the port that is being forwarded in little-endian + * format. */ public class PortForward { - private ApiClient apiClient; - - /** - * Simple PortForward API constructor, uses default configuration - */ - public PortForward() { - this(Configuration.getDefaultApiClient()); + private ApiClient apiClient; + + /** Simple PortForward API constructor, uses default configuration */ + public PortForward() { + this(Configuration.getDefaultApiClient()); + } + + /** + * PortForward API Constructor + * + * @param apiClient The api client to use. + */ + public PortForward(ApiClient apiClient) { + this.apiClient = apiClient; + } + + /** + * Get the API client for these PortForward operations. + * + * @return The API client that will be used. + */ + public ApiClient getApiClient() { + return apiClient; + } + + /** + * Set the API client for subsequent PortForward operations. + * + * @param apiClient The new API client to use. + */ + public void setApiClient(ApiClient apiClient) { + this.apiClient = apiClient; + } + + private String makePath(String namespace, String name) { + return "/api/v1/namespaces/" + namespace + "/pods/" + name + "/portforward"; + } + + /** + * PortForward to a container + * + * @param pod The pod where the port forward is run. + * @param ports The ports to forward + * @return The result of the Port Forward request. + */ + public PortForwardResult forward(V1Pod pod, List ports) + throws ApiException, IOException { + return forward(pod.getMetadata().getNamespace(), pod.getMetadata().getNamespace(), ports); + } + + /** + * PortForward to a container. + * + * @param namespace The namespace of the Pod + * @param name The name of the Pod + * @param ports The ports to forward + * @return The result of the Port Forward request. + */ + public PortForwardResult forward(String namespace, String name, List ports) + throws ApiException, IOException { + String path = makePath(namespace, name); + WebSocketStreamHandler handler = new WebSocketStreamHandler(); + PortForwardResult result = new PortForwardResult(handler, ports); + List queryParams = new ArrayList<>(); + for (Integer port : ports) { + queryParams.add(new Pair("ports", port.toString())); } + WebSockets.stream(path, "GET", queryParams, apiClient, handler); - /** - * PortForward API Constructor - * @param apiClient The api client to use. - */ - public PortForward(ApiClient apiClient) { - this.apiClient = apiClient; - } + // Wait for streams to start. + result.init(); + + return result; + } + + /** + * PortForwardResult contains the result of an Attach call, it includes streams for stdout stderr + * and stdin. + */ + public static class PortForwardResult { + private WebSocketStreamHandler handler; + private HashMap streams; + private List ports; /** - * Get the API client for these PortForward operations. - * @return The API client that will be used. + * Constructor + * + * @param handler The web socket handler + * @param ports The list of ports that are being forwarded. */ - public ApiClient getApiClient() { - return apiClient; + public PortForwardResult(WebSocketStreamHandler handler, List ports) + throws IOException { + this.handler = handler; + this.streams = new HashMap<>(); + this.ports = ports; } - /** - * Set the API client for subsequent PortForward operations. - * @param apiClient The new API client to use. - */ - public void setApiClient(ApiClient apiClient) { - this.apiClient = apiClient; + /** Initialize the connection. Must be called after the web socket has been opened. */ + public void init() throws IOException { + for (int i = 0; i < ports.size(); i++) { + InputStream is = handler.getInputStream(i * 2); + byte[] data = new byte[2]; + is.read(data); + int port = (data[0] & 0xFF) + (data[1] & 0xFF) * 256; + streams.put(port, i); + } } - private String makePath(String namespace, String name) { - return "/api/v1/namespaces/" + - namespace + - "/pods/" + - name + - "/portforward"; + private int findPortIndex(int portNumber) { + Integer ix = streams.get(portNumber); + if (ix == null) { + return -1; + } + return ix.intValue(); } /** - * PortForward to a container - * - * @param pod The pod where the port forward is run. - * @param ports The ports to forward - * @return The result of the Port Forward request. + * Get the output stream for the specified port number (e.g. 80) + * + * @param port The port number to get the stream for. + * @return The OutputStream for the specified port, null if there is no such port. */ - public PortForwardResult forward(V1Pod pod, List ports) throws ApiException, IOException { - return forward(pod.getMetadata().getNamespace(), pod.getMetadata().getNamespace(), ports); + public OutputStream getOutboundStream(int port) { + int portIndex = findPortIndex(port); + if (portIndex == -1) { + return null; + } + return handler.getOutputStream(portIndex * 2); } /** - * PortForward to a container. - * - * @param namespace The namespace of the Pod - * @param name The name of the Pod - * @param ports The ports to forward - * @return The result of the Port Forward request. + * Get the error stream for a port number (e.g. 80) + * + * @param port The port number to get the stream for. + * @return The error stream, or null if there is no such port. */ - public PortForwardResult forward(String namespace, String name, List ports) throws ApiException, IOException { - String path = makePath(namespace, name); - WebSocketStreamHandler handler = new WebSocketStreamHandler(); - PortForwardResult result = new PortForwardResult(handler, ports); - List queryParams = new ArrayList<>(); - for (Integer port : ports) { - queryParams.add(new Pair("ports", port.toString())); - } - WebSockets.stream(path, "GET", queryParams, apiClient, handler); - - // Wait for streams to start. - result.init(); - - return result; + public OutputStream getErrorStream(int port) { + int portIndex = findPortIndex(port); + if (portIndex == -1) { + return null; + } + return handler.getOutputStream(portIndex * 2 + 1); } /** - * PortForwardResult contains the result of an Attach call, it includes streams for stdout - * stderr and stdin. + * Get the input stream for a port number (e.g. 80) + * + * @param port The port number to get the stream for. + * @return The input stream, or null if no such port exists. */ - public static class PortForwardResult { - private WebSocketStreamHandler handler; - private HashMap streams; - private List ports; - - /** - * Constructor - * @param handler The web socket handler - * @param ports The list of ports that are being forwarded. - */ - public PortForwardResult(WebSocketStreamHandler handler, List ports) throws IOException { - this.handler = handler; - this.streams = new HashMap<>(); - this.ports = ports; - } - - /** - * Initialize the connection. Must be called after the web socket has been opened. - */ - public void init() throws IOException { - for (int i = 0; i < ports.size(); i++) { - InputStream is = handler.getInputStream(i * 2); - byte[] data = new byte[2]; - is.read(data); - int port = (data[0] & 0xFF) + (data[1] & 0xFF) * 256; - streams.put(port, i); - } - } - - private int findPortIndex(int portNumber) { - Integer ix = streams.get(portNumber); - if (ix == null) { - return -1; - } - return ix.intValue(); - } - - /** - * Get the output stream for the specified port number (e.g. 80) - * @param port The port number to get the stream for. - * @return The OutputStream for the specified port, null if there is no such port. - */ - public OutputStream getOutboundStream(int port) { - int portIndex = findPortIndex(port); - if (portIndex == -1) { - return null; - } - return handler.getOutputStream(portIndex * 2); - } - - /** - * Get the error stream for a port number (e.g. 80) - * @param port The port number to get the stream for. - * @return The error stream, or null if there is no such port. - */ - public OutputStream getErrorStream(int port) { - int portIndex = findPortIndex(port); - if (portIndex == -1) { - return null; - } - return handler.getOutputStream(portIndex * 2 + 1); - } - - /** - * Get the input stream for a port number (e.g. 80) - * @param port The port number to get the stream for. - * @return The input stream, or null if no such port exists. - */ - public InputStream getInputStream(int port) throws IOException { - int portIndex = findPortIndex(port); - if (portIndex == -1) { - return null; - } - return handler.getInputStream(portIndex * 2); - } + public InputStream getInputStream(int port) throws IOException { + int portIndex = findPortIndex(port); + if (portIndex == -1) { + return null; + } + return handler.getInputStream(portIndex * 2); } -} \ No newline at end of file + } +} diff --git a/util/src/main/java/io/kubernetes/client/ProtoClient.java b/util/src/main/java/io/kubernetes/client/ProtoClient.java index 9844f5f991..780ae423f3 100644 --- a/util/src/main/java/io/kubernetes/client/ProtoClient.java +++ b/util/src/main/java/io/kubernetes/client/ProtoClient.java @@ -1,11 +1,5 @@ package io.kubernetes.client; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; - import com.google.common.io.ByteStreams; import com.google.common.primitives.Bytes; import com.google.protobuf.Message; @@ -13,235 +7,288 @@ import com.squareup.okhttp.Request; import com.squareup.okhttp.RequestBody; import com.squareup.okhttp.Response; - import io.kubernetes.client.proto.Meta.DeleteOptions; import io.kubernetes.client.proto.Meta.Status; import io.kubernetes.client.proto.Runtime.TypeMeta; import io.kubernetes.client.proto.Runtime.Unknown; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; public class ProtoClient { - /** - * ObjectOrStatus is an object that is the return from a method call - * it holds either an API Object or an API Status object, but not both. - * Only one field may be non-null at a time. - * - * Oh, how I long for multi-return... - */ - public static class ObjectOrStatus { - public ObjectOrStatus(T obj, Status status) { - this.object = obj; - this.status = status; - } - - public T object; - public Status status; - - public String toString() { - if (object != null) { - return object.toString(); - } - return status.toString(); - } + /** + * ObjectOrStatus is an object that is the return from a method call it holds either an API Object + * or an API Status object, but not both. Only one field may be non-null at a time. + * + *

Oh, how I long for multi-return... + */ + public static class ObjectOrStatus { + public ObjectOrStatus(T obj, Status status) { + this.object = obj; + this.status = status; } - private ApiClient apiClient; - // Magic number for the beginning of proto encoded. - // https://github.com/kubernetes/apimachinery/blob/master/pkg/runtime/serializer/protobuf/protobuf.go#L42 - private static final byte[] MAGIC = new byte[] { 0x6b, 0x38, 0x73, 0x00 }; - private static final String MEDIA_TYPE = "application/vnd.kubernetes.protobuf"; - - /** - * Simple Protocol Budder API client constructor, uses default configuration - */ - public ProtoClient() { - this(Configuration.getDefaultApiClient()); - } + public T object; + public Status status; - /** - * ProtocolBuffer Client Constructor - * @param apiClient The api client to use. - */ - public ProtoClient(ApiClient apiClient) { - this.apiClient = apiClient; + public String toString() { + if (object != null) { + return object.toString(); + } + return status.toString(); } + } - /** - * Get the API client for these ProtocolBuffer operations. - * @return The API client that will be used. - */ - public ApiClient getApiClient() { - return apiClient; - } + private ApiClient apiClient; + // Magic number for the beginning of proto encoded. + // https://github.com/kubernetes/apimachinery/blob/master/pkg/runtime/serializer/protobuf/protobuf.go#L42 + private static final byte[] MAGIC = new byte[] {0x6b, 0x38, 0x73, 0x00}; + private static final String MEDIA_TYPE = "application/vnd.kubernetes.protobuf"; - /** - * Set the API client for subsequent ProtocolBuffer operations. - * @param apiClient The new API client to use. - */ - public void setApiClient(ApiClient apiClient) { - this.apiClient = apiClient; - } + /** Simple Protocol Budder API client constructor, uses default configuration */ + public ProtoClient() { + this(Configuration.getDefaultApiClient()); + } - /** - * Get a Kubernetes API object using protocol buffer encoding. - * @param builder The appropriate Builder for the object receveived from the request. - * @param path The URL path to call (e.g. /api/v1/namespaces/default/pods/pod-name) - * @return An ObjectOrStatus which contains the Object requested, or a Status about the request. - */ - public ObjectOrStatus get(T.Builder builder, String path) throws ApiException, IOException { - return request(builder, path, "GET", null, null, null); - } + /** + * ProtocolBuffer Client Constructor + * + * @param apiClient The api client to use. + */ + public ProtoClient(ApiClient apiClient) { + this.apiClient = apiClient; + } - /** - * List is fluent, semantic sugar method on top of get, which is intended - * to convey that the object is a List of objects rather than a single object - * @param builder The appropriate Builder for the object receveived from the request. - * @param path The URL path to call (e.g. /api/v1/namespaces/default/pods/pod-name) - * @return An ObjectOrStatus which contains the Object requested, or a Status about the request. - */ - public ObjectOrStatus list(T.Builder builder, String path) throws ApiException, IOException { - return get(builder, path); - } + /** + * Get the API client for these ProtocolBuffer operations. + * + * @return The API client that will be used. + */ + public ApiClient getApiClient() { + return apiClient; + } - /** - * Create a Kubernetes API object using protocol buffer encoding. Performs a POST - * @param obj The object to create - * @param path The URL path to call - * @param apiVersion The api version to use - * @param kind The kind of the object - * @return An ObjectOrStatus which contains the Object requested, or a Status about the request. - */ - public ObjectOrStatus create(T obj, String path, String apiVersion, String kind) - throws ApiException, IOException { - return request(obj.newBuilderForType(), path, "POST", obj, apiVersion, kind); - } + /** + * Set the API client for subsequent ProtocolBuffer operations. + * + * @param apiClient The new API client to use. + */ + public void setApiClient(ApiClient apiClient) { + this.apiClient = apiClient; + } - /** - * Update a Kubernetes API object using protocol buffer encoding. Performs a PUT - * @param obj The object to create - * @param path The URL path to call - * @param apiVersion The api version to use - * @param kind The kind of the object - * @return An ObjectOrStatus which contains the Object requested, or a Status about the request. - */ - public ObjectOrStatus update(T obj, String path, String apiVersion, String kind) - throws ApiException, IOException { - return request(obj.newBuilderForType(), path, "PUT", obj, apiVersion, kind); - } + /** + * Get a Kubernetes API object using protocol buffer encoding. + * + * @param builder The appropriate Builder for the object receveived from the request. + * @param path The URL path to call (e.g. /api/v1/namespaces/default/pods/pod-name) + * @return An ObjectOrStatus which contains the Object requested, or a Status about the request. + */ + public ObjectOrStatus get(T.Builder builder, String path) + throws ApiException, IOException { + return request(builder, path, "GET", null, null, null); + } + + /** + * List is fluent, semantic sugar method on top of get, which is intended to convey that the + * object is a List of objects rather than a single object + * + * @param builder The appropriate Builder for the object receveived from the request. + * @param path The URL path to call (e.g. /api/v1/namespaces/default/pods/pod-name) + * @return An ObjectOrStatus which contains the Object requested, or a Status about the request. + */ + public ObjectOrStatus list(T.Builder builder, String path) + throws ApiException, IOException { + return get(builder, path); + } + + /** + * Create a Kubernetes API object using protocol buffer encoding. Performs a POST + * + * @param obj The object to create + * @param path The URL path to call + * @param apiVersion The api version to use + * @param kind The kind of the object + * @return An ObjectOrStatus which contains the Object requested, or a Status about the request. + */ + public ObjectOrStatus create( + T obj, String path, String apiVersion, String kind) throws ApiException, IOException { + return request(obj.newBuilderForType(), path, "POST", obj, apiVersion, kind); + } - /** - * Delete a kubernetes API object using protocol buffer encoding. - * @param builder The builder for the response - * @param path The path to call in the API server - * @return The response status - */ - public ObjectOrStatus delete(T.Builder builder, String path) throws ApiException, IOException { - return request(builder, path, "DELETE", null, null, null); + /** + * Update a Kubernetes API object using protocol buffer encoding. Performs a PUT + * + * @param obj The object to create + * @param path The URL path to call + * @param apiVersion The api version to use + * @param kind The kind of the object + * @return An ObjectOrStatus which contains the Object requested, or a Status about the request. + */ + public ObjectOrStatus update( + T obj, String path, String apiVersion, String kind) throws ApiException, IOException { + return request(obj.newBuilderForType(), path, "PUT", obj, apiVersion, kind); + } + + /** + * Delete a kubernetes API object using protocol buffer encoding. + * + * @param builder The builder for the response + * @param path The path to call in the API server + * @return The response status + */ + public ObjectOrStatus delete(T.Builder builder, String path) + throws ApiException, IOException { + return request(builder, path, "DELETE", null, null, null); + } + + /** + * Delete a kubernetes API object using protocol buffer encoding. + * + * @param builder The builder for the response + * @param path The path to call in the API server + * @param deleteOptions optional deleteOptions + * @return The response status + */ + public ObjectOrStatus delete( + T.Builder builder, String path, DeleteOptions deleteOptions) + throws ApiException, IOException { + if (deleteOptions == null) { + return delete(builder, path); } - /** - * Delete a kubernetes API object using protocol buffer encoding. - * @param builder The builder for the response - * @param path The path to call in the API server - * @param deleteOptions optional deleteOptions - * @return The response status - */ - public ObjectOrStatus delete(T.Builder builder, String path, DeleteOptions deleteOptions) throws ApiException, IOException { - if (deleteOptions == null) { - return delete(builder,path); - } - - HashMap headers = new HashMap<>(); - headers.put("Content-Type", MEDIA_TYPE); - headers.put("Accept", MEDIA_TYPE); - String[] localVarAuthNames = new String[] { "BearerToken" }; - Request request = apiClient.buildRequest(path, "DELETE", new ArrayList(), new ArrayList(), null, - headers, new HashMap(), localVarAuthNames, null); - byte[] bytes = encode(deleteOptions, "v1", "DeleteOptions"); - request = request.newBuilder().delete(RequestBody.create(MediaType.parse(MEDIA_TYPE), bytes)).build(); - Response resp = apiClient.getHttpClient().newCall(request).execute(); - Unknown u = parse(resp.body().byteStream()); - resp.body().close(); - - if (u.getTypeMeta().getApiVersion().equals("v1") && - u.getTypeMeta().getKind().equals("Status")) { - Status status = Status.newBuilder().mergeFrom(u.getRaw()).build(); - return new ObjectOrStatus(null, status); - } - - return new ObjectOrStatus((T) builder.mergeFrom(u.getRaw()).build(), null); + HashMap headers = new HashMap<>(); + headers.put("Content-Type", MEDIA_TYPE); + headers.put("Accept", MEDIA_TYPE); + String[] localVarAuthNames = new String[] {"BearerToken"}; + Request request = + apiClient.buildRequest( + path, + "DELETE", + new ArrayList(), + new ArrayList(), + null, + headers, + new HashMap(), + localVarAuthNames, + null); + byte[] bytes = encode(deleteOptions, "v1", "DeleteOptions"); + request = + request.newBuilder().delete(RequestBody.create(MediaType.parse(MEDIA_TYPE), bytes)).build(); + Response resp = apiClient.getHttpClient().newCall(request).execute(); + Unknown u = parse(resp.body().byteStream()); + resp.body().close(); + + if (u.getTypeMeta().getApiVersion().equals("v1") + && u.getTypeMeta().getKind().equals("Status")) { + Status status = Status.newBuilder().mergeFrom(u.getRaw()).build(); + return new ObjectOrStatus(null, status); } - /** - * Generic protocol buffer based HTTP request. - * Not intended for general consumption, but public for advance use cases. - * @param builder The appropriate Builder for the object receveived from the request. - * @param method The HTTP method (e.g. GET) for this request. - * @param path The URL path to call (e.g. /api/v1/namespaces/default/pods/pod-name) - * @param body The body to send with the request (optional) - * @param apiVersion The 'apiVersion' to use when encoding, required if body is non-null, ignored otherwise. - * @param kind The 'kind' field to use when encoding, required if body is non-null, ignored otherwise. - * @return An ObjectOrStatus which contains the Object requested, or a Status about the request. - */ - public ObjectOrStatus request(T.Builder builder, String path, String method, T body, String apiVersion, - String kind) throws ApiException, IOException { - HashMap headers = new HashMap<>(); - headers.put("Content-Type", MEDIA_TYPE); - headers.put("Accept", MEDIA_TYPE); - String[] localVarAuthNames = new String[] { "BearerToken" }; - Request request = apiClient.buildRequest(path, method, new ArrayList(), new ArrayList(), null, - headers, new HashMap(), localVarAuthNames, null); - if (body != null) { - byte[] bytes = encode(body, apiVersion, kind); - switch (method) { - case "POST": - request = request.newBuilder().post(RequestBody.create(MediaType.parse(MEDIA_TYPE), bytes)).build(); - break; - case "PUT": - request = request.newBuilder().put(RequestBody.create(MediaType.parse(MEDIA_TYPE), bytes)).build(); - break; - case "PATCH": - request = request.newBuilder().patch(RequestBody.create(MediaType.parse(MEDIA_TYPE), bytes)).build(); - break; - default: - throw new ApiException("Unknown proto client API method: " + method); - } - } - Response resp = apiClient.getHttpClient().newCall(request).execute(); - Unknown u = parse(resp.body().byteStream()); - resp.body().close(); - - if (u.getTypeMeta().getApiVersion().equals("v1") && - u.getTypeMeta().getKind().equals("Status")) { - Status status = Status.newBuilder().mergeFrom(u.getRaw()).build(); - return new ObjectOrStatus(null, status); - } - - return new ObjectOrStatus((T) builder.mergeFrom(u.getRaw()).build(), null); + return new ObjectOrStatus((T) builder.mergeFrom(u.getRaw()).build(), null); + } + + /** + * Generic protocol buffer based HTTP request. Not intended for general consumption, but public + * for advance use cases. + * + * @param builder The appropriate Builder for the object receveived from the request. + * @param method The HTTP method (e.g. GET) for this request. + * @param path The URL path to call (e.g. /api/v1/namespaces/default/pods/pod-name) + * @param body The body to send with the request (optional) + * @param apiVersion The 'apiVersion' to use when encoding, required if body is non-null, ignored + * otherwise. + * @param kind The 'kind' field to use when encoding, required if body is non-null, ignored + * otherwise. + * @return An ObjectOrStatus which contains the Object requested, or a Status about the request. + */ + public ObjectOrStatus request( + T.Builder builder, String path, String method, T body, String apiVersion, String kind) + throws ApiException, IOException { + HashMap headers = new HashMap<>(); + headers.put("Content-Type", MEDIA_TYPE); + headers.put("Accept", MEDIA_TYPE); + String[] localVarAuthNames = new String[] {"BearerToken"}; + Request request = + apiClient.buildRequest( + path, + method, + new ArrayList(), + new ArrayList(), + null, + headers, + new HashMap(), + localVarAuthNames, + null); + if (body != null) { + byte[] bytes = encode(body, apiVersion, kind); + switch (method) { + case "POST": + request = + request + .newBuilder() + .post(RequestBody.create(MediaType.parse(MEDIA_TYPE), bytes)) + .build(); + break; + case "PUT": + request = + request + .newBuilder() + .put(RequestBody.create(MediaType.parse(MEDIA_TYPE), bytes)) + .build(); + break; + case "PATCH": + request = + request + .newBuilder() + .patch(RequestBody.create(MediaType.parse(MEDIA_TYPE), bytes)) + .build(); + break; + default: + throw new ApiException("Unknown proto client API method: " + method); + } } + Response resp = apiClient.getHttpClient().newCall(request).execute(); + Unknown u = parse(resp.body().byteStream()); + resp.body().close(); - // This isn't really documented anywhere except the code, but - // the proto-buf format is: - // * 4 byte magic number - // * Protocol Buffer encoded object of type runtime.Unknown - // * the 'raw' field in that object contains a Protocol Buffer - // encoding of the actual object. - // TODO: Document this somewhere proper. - - private byte[] encode(Message msg, String apiVersion, String kind) { - // It is unfortunate that we have to include apiVersion and kind, - // since we should be able to extract it from the Message, but - // for now at least, those fields are missing from the proto-buffer. - Unknown u = Unknown.newBuilder().setTypeMeta(TypeMeta.newBuilder().setApiVersion(apiVersion).setKind(kind)) - .setRaw(msg.toByteString()).build(); - return Bytes.concat(MAGIC, u.toByteArray()); + if (u.getTypeMeta().getApiVersion().equals("v1") + && u.getTypeMeta().getKind().equals("Status")) { + Status status = Status.newBuilder().mergeFrom(u.getRaw()).build(); + return new ObjectOrStatus(null, status); } - private Unknown parse(InputStream stream) throws ApiException, IOException { - byte[] magic = new byte[4]; - ByteStreams.readFully(stream, magic); - if (!Arrays.equals(magic, MAGIC)) { - throw new ApiException("Unexpected magic number: " + magic); - } - return Unknown.parseFrom(stream); + return new ObjectOrStatus((T) builder.mergeFrom(u.getRaw()).build(), null); + } + + // This isn't really documented anywhere except the code, but + // the proto-buf format is: + // * 4 byte magic number + // * Protocol Buffer encoded object of type runtime.Unknown + // * the 'raw' field in that object contains a Protocol Buffer + // encoding of the actual object. + // TODO: Document this somewhere proper. + + private byte[] encode(Message msg, String apiVersion, String kind) { + // It is unfortunate that we have to include apiVersion and kind, + // since we should be able to extract it from the Message, but + // for now at least, those fields are missing from the proto-buffer. + Unknown u = + Unknown.newBuilder() + .setTypeMeta(TypeMeta.newBuilder().setApiVersion(apiVersion).setKind(kind)) + .setRaw(msg.toByteString()) + .build(); + return Bytes.concat(MAGIC, u.toByteArray()); + } + + private Unknown parse(InputStream stream) throws ApiException, IOException { + byte[] magic = new byte[4]; + ByteStreams.readFully(stream, magic); + if (!Arrays.equals(magic, MAGIC)) { + throw new ApiException("Unexpected magic number: " + magic); } + return Unknown.parseFrom(stream); + } } diff --git a/util/src/main/java/io/kubernetes/client/util/ClientBuilder.java b/util/src/main/java/io/kubernetes/client/util/ClientBuilder.java index 3734ab8726..80ff36c279 100644 --- a/util/src/main/java/io/kubernetes/client/util/ClientBuilder.java +++ b/util/src/main/java/io/kubernetes/client/util/ClientBuilder.java @@ -12,6 +12,14 @@ */ package io.kubernetes.client.util; +import static io.kubernetes.client.util.Config.ENV_KUBECONFIG; +import static io.kubernetes.client.util.Config.ENV_SERVICE_HOST; +import static io.kubernetes.client.util.Config.ENV_SERVICE_PORT; +import static io.kubernetes.client.util.Config.SERVICEACCOUNT_CA_PATH; +import static io.kubernetes.client.util.Config.SERVICEACCOUNT_TOKEN_PATH; +import static io.kubernetes.client.util.KubeConfig.*; + +import io.kubernetes.client.ApiClient; import io.kubernetes.client.util.credentials.AccessTokenAuthentication; import io.kubernetes.client.util.credentials.Authentication; import io.kubernetes.client.util.credentials.KubeconfigAuthentication; @@ -20,25 +28,13 @@ import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; - import java.io.Reader; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Paths; import org.apache.log4j.Logger; -import io.kubernetes.client.ApiClient; - -import static io.kubernetes.client.util.Config.ENV_KUBECONFIG; -import static io.kubernetes.client.util.Config.ENV_SERVICE_HOST; -import static io.kubernetes.client.util.Config.ENV_SERVICE_PORT; -import static io.kubernetes.client.util.Config.SERVICEACCOUNT_CA_PATH; -import static io.kubernetes.client.util.Config.SERVICEACCOUNT_TOKEN_PATH; -import static io.kubernetes.client.util.KubeConfig.*; - -/** - * A Builder which allows the construction of {@link ApiClient}s in a fluent fashion. - */ +/** A Builder which allows the construction of {@link ApiClient}s in a fluent fashion. */ public class ClientBuilder { private static final Logger log = Logger.getLogger(ClientBuilder.class); @@ -51,8 +47,10 @@ public class ClientBuilder { /** * Creates an {@link ApiClient} by calling {@link #standard()} and {@link #build()}. * - * @return An ApiClient configured using the precedence specified for {@link #standard()}. - * @throws IOException if the configuration file or a file specified in a configuration file cannot be read. + * @return An ApiClient configured using the precedence specified for {@link + * #standard()}. + * @throws IOException if the configuration file or a file specified in a configuration file + * cannot be read. */ public static ApiClient defaultClient() throws IOException { return ClientBuilder.standard().build(); @@ -62,14 +60,15 @@ public static ApiClient defaultClient() throws IOException { * Creates a builder which is pre-configured in the following way * *

* * @return ClientBuilder pre-configured using the above precedence - * @throws IOException if the configuration file or a file specified in a configuration file cannot be read. + * @throws IOException if the configuration file or a file specified in a configuration file + * cannot be read. */ public static ClientBuilder standard() throws IOException { final FileReader kubeConfigReader = findConfigFromEnv(); @@ -103,7 +102,7 @@ private static FileReader findConfigFromEnv() throws FileNotFoundException { private static FileReader findConfigInHomeDir() throws FileNotFoundException { final File config = new File(new File(System.getenv(ENV_HOME), KUBEDIR), KUBECONFIG); - if(config.exists()) { + if (config.exists()) { return new FileReader(config); } else { log.debug("Could not find ~/.kube/config"); @@ -124,8 +123,9 @@ public static ClientBuilder cluster() throws IOException { final String port = System.getenv(ENV_SERVICE_PORT); builder.setBasePath("https://" + host + ":" + port); - final String token = new String(Files.readAllBytes(Paths.get(SERVICEACCOUNT_TOKEN_PATH)), - Charset.defaultCharset()); + final String token = + new String( + Files.readAllBytes(Paths.get(SERVICEACCOUNT_TOKEN_PATH)), Charset.defaultCharset()); builder.setCertificateAuthority(Files.readAllBytes(Paths.get(SERVICEACCOUNT_CA_PATH))); builder.setAuthentication(new AccessTokenAuthentication(token)); @@ -135,7 +135,7 @@ public static ClientBuilder cluster() throws IOException { /** * Creates a builder which is pre-configured from a {@link KubeConfig}. * - * To load a KubeConfig, see {@link KubeConfig#loadKubeConfig(Reader)}. + *

To load a KubeConfig, see {@link KubeConfig#loadKubeConfig(Reader)}. * * @param config The {@link KubeConfig} to configure the builder from. * @return ClientBuilder configured from the provided KubeConfig @@ -153,8 +153,9 @@ public static ClientBuilder kubeconfig(KubeConfig config) throws IOException { } } - final byte[] caBytes = KubeConfig.getDataOrFile(config.getCertificateAuthorityData(), - config.getCertificateAuthorityFile()); + final byte[] caBytes = + KubeConfig.getDataOrFile( + config.getCertificateAuthorityData(), config.getCertificateAuthorityFile()); if (caBytes != null) { builder.setCertificateAuthority(caBytes); } @@ -220,4 +221,4 @@ public ApiClient build() { return client; } -} \ No newline at end of file +} diff --git a/util/src/main/java/io/kubernetes/client/util/Config.java b/util/src/main/java/io/kubernetes/client/util/Config.java index ff4270975c..98cced0345 100644 --- a/util/src/main/java/io/kubernetes/client/util/Config.java +++ b/util/src/main/java/io/kubernetes/client/util/Config.java @@ -15,97 +15,91 @@ import io.kubernetes.client.ApiClient; import io.kubernetes.client.util.credentials.AccessTokenAuthentication; import io.kubernetes.client.util.credentials.UsernamePasswordAuthentication; -import org.apache.log4j.Logger; - import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; +import org.apache.log4j.Logger; public class Config { - public static final String SERVICEACCOUNT_ROOT = - "/var/run/secrets/kubernetes.io/serviceaccount"; - public static final String SERVICEACCOUNT_CA_PATH = - SERVICEACCOUNT_ROOT + "/ca.crt"; - public static final String SERVICEACCOUNT_TOKEN_PATH = - SERVICEACCOUNT_ROOT + "/token"; - public static final String ENV_KUBECONFIG = "KUBECONFIG"; - public static final String ENV_SERVICE_HOST = "KUBERNETES_SERVICE_HOST"; - public static final String ENV_SERVICE_PORT = "KUBERNETES_SERVICE_PORT"; - // The last resort host to try - public static final String DEFAULT_FALLBACK_HOST = "http://localhost:8080"; - - private static final Logger log = Logger.getLogger(Config.class); - - public static ApiClient fromCluster() throws IOException { - return ClientBuilder.cluster().build(); - } - - public static ApiClient fromUrl(String url) { - return fromUrl(url, true); - } - - public static ApiClient fromUrl(String url, boolean validateSSL) { - return new ApiClient() - .setBasePath(url) - .setVerifyingSsl(validateSSL); - } - - public static ApiClient fromUserPassword(String url, String user, String password) { - return fromUserPassword(url, user, password, true); - } - - public static ApiClient fromUserPassword(String url, String user, String password, boolean validateSSL) { - return new ClientBuilder() - .setBasePath(url) - .setAuthentication(new UsernamePasswordAuthentication(user, password)) - .setVerifyingSsl(validateSSL) - .build(); - } - - public static ApiClient fromToken(String url, String token) { - return fromToken(url, token, true); - } - - public static ApiClient fromToken(String url, String token, boolean validateSSL) { - return new ClientBuilder() - .setBasePath(url) - .setAuthentication(new AccessTokenAuthentication(token)) - .setVerifyingSsl(validateSSL) - .build(); - } - - public static ApiClient fromConfig(String fileName) throws IOException { - return fromConfig(new FileReader(fileName)); - } - - public static ApiClient fromConfig(InputStream stream) throws IOException { - return fromConfig(new InputStreamReader(stream)); - } - - public static ApiClient fromConfig(Reader input) throws IOException { - return fromConfig(KubeConfig.loadKubeConfig(input)); - } - - public static ApiClient fromConfig(KubeConfig config) throws IOException { - return ClientBuilder - .kubeconfig(config) - .build(); - } - - /** - * Easy client creation, follows this plan - *

- * - * @return The best APIClient given the previously described rules - */ - public static ApiClient defaultClient() throws IOException { - return ClientBuilder.standard().build(); - } + public static final String SERVICEACCOUNT_ROOT = "/var/run/secrets/kubernetes.io/serviceaccount"; + public static final String SERVICEACCOUNT_CA_PATH = SERVICEACCOUNT_ROOT + "/ca.crt"; + public static final String SERVICEACCOUNT_TOKEN_PATH = SERVICEACCOUNT_ROOT + "/token"; + public static final String ENV_KUBECONFIG = "KUBECONFIG"; + public static final String ENV_SERVICE_HOST = "KUBERNETES_SERVICE_HOST"; + public static final String ENV_SERVICE_PORT = "KUBERNETES_SERVICE_PORT"; + // The last resort host to try + public static final String DEFAULT_FALLBACK_HOST = "http://localhost:8080"; + + private static final Logger log = Logger.getLogger(Config.class); + + public static ApiClient fromCluster() throws IOException { + return ClientBuilder.cluster().build(); + } + + public static ApiClient fromUrl(String url) { + return fromUrl(url, true); + } + + public static ApiClient fromUrl(String url, boolean validateSSL) { + return new ApiClient().setBasePath(url).setVerifyingSsl(validateSSL); + } + + public static ApiClient fromUserPassword(String url, String user, String password) { + return fromUserPassword(url, user, password, true); + } + + public static ApiClient fromUserPassword( + String url, String user, String password, boolean validateSSL) { + return new ClientBuilder() + .setBasePath(url) + .setAuthentication(new UsernamePasswordAuthentication(user, password)) + .setVerifyingSsl(validateSSL) + .build(); + } + + public static ApiClient fromToken(String url, String token) { + return fromToken(url, token, true); + } + + public static ApiClient fromToken(String url, String token, boolean validateSSL) { + return new ClientBuilder() + .setBasePath(url) + .setAuthentication(new AccessTokenAuthentication(token)) + .setVerifyingSsl(validateSSL) + .build(); + } + + public static ApiClient fromConfig(String fileName) throws IOException { + return fromConfig(new FileReader(fileName)); + } + + public static ApiClient fromConfig(InputStream stream) throws IOException { + return fromConfig(new InputStreamReader(stream)); + } + + public static ApiClient fromConfig(Reader input) throws IOException { + return fromConfig(KubeConfig.loadKubeConfig(input)); + } + + public static ApiClient fromConfig(KubeConfig config) throws IOException { + return ClientBuilder.kubeconfig(config).build(); + } + + /** + * Easy client creation, follows this plan + * + * + * + * @return The best APIClient given the previously described rules + */ + public static ApiClient defaultClient() throws IOException { + return ClientBuilder.standard().build(); + } } diff --git a/util/src/main/java/io/kubernetes/client/util/KubeConfig.java b/util/src/main/java/io/kubernetes/client/util/KubeConfig.java index 0bd1d7b2c2..4c2f36f25b 100644 --- a/util/src/main/java/io/kubernetes/client/util/KubeConfig.java +++ b/util/src/main/java/io/kubernetes/client/util/KubeConfig.java @@ -12,14 +12,7 @@ */ package io.kubernetes.client.util; -import com.google.common.base.Charsets; import io.kubernetes.client.util.authenticators.Authenticator; -import java.nio.file.Paths; -import org.apache.commons.codec.binary.Base64; -import org.apache.log4j.Logger; -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.constructor.SafeConstructor; - import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; @@ -27,224 +20,222 @@ import java.io.Reader; import java.nio.file.FileSystems; import java.nio.file.Files; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; +import org.apache.commons.codec.binary.Base64; +import org.apache.log4j.Logger; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.constructor.SafeConstructor; -/** - * KubeConfig represents a kubernetes client configuration - */ +/** KubeConfig represents a kubernetes client configuration */ public class KubeConfig { - // Defaults for where to find a kubeconfig file - public static final String ENV_HOME = "HOME"; - public static final String KUBEDIR = ".kube"; - public static final String KUBECONFIG = "config"; - private static Map authenticators = new HashMap<>(); - - // Note to the reader: I considered creating a Config object - // and parsing into that instead of using Maps, but honestly - // this seemed cleaner than a bunch of boilerplate classes - - private ArrayList clusters; - private ArrayList contexts; - private ArrayList users; - Map currentContext; - Map currentCluster; - Map currentUser; - String currentNamespace; - - private static final Logger log = Logger.getLogger(KubeConfig.class); - - public static void registerAuthenticator(Authenticator auth) { - synchronized (authenticators) { - authenticators.put(auth.getName(), auth); - } - } - - /** - * Load a Kubernetes config from the default location - */ - public static KubeConfig loadDefaultKubeConfig() throws FileNotFoundException { - File config = new File(new File(System.getenv(ENV_HOME), KUBEDIR), KUBECONFIG); - if (!config.exists()) { - return null; - } - return loadKubeConfig(new FileReader(config)); - } - - /** - * Load a Kubernetes config from a Reader - */ - public static KubeConfig loadKubeConfig(Reader input) { - Yaml yaml = new Yaml(new SafeConstructor()); - Object config = yaml.load(input); - Map configMap = (Map)config; - - String currentContext = (String)configMap.get("current-context"); - ArrayList contexts = (ArrayList)configMap.get("contexts"); - ArrayList clusters = (ArrayList)configMap.get("clusters"); - ArrayList users = (ArrayList)configMap.get("users"); - - KubeConfig kubeConfig = new KubeConfig(contexts, clusters, users); - kubeConfig.setContext(currentContext); - - return kubeConfig; - } - - public KubeConfig(ArrayList contexts, - ArrayList clusters, - ArrayList users) { - this.contexts = contexts; - this.clusters = clusters; - this.users = users; - } - - public boolean setContext(String context) { - if (context == null) { - return false; - } - - currentCluster = null; - currentUser = null; - Map ctx = findObject(contexts, context); - if (ctx == null) { - return false; - } - currentContext = (Map) ctx.get("context"); - if (currentContext == null) { - return false; - } - String cluster = (String) currentContext.get("cluster"); - String user = (String) currentContext.get("user"); - currentNamespace = (String) currentContext.get("namespace"); - if (cluster != null) { - Map obj = findObject(clusters, cluster); - if (obj != null) { - currentCluster = (Map) obj.get("cluster"); - } - } - if (user != null) { - Map obj = findObject(users, user); - if (obj != null) { - currentUser = (Map) obj.get("user"); - } - } - return true; - } - - public String getNamespace() { - return currentNamespace; - } - - public String getServer() { - return getData(currentCluster, "server"); - } - - public String getCertificateAuthorityData() { - return getData(currentCluster, "certificate-authority-data"); - } - - public String getCertificateAuthorityFile() { - return getData(currentCluster, "certificate-authority"); - } - - public String getClientCertificateFile() { - return getData(currentUser, "client-certificate"); - } - - public String getClientCertificateData() { - return getData(currentUser, "client-certificate-data"); - } - - public String getClientKeyFile() { - return getData(currentUser, "client-key"); - } - - public String getClientKeyData() { - return getData(currentUser, "client-key-data"); - } - - public String getUsername() { - return getData(currentUser, "username"); - } - - public String getPassword() { - return getData(currentUser, "password"); - } - - public String getAccessToken() { - if (currentUser == null) { - return null; - } - - Object authProvider = currentUser.get("auth-provider"); - if (authProvider != null) { Map authProviderMap = (Map) authProvider; - Map authConfig = (Map) authProviderMap.get("config"); - if (authConfig != null) { - String name = (String) authProviderMap.get("name"); - Authenticator auth = authenticators.get(name); - if (auth != null) { - if (auth.isExpired(authConfig)) { - authConfig = auth.refresh(authConfig); - // TODO persist things here. - } - return auth.getToken(authConfig); - } - } - } - if (currentUser.containsKey("token")) { - return (String) currentUser.get("token"); - } - if (currentUser.containsKey("tokenFile")) { - String tokenFile = (String) currentUser.get("tokenFile"); - try { - byte[] data = Files.readAllBytes(FileSystems.getDefault().getPath(tokenFile)); - return new String(data, "UTF-8"); - } catch (IOException ex) { - log.error("Failed to read token file", ex); - } - } - return null; - } - - public boolean verifySSL() { - if (currentCluster == null) { - return false; - } - if (currentCluster.containsKey("insecure-skip-tls-verify")) { - return ! ((Boolean) currentCluster.get("insecure-skip-tls-verify")).booleanValue(); - } - return true; - } - - private static String getData(Map obj, String key) { - if (obj == null) { - return null; - } - return (String) obj.get(key); - } - - private static Map findObject(ArrayList list, String name) { - if (list == null) { - return null; - } - for (Object obj : list) { - Map map = (Map)obj; - if (name.equals((String)map.get("name"))) { - return map; - } - } - return null; - } - - public static byte[] getDataOrFile(final String data, final String file) - throws IOException { - if(data != null) { - return Base64.decodeBase64(data); - } - if(file != null) { - return Files.readAllBytes(Paths.get(file)); - } - return null; - } -} \ No newline at end of file + // Defaults for where to find a kubeconfig file + public static final String ENV_HOME = "HOME"; + public static final String KUBEDIR = ".kube"; + public static final String KUBECONFIG = "config"; + private static Map authenticators = new HashMap<>(); + + // Note to the reader: I considered creating a Config object + // and parsing into that instead of using Maps, but honestly + // this seemed cleaner than a bunch of boilerplate classes + + private ArrayList clusters; + private ArrayList contexts; + private ArrayList users; + Map currentContext; + Map currentCluster; + Map currentUser; + String currentNamespace; + + private static final Logger log = Logger.getLogger(KubeConfig.class); + + public static void registerAuthenticator(Authenticator auth) { + synchronized (authenticators) { + authenticators.put(auth.getName(), auth); + } + } + + /** Load a Kubernetes config from the default location */ + public static KubeConfig loadDefaultKubeConfig() throws FileNotFoundException { + File config = new File(new File(System.getenv(ENV_HOME), KUBEDIR), KUBECONFIG); + if (!config.exists()) { + return null; + } + return loadKubeConfig(new FileReader(config)); + } + + /** Load a Kubernetes config from a Reader */ + public static KubeConfig loadKubeConfig(Reader input) { + Yaml yaml = new Yaml(new SafeConstructor()); + Object config = yaml.load(input); + Map configMap = (Map) config; + + String currentContext = (String) configMap.get("current-context"); + ArrayList contexts = (ArrayList) configMap.get("contexts"); + ArrayList clusters = (ArrayList) configMap.get("clusters"); + ArrayList users = (ArrayList) configMap.get("users"); + + KubeConfig kubeConfig = new KubeConfig(contexts, clusters, users); + kubeConfig.setContext(currentContext); + + return kubeConfig; + } + + public KubeConfig( + ArrayList contexts, ArrayList clusters, ArrayList users) { + this.contexts = contexts; + this.clusters = clusters; + this.users = users; + } + + public boolean setContext(String context) { + if (context == null) { + return false; + } + + currentCluster = null; + currentUser = null; + Map ctx = findObject(contexts, context); + if (ctx == null) { + return false; + } + currentContext = (Map) ctx.get("context"); + if (currentContext == null) { + return false; + } + String cluster = (String) currentContext.get("cluster"); + String user = (String) currentContext.get("user"); + currentNamespace = (String) currentContext.get("namespace"); + if (cluster != null) { + Map obj = findObject(clusters, cluster); + if (obj != null) { + currentCluster = (Map) obj.get("cluster"); + } + } + if (user != null) { + Map obj = findObject(users, user); + if (obj != null) { + currentUser = (Map) obj.get("user"); + } + } + return true; + } + + public String getNamespace() { + return currentNamespace; + } + + public String getServer() { + return getData(currentCluster, "server"); + } + + public String getCertificateAuthorityData() { + return getData(currentCluster, "certificate-authority-data"); + } + + public String getCertificateAuthorityFile() { + return getData(currentCluster, "certificate-authority"); + } + + public String getClientCertificateFile() { + return getData(currentUser, "client-certificate"); + } + + public String getClientCertificateData() { + return getData(currentUser, "client-certificate-data"); + } + + public String getClientKeyFile() { + return getData(currentUser, "client-key"); + } + + public String getClientKeyData() { + return getData(currentUser, "client-key-data"); + } + + public String getUsername() { + return getData(currentUser, "username"); + } + + public String getPassword() { + return getData(currentUser, "password"); + } + + public String getAccessToken() { + if (currentUser == null) { + return null; + } + + Object authProvider = currentUser.get("auth-provider"); + if (authProvider != null) { + Map authProviderMap = (Map) authProvider; + Map authConfig = (Map) authProviderMap.get("config"); + if (authConfig != null) { + String name = (String) authProviderMap.get("name"); + Authenticator auth = authenticators.get(name); + if (auth != null) { + if (auth.isExpired(authConfig)) { + authConfig = auth.refresh(authConfig); + // TODO persist things here. + } + return auth.getToken(authConfig); + } + } + } + if (currentUser.containsKey("token")) { + return (String) currentUser.get("token"); + } + if (currentUser.containsKey("tokenFile")) { + String tokenFile = (String) currentUser.get("tokenFile"); + try { + byte[] data = Files.readAllBytes(FileSystems.getDefault().getPath(tokenFile)); + return new String(data, "UTF-8"); + } catch (IOException ex) { + log.error("Failed to read token file", ex); + } + } + return null; + } + + public boolean verifySSL() { + if (currentCluster == null) { + return false; + } + if (currentCluster.containsKey("insecure-skip-tls-verify")) { + return !((Boolean) currentCluster.get("insecure-skip-tls-verify")).booleanValue(); + } + return true; + } + + private static String getData(Map obj, String key) { + if (obj == null) { + return null; + } + return (String) obj.get(key); + } + + private static Map findObject(ArrayList list, String name) { + if (list == null) { + return null; + } + for (Object obj : list) { + Map map = (Map) obj; + if (name.equals((String) map.get("name"))) { + return map; + } + } + return null; + } + + public static byte[] getDataOrFile(final String data, final String file) throws IOException { + if (data != null) { + return Base64.decodeBase64(data); + } + if (file != null) { + return Files.readAllBytes(Paths.get(file)); + } + return null; + } +} diff --git a/util/src/main/java/io/kubernetes/client/util/SSLUtils.java b/util/src/main/java/io/kubernetes/client/util/SSLUtils.java index c91f130491..ef2479efdd 100644 --- a/util/src/main/java/io/kubernetes/client/util/SSLUtils.java +++ b/util/src/main/java/io/kubernetes/client/util/SSLUtils.java @@ -1,35 +1,28 @@ // The functions in this file are heavily derived/copied -// from https://github.com/fabric8io/kubernetes-client/tree/master/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/internal +// from +// https://github.com/fabric8io/kubernetes-client/tree/master/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/internal // The copyright header from those files is preserved here: /** * Copyright (C) 2015 Red Hat, Inc. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + *

http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and + *

Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ - package io.kubernetes.client.util; -import org.apache.commons.codec.binary.Base64; - -import javax.net.ssl.KeyManager; -import javax.net.ssl.KeyManagerFactory; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -47,220 +40,252 @@ import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.RSAPrivateCrtKeySpec; +import javax.net.ssl.KeyManager; +import javax.net.ssl.KeyManagerFactory; +import org.apache.commons.codec.binary.Base64; public class SSLUtils { - public static boolean isNotNullOrEmpty(String val) { - return val != null && val.length() > 0; - } + public static boolean isNotNullOrEmpty(String val) { + return val != null && val.length() > 0; + } - public static KeyManager[] keyManagers(byte[] certData, byte[] keyData, - String algo, String passphrase, String keyStoreFile, String keyStorePassphrase) - throws NoSuchAlgorithmException, UnrecoverableKeyException, KeyStoreException, CertificateException, - InvalidKeySpecException, IOException { - KeyManager[] keyManagers = null; - if (certData != null && keyData != null) { - KeyStore keyStore = createKeyStore(certData, keyData, algo, passphrase, keyStoreFile, - keyStorePassphrase); - KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); - kmf.init(keyStore, passphrase.toCharArray()); - keyManagers = kmf.getKeyManagers(); - } - return keyManagers; + public static KeyManager[] keyManagers( + byte[] certData, + byte[] keyData, + String algo, + String passphrase, + String keyStoreFile, + String keyStorePassphrase) + throws NoSuchAlgorithmException, UnrecoverableKeyException, KeyStoreException, + CertificateException, InvalidKeySpecException, IOException { + KeyManager[] keyManagers = null; + if (certData != null && keyData != null) { + KeyStore keyStore = + createKeyStore(certData, keyData, algo, passphrase, keyStoreFile, keyStorePassphrase); + KeyManagerFactory kmf = + KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + kmf.init(keyStore, passphrase.toCharArray()); + keyManagers = kmf.getKeyManagers(); } + return keyManagers; + } - public static KeyStore createKeyStore(byte[] clientCertData, byte[] clientKeyData, String clientKeyAlgo, - String clientKeyPassphrase, String keyStoreFile, String keyStorePassphrase) throws IOException, - CertificateException, NoSuchAlgorithmException, InvalidKeySpecException, KeyStoreException { - try (InputStream certInputStream = new ByteArrayInputStream(clientCertData); - InputStream keyInputStream = new ByteArrayInputStream(clientKeyData)) { - return createKeyStore(certInputStream, keyInputStream, clientKeyAlgo, - clientKeyPassphrase != null ? clientKeyPassphrase.toCharArray() : null, - keyStoreFile, getKeyStorePassphrase(keyStorePassphrase)); - } + public static KeyStore createKeyStore( + byte[] clientCertData, + byte[] clientKeyData, + String clientKeyAlgo, + String clientKeyPassphrase, + String keyStoreFile, + String keyStorePassphrase) + throws IOException, CertificateException, NoSuchAlgorithmException, InvalidKeySpecException, + KeyStoreException { + try (InputStream certInputStream = new ByteArrayInputStream(clientCertData); + InputStream keyInputStream = new ByteArrayInputStream(clientKeyData)) { + return createKeyStore( + certInputStream, + keyInputStream, + clientKeyAlgo, + clientKeyPassphrase != null ? clientKeyPassphrase.toCharArray() : null, + keyStoreFile, + getKeyStorePassphrase(keyStorePassphrase)); } + } - public static KeyStore createKeyStore(InputStream certInputStream, InputStream keyInputStream, String clientKeyAlgo, - char[] clientKeyPassphrase, String keyStoreFile, char[] keyStorePassphrase) throws IOException, - CertificateException, NoSuchAlgorithmException, InvalidKeySpecException, KeyStoreException { - CertificateFactory certFactory = CertificateFactory.getInstance("X509"); - X509Certificate cert = (X509Certificate) certFactory.generateCertificate(certInputStream); - - byte[] keyBytes = decodePem(keyInputStream); - - PrivateKey privateKey; - - KeyFactory keyFactory = KeyFactory.getInstance(clientKeyAlgo); - try { - // First let's try PKCS8 - privateKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(keyBytes)); - } catch (InvalidKeySpecException e) { - // Otherwise try PKCS1 - RSAPrivateCrtKeySpec keySpec = decodePKCS1(keyBytes); - privateKey = keyFactory.generatePrivate(keySpec); - } - - KeyStore keyStore = KeyStore.getInstance("JKS"); - if (keyStoreFile != null && keyStoreFile.length() > 0) { - keyStore.load(new FileInputStream(keyStoreFile), keyStorePassphrase); - } else { - loadDefaultKeyStoreFile(keyStore, keyStorePassphrase); - } - - String alias = cert.getSubjectX500Principal().getName(); - keyStore.setKeyEntry(alias, privateKey, clientKeyPassphrase, new Certificate[] { cert }); - - return keyStore; + public static KeyStore createKeyStore( + InputStream certInputStream, + InputStream keyInputStream, + String clientKeyAlgo, + char[] clientKeyPassphrase, + String keyStoreFile, + char[] keyStorePassphrase) + throws IOException, CertificateException, NoSuchAlgorithmException, InvalidKeySpecException, + KeyStoreException { + CertificateFactory certFactory = CertificateFactory.getInstance("X509"); + X509Certificate cert = (X509Certificate) certFactory.generateCertificate(certInputStream); + + byte[] keyBytes = decodePem(keyInputStream); + + PrivateKey privateKey; + + KeyFactory keyFactory = KeyFactory.getInstance(clientKeyAlgo); + try { + // First let's try PKCS8 + privateKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(keyBytes)); + } catch (InvalidKeySpecException e) { + // Otherwise try PKCS1 + RSAPrivateCrtKeySpec keySpec = decodePKCS1(keyBytes); + privateKey = keyFactory.generatePrivate(keySpec); } - // This method is inspired and partly taken over from - // http://oauth.googlecode.com/svn/code/java/ - // All credits to belong to them. - private static byte[] decodePem(InputStream keyInputStream) throws IOException { - BufferedReader reader = new BufferedReader(new InputStreamReader(keyInputStream)); - try { - String line; - while ((line = reader.readLine()) != null) { - if (line.contains("-----BEGIN ")) { - return readBytes(reader, line.trim().replace("BEGIN", "END")); - } - } - throw new IOException("PEM is invalid: no begin marker"); - } finally { - reader.close(); - } + KeyStore keyStore = KeyStore.getInstance("JKS"); + if (keyStoreFile != null && keyStoreFile.length() > 0) { + keyStore.load(new FileInputStream(keyStoreFile), keyStorePassphrase); + } else { + loadDefaultKeyStoreFile(keyStore, keyStorePassphrase); } - private static byte[] readBytes(BufferedReader reader, String endMarker) throws IOException { - String line; - StringBuffer buf = new StringBuffer(); + String alias = cert.getSubjectX500Principal().getName(); + keyStore.setKeyEntry(alias, privateKey, clientKeyPassphrase, new Certificate[] {cert}); - while ((line = reader.readLine()) != null) { - if (line.indexOf(endMarker) != -1) { - return Base64.decodeBase64(buf.toString()); - } - buf.append(line.trim()); + return keyStore; + } + + // This method is inspired and partly taken over from + // http://oauth.googlecode.com/svn/code/java/ + // All credits to belong to them. + private static byte[] decodePem(InputStream keyInputStream) throws IOException { + BufferedReader reader = new BufferedReader(new InputStreamReader(keyInputStream)); + try { + String line; + while ((line = reader.readLine()) != null) { + if (line.contains("-----BEGIN ")) { + return readBytes(reader, line.trim().replace("BEGIN", "END")); } - throw new IOException("PEM is invalid : No end marker"); + } + throw new IOException("PEM is invalid: no begin marker"); + } finally { + reader.close(); } + } - public static RSAPrivateCrtKeySpec decodePKCS1(byte[] keyBytes) throws IOException { - DerParser parser = new DerParser(keyBytes); - Asn1Object sequence = parser.read(); - sequence.validateSequence(); - parser = new DerParser(sequence.getValue()); - parser.read(); + private static byte[] readBytes(BufferedReader reader, String endMarker) throws IOException { + String line; + StringBuffer buf = new StringBuffer(); - return new RSAPrivateCrtKeySpec(next(parser), next(parser), next(parser), next(parser), next(parser), - next(parser), next(parser), next(parser)); + while ((line = reader.readLine()) != null) { + if (line.indexOf(endMarker) != -1) { + return Base64.decodeBase64(buf.toString()); + } + buf.append(line.trim()); } + throw new IOException("PEM is invalid : No end marker"); + } - private static BigInteger next(DerParser parser) throws IOException { - return parser.read().getInteger(); - } + public static RSAPrivateCrtKeySpec decodePKCS1(byte[] keyBytes) throws IOException { + DerParser parser = new DerParser(keyBytes); + Asn1Object sequence = parser.read(); + sequence.validateSequence(); + parser = new DerParser(sequence.getValue()); + parser.read(); + + return new RSAPrivateCrtKeySpec( + next(parser), + next(parser), + next(parser), + next(parser), + next(parser), + next(parser), + next(parser), + next(parser)); + } - static class DerParser { + private static BigInteger next(DerParser parser) throws IOException { + return parser.read().getInteger(); + } - private InputStream in; + static class DerParser { - DerParser(byte[] bytes) throws IOException { - this.in = new ByteArrayInputStream(bytes); - } + private InputStream in; - Asn1Object read() throws IOException { - int tag = in.read(); + DerParser(byte[] bytes) throws IOException { + this.in = new ByteArrayInputStream(bytes); + } - if (tag == -1) { - throw new IOException("Invalid DER: stream too short, missing tag"); - } + Asn1Object read() throws IOException { + int tag = in.read(); - int length = getLength(); - byte[] value = new byte[length]; - if (in.read(value) < length) { - throw new IOException("Invalid DER: stream too short, missing value"); - } + if (tag == -1) { + throw new IOException("Invalid DER: stream too short, missing tag"); + } - return new Asn1Object(tag, value); - } + int length = getLength(); + byte[] value = new byte[length]; + if (in.read(value) < length) { + throw new IOException("Invalid DER: stream too short, missing value"); + } - private int getLength() throws IOException { - int i = in.read(); - if (i == -1) { - throw new IOException("Invalid DER: length missing"); - } + return new Asn1Object(tag, value); + } - if ((i & ~0x7F) == 0) { - return i; - } + private int getLength() throws IOException { + int i = in.read(); + if (i == -1) { + throw new IOException("Invalid DER: length missing"); + } - int num = i & 0x7F; - if (i >= 0xFF || num > 4) { - throw new IOException("Invalid DER: length field too big (" + i + ")"); - } + if ((i & ~0x7F) == 0) { + return i; + } - byte[] bytes = new byte[num]; - if (in.read(bytes) < num) { - throw new IOException("Invalid DER: length too short"); - } + int num = i & 0x7F; + if (i >= 0xFF || num > 4) { + throw new IOException("Invalid DER: length field too big (" + i + ")"); + } - return new BigInteger(1, bytes).intValue(); - } - } + byte[] bytes = new byte[num]; + if (in.read(bytes) < num) { + throw new IOException("Invalid DER: length too short"); + } - static class Asn1Object { + return new BigInteger(1, bytes).intValue(); + } + } - private final int type; - private final byte[] value; - private final int tag; + static class Asn1Object { - public Asn1Object(int tag, byte[] value) { - this.tag = tag; - this.type = tag & 0x1F; - this.value = value; - } + private final int type; + private final byte[] value; + private final int tag; - public byte[] getValue() { - return value; - } + public Asn1Object(int tag, byte[] value) { + this.tag = tag; + this.type = tag & 0x1F; + this.value = value; + } - BigInteger getInteger() throws IOException { - if (type != 0x02) { - throw new IOException("Invalid DER: object is not integer"); //$NON-NLS-1$ - } - return new BigInteger(value); - } + public byte[] getValue() { + return value; + } - void validateSequence() throws IOException { - if (type != 0x10) { - throw new IOException("Invalid DER: not a sequence"); - } - if ((tag & 0x20) != 0x20) { - throw new IOException("Invalid DER: can't parse primitive entity"); - } - } + BigInteger getInteger() throws IOException { + if (type != 0x02) { + throw new IOException("Invalid DER: object is not integer"); // $NON-NLS-1$ + } + return new BigInteger(value); } - private static void loadDefaultKeyStoreFile(KeyStore keyStore, char[] keyStorePassphrase) - throws CertificateException, NoSuchAlgorithmException, IOException { + void validateSequence() throws IOException { + if (type != 0x10) { + throw new IOException("Invalid DER: not a sequence"); + } + if ((tag & 0x20) != 0x20) { + throw new IOException("Invalid DER: can't parse primitive entity"); + } + } + } - String keyStorePath = System.getProperty("javax.net.ssl.keyStore"); - if (keyStorePath != null && keyStorePath.length() > 0) { - File keyStoreFile = new File(keyStorePath); - if (loadDefaultStoreFile(keyStore, keyStoreFile, keyStorePassphrase)) { - return; - } - } + private static void loadDefaultKeyStoreFile(KeyStore keyStore, char[] keyStorePassphrase) + throws CertificateException, NoSuchAlgorithmException, IOException { - keyStore.load(null); + String keyStorePath = System.getProperty("javax.net.ssl.keyStore"); + if (keyStorePath != null && keyStorePath.length() > 0) { + File keyStoreFile = new File(keyStorePath); + if (loadDefaultStoreFile(keyStore, keyStoreFile, keyStorePassphrase)) { + return; + } } - private static boolean loadDefaultStoreFile(KeyStore keyStore, File fileToLoad, char[] passphrase) - throws CertificateException, NoSuchAlgorithmException, IOException { - if (fileToLoad.exists() && fileToLoad.isFile() && fileToLoad.length() > 0) { - keyStore.load(new FileInputStream(fileToLoad), passphrase); - return true; - } - return false; + keyStore.load(null); + } + + private static boolean loadDefaultStoreFile(KeyStore keyStore, File fileToLoad, char[] passphrase) + throws CertificateException, NoSuchAlgorithmException, IOException { + if (fileToLoad.exists() && fileToLoad.isFile() && fileToLoad.length() > 0) { + keyStore.load(new FileInputStream(fileToLoad), passphrase); + return true; } + return false; + } private static char[] getKeyStorePassphrase(String keyStorePassphrase) { if (keyStorePassphrase == null || keyStorePassphrase.length() == 0) { @@ -268,4 +293,4 @@ private static char[] getKeyStorePassphrase(String keyStorePassphrase) { } return keyStorePassphrase.toCharArray(); } -} \ No newline at end of file +} diff --git a/util/src/main/java/io/kubernetes/client/util/Watch.java b/util/src/main/java/io/kubernetes/client/util/Watch.java index d72de1247d..7d049a3de6 100644 --- a/util/src/main/java/io/kubernetes/client/util/Watch.java +++ b/util/src/main/java/io/kubernetes/client/util/Watch.java @@ -20,127 +20,126 @@ import io.kubernetes.client.ApiClient; import io.kubernetes.client.ApiException; import io.kubernetes.client.JSON; - import io.kubernetes.client.models.V1Status; import java.io.IOException; import java.lang.reflect.Type; import java.util.Iterator; /** - * Watch class implements watch mechansim of kubernetes. For every list API - * call with a watch parameter you should be able to pass its call to this class - * and watch changes to that list. For example CoreV1Api.listNamespace has watch - * parameter, so you can create a call using CoreV1Api.listNamespaceCall and - * set watch to True and watch the changes to namespaces. + * Watch class implements watch mechansim of kubernetes. For every list API call with a watch + * parameter you should be able to pass its call to this class and watch changes to that list. For + * example CoreV1Api.listNamespace has watch parameter, so you can create a call using + * CoreV1Api.listNamespaceCall and set watch to True and watch the changes to namespaces. */ -public class Watch implements Iterable>, - Iterator>, - java.io.Closeable { +public class Watch + implements Iterable>, Iterator>, java.io.Closeable { - /** - * Response class holds a watch response that has a `type` that can be - * ADDED, MODIFIED, DELETED and ERROR. It also hold the actual target - * object. - */ - public static class Response { - @SerializedName("type") - public String type; + /** + * Response class holds a watch response that has a `type` that can be ADDED, MODIFIED, DELETED + * and ERROR. It also hold the actual target object. + */ + public static class Response { + @SerializedName("type") + public String type; - @SerializedName("object") - public T object; + @SerializedName("object") + public T object; - public V1Status status; + public V1Status status; - Response(String type, T object) { - this.type = type; - this.object = object; - this.status = null; - } + Response(String type, T object) { + this.type = type; + this.object = object; + this.status = null; + } - Response(String type, V1Status status) { - this.type = type; - this.object = null; - this.status = status; - } + Response(String type, V1Status status) { + this.type = type; + this.object = null; + this.status = status; } + } - Type watchType; - ResponseBody response; - JSON json; + Type watchType; + ResponseBody response; + JSON json; - /** - * Creates a watch on a TYPENAME (T) using an API Client and a Call object. - * @param client the API client - * @param call the call object returned by api.{ListOperation}Call(...) - * method. Make sure watch flag is set in the call. - * @param watchType The type of the WatchResponse<T>. Use something like - * new TypeToken<Watch.Response<TYPENAME>>(){}.getType() - * @param TYPENAME. - * @return Watch object on TYPENAME - * @throws ApiException on IO exceptions. - */ - public static Watch createWatch(ApiClient client, Call call, Type watchType) throws ApiException { - try { - com.squareup.okhttp.Response response = call.execute(); - if (!response.isSuccessful()) { - String respBody = null; - if (response.body() != null) { - try { - respBody = response.body().string(); - } catch (IOException e) { - throw new ApiException(response.message(), e, response.code(), response.headers().toMultimap()); - } - } - throw new ApiException(response.message(), response.code(), response.headers().toMultimap(), respBody); - } - return new Watch<>(client.getJSON(), response.body(), watchType); - } catch (IOException e) { - throw new ApiException(e); + /** + * Creates a watch on a TYPENAME (T) using an API Client and a Call object. + * + * @param client the API client + * @param call the call object returned by api.{ListOperation}Call(...) method. Make sure watch + * flag is set in the call. + * @param watchType The type of the WatchResponse<T>. Use something like new + * TypeToken<Watch.Response<TYPENAME>>(){}.getType() + * @param TYPENAME. + * @return Watch object on TYPENAME + * @throws ApiException on IO exceptions. + */ + public static Watch createWatch(ApiClient client, Call call, Type watchType) + throws ApiException { + try { + com.squareup.okhttp.Response response = call.execute(); + if (!response.isSuccessful()) { + String respBody = null; + if (response.body() != null) { + try { + respBody = response.body().string(); + } catch (IOException e) { + throw new ApiException( + response.message(), e, response.code(), response.headers().toMultimap()); + } } + throw new ApiException( + response.message(), response.code(), response.headers().toMultimap(), respBody); + } + return new Watch<>(client.getJSON(), response.body(), watchType); + } catch (IOException e) { + throw new ApiException(e); } + } - private Watch(JSON json, ResponseBody body, Type watchType) { - this.response = body; - this.watchType = watchType; - this.json = json; - } + private Watch(JSON json, ResponseBody body, Type watchType) { + this.response = body; + this.watchType = watchType; + this.json = json; + } - public Response next() { - try { - String line = response.source().readUtf8Line(); - if (line == null) { - throw new RuntimeException("Null response from the server."); - } - try { - return json.deserialize(line, watchType); - } catch (JsonParseException ex) { - Type statusType = new TypeToken>(){}.getType(); - Response status = json.deserialize(line, statusType); - return new Response(status.type, status.object); - } - } catch (IOException e) { - throw new RuntimeException("IO Exception during next method.", e); - } + public Response next() { + try { + String line = response.source().readUtf8Line(); + if (line == null) { + throw new RuntimeException("Null response from the server."); + } + try { + return json.deserialize(line, watchType); + } catch (JsonParseException ex) { + Type statusType = new TypeToken>() {}.getType(); + Response status = json.deserialize(line, statusType); + return new Response(status.type, status.object); + } + } catch (IOException e) { + throw new RuntimeException("IO Exception during next method.", e); } + } - public boolean hasNext() { - try { - return !response.source().exhausted(); - } catch (IOException e) { - throw new RuntimeException("IO Exception during hasNext method.", - e); - } + public boolean hasNext() { + try { + return !response.source().exhausted(); + } catch (IOException e) { + throw new RuntimeException("IO Exception during hasNext method.", e); } + } - public Iterator> iterator() { - return this; - } + public Iterator> iterator() { + return this; + } - public void remove() { - throw new UnsupportedOperationException("remove"); - } - - public void close() throws IOException { - this.response.close(); - } + public void remove() { + throw new UnsupportedOperationException("remove"); + } + + public void close() throws IOException { + this.response.close(); + } } diff --git a/util/src/main/java/io/kubernetes/client/util/WebSocketStreamHandler.java b/util/src/main/java/io/kubernetes/client/util/WebSocketStreamHandler.java index c07e4f4dda..a69d9abb66 100644 --- a/util/src/main/java/io/kubernetes/client/util/WebSocketStreamHandler.java +++ b/util/src/main/java/io/kubernetes/client/util/WebSocketStreamHandler.java @@ -15,166 +15,168 @@ import com.google.common.base.Charsets; import com.google.common.io.ByteStreams; import com.google.common.io.CharStreams; - import com.squareup.okhttp.RequestBody; import com.squareup.okhttp.ws.WebSocket; -import okio.ByteString; -import org.apache.log4j.Logger; - -import java.io.Closeable; import java.io.ByteArrayInputStream; -import java.io.InputStream; +import java.io.Closeable; import java.io.IOException; +import java.io.InputStream; import java.io.OutputStream; import java.io.PipedInputStream; import java.io.PipedOutputStream; import java.io.Reader; import java.util.HashMap; import java.util.Map; +import okio.ByteString; +import org.apache.log4j.Logger; /** - * WebSocketStreamHandler understands the Kubernetes streaming protocol and separates - * a single WebSockets stream into a number of different streams using that protocol. + * WebSocketStreamHandler understands the Kubernetes streaming protocol and separates a single + * WebSockets stream into a number of different streams using that protocol. */ public class WebSocketStreamHandler implements WebSockets.SocketListener, Closeable { - Map output; - Map input; - WebSocket socket; - String protocol; + Map output; + Map input; + WebSocket socket; + String protocol; - private static final Logger log = Logger.getLogger(WebSockets.class); + private static final Logger log = Logger.getLogger(WebSockets.class); - public WebSocketStreamHandler() { - output = new HashMap<>(); - input = new HashMap<>(); + public WebSocketStreamHandler() { + output = new HashMap<>(); + input = new HashMap<>(); + } + + @Override + public void open(String protocol, WebSocket socket) { + this.protocol = protocol; + this.socket = socket; + } + + @Override + public void bytesMessage(InputStream in) { + try { + OutputStream out = getSocketInputOutputStream(in.read()); + ByteStreams.copy(in, out); + } catch (IOException ex) { + log.error("Error writing message", ex); } + } - @Override - public void open(String protocol, WebSocket socket) { - this.protocol = protocol; - this.socket = socket; + @Override + public void textMessage(Reader in) { + try { + OutputStream out = getSocketInputOutputStream(in.read()); + InputStream inStream = + new ByteArrayInputStream(CharStreams.toString(in).getBytes(Charsets.UTF_8)); + ByteStreams.copy(inStream, out); + } catch (IOException ex) { + log.error("Error writing message", ex); } - - @Override - public void bytesMessage(InputStream in) { - try { - OutputStream out = getSocketInputOutputStream(in.read()); - ByteStreams.copy(in, out); - } catch (IOException ex) { - log.error("Error writing message", ex); - } + } + + @Override + public void close() { + for (PipedOutputStream out : output.values()) { + try { + out.close(); + } catch (IOException ex) { + // TODO use a logger here + ex.printStackTrace(); + } } - - @Override - public void textMessage(Reader in) { - try { - OutputStream out = getSocketInputOutputStream(in.read()); - InputStream inStream = - new ByteArrayInputStream(CharStreams.toString(in).getBytes(Charsets.UTF_8)); - ByteStreams.copy(inStream, out); - } catch (IOException ex) { - log.error("Error writing message", ex); - } + for (PipedInputStream in : input.values()) { + try { + in.close(); + } catch (IOException ex) { + // TODO use a logger here + ex.printStackTrace(); + } } - - @Override - public void close() { - for (PipedOutputStream out: output.values()) { - try { - out.close(); - } catch (IOException ex) { - // TODO use a logger here - ex.printStackTrace(); - } - } - for (PipedInputStream in: input.values()) { - try { - in.close(); - } catch (IOException ex) { - // TODO use a logger here - ex.printStackTrace(); - } - } + } + + /** + * Get a specific input stream using its identifier + * + * @param stream The stream to return + * @return The specified stream. + */ + public synchronized InputStream getInputStream(int stream) { + if (!input.containsKey(stream)) { + try { + PipedInputStream pipeIn = new PipedInputStream(); + PipedOutputStream pipeOut = new PipedOutputStream(pipeIn); + output.put(stream, pipeOut); + input.put(stream, pipeIn); + } catch (IOException ex) { + // This is _very_ unlikely, as it requires the above constructor to fail. + // don't force callers to catch, but still throw + throw new IllegalStateException(ex); + } + } + return input.get(stream); + } + + /** + * Gets a specific output stream using it's identified + * + * @param stream The stream to return + * @return The specified stream. + */ + public OutputStream getOutputStream(int stream) { + return new WebSocketOutputStream(stream); + } + + /** + * Get the pipe to write data to a specific InputStream. This is called when new data is read from + * the web socket, to send the data on to the right stream. + * + * @param stream The stream to return + * @return The specified stream. + */ + private synchronized OutputStream getSocketInputOutputStream(int stream) { + if (!output.containsKey(stream)) { + try { + PipedInputStream pipeIn = new PipedInputStream(); + PipedOutputStream pipeOut = new PipedOutputStream(pipeIn); + output.put(stream, pipeOut); + input.put(stream, pipeIn); + } catch (IOException ex) { + // This is _very_ unlikely, as it requires the above constructor to fail. + // don't force callers to catch, but still throw + throw new IllegalStateException(ex); + } } + return output.get(stream); + } + + private class WebSocketOutputStream extends OutputStream { + private byte stream; - /** - * Get a specific input stream using its identifier - * @param stream The stream to return - * @return The specified stream. - */ - public synchronized InputStream getInputStream(int stream) { - if (!input.containsKey(stream)) { - try { - PipedInputStream pipeIn = new PipedInputStream(); - PipedOutputStream pipeOut = new PipedOutputStream(pipeIn); - output.put(stream, pipeOut); - input.put(stream, pipeIn); - } catch (IOException ex) { - // This is _very_ unlikely, as it requires the above constructor to fail. - // don't force callers to catch, but still throw - throw new IllegalStateException(ex); - } - } - return input.get(stream); + public WebSocketOutputStream(int stream) { + this.stream = (byte) stream; } - /** - * Gets a specific output stream using it's identified - * @param stream The stream to return - * @return The specified stream. - */ - public OutputStream getOutputStream(int stream) { - return new WebSocketOutputStream(stream); + @Override + public void write(int b) throws IOException { + write(new byte[] {(byte) b}); } - /** - * Get the pipe to write data to a specific InputStream. This is called when - * new data is read from the web socket, to send the data on to the right stream. - * @param stream The stream to return - * @return The specified stream. - */ - private synchronized OutputStream getSocketInputOutputStream(int stream) { - if (!output.containsKey(stream)) { - try { - PipedInputStream pipeIn = new PipedInputStream(); - PipedOutputStream pipeOut = new PipedOutputStream(pipeIn); - output.put(stream, pipeOut); - input.put(stream, pipeIn); - } catch (IOException ex) { - // This is _very_ unlikely, as it requires the above constructor to fail. - // don't force callers to catch, but still throw - throw new IllegalStateException(ex); - } - } - return output.get(stream); + @Override + public void write(byte[] b) throws IOException { + this.write(b, 0, b.length); } - private class WebSocketOutputStream extends OutputStream { - private byte stream; - - public WebSocketOutputStream(int stream) { - this.stream = (byte) stream; - } - - @Override - public void write(int b) throws IOException { - write(new byte[] { (byte) b}); - } - - @Override - public void write(byte[] b) throws IOException { - this.write(b, 0, b.length); - } - - @Override - public void write(byte[] b, int offset, int length) throws IOException { - if (WebSocketStreamHandler.this.socket == null) { - throw new IOException("No websocket connection!"); - } - byte[] buffer = new byte[length + 1]; - buffer[0] = stream; - System.arraycopy(b, offset, buffer, 1, length); - WebSocketStreamHandler.this.socket.sendMessage(RequestBody.create(WebSocket.BINARY, ByteString.of(buffer))); - } + @Override + public void write(byte[] b, int offset, int length) throws IOException { + if (WebSocketStreamHandler.this.socket == null) { + throw new IOException("No websocket connection!"); + } + byte[] buffer = new byte[length + 1]; + buffer[0] = stream; + System.arraycopy(b, offset, buffer, 1, length); + WebSocketStreamHandler.this.socket.sendMessage( + RequestBody.create(WebSocket.BINARY, ByteString.of(buffer))); } + } } diff --git a/util/src/main/java/io/kubernetes/client/util/WebSockets.java b/util/src/main/java/io/kubernetes/client/util/WebSockets.java index 6bc088c05f..2d3106206d 100644 --- a/util/src/main/java/io/kubernetes/client/util/WebSockets.java +++ b/util/src/main/java/io/kubernetes/client/util/WebSockets.java @@ -12,8 +12,10 @@ */ package io.kubernetes.client.util; +import static com.squareup.okhttp.ws.WebSocket.BINARY; +import static com.squareup.okhttp.ws.WebSocket.TEXT; + import com.google.common.net.HttpHeaders; -import com.squareup.okhttp.Call; import com.squareup.okhttp.Request; import com.squareup.okhttp.Response; import com.squareup.okhttp.ResponseBody; @@ -23,129 +25,134 @@ import io.kubernetes.client.ApiClient; import io.kubernetes.client.ApiException; import io.kubernetes.client.Pair; -import okio.Buffer; -import org.apache.log4j.Logger; - -import java.io.Closeable; import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; import java.io.Reader; -import java.util.List; import java.util.ArrayList; import java.util.HashMap; - -import static com.squareup.okhttp.ws.WebSocket.BINARY; -import static com.squareup.okhttp.ws.WebSocket.TEXT; +import java.util.List; +import okio.Buffer; +import org.apache.log4j.Logger; public class WebSockets { - public static final String V4_STREAM_PROTOCOL = "v4.channel.k8s.io"; - public static final String V3_STREAM_PROTOCOL = "v3.channel.k8s.io"; - public static final String V2_STREAM_PROTOCOL = "v2.channel.k8s.io"; - public static final String V1_STREAM_PROTOCOL = "channel.k8s.io"; - public static final String STREAM_PROTOCOL_HEADER = "X-Stream-Protocol-Version"; - public static final String SPDY_3_1 = "SPDY/3.1"; + public static final String V4_STREAM_PROTOCOL = "v4.channel.k8s.io"; + public static final String V3_STREAM_PROTOCOL = "v3.channel.k8s.io"; + public static final String V2_STREAM_PROTOCOL = "v2.channel.k8s.io"; + public static final String V1_STREAM_PROTOCOL = "channel.k8s.io"; + public static final String STREAM_PROTOCOL_HEADER = "X-Stream-Protocol-Version"; + public static final String SPDY_3_1 = "SPDY/3.1"; + + private static final Logger log = Logger.getLogger(WebSockets.class); - private static final Logger log = Logger.getLogger(WebSockets.class); + /** A simple interface for a listener on a web socket */ + public interface SocketListener { + /** Called when the socket is opened */ + public void open(String protocol, WebSocket socket); /** - * A simple interface for a listener on a web socket + * Callled when a binary media type message is received + * + * @param in The input stream containing the binary data */ - public interface SocketListener { - /** - * Called when the socket is opened - */ - public void open(String protocol, WebSocket socket); - - /** - * Callled when a binary media type message is received - * @param in The input stream containing the binary data - */ - public void bytesMessage(InputStream in); - - /** - * Called when a text media type message is received - * @param in The character stream containing the message - */ - public void textMessage(Reader in); - - /** - * Called when the stream is closed. - */ - public void close(); - } + public void bytesMessage(InputStream in); /** - * Create a new WebSocket stream - * @param path The HTTP Path to request from the API - * @param method The HTTP method to use for the call - * @param client The ApiClient for communicating with the API - * @param listener The socket listener to handle socket events + * Called when a text media type message is received + * + * @param in The character stream containing the message */ - public static void stream(String path, String method, ApiClient client, SocketListener listener) throws ApiException, IOException { - stream(path, method, new ArrayList(), client, listener); + public void textMessage(Reader in); + + /** Called when the stream is closed. */ + public void close(); + } + + /** + * Create a new WebSocket stream + * + * @param path The HTTP Path to request from the API + * @param method The HTTP method to use for the call + * @param client The ApiClient for communicating with the API + * @param listener The socket listener to handle socket events + */ + public static void stream(String path, String method, ApiClient client, SocketListener listener) + throws ApiException, IOException { + stream(path, method, new ArrayList(), client, listener); + } + + public static void stream( + String path, String method, List queryParams, ApiClient client, SocketListener listener) + throws ApiException, IOException { + + HashMap headers = new HashMap(); + String allProtocols = + String.format( + "%s,%s,%s,%s", + V4_STREAM_PROTOCOL, V3_STREAM_PROTOCOL, V2_STREAM_PROTOCOL, V1_STREAM_PROTOCOL); + headers.put(STREAM_PROTOCOL_HEADER, allProtocols); + headers.put(HttpHeaders.CONNECTION, HttpHeaders.UPGRADE); + headers.put(HttpHeaders.UPGRADE, SPDY_3_1); + + Request request = + client.buildRequest( + path, + method, + queryParams, + new ArrayList(), + null, + headers, + new HashMap(), + new String[0], + null); + streamRequest(request, client, listener); + } + + /* + If we ever upgrade to okhttp 3... + public static void stream(Call call, ApiClient client, SocketListener listener) { + streamRequest(call.request(), client, listener); + } + */ + + private static void streamRequest(Request request, ApiClient client, SocketListener listener) { + WebSocketCall.create(client.getHttpClient(), request).enqueue(new Listener(listener)); + } + + public static class Listener implements WebSocketListener { + private SocketListener listener; + + public Listener(SocketListener listener) { + this.listener = listener; } - public static void stream(String path, String method, List queryParams, ApiClient client, SocketListener listener) throws ApiException, IOException { - - HashMap headers = new HashMap(); - String allProtocols = String.format("%s,%s,%s,%s", V4_STREAM_PROTOCOL, V3_STREAM_PROTOCOL, V2_STREAM_PROTOCOL, V1_STREAM_PROTOCOL); - headers.put(STREAM_PROTOCOL_HEADER, allProtocols); - headers.put(HttpHeaders.CONNECTION, HttpHeaders.UPGRADE); - headers.put(HttpHeaders.UPGRADE, SPDY_3_1); - - Request request = client.buildRequest(path, method, queryParams, new ArrayList(), null, headers, new HashMap(), new String[0], null); - streamRequest(request, client, listener); + @Override + public void onOpen(final WebSocket webSocket, Response response) { + String protocol = response.header(STREAM_PROTOCOL_HEADER, "missing"); + listener.open(protocol, webSocket); } - /* - If we ever upgrade to okhttp 3... - public static void stream(Call call, ApiClient client, SocketListener listener) { - streamRequest(call.request(), client, listener); + @Override + public void onMessage(ResponseBody body) throws IOException { + if (body.contentType() == TEXT) { + listener.textMessage(body.charStream()); + } else if (body.contentType() == BINARY) { + listener.bytesMessage(body.byteStream()); + } + body.close(); } - */ - private static void streamRequest(Request request, ApiClient client, SocketListener listener) { - WebSocketCall.create(client.getHttpClient(), request).enqueue(new Listener(listener)); + @Override + public void onPong(Buffer payload) {} + + @Override + public void onClose(int code, String reason) { + listener.close(); } - public static class Listener implements WebSocketListener { - private SocketListener listener; - - public Listener(SocketListener listener) { - this.listener = listener; - } - - @Override - public void onOpen(final WebSocket webSocket, Response response) { - String protocol = response.header(STREAM_PROTOCOL_HEADER, "missing"); - listener.open(protocol, webSocket); - } - - @Override - public void onMessage(ResponseBody body) throws IOException { - if (body.contentType() == TEXT) { - listener.textMessage(body.charStream()); - } else if (body.contentType() == BINARY) { - listener.bytesMessage(body.byteStream()); - } - body.close(); - } - - @Override - public void onPong(Buffer payload) { - } - - @Override - public void onClose(int code, String reason) { - listener.close(); - } - - @Override - public void onFailure(IOException e, Response res) { - e.printStackTrace(); - listener.close(); - } + @Override + public void onFailure(IOException e, Response res) { + e.printStackTrace(); + listener.close(); } + } } - diff --git a/util/src/main/java/io/kubernetes/client/util/authenticators/Authenticator.java b/util/src/main/java/io/kubernetes/client/util/authenticators/Authenticator.java index 7a226f180a..ef8f30eb60 100644 --- a/util/src/main/java/io/kubernetes/client/util/authenticators/Authenticator.java +++ b/util/src/main/java/io/kubernetes/client/util/authenticators/Authenticator.java @@ -15,30 +15,27 @@ import java.util.Map; /** - * The Authenticator interface represents a plugin that can handle - * a specific type of authentication information (e.g. 'gcp') + * The Authenticator interface represents a plugin that can handle a specific type of authentication + * information (e.g. 'gcp') */ public interface Authenticator { - /** - * Return the name of this authenticator, this should be the - * value that is also in a kubeconfig file. - */ - public String getName(); + /** + * Return the name of this authenticator, this should be the value that is also in a kubeconfig + * file. + */ + public String getName(); - /** - * Get a token from this authenticator. - * @param config The configuration information for this authenticator - * @return The new token, null of no such token can be found/generated - */ - public String getToken(Map config); + /** + * Get a token from this authenticator. + * + * @param config The configuration information for this authenticator + * @return The new token, null of no such token can be found/generated + */ + public String getToken(Map config); - /** - * Determine if this config is expired - */ - public boolean isExpired(Map config); + /** Determine if this config is expired */ + public boolean isExpired(Map config); - /** - * Refresh an expired token with a new fresh one. - */ - public Map refresh(Map config); + /** Refresh an expired token with a new fresh one. */ + public Map refresh(Map config); } diff --git a/util/src/main/java/io/kubernetes/client/util/authenticators/GCPAuthenticator.java b/util/src/main/java/io/kubernetes/client/util/authenticators/GCPAuthenticator.java index 964b5535f8..791d48eaee 100644 --- a/util/src/main/java/io/kubernetes/client/util/authenticators/GCPAuthenticator.java +++ b/util/src/main/java/io/kubernetes/client/util/authenticators/GCPAuthenticator.java @@ -13,39 +13,39 @@ package io.kubernetes.client.util.authenticators; import io.kubernetes.client.util.KubeConfig; - import java.util.Date; import java.util.Map; /** - * The Authenticator interface represents a plugin that can handle - * a specific type of authentication information (e.g. 'gcp') + * The Authenticator interface represents a plugin that can handle a specific type of authentication + * information (e.g. 'gcp') */ public class GCPAuthenticator implements Authenticator { - static { - KubeConfig.registerAuthenticator(new GCPAuthenticator()); - } - @Override - public String getName() { - return "gcp"; - } + static { + KubeConfig.registerAuthenticator(new GCPAuthenticator()); + } - @Override - public String getToken(Map config) { - return (String) config.get("access-token"); - } + @Override + public String getName() { + return "gcp"; + } - @Override - public boolean isExpired(Map config) { - Date expiry = (Date) config.get("expiry"); - if (expiry != null && expiry.compareTo(new Date()) <= 0) { - return true; - } - return false; - } + @Override + public String getToken(Map config) { + return (String) config.get("access-token"); + } - @Override - public Map refresh(Map config) { - throw new IllegalStateException("Unimplemented"); + @Override + public boolean isExpired(Map config) { + Date expiry = (Date) config.get("expiry"); + if (expiry != null && expiry.compareTo(new Date()) <= 0) { + return true; } -} \ No newline at end of file + return false; + } + + @Override + public Map refresh(Map config) { + throw new IllegalStateException("Unimplemented"); + } +} diff --git a/util/src/main/java/io/kubernetes/client/util/credentials/AccessTokenAuthentication.java b/util/src/main/java/io/kubernetes/client/util/credentials/AccessTokenAuthentication.java index f77ee6a36d..9e309fe176 100644 --- a/util/src/main/java/io/kubernetes/client/util/credentials/AccessTokenAuthentication.java +++ b/util/src/main/java/io/kubernetes/client/util/credentials/AccessTokenAuthentication.java @@ -3,9 +3,7 @@ import com.google.common.base.Preconditions; import io.kubernetes.client.ApiClient; -/** - * Uses a Bearer Token to configure {@link ApiClient} authentication to the Kubernetes API. - */ +/** Uses a Bearer Token to configure {@link ApiClient} authentication to the Kubernetes API. */ public class AccessTokenAuthentication implements Authentication { private String token; @@ -14,7 +12,8 @@ public AccessTokenAuthentication(final String token) { this.token = token; } - @Override public void provide(ApiClient client) { + @Override + public void provide(ApiClient client) { client.setApiKeyPrefix("Bearer"); client.setApiKey(token); } diff --git a/util/src/main/java/io/kubernetes/client/util/credentials/Authentication.java b/util/src/main/java/io/kubernetes/client/util/credentials/Authentication.java index 0bfd6579a7..e26420dcd6 100644 --- a/util/src/main/java/io/kubernetes/client/util/credentials/Authentication.java +++ b/util/src/main/java/io/kubernetes/client/util/credentials/Authentication.java @@ -11,5 +11,4 @@ public interface Authentication { void provide(ApiClient client); - } diff --git a/util/src/main/java/io/kubernetes/client/util/credentials/ClientCertificateAuthentication.java b/util/src/main/java/io/kubernetes/client/util/credentials/ClientCertificateAuthentication.java index 07d82b1966..38b169c695 100644 --- a/util/src/main/java/io/kubernetes/client/util/credentials/ClientCertificateAuthentication.java +++ b/util/src/main/java/io/kubernetes/client/util/credentials/ClientCertificateAuthentication.java @@ -11,9 +11,7 @@ import javax.net.ssl.KeyManager; import org.apache.log4j.Logger; -/** - * Uses Client Certificates to configure {@link ApiClient} authentication to the Kubernetes API. - */ +/** Uses Client Certificates to configure {@link ApiClient} authentication to the Kubernetes API. */ public class ClientCertificateAuthentication implements Authentication { private static final Logger log = Logger.getLogger(ClientCertificateAuthentication.class); private final byte[] certificate; @@ -24,12 +22,18 @@ public ClientCertificateAuthentication(final byte[] certificate, final byte[] ke this.key = key; } - @Override public void provide(ApiClient client) { + @Override + public void provide(ApiClient client) { try { final KeyManager[] keyManagers = SSLUtils.keyManagers(certificate, key, "RSA", "", null, null); client.setKeyManagers(keyManagers); - } catch (NoSuchAlgorithmException | UnrecoverableKeyException | CertificateException | KeyStoreException | InvalidKeySpecException | IOException e) { + } catch (NoSuchAlgorithmException + | UnrecoverableKeyException + | CertificateException + | KeyStoreException + | InvalidKeySpecException + | IOException e) { log.warn("Could not create key manager for Client Certificate authentication.", e); throw new RuntimeException(e); } diff --git a/util/src/main/java/io/kubernetes/client/util/credentials/KubeconfigAuthentication.java b/util/src/main/java/io/kubernetes/client/util/credentials/KubeconfigAuthentication.java index d208058911..d132b3760d 100644 --- a/util/src/main/java/io/kubernetes/client/util/credentials/KubeconfigAuthentication.java +++ b/util/src/main/java/io/kubernetes/client/util/credentials/KubeconfigAuthentication.java @@ -7,11 +7,12 @@ /** * Uses a {@link KubeConfig} to configure {@link ApiClient} authentication to the Kubernetes API. * - * Tries to configure the following authentication mechanisms in this order. + *

Tries to configure the following authentication mechanisms in this order. + * *

    - *
  • {@link ClientCertificateAuthentication} (using client certificate files or data)
  • - *
  • {@link UsernamePasswordAuthentication}
  • - *
  • {@link AccessTokenAuthentication}
  • + *
  • {@link ClientCertificateAuthentication} (using client certificate files or data) + *
  • {@link UsernamePasswordAuthentication} + *
  • {@link AccessTokenAuthentication} *
*/ public class KubeconfigAuthentication implements Authentication { @@ -23,23 +24,26 @@ public class KubeconfigAuthentication implements Authentication { private final byte[] clientKey; public KubeconfigAuthentication(final KubeConfig config) throws IOException { - this.clientCert = KubeConfig.getDataOrFile(config.getClientCertificateData(), config.getClientCertificateFile()); + this.clientCert = + KubeConfig.getDataOrFile( + config.getClientCertificateData(), config.getClientCertificateFile()); this.clientKey = KubeConfig.getDataOrFile(config.getClientKeyData(), config.getClientKeyFile()); this.username = config.getUsername(); this.password = config.getPassword(); this.token = config.getAccessToken(); } - @Override public void provide(ApiClient client) { - if(clientCert != null && clientKey != null) { + @Override + public void provide(ApiClient client) { + if (clientCert != null && clientKey != null) { new ClientCertificateAuthentication(clientCert, clientKey); } - if(username != null && password != null) { + if (username != null && password != null) { new UsernamePasswordAuthentication(username, password).provide(client); } - if(token != null) { + if (token != null) { new AccessTokenAuthentication(token).provide(client); } } diff --git a/util/src/main/java/io/kubernetes/client/util/credentials/UsernamePasswordAuthentication.java b/util/src/main/java/io/kubernetes/client/util/credentials/UsernamePasswordAuthentication.java index 24a314f81a..7dcc5859ec 100644 --- a/util/src/main/java/io/kubernetes/client/util/credentials/UsernamePasswordAuthentication.java +++ b/util/src/main/java/io/kubernetes/client/util/credentials/UsernamePasswordAuthentication.java @@ -16,9 +16,11 @@ public UsernamePasswordAuthentication(final String username, final String passwo this.password = password; } - @Override public void provide(ApiClient client) { + @Override + public void provide(ApiClient client) { final String usernameAndPassword = username + ":" + password; client.setApiKeyPrefix("Basic"); - client.setApiKey(ByteString.of(usernameAndPassword.getBytes(Charset.forName("ISO-8859-1"))).base64()); + client.setApiKey( + ByteString.of(usernameAndPassword.getBytes(Charset.forName("ISO-8859-1"))).base64()); } } diff --git a/util/src/test/java/io/kubernetes/client/util/ClientBuilderTest.java b/util/src/test/java/io/kubernetes/client/util/ClientBuilderTest.java index ccef4d2fc7..1b2d6c539e 100644 --- a/util/src/test/java/io/kubernetes/client/util/ClientBuilderTest.java +++ b/util/src/test/java/io/kubernetes/client/util/ClientBuilderTest.java @@ -19,160 +19,137 @@ import static org.mockito.Mockito.verify; import com.google.common.io.Resources; -import io.kubernetes.client.util.credentials.AccessTokenAuthentication; +import io.kubernetes.client.ApiClient; import io.kubernetes.client.util.credentials.Authentication; -import io.kubernetes.client.util.credentials.UsernamePasswordAuthentication; import java.io.IOException; -import java.nio.charset.Charset; - import java.nio.file.Files; import java.nio.file.Paths; - import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.contrib.java.lang.system.EnvironmentVariables; -import io.kubernetes.client.ApiClient; -import okio.ByteString; - -/** - * Tests for the ConfigBuilder helper class - */ +/** Tests for the ConfigBuilder helper class */ public class ClientBuilderTest { - private static final String HOME_PATH = Resources.getResource("").getPath(); - private static final String KUBECONFIG_FILE_PATH = Resources.getResource("kubeconfig").getPath(); - private static final String KUBECONFIG_HTTP_FILE_PATH = Resources.getResource("kubeconfig-http").getPath(); - private static final String KUBECONFIG_HTTPS_FILE_PATH = Resources.getResource("kubeconfig-https").getPath(); - private static final String SSL_CA_CERT_PATH = Resources.getResource("ca-cert.pem").getPath(); - private static final String INVALID_SSL_CA_CERT_PATH = Resources.getResource("ca-cert-invalid.pem").getPath(); - - private String basePath = "http://localhost"; + private static final String HOME_PATH = Resources.getResource("").getPath(); + private static final String KUBECONFIG_FILE_PATH = Resources.getResource("kubeconfig").getPath(); + private static final String KUBECONFIG_HTTP_FILE_PATH = + Resources.getResource("kubeconfig-http").getPath(); + private static final String KUBECONFIG_HTTPS_FILE_PATH = + Resources.getResource("kubeconfig-https").getPath(); + private static final String SSL_CA_CERT_PATH = Resources.getResource("ca-cert.pem").getPath(); + private static final String INVALID_SSL_CA_CERT_PATH = + Resources.getResource("ca-cert-invalid.pem").getPath(); + + private String basePath = "http://localhost"; private String apiKey = "ABCD"; private String userName = "userName"; private String password = "password"; private String apiKeyPrefix = "Bearer"; - @Rule - public final EnvironmentVariables environmentVariables = new EnvironmentVariables(); + @Rule public final EnvironmentVariables environmentVariables = new EnvironmentVariables(); - @Before - public void setup() { - environmentVariables.set("HOME", "/non-existent"); - } + @Before + public void setup() { + environmentVariables.set("HOME", "/non-existent"); + } - @Test - public void testDefaultClientWithNoFiles() throws IOException { - environmentVariables.set("HOME", "/non-existent"); - final ApiClient client = ClientBuilder.defaultClient(); - assertEquals("http://localhost:8080", client.getBasePath()); - } + @Test + public void testDefaultClientWithNoFiles() throws IOException { + environmentVariables.set("HOME", "/non-existent"); + final ApiClient client = ClientBuilder.defaultClient(); + assertEquals("http://localhost:8080", client.getBasePath()); + } - @Test - public void testDefaultClientReadsHomeDir() throws Exception { + @Test + public void testDefaultClientReadsHomeDir() throws Exception { environmentVariables.set("HOME", HOME_PATH); ApiClient client = ClientBuilder.defaultClient(); assertEquals("http://home.dir.com", client.getBasePath()); - } - - @Test - public void testDefaultClientReadsKubeConfig() throws Exception { - environmentVariables.set("KUBECONFIG", KUBECONFIG_FILE_PATH); - final ApiClient client = ClientBuilder.defaultClient(); - assertEquals("http://kubeconfig.dir.com", client.getBasePath()); - } - - @Test - public void testKubeconfigPreferredOverHomeDir() throws Exception { - environmentVariables.set("HOME", HOME_PATH); - environmentVariables.set("KUBECONFIG", KUBECONFIG_FILE_PATH); - final ApiClient client = ClientBuilder - .standard() - .build(); - // $KUBECONFIG should take precedence over $HOME/.kube/config - assertEquals("http://kubeconfig.dir.com", client.getBasePath()); - } - - @Test - public void testInvalidKubeconfig() throws Exception { - environmentVariables.set("KUBECONFIG", "/non-existent"); - final ApiClient client = ClientBuilder - .standard() - .build(); - assertThat(client.getBasePath(), is(Config.DEFAULT_FALLBACK_HOST)); - } - - @Test - public void testKubeconfigAddsSchemeHttps() throws Exception { - environmentVariables.set("KUBECONFIG", KUBECONFIG_HTTPS_FILE_PATH); - final ApiClient client = ClientBuilder - .standard() - .build(); - assertThat(client.getBasePath(), is("https://localhost:443")); - } - - @Test - public void testKubeconfigAddsSchemeHttp() throws Exception { - environmentVariables.set("KUBECONFIG", KUBECONFIG_HTTP_FILE_PATH); - final ApiClient client = ClientBuilder - .standard() - .build(); - assertThat(client.getBasePath(), is("http://localhost")); - } - - @Test - public void testKubeconfigDisablesVerifySsl() throws Exception { - environmentVariables.set("KUBECONFIG", KUBECONFIG_HTTP_FILE_PATH); - final ApiClient client = ClientBuilder - .standard() - .build(); - assertThat(client.isVerifyingSsl(), is(false)); - } - - @Test - public void testBasePathTrailingSlash() throws Exception { - final ApiClient client = ClientBuilder - .standard() - .setBasePath("http://localhost/") - .build(); - assertThat(client.getBasePath(), is("http://localhost")); - } - - @Test - public void testStandardVerifiesSsl() throws IOException { - environmentVariables.set("HOME", "/non-existent"); - final ApiClient client = ClientBuilder - .standard() - .build(); - assertThat(client.isVerifyingSsl(), is(true)); - } - - @Test - public void testCredentialProviderInvoked() throws IOException { - final Authentication provider = mock(Authentication.class); - final ApiClient client = ClientBuilder - .standard() - .setAuthentication(provider) - .build(); - verify(provider).provide(client); - } - - /** - * We can't verify anything here because of how things are configured in swagger-codegen and - * okhttp but combined with {@link #testSslCertCaBad()} we have some certainty that it is being - * invoked. - */ - @Test - public void testSslCertCaGood() throws Exception { - final ApiClient client = new ClientBuilder() - .setCertificateAuthority(Files.readAllBytes(Paths.get(SSL_CA_CERT_PATH))) - .build(); - } - - @Test(expected = RuntimeException.class) - public void testSslCertCaBad() throws Exception { - final ApiClient client = new ClientBuilder() - .setCertificateAuthority(Files.readAllBytes(Paths.get(INVALID_SSL_CA_CERT_PATH))) - .build(); - } + } + + @Test + public void testDefaultClientReadsKubeConfig() throws Exception { + environmentVariables.set("KUBECONFIG", KUBECONFIG_FILE_PATH); + final ApiClient client = ClientBuilder.defaultClient(); + assertEquals("http://kubeconfig.dir.com", client.getBasePath()); + } + + @Test + public void testKubeconfigPreferredOverHomeDir() throws Exception { + environmentVariables.set("HOME", HOME_PATH); + environmentVariables.set("KUBECONFIG", KUBECONFIG_FILE_PATH); + final ApiClient client = ClientBuilder.standard().build(); + // $KUBECONFIG should take precedence over $HOME/.kube/config + assertEquals("http://kubeconfig.dir.com", client.getBasePath()); + } + + @Test + public void testInvalidKubeconfig() throws Exception { + environmentVariables.set("KUBECONFIG", "/non-existent"); + final ApiClient client = ClientBuilder.standard().build(); + assertThat(client.getBasePath(), is(Config.DEFAULT_FALLBACK_HOST)); + } + + @Test + public void testKubeconfigAddsSchemeHttps() throws Exception { + environmentVariables.set("KUBECONFIG", KUBECONFIG_HTTPS_FILE_PATH); + final ApiClient client = ClientBuilder.standard().build(); + assertThat(client.getBasePath(), is("https://localhost:443")); + } + + @Test + public void testKubeconfigAddsSchemeHttp() throws Exception { + environmentVariables.set("KUBECONFIG", KUBECONFIG_HTTP_FILE_PATH); + final ApiClient client = ClientBuilder.standard().build(); + assertThat(client.getBasePath(), is("http://localhost")); + } + + @Test + public void testKubeconfigDisablesVerifySsl() throws Exception { + environmentVariables.set("KUBECONFIG", KUBECONFIG_HTTP_FILE_PATH); + final ApiClient client = ClientBuilder.standard().build(); + assertThat(client.isVerifyingSsl(), is(false)); + } + + @Test + public void testBasePathTrailingSlash() throws Exception { + final ApiClient client = ClientBuilder.standard().setBasePath("http://localhost/").build(); + assertThat(client.getBasePath(), is("http://localhost")); + } + + @Test + public void testStandardVerifiesSsl() throws IOException { + environmentVariables.set("HOME", "/non-existent"); + final ApiClient client = ClientBuilder.standard().build(); + assertThat(client.isVerifyingSsl(), is(true)); + } + + @Test + public void testCredentialProviderInvoked() throws IOException { + final Authentication provider = mock(Authentication.class); + final ApiClient client = ClientBuilder.standard().setAuthentication(provider).build(); + verify(provider).provide(client); + } + + /** + * We can't verify anything here because of how things are configured in swagger-codegen and + * okhttp but combined with {@link #testSslCertCaBad()} we have some certainty that it is being + * invoked. + */ + @Test + public void testSslCertCaGood() throws Exception { + final ApiClient client = + new ClientBuilder() + .setCertificateAuthority(Files.readAllBytes(Paths.get(SSL_CA_CERT_PATH))) + .build(); + } + + @Test(expected = RuntimeException.class) + public void testSslCertCaBad() throws Exception { + final ApiClient client = + new ClientBuilder() + .setCertificateAuthority(Files.readAllBytes(Paths.get(INVALID_SSL_CA_CERT_PATH))) + .build(); + } } diff --git a/util/src/test/java/io/kubernetes/client/util/ConfigTest.java b/util/src/test/java/io/kubernetes/client/util/ConfigTest.java index 9f8e372283..c318553819 100644 --- a/util/src/test/java/io/kubernetes/client/util/ConfigTest.java +++ b/util/src/test/java/io/kubernetes/client/util/ConfigTest.java @@ -12,126 +12,117 @@ */ package io.kubernetes.client.util; -import io.kubernetes.client.ApiClient; +import static org.junit.Assert.*; +import io.kubernetes.client.ApiClient; import java.io.File; import java.io.FileWriter; import java.io.IOException; - -import static org.junit.Assert.*; -import org.junit.After; import org.junit.Before; -import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; -import org.junit.rules.TemporaryFolder; import org.junit.contrib.java.lang.system.EnvironmentVariables; +import org.junit.rules.TemporaryFolder; -/** - * Tests for the Config helper class - */ +/** Tests for the Config helper class */ public class ConfigTest { - @Rule - public final EnvironmentVariables environmentVariables - = new EnvironmentVariables(); + @Rule public final EnvironmentVariables environmentVariables = new EnvironmentVariables(); - @Rule - public TemporaryFolder folder= new TemporaryFolder(); + @Rule public TemporaryFolder folder = new TemporaryFolder(); - - @Test - public void testDefaultClientNothingPresent() { - environmentVariables.set("HOME", "/non-existent"); - try { - ApiClient client = Config.defaultClient(); - assertEquals("http://localhost:8080", client.getBasePath()); - } catch (IOException ex) { - fail("Unexpected exception: " + ex); - } + @Test + public void testDefaultClientNothingPresent() { + environmentVariables.set("HOME", "/non-existent"); + try { + ApiClient client = Config.defaultClient(); + assertEquals("http://localhost:8080", client.getBasePath()); + } catch (IOException ex) { + fail("Unexpected exception: " + ex); } + } - public static String HOME_CONFIG = - "apiVersion: v1\n" + - "clusters:\n" + - "- cluster:\n" + - " server: http://home.dir.com\n" + - " name: foo\n" + - "contexts:\n" + - "- context:\n" + - " cluster: foo\n" + - " name: foo-context\n" + - "current-context: foo-context\n"; + public static String HOME_CONFIG = + "apiVersion: v1\n" + + "clusters:\n" + + "- cluster:\n" + + " server: http://home.dir.com\n" + + " name: foo\n" + + "contexts:\n" + + "- context:\n" + + " cluster: foo\n" + + " name: foo-context\n" + + "current-context: foo-context\n"; - public static String KUBECONFIG = - "apiVersion: v1\n" + - "clusters:\n" + - "- cluster:\n" + - " server: http://kubeconfig.dir.com\n" + - " name: foo\n" + - "contexts:\n" + - "- context:\n" + - " cluster: foo\n" + - " name: foo-context\n" + - "current-context: foo-context\n"; + public static String KUBECONFIG = + "apiVersion: v1\n" + + "clusters:\n" + + "- cluster:\n" + + " server: http://kubeconfig.dir.com\n" + + " name: foo\n" + + "contexts:\n" + + "- context:\n" + + " cluster: foo\n" + + " name: foo-context\n" + + "current-context: foo-context\n"; - File config = null; - File dir = null; - File kubedir = null; - File configFile = null; + File config = null; + File dir = null; + File kubedir = null; + File configFile = null; - @Before - public void setUp() throws IOException { - dir = folder.newFolder(); - kubedir = new File(dir, ".kube"); - kubedir.mkdir(); - config = new File(kubedir, "config"); - FileWriter writer = new FileWriter(config); - writer.write(HOME_CONFIG); - writer.flush(); - writer.close(); + @Before + public void setUp() throws IOException { + dir = folder.newFolder(); + kubedir = new File(dir, ".kube"); + kubedir.mkdir(); + config = new File(kubedir, "config"); + FileWriter writer = new FileWriter(config); + writer.write(HOME_CONFIG); + writer.flush(); + writer.close(); - configFile = folder.newFile("config"); - writer = new FileWriter(configFile); - writer.write(KUBECONFIG); - writer.flush(); - writer.close(); - } + configFile = folder.newFile("config"); + writer = new FileWriter(configFile); + writer.write(KUBECONFIG); + writer.flush(); + writer.close(); + } - @Test - public void testDefaultClientHomeDir() { - try { - environmentVariables.set("HOME", dir.getCanonicalPath()); - ApiClient client = Config.defaultClient(); - assertEquals("http://home.dir.com", client.getBasePath()); - } catch (Exception ex) { - ex.printStackTrace(); - fail("Unexpected exception: " + ex); - } + @Test + public void testDefaultClientHomeDir() { + try { + environmentVariables.set("HOME", dir.getCanonicalPath()); + ApiClient client = Config.defaultClient(); + assertEquals("http://home.dir.com", client.getBasePath()); + } catch (Exception ex) { + ex.printStackTrace(); + fail("Unexpected exception: " + ex); } + } - @Test - public void testDefaultClientKubeConfig() { - try { - environmentVariables.set("KUBECONFIG", configFile.getCanonicalPath()); - ApiClient client = Config.defaultClient(); - assertEquals("http://kubeconfig.dir.com", client.getBasePath()); - } catch (Exception ex) { - ex.printStackTrace(); - fail("Unexpected exception: " + ex); - } + @Test + public void testDefaultClientKubeConfig() { + try { + environmentVariables.set("KUBECONFIG", configFile.getCanonicalPath()); + ApiClient client = Config.defaultClient(); + assertEquals("http://kubeconfig.dir.com", client.getBasePath()); + } catch (Exception ex) { + ex.printStackTrace(); + fail("Unexpected exception: " + ex); } + } - @Test - public void testDefaultClientPrecedence() { - try { - environmentVariables.set("HOME", dir.getCanonicalPath()); - environmentVariables.set("KUBECONFIG", configFile.getCanonicalPath()); - ApiClient client = Config.defaultClient(); - // $KUBECONFIG should take precedence over $HOME/.kube/config - assertEquals("http://kubeconfig.dir.com", client.getBasePath()); - } catch (Exception ex) { - ex.printStackTrace(); - fail("Unexpected exception: " + ex); - } + @Test + public void testDefaultClientPrecedence() { + try { + environmentVariables.set("HOME", dir.getCanonicalPath()); + environmentVariables.set("KUBECONFIG", configFile.getCanonicalPath()); + ApiClient client = Config.defaultClient(); + // $KUBECONFIG should take precedence over $HOME/.kube/config + assertEquals("http://kubeconfig.dir.com", client.getBasePath()); + } catch (Exception ex) { + ex.printStackTrace(); + fail("Unexpected exception: " + ex); } + } } diff --git a/util/src/test/java/io/kubernetes/client/util/KubeConfigTest.java b/util/src/test/java/io/kubernetes/client/util/KubeConfigTest.java index de9986923e..232a7c4012 100644 --- a/util/src/test/java/io/kubernetes/client/util/KubeConfigTest.java +++ b/util/src/test/java/io/kubernetes/client/util/KubeConfigTest.java @@ -12,115 +12,108 @@ */ package io.kubernetes.client.util; -import io.kubernetes.client.util.authenticators.GCPAuthenticator; +import static org.junit.Assert.*; +import io.kubernetes.client.util.authenticators.GCPAuthenticator; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.StringReader; import java.nio.file.Files; - -import static org.junit.Assert.*; -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; -/** - * Tests for the KubeConfigConfig helper class - */ +/** Tests for the KubeConfigConfig helper class */ public class KubeConfigTest { - @Rule - public TemporaryFolder folder= new TemporaryFolder(); + @Rule public TemporaryFolder folder = new TemporaryFolder(); - public static String KUBECONFIG_TOKEN = - "apiVersion: v1\n" + - "clusters:\n" + - "- cluster:\n" + - " server: http://kubeconfig.dir.com\n" + - " name: foo\n" + - "users:\n" + - "- user:\n" + - " token: foobaz\n" + - " name: foo\n" + - "contexts:\n" + - "- context:\n" + - " cluster: foo\n" + - " namespace: some_namespace\n" + - " user: foo\n" + - " name: foo-context\n" + - "current-context: foo-context\n"; + public static String KUBECONFIG_TOKEN = + "apiVersion: v1\n" + + "clusters:\n" + + "- cluster:\n" + + " server: http://kubeconfig.dir.com\n" + + " name: foo\n" + + "users:\n" + + "- user:\n" + + " token: foobaz\n" + + " name: foo\n" + + "contexts:\n" + + "- context:\n" + + " cluster: foo\n" + + " namespace: some_namespace\n" + + " user: foo\n" + + " name: foo-context\n" + + "current-context: foo-context\n"; - @Test - public void testToken() { - KubeConfig config = KubeConfig.loadKubeConfig(new StringReader(KUBECONFIG_TOKEN)); - assertEquals(config.getAccessToken(), "foobaz"); - } + @Test + public void testToken() { + KubeConfig config = KubeConfig.loadKubeConfig(new StringReader(KUBECONFIG_TOKEN)); + assertEquals(config.getAccessToken(), "foobaz"); + } - @Test - public void testTokenFile() throws IOException { - String token = "flubble"; - File tokenFile = folder.newFile("token-file.txt"); - Files.write(tokenFile.toPath(), token.getBytes("UTF-8")); + @Test + public void testTokenFile() throws IOException { + String token = "flubble"; + File tokenFile = folder.newFile("token-file.txt"); + Files.write(tokenFile.toPath(), token.getBytes("UTF-8")); - String replace = KUBECONFIG_TOKEN.replace("foobaz", tokenFile.getCanonicalPath()); - replace = replace.replace("token:", "tokenFile:"); - KubeConfig config = KubeConfig.loadKubeConfig(new StringReader(replace)); - assertEquals(config.getAccessToken(), token); - } + String replace = KUBECONFIG_TOKEN.replace("foobaz", tokenFile.getCanonicalPath()); + replace = replace.replace("token:", "tokenFile:"); + KubeConfig config = KubeConfig.loadKubeConfig(new StringReader(replace)); + assertEquals(config.getAccessToken(), token); + } - public static String GCP_CONFIG = - "apiVersion: v1\n" + - "contexts:\n" + - "- context:\n" + - " user: gke-cluster\n" + - " name: foo-context\n" + - "current-context: foo-context\n" + - "users:\n" + - "- name: gke-cluster\n" + - " user:\n" + - " auth-provider:\n" + - " config:\n" + - " access-token: fake-token\n" + - " cmd-args: config config-helper --format=json\n" + - " cmd-path: /usr/lib/google-cloud-sdk/bin/gcloud\n" + - " expiry: 2117-06-22T18:27:02Z\n" + - " expiry-key: '{.credential.token_expiry}'\n" + - " token-key: '{.credential.access_token}'\n" + - " name: gcp\n"; + public static String GCP_CONFIG = + "apiVersion: v1\n" + + "contexts:\n" + + "- context:\n" + + " user: gke-cluster\n" + + " name: foo-context\n" + + "current-context: foo-context\n" + + "users:\n" + + "- name: gke-cluster\n" + + " user:\n" + + " auth-provider:\n" + + " config:\n" + + " access-token: fake-token\n" + + " cmd-args: config config-helper --format=json\n" + + " cmd-path: /usr/lib/google-cloud-sdk/bin/gcloud\n" + + " expiry: 2117-06-22T18:27:02Z\n" + + " expiry-key: '{.credential.token_expiry}'\n" + + " token-key: '{.credential.access_token}'\n" + + " name: gcp\n"; - @Test - public void testGCPAuthProvider() { - KubeConfig.registerAuthenticator(new GCPAuthenticator()); + @Test + public void testGCPAuthProvider() { + KubeConfig.registerAuthenticator(new GCPAuthenticator()); - try { - File config = folder.newFile("config"); - FileWriter writer = new FileWriter(config); - writer.write(GCP_CONFIG); - writer.flush(); - writer.close(); + try { + File config = folder.newFile("config"); + FileWriter writer = new FileWriter(config); + writer.write(GCP_CONFIG); + writer.flush(); + writer.close(); - KubeConfig kc = KubeConfig.loadKubeConfig(new FileReader(config)); - assertEquals("fake-token", kc.getAccessToken()); - } catch (Exception ex) { - ex.printStackTrace(); - fail("Unexpected exception: " + ex); - } + KubeConfig kc = KubeConfig.loadKubeConfig(new FileReader(config)); + assertEquals("fake-token", kc.getAccessToken()); + } catch (Exception ex) { + ex.printStackTrace(); + fail("Unexpected exception: " + ex); } + } - @Test - public void testNamespace() { - KubeConfig config = KubeConfig.loadKubeConfig(new StringReader(KUBECONFIG_TOKEN)); - assertEquals(config.getNamespace(), "some_namespace"); - } + @Test + public void testNamespace() { + KubeConfig config = KubeConfig.loadKubeConfig(new StringReader(KUBECONFIG_TOKEN)); + assertEquals(config.getNamespace(), "some_namespace"); + } - @Test - public void testNullNamespace() { - KubeConfig config = KubeConfig.loadKubeConfig(new StringReader(GCP_CONFIG)); - assertNull(config.getNamespace()); - } + @Test + public void testNullNamespace() { + KubeConfig config = KubeConfig.loadKubeConfig(new StringReader(GCP_CONFIG)); + assertNull(config.getNamespace()); + } } diff --git a/util/src/test/java/io/kubernetes/client/util/TestUtils.java b/util/src/test/java/io/kubernetes/client/util/TestUtils.java index 727bc3a664..00a98f6eae 100644 --- a/util/src/test/java/io/kubernetes/client/util/TestUtils.java +++ b/util/src/test/java/io/kubernetes/client/util/TestUtils.java @@ -6,7 +6,6 @@ public class TestUtils { public static ApiKeyAuth getApiKeyAuthFromClient(ApiClient client) { - return (ApiKeyAuth)client.getAuthentications().get("BearerToken"); + return (ApiKeyAuth) client.getAuthentications().get("BearerToken"); } - } diff --git a/util/src/test/java/io/kubernetes/client/util/credentials/AccessTokenAuthenticationTest.java b/util/src/test/java/io/kubernetes/client/util/credentials/AccessTokenAuthenticationTest.java index ec99fddfc9..634e2ab90a 100644 --- a/util/src/test/java/io/kubernetes/client/util/credentials/AccessTokenAuthenticationTest.java +++ b/util/src/test/java/io/kubernetes/client/util/credentials/AccessTokenAuthenticationTest.java @@ -1,12 +1,12 @@ package io.kubernetes.client.util.credentials; -import io.kubernetes.client.ApiClient; -import org.junit.Test; - import static io.kubernetes.client.util.TestUtils.getApiKeyAuthFromClient; import static org.hamcrest.core.Is.is; import static org.junit.Assert.*; +import io.kubernetes.client.ApiClient; +import org.junit.Test; + public class AccessTokenAuthenticationTest { @Test @@ -21,5 +21,4 @@ public void testTokenProvided() { public void testTokenNonnull() { new AccessTokenAuthentication(null); } - -} \ No newline at end of file +} diff --git a/util/src/test/java/io/kubernetes/client/util/credentials/ClientCertificateAuthenticationTest.java b/util/src/test/java/io/kubernetes/client/util/credentials/ClientCertificateAuthenticationTest.java index 287de894a0..9d9dbae047 100644 --- a/util/src/test/java/io/kubernetes/client/util/credentials/ClientCertificateAuthenticationTest.java +++ b/util/src/test/java/io/kubernetes/client/util/credentials/ClientCertificateAuthenticationTest.java @@ -19,8 +19,8 @@ public void testValidCertificates() throws Exception { } @Test(expected = RuntimeException.class) - public void testInvalidCertificates() { + public void testInvalidCertificates() { final ApiClient client = new ApiClient(); - new ClientCertificateAuthentication(new byte[]{}, new byte[]{}).provide(client); + new ClientCertificateAuthentication(new byte[] {}, new byte[] {}).provide(client); } -} \ No newline at end of file +} diff --git a/util/src/test/java/io/kubernetes/client/util/credentials/UsernamePasswordAuthenticationTest.java b/util/src/test/java/io/kubernetes/client/util/credentials/UsernamePasswordAuthenticationTest.java index 44ac5b4ab9..41c5db1c77 100644 --- a/util/src/test/java/io/kubernetes/client/util/credentials/UsernamePasswordAuthenticationTest.java +++ b/util/src/test/java/io/kubernetes/client/util/credentials/UsernamePasswordAuthenticationTest.java @@ -1,28 +1,28 @@ package io.kubernetes.client.util.credentials; +import static io.kubernetes.client.util.TestUtils.getApiKeyAuthFromClient; +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.*; + import com.google.common.base.Charsets; import io.kubernetes.client.ApiClient; -import java.nio.charset.Charset; import okio.ByteString; import org.junit.Test; -import static io.kubernetes.client.util.TestUtils.getApiKeyAuthFromClient; -import static org.hamcrest.core.Is.is; -import static org.junit.Assert.*; - public class UsernamePasswordAuthenticationTest { private static final String USERNAME = "username"; private static final String PASSWORD = "password"; - public static final byte[] USERNAME_PASSWORD_BYTES = (USERNAME + ":" + PASSWORD).getBytes( - Charsets.ISO_8859_1); + public static final byte[] USERNAME_PASSWORD_BYTES = + (USERNAME + ":" + PASSWORD).getBytes(Charsets.ISO_8859_1); @Test public void testUsernamePasswordProvided() { final ApiClient client = new ApiClient(); new UsernamePasswordAuthentication(USERNAME, PASSWORD).provide(client); assertThat(getApiKeyAuthFromClient(client).getApiKeyPrefix(), is("Basic")); - assertThat(getApiKeyAuthFromClient(client).getApiKey(), is(ByteString.of(USERNAME_PASSWORD_BYTES).base64())); + assertThat( + getApiKeyAuthFromClient(client).getApiKey(), + is(ByteString.of(USERNAME_PASSWORD_BYTES).base64())); } - -} \ No newline at end of file +}