package org.apache.mesos.logstash.common.network; import org.apache.commons.exec.CommandLine; import org.apache.commons.exec.DefaultExecutor; import org.apache.commons.exec.PumpStreamHandler; import org.apache.commons.exec.environment.EnvironmentUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.InterfaceAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.net.UnknownHostException; import java.nio.charset.Charset; import java.util.Collections; import java.util.Enumeration; import java.util.Map; /** * Utilities to help with networking */ @SuppressWarnings("PMD.AvoidUsingHardCodedIP") public class NetworkUtils { private static final Logger LOG = LoggerFactory.getLogger(NetworkUtils.class); public static final String DOCKER_MACHINE_IP = "docker-machine ip"; public static final String LOCALHOST = "127.0.0.1"; public static final String DOCKER_MACHINE_NAME = "DOCKER_MACHINE_NAME"; public InetAddress hostAddress() { try { return InetAddress.getLocalHost(); } catch (UnknownHostException e) { LOG.error("", e); throw new RuntimeException("Unable to bind to local host."); } } public InetSocketAddress hostSocket(int port) { return new InetSocketAddress(hostAddress(), port); } public String addressToString(InetSocketAddress address, Boolean useIpAddress) { if (useIpAddress) { return "http://" + address.getAddress().getHostAddress() + ":" + address.getPort(); } else { return "http://" + address.getAddress().getHostName() + ":" + address.getPort(); } } public String getDockerMachineName(Map<String, String> environment) { String envVar = DOCKER_MACHINE_NAME; String dockerMachineName = environment.getOrDefault(envVar, ""); if (dockerMachineName == null || dockerMachineName.isEmpty()) { LOG.debug("The environmental variable DOCKER_MACHINE_NAME was not found. Using docker0 address."); } return dockerMachineName; } public String getDockerHostIpAddress(Map<String, String> environment) { String ipAddress = LOCALHOST; // Default of localhost String dockerMachineName = getDockerMachineName(environment); if (!dockerMachineName.isEmpty()) { LOG.debug("Docker machine name = " + dockerMachineName); CommandLine commandline = CommandLine.parse(DOCKER_MACHINE_IP); commandline.addArgument(dockerMachineName); LOG.debug("Running exec: " + commandline.toString()); try { ipAddress = StringUtils.strip(runCommand(commandline)); } catch (IOException e) { LOG.error("Unable to run exec command to find ip address.", e); } } else { ipAddress = getDocker0AdapterIPAddress(); } LOG.debug("Returned IP address: " + ipAddress); return ipAddress; } public Map<String, String> getEnvironment() { Map<String, String> env = Collections.emptyMap(); try { env = EnvironmentUtils.getProcEnvironment(); } catch (IOException e) { LOG.error("Unable to get environmental variables", e); } return env; } public String runCommand(CommandLine commandline) throws IOException { DefaultExecutor exec = new DefaultExecutor(); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); PumpStreamHandler streamHandler = new PumpStreamHandler(outputStream); exec.setStreamHandler(streamHandler); exec.execute(commandline); return outputStream.toString(Charset.defaultCharset().name()); } public String getDocker0AdapterIPAddress() { InetAddress docker0 = getLocalAddress("docker0"); if (docker0 == null) { LOG.error("Could not get address for docker0"); return LOCALHOST; } else { return docker0.getHostAddress(); } } private InetAddress getLocalAddress(String adaptorName){ try { Enumeration<NetworkInterface> b = NetworkInterface.getNetworkInterfaces(); while (b.hasMoreElements()) { NetworkInterface networkInterface = b.nextElement(); if (networkInterface.getName().equals(adaptorName)) { for (InterfaceAddress f : networkInterface.getInterfaceAddresses()) { if (f.getAddress().isSiteLocalAddress()) { return f.getAddress(); } } } } } catch (SocketException e) { e.printStackTrace(); } return null; } }