-
Notifications
You must be signed in to change notification settings - Fork 38.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adjust the cassandra example to use the service account. #8454
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,14 @@ | ||
package io.k8s.cassandra; | ||
|
||
import java.io.IOException; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.nio.file.Paths; | ||
import java.net.InetAddress; | ||
import java.net.UnknownHostException; | ||
import java.net.URL; | ||
import java.net.URLConnection; | ||
import java.security.cert.X509Certificate; | ||
import java.security.KeyManagementException; | ||
import java.security.NoSuchAlgorithmException; | ||
import java.security.SecureRandom; | ||
|
@@ -13,6 +17,13 @@ | |
import java.util.List; | ||
import java.util.Map; | ||
|
||
import javax.net.ssl.HostnameVerifier; | ||
import javax.net.ssl.HttpsURLConnection; | ||
import javax.net.ssl.SSLContext; | ||
import javax.net.ssl.SSLSession; | ||
import javax.net.ssl.TrustManager; | ||
import javax.net.ssl.X509TrustManager; | ||
|
||
import org.codehaus.jackson.JsonNode; | ||
import org.codehaus.jackson.annotate.JsonIgnoreProperties; | ||
import org.codehaus.jackson.map.ObjectMapper; | ||
|
@@ -45,10 +56,17 @@ private static String getEnvOrDefault(String var, String def) { | |
return val; | ||
} | ||
|
||
private static String getServiceAccountToken() throws IOException { | ||
String file = "/var/run/secrets/kubernetes.io/serviceaccount/token"; | ||
return new String(Files.readAllBytes(Paths.get(file))); | ||
} | ||
|
||
private static final Logger logger = LoggerFactory.getLogger(KubernetesSeedProvider.class); | ||
|
||
private List defaultSeeds; | ||
|
||
private TrustManager[] trustAll; | ||
private HostnameVerifier trustAllHosts; | ||
|
||
public KubernetesSeedProvider(Map<String, String> params) { | ||
// Taken from SimpleSeedProvider.java | ||
// These are used as a fallback, if we get nothing from k8s. | ||
|
@@ -65,21 +83,43 @@ public KubernetesSeedProvider(Map<String, String> params) { | |
logger.warn("Seed provider couldn't lookup host " + host); | ||
} | ||
} | ||
} | ||
// TODO: Load the CA cert when it is available on all platforms. | ||
trustAll = new TrustManager[] { | ||
new X509TrustManager() { | ||
public void checkServerTrusted(X509Certificate[] certs, String authType) {} | ||
public void checkClientTrusted(X509Certificate[] certs, String authType) {} | ||
public X509Certificate[] getAcceptedIssuers() { return null; } | ||
} | ||
}; | ||
trustAllHosts = new HostnameVerifier() { | ||
public boolean verify(String hostname, SSLSession session) { | ||
return true; | ||
} | ||
}; | ||
} | ||
|
||
public List<InetAddress> getSeeds() { | ||
List<InetAddress> list = new ArrayList<InetAddress>(); | ||
String protocol = getEnvOrDefault("KUBERNETES_API_PROTOCOL", "http"); | ||
String hostName = getEnvOrDefault("KUBERNETES_RO_SERVICE_HOST", "localhost"); | ||
String hostPort = getEnvOrDefault("KUBERNETES_RO_SERVICE_PORT", "8080"); | ||
|
||
String host = protocol + "://" + hostName + ":" + hostPort; | ||
String host = "https://kubernetes.default.cluster.local"; | ||
String serviceName = getEnvOrDefault("CASSANDRA_SERVICE", "cassandra"); | ||
String path = "/api/v1beta3/namespaces/default/endpoints/"; | ||
try { | ||
String token = getServiceAccountToken(); | ||
|
||
SSLContext ctx = SSLContext.getInstance("SSL"); | ||
ctx.init(null, trustAll, new SecureRandom()); | ||
|
||
URL url = new URL(host + path + serviceName); | ||
HttpsURLConnection conn = (HttpsURLConnection)url.openConnection(); | ||
|
||
// TODO: Remove this once the CA cert is propogated everywhere, and replace | ||
// with loading the CA cert. | ||
conn.setSSLSocketFactory(ctx.getSocketFactory()); | ||
conn.setHostnameVerifier(trustAllHosts); | ||
|
||
conn.addRequestProperty("Authorization", "Bearer " + token); | ||
ObjectMapper mapper = new ObjectMapper(); | ||
Endpoints endpoints = mapper.readValue(url, Endpoints.class); | ||
Endpoints endpoints = mapper.readValue(conn.getInputStream(), Endpoints.class); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Better way to do this is make a headless service & read the SRV records from DNS; no k8s api calls needed! Not sure if everything has landed for that to work yet though. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, sadly there is no standard SRV record library for Java that I can find... (spotify does have one that has been open sourced, though...) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @brendanburns We use dnsjava from http://www.xbill.org/dnsjava/ - very robust library indeed. |
||
if (endpoints != null) { | ||
// Here is a problem point, endpoints.subsets can be null in first node cases. | ||
if (endpoints.subsets != null && !endpoints.subsets.isEmpty()){ | ||
|
@@ -90,8 +130,8 @@ public List<InetAddress> getSeeds() { | |
} | ||
} | ||
} | ||
} catch (IOException ex) { | ||
logger.warn("Request to kubernetes apiserver failed"); | ||
} catch (IOException | NoSuchAlgorithmException | KeyManagementException ex) { | ||
logger.warn("Request to kubernetes apiserver failed", ex); | ||
} | ||
if (list.size() == 0) { | ||
// If we got nothing, we might be the first instance, in that case | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm gonna merge this, but maybe in a followup you can fix this to get the namespace from the downward API? This forces the example to work only in the default namespace unnecessarily.