Przeglądaj źródła

implement support for tls ca or fallback to service account ca.pem

Grega Bremec 7 miesięcy temu
rodzic
commit
a228cfd3f4
1 zmienionych plików z 53 dodań i 7 usunięć
  1. 53 7
      src/main/java/com/redhat/training/Activator.java

+ 53 - 7
src/main/java/com/redhat/training/Activator.java

@@ -6,8 +6,16 @@ import java.io.FileReader;
 import java.io.IOException;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
 import java.util.Optional;
 
+import javax.net.ssl.SSLContext;
+
+import org.apache.http.ssl.SSLContextBuilder;
+import org.apache.http.ssl.SSLContexts;
 import org.eclipse.microprofile.config.inject.ConfigProperty;
 import org.eclipse.microprofile.rest.client.RestClientBuilder;
 import org.jboss.logging.Logger;
@@ -26,16 +34,20 @@ public class Activator {
     Optional<String> token;
 
     @ConfigProperty(name = "api.endpoint")
-    Optional<String> api;
+    Optional<String> apiserver;
+
+    @ConfigProperty(name = "api.tlsca.file")
+    Optional<String> tlsca;
 
     ApiClient k8s;
 
     @PostConstruct
     public void checkEnv() {
+        // Check for API token.
         if (token.isPresent() && !token.get().isEmpty()) {
             LOG.debug("Got API token from environment.");
         } else {
-            LOG.info("API token not found in environment. Trying service account.");
+            LOG.warn("API token not found in environment. Trying service account.");
             File tf = new File("/var/run/secrets/kubernetes.io/serviceaccount/token");
             if (tf.exists()) {
                 try {
@@ -43,23 +55,57 @@ public class Activator {
                     this.token = Optional.of(br.readLine());
                     br.close();
                 } catch (IOException ioe) {
-                    throw new RuntimeException("Can not load service account token: " + ioe.getMessage());
+                    throw new RuntimeException("Can not load service account token: " + ioe.getMessage(), ioe);
                 }
             } else {
                 throw new RuntimeException("API token unobtainable. Can not talk to API.");
             }
         }
-        if (api.isPresent() && !api.get().isEmpty()) {
+
+        // Check for API server.
+        if (apiserver.isPresent() && !apiserver.get().isEmpty()) {
             LOG.debug("Got API server endpoint from environment.");
         } else {
             LOG.warn("API server endpoint not set, defaulting to internal API server.");
-            api = Optional.of("https://kubernetes.default/");
+            apiserver = Optional.of("https://kubernetes.default/");
+        }
+
+        // Check for TLS CA cert.
+        SSLContext sc = null;
+        if (apiserver.get().startsWith("https://")) {
+            File tlscaFile;
+            if (tlsca.isPresent() && !tlsca.get().isEmpty()) {
+                LOG.debug("Got TLS CA cert file from environment, checking.");
+                tlscaFile = new File(tlsca.get());
+            } else {
+                LOG.warn("TLS CA cert not found in environment. Trying service account.");
+                tlscaFile = new File("/var/run/secrets/kubernetes.io/serviceaccount/ca.crt");
+            }
+            if (!tlscaFile.exists()) {
+                throw new RuntimeException("TLS CA cert file set, but does not exist.");
+            }
+            LOG.info("Attempting to build SSLContext with " + tlscaFile.getAbsolutePath());
+            try {
+                SSLContextBuilder scb = SSLContexts.custom().loadTrustMaterial(tlscaFile);
+                sc = scb.build();
+            } catch (NoSuchAlgorithmException | KeyStoreException | CertificateException | IOException | KeyManagementException e) {
+                throw new RuntimeException("Could not load TLS CA: " + e.getMessage(), e);
+            }
         }
 
         try {
-            this.k8s = RestClientBuilder.newBuilder().baseUri(new URI(this.api.get())).build(ApiClient.class);
+            if (sc == null) {
+                this.k8s = RestClientBuilder.newBuilder()
+                                            .baseUri(new URI(this.apiserver.get()))
+                                            .build(ApiClient.class);
+            } else {
+                this.k8s = RestClientBuilder.newBuilder()
+                                            .baseUri(new URI(this.apiserver.get()))
+                                            .sslContext(sc)
+                                            .build(ApiClient.class);
+            }
         } catch (URISyntaxException use) {
-            throw new RuntimeException("Could not construct BASE URI for REST client: " + use.getMessage());
+            throw new RuntimeException("Could not construct BASE URI for REST client: " + use.getMessage(), use);
         }
     }