package io.cattle.platform.server.context;
import io.cattle.platform.archaius.util.ArchaiusUtil;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Collections;
import org.apache.commons.lang.StringUtils;
import com.netflix.config.DynamicIntProperty;
import com.netflix.config.DynamicStringProperty;
public class ServerContext {
public static final DynamicIntProperty HTTP_PORT = ArchaiusUtil.getInt("cattle.http.port");
public static final DynamicIntProperty HTTPS_PORT = ArchaiusUtil.getInt("cattle.https.port");
public static final DynamicStringProperty URL_PATH = ArchaiusUtil.getString("cattle.url.path");
public static final DynamicStringProperty SERVER_IP = ArchaiusUtil.getString("cattle.server.ip");
public static final DynamicStringProperty SERVER_ID = ArchaiusUtil.getString("cattle.server.id");
public static final DynamicStringProperty HOST = ArchaiusUtil.getString("api.host");
private static final String FOUND_SERVER_IP = lookupServerIp();
private static final String SERVER_ID_FORMAT = System.getProperty("cattle.server.id.format", "%s");
public static final String HOST_API_PROXY_MODE_OFF = "off";
public static final String HOST_API_PROXY_MODE_EMBEDDED = "embedded";
public static final String HOST_API_PROXY_MODE_HA = "ha";
public static boolean isCustomApiHost() {
return !StringUtils.isBlank(HOST.get());
}
public enum BaseProtocol {
HTTP, WEBSOCKET
}
public static String getLocalhostUrl(BaseProtocol proto) {
StringBuilder buffer = new StringBuilder();
if (HTTPS_PORT.get() > 0) {
buffer.append("https://localhost");
buffer.append(":").append(HTTPS_PORT.get());
} else {
buffer.append("http://localhost");
buffer.append(":").append(HTTP_PORT.get());
}
String url = buffer.toString();
if (BaseProtocol.WEBSOCKET.equals(proto)) {
url = url.replaceFirst("http", "ws");
} else {
// websocket endpoints don't follow same pathing as rest of api
url += URL_PATH.get();
}
return url;
}
public static String getHostApiBaseUrl(BaseProtocol proto) {
String url = null;
if (ServerContext.isCustomApiHost()) {
String apiHost = HOST.get();
if (!apiHost.startsWith("http")) {
apiHost = "http://" + apiHost;
}
url = apiHost;
}
if (url == null) {
StringBuilder buffer = new StringBuilder();
if (HTTPS_PORT.get() > 0) {
buffer.append("https://");
buffer.append(getServerIp());
buffer.append(":").append(HTTPS_PORT.get());
} else {
buffer.append("http://");
buffer.append(getServerIp());
buffer.append(":").append(HTTP_PORT.get());
}
url = buffer.toString();
}
if (BaseProtocol.WEBSOCKET.equals(proto)) {
url = url.replaceFirst("http", "ws");
} else {
// websocket endpoints don't follow same pathing as rest of api
url += URL_PATH.get();
}
return url;
}
public static String getServerId() {
String id = SERVER_ID.get();
String ip = getServerIp();
if (id != null) {
return String.format(id, ip);
}
return String.format(SERVER_ID_FORMAT, ip);
}
public static String getHostApiProxyMode() {
String embedded = System.getenv("CATTLE_HOST_API_PROXY_MODE");
if (StringUtils.isEmpty(embedded)) {
embedded = System.getProperty("host.api.proxy.mode", "off");
}
return embedded;
}
protected static String getServerIp() {
String ip = SERVER_IP.get();
return ip == null ? FOUND_SERVER_IP : ip;
}
protected static String lookupServerIp() {
String address = null;
String v6Address = null;
try {
for (NetworkInterface iface : Collections.list(NetworkInterface.getNetworkInterfaces())) {
for (InetAddress addr : Collections.list(iface.getInetAddresses())) {
if (addr instanceof Inet6Address) {
v6Address = addr.getHostAddress();
} else {
if (!addr.isLoopbackAddress() && (address == null || !addr.isSiteLocalAddress())) {
address = addr.getHostAddress();
}
}
}
}
if (address != null) {
return address;
} else if (v6Address != null) {
return v6Address;
} else {
return "localhost";
}
} catch (SocketException e) {
throw new IllegalStateException("Failed to lookup IP of server", e);
}
}
}