org.jgroups.ping.kube.KubePing Maven / Gradle / Ivy
/**
* Copyright 2014 Red Hat, Inc.
*
* Red Hat licenses this file to you 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
*
* 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 org.jgroups.ping.kube;
import static org.jgroups.ping.common.Utils.getSystemEnv;
import static org.jgroups.ping.common.Utils.getSystemEnvInt;
import static org.jgroups.ping.common.Utils.readFileToString;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jgroups.annotations.MBean;
import org.jgroups.annotations.Property;
import org.jgroups.conf.ClassConfigurator;
import org.jgroups.ping.common.OpenshiftPing;
import org.jgroups.ping.common.stream.CertificateStreamProvider;
import org.jgroups.ping.common.stream.InsecureStreamProvider;
import org.jgroups.ping.common.stream.StreamProvider;
import org.openshift.ping.common.stream.TokenStreamProvider;
/**
* @author Ales Justin
*/
@MBean(description = "Kubernetes based discovery protocol")
public class KubePing extends OpenshiftPing {
public static final short KUBERNETES_PING_ID = 2010;
public static final short JGROUPS_KUBE_PING_ID = 2011;
static {
ClassConfigurator.addProtocol(KUBERNETES_PING_ID, KubePing.class);
}
@Property
private String masterProtocol;
@Property
private String masterHost;
@Property
private int masterPort;
@Property
private String apiVersion = "v1";
@Property
private String namespace; // DO NOT HARDCODE A DEFAULT (i.e.: "default") - SEE isClusteringEnabled() and init() METHODS BELOW!
private String _namespace;
@Property
private String labels;
private String _labels;
@Property
private int serverPort = 8888;
private int _serverPort;
@Property
private String clientCertFile;
@Property
private String clientKeyFile;
@Property
private String clientKeyPassword;
@Property
private String clientKeyAlgo = "RSA";
@Property
private String caCertFile = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt";
@Property
private String saTokenFile = "/var/run/secrets/kubernetes.io/serviceaccount/token";
private Client _client;
public KubePing() {
super("OPENSHIFT_KUBE_PING_");
}
public void setMasterProtocol(String masterProtocol) {
this.masterProtocol = masterProtocol;
}
public void setMasterHost(String masterMost) {
this.masterHost = masterMost;
}
public void setMasterPort(int masterPort) {
this.masterPort = masterPort;
}
public void setNamespace(String namespace) {
this.namespace = namespace;
}
@Override
protected boolean isClusteringEnabled() {
return _namespace != null;
}
@Override
protected int getServerPort() {
return _serverPort;
}
protected Client getClient() {
return _client;
}
public void init() throws Exception {
super.init();
_namespace = getSystemEnv(getSystemEnvName("NAMESPACE"), namespace, true);
if (_namespace == null) {
if (log.isInfoEnabled()) {
log.info(String.format("namespace not set; clustering disabled"));
}
// no further initialization necessary
return;
}
if (log.isInfoEnabled()) {
log.info(String.format("namespace [%s] set; clustering enabled", _namespace));
}
String mProtocol = getSystemEnv(getSystemEnvName("MASTER_PROTOCOL"), masterProtocol, true);
String mHost;
int mPort;
Map headers = new HashMap();
StreamProvider streamProvider;
String cCertFile = getSystemEnv(new String[]{getSystemEnvName("CLIENT_CERT_FILE"), "KUBERNETES_CLIENT_CERTIFICATE_FILE"}, clientCertFile, true);
if (cCertFile != null) {
if (mProtocol == null) {
mProtocol = "http";
}
mHost = getSystemEnv(new String[]{getSystemEnvName("MASTER_HOST"), "KUBERNETES_RO_SERVICE_HOST"}, masterHost, true);
mPort = getSystemEnvInt(new String[]{getSystemEnvName("MASTER_PORT"), "KUBERNETES_RO_SERVICE_PORT"}, masterPort);
String cKeyFile = getSystemEnv(new String[]{getSystemEnvName("CLIENT_KEY_FILE"), "KUBERNETES_CLIENT_KEY_FILE"}, clientKeyFile, true);
String cKeyPassword = getSystemEnv(new String[]{getSystemEnvName("CLIENT_KEY_PASSWORD"), "KUBERNETES_CLIENT_KEY_PASSWORD"}, clientKeyPassword, false);
String cKeyAlgo = getSystemEnv(new String[]{getSystemEnvName("CLIENT_KEY_ALGO"), "KUBERNETES_CLIENT_KEY_ALGO"}, clientKeyAlgo, true);
String lCaCertFile = getSystemEnv(new String[]{getSystemEnvName("CA_CERT_FILE"), "KUBERNETES_CA_CERTIFICATE_FILE"}, caCertFile, true);
streamProvider = new CertificateStreamProvider(cCertFile, cKeyFile, cKeyPassword, cKeyAlgo, lCaCertFile);
} else {
if (mProtocol == null) {
mProtocol = "https";
}
mHost = getSystemEnv(new String[]{getSystemEnvName("MASTER_HOST"), "KUBERNETES_SERVICE_HOST"}, masterHost, true);
mPort = getSystemEnvInt(new String[]{getSystemEnvName("MASTER_PORT"), "KUBERNETES_SERVICE_PORT"}, masterPort);
String saToken = readFileToString(getSystemEnv(getSystemEnvName("SA_TOKEN_FILE"), saTokenFile, true));
String lCaCertFile = getSystemEnv(new String[]{getSystemEnvName("CA_CERT_FILE"), "KUBERNETES_CA_CERTIFICATE_FILE"}, caCertFile, true);
streamProvider = new TokenStreamProvider(saToken, lCaCertFile);
}
String ver = getSystemEnv(getSystemEnvName("API_VERSION"), apiVersion, true);
String url = String.format("%s://%s:%s/api/%s", mProtocol, mHost, mPort, ver);
_labels = getSystemEnv(getSystemEnvName("LABELS"), labels, true);
_serverPort = getSystemEnvInt(getSystemEnvName("SERVER_PORT"), serverPort);
_client = new Client(url, headers, getConnectTimeout(), getReadTimeout(), getOperationAttempts(), getOperationSleep(), streamProvider, _serverPort);
if(log.isDebugEnabled()) {
log.debug("KubePING configuration: " + toString());
}
}
@Override
public void destroy() {
_namespace = null;
_labels = null;
_serverPort = 0;
_client = null;
super.destroy();
}
@Override
protected synchronized List doReadAll(String clusterName) {
Client client = getClient();
List pods;
try {
pods = client.getPods(_namespace, _labels);
} catch (Exception e) {
if (log.isWarnEnabled()) {
log.warn(String.format("Problem getting Pod json from Kubernetes %s for cluster [%s], namespace [%s], labels [%s]; encountered [%s: %s]",
client.info(), clusterName, _namespace, _labels, e.getClass().getName(), e.getMessage()));
}
pods = Collections.emptyList();
}
List retval = new ArrayList<>();
for (Pod pod : pods) {
pod.getContainers().stream()
.filter(container -> client.accept(container))
.flatMap(container -> container.getPorts().stream())
.filter(port -> client.accept(port))
.map(port -> port.getContainerPort())
.forEach(portAsInt -> {
retval.add(new InetSocketAddress(pod.getPodIP(), portAsInt));
});
}
return retval;
}
@Override
public String toString() {
return "KubePing{" +
"_namespace='" + _namespace + '\'' +
", _labels='" + _labels + '\'' +
", _serverPort=" + _serverPort +
'}';
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy