Skip to content
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

Validate HTTP connectivity for Agent traces port #464

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ of this software and associated documentation files (the "Software"), to deal
import com.timgroup.statsd.NonBlockingStatsDClient;
import com.timgroup.statsd.ServiceCheck;
import com.timgroup.statsd.StatsDClient;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
Expand Down Expand Up @@ -57,7 +58,6 @@ of this software and associated documentation files (the "Software"), to deal
import org.datadog.jenkins.plugins.datadog.traces.mapper.JsonTraceSpanMapper;
import org.datadog.jenkins.plugins.datadog.traces.write.*;
import org.datadog.jenkins.plugins.datadog.util.CircuitBreaker;
import org.datadog.jenkins.plugins.datadog.util.SuppressFBWarnings;
import org.datadog.jenkins.plugins.datadog.util.TagsUtil;
import org.json.JSONArray;
import org.json.JSONObject;
Expand Down Expand Up @@ -348,7 +348,7 @@ private void flushSafely() throws IOException {

@Override
public TraceWriteStrategy createTraceWriteStrategy() {
Set<String> agentEndpoints = fetchAgentEndpoints();
Set<String> agentEndpoints = fetchAgentEndpoints(client, hostname, traceCollectionPort);
boolean evpProxyExists = agentEndpoints.contains("/evp_proxy/v3/");
if (evpProxyExists) {
DatadogGlobalConfiguration datadogGlobalDescriptor = DatadogUtilities.getDatadogGlobalDescriptor();
Expand All @@ -375,7 +375,7 @@ public TraceWriteStrategy createTraceWriteStrategy() {
* @return a set of endpoints (if /info wasn't available, it will be empty)
*/
@SuppressFBWarnings("REC_CATCH_EXCEPTION")
Set<String> fetchAgentEndpoints() {
public static Set<String> fetchAgentEndpoints(HttpClient client, String hostname, Integer traceCollectionPort) {
logger.fine("Fetching Agent info");

String url = String.format("http://%s:%d/info", hostname, traceCollectionPort);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.logging.Logger;
import javax.annotation.Nonnull;
import jenkins.model.Jenkins;
import org.apache.commons.lang.StringUtils;
import org.datadog.jenkins.plugins.datadog.DatadogClient;
import org.datadog.jenkins.plugins.datadog.DatadogUtilities;
import org.datadog.jenkins.plugins.datadog.clients.DatadogAgentClient;
import org.datadog.jenkins.plugins.datadog.clients.HttpClient;
import org.jenkinsci.Symbol;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.QueryParameter;
Expand All @@ -41,6 +43,8 @@ public class DatadogAgentConfiguration extends DatadogClientConfiguration {
static final Integer DEFAULT_TRACE_COLLECTION_PORT_VALUE = 8126;
static final Integer DEFAULT_LOG_COLLECTION_PORT_VALUE = null;

private static final int AGENT_CONNECTIVITY_CHECK_TIMEOUT_MILLIS = 2_000;

private final String agentHost;
private final Integer agentPort;
private final Integer agentLogCollectionPort;
Expand Down Expand Up @@ -77,24 +81,28 @@ public DatadogClient createClient() {

@Override
public void validateTracesConnection() throws Descriptor.FormException {
FormValidation connectivityCheckResult = checkTracesConnectivity(agentHost, agentTraceCollectionPort);
if (connectivityCheckResult.kind == FormValidation.Kind.ERROR) {
throw new Descriptor.FormException("CI Visibility connectivity check failed: " + connectivityCheckResult.getMessage(), "ciVisibilityData");
}
}

private static FormValidation checkTracesConnectivity(String agentHost, Integer agentTraceCollectionPort) {
if (StringUtils.isBlank(agentHost)) {
throw new Descriptor.FormException("CI Visibility requires agent host to be set", "agentHost");
return FormValidation.error("Host name missing");
}
if (agentTraceCollectionPort == null) {
throw new Descriptor.FormException("CI Visibility requires agent trace collection port to be set", "agentTraceCollectionPort");
return FormValidation.error("Trace collection port missing");
}
String errorMessage = checkConnectivity(agentHost, agentTraceCollectionPort);
if (errorMessage != null) {
throw new Descriptor.FormException("CI Visibility connectivity check failed: " + errorMessage, "ciVisibilityData");
}
}

private static String checkConnectivity(final String host, final int port) {
try (Socket ignored = new Socket(host, port)) {
return null;
} catch (Exception ex) {
DatadogUtilities.severe(logger, ex, "Failed to create socket to host: " + host + ", port: " + port);
return ex.getMessage();
try {
Set<String> endpoints = DatadogAgentClient.fetchAgentEndpoints(new HttpClient(AGENT_CONNECTIVITY_CHECK_TIMEOUT_MILLIS), agentHost, agentTraceCollectionPort);
if (!endpoints.isEmpty()) {
return FormValidation.ok("Success!");
} else {
return FormValidation.error("Failed to reach Datadog Agent using host " + agentHost + " and port " + agentTraceCollectionPort);
}
} catch (Exception e) {
return FormValidation.error(e.getMessage());
}
}

Expand All @@ -106,12 +114,21 @@ public void validateLogsConnection() throws Descriptor.FormException {
if (agentLogCollectionPort == null) {
throw new Descriptor.FormException("Logs collection requires agent log collection port to be set", "agentLogCollectionPort");
}
String errorMessage = checkConnectivity(agentHost, agentLogCollectionPort);
String errorMessage = checkTcpConnectivity(agentHost, agentLogCollectionPort);
if (errorMessage != null) {
throw new Descriptor.FormException("Logs collection connectivity check failed: " + errorMessage, "collectBuildLogs");
}
}

private static String checkTcpConnectivity(final String host, final int port) {
try (Socket ignored = new Socket(host, port)) {
return null;
} catch (Exception ex) {
DatadogUtilities.severe(logger, ex, "Failed to create socket to host: " + host + ", port: " + port);
return ex.getMessage();
}
}

@Override
public Map<String, String> toEnvironmentVariables() {
if (StringUtils.isBlank(agentHost)) {
Expand Down Expand Up @@ -194,7 +211,7 @@ public FormValidation doCheckLogConnectivity(@QueryParameter("agentHost") final
if (agentLogCollectionPort == null) {
return FormValidation.error("Please enter log collection port value");
}
String errorMessage = checkConnectivity(agentHost, agentLogCollectionPort);
String errorMessage = checkTcpConnectivity(agentHost, agentLogCollectionPort);
if (errorMessage != null) {
return FormValidation.error("Connectivity check failed: " + errorMessage);
}
Expand All @@ -205,17 +222,7 @@ public FormValidation doCheckLogConnectivity(@QueryParameter("agentHost") final
@SuppressWarnings("lgtm[jenkins/no-permission-check]") // no side effects, no private information returned
public FormValidation doCheckTraceConnectivity(@QueryParameter("agentHost") final String agentHost,
@QueryParameter("agentTraceCollectionPort") Integer agentTraceCollectionPort) {
if (StringUtils.isBlank(agentHost)) {
return FormValidation.error("Please enter host value");
}
if (agentTraceCollectionPort == null) {
return FormValidation.error("Please enter trace collection port value");
}
String errorMessage = checkConnectivity(agentHost, agentTraceCollectionPort);
if (errorMessage != null) {
return FormValidation.error("Connectivity check failed: " + errorMessage);
}
return FormValidation.ok("Success!");
return checkTracesConnectivity(agentHost, agentTraceCollectionPort);
}

public static String getDefaultAgentHost() {
Expand Down Expand Up @@ -338,4 +345,4 @@ public boolean equals(Object o) {
public int hashCode() {
return Objects.hash(agentHost, agentPort, agentLogCollectionPort, agentTraceCollectionPort);
}
}
}
Loading