From 0277c0d046fb5b6fac939615cc76037e6ec90956 Mon Sep 17 00:00:00 2001 From: Nikita Tkachenko Date: Thu, 19 Sep 2024 19:03:04 +0200 Subject: [PATCH] Only show Datadog link if site is configured + allow configuring site when reporting to agent --- .../datadog/DatadogGlobalConfiguration.java | 7 ++- .../DatadogAgentConfiguration.java | 52 +++++++++++++++---- .../DatadogApiConfiguration.java | 5 ++ .../DatadogClientConfiguration.java | 9 +++- .../api/intake/DatadogIntakeSite.java | 12 ++++- .../listeners/DatadogBuildListener.java | 12 +++-- .../datadog/model/DatadogLinkAction.java | 15 +++--- .../DatadogAgentConfiguration/config.jelly | 4 ++ .../DatadogAgentConfiguration/help-site.html | 4 ++ .../datadog/apm/TracerInjectionIT.java | 3 +- 10 files changed, 97 insertions(+), 26 deletions(-) create mode 100644 src/main/resources/org/datadog/jenkins/plugins/datadog/configuration/DatadogAgentConfiguration/help-site.html diff --git a/src/main/java/org/datadog/jenkins/plugins/datadog/DatadogGlobalConfiguration.java b/src/main/java/org/datadog/jenkins/plugins/datadog/DatadogGlobalConfiguration.java index d7ecc736..ce5d966f 100644 --- a/src/main/java/org/datadog/jenkins/plugins/datadog/DatadogGlobalConfiguration.java +++ b/src/main/java/org/datadog/jenkins/plugins/datadog/DatadogGlobalConfiguration.java @@ -25,10 +25,12 @@ of this software and associated documentation files (the "Software"), to deal package org.datadog.jenkins.plugins.datadog; +import static org.datadog.jenkins.plugins.datadog.configuration.DatadogAgentConfiguration.DatadogAgentConfigurationDescriptor.*; import static org.datadog.jenkins.plugins.datadog.configuration.DatadogAgentConfiguration.DatadogAgentConfigurationDescriptor.getDefaultAgentHost; import static org.datadog.jenkins.plugins.datadog.configuration.DatadogAgentConfiguration.DatadogAgentConfigurationDescriptor.getDefaultAgentLogCollectionPort; import static org.datadog.jenkins.plugins.datadog.configuration.DatadogAgentConfiguration.DatadogAgentConfigurationDescriptor.getDefaultAgentPort; import static org.datadog.jenkins.plugins.datadog.configuration.DatadogAgentConfiguration.DatadogAgentConfigurationDescriptor.getDefaultAgentTraceCollectionPort; +import static org.datadog.jenkins.plugins.datadog.configuration.api.intake.DatadogIntakeSite.DatadogIntakeSiteDescriptor.getSite; import static org.datadog.jenkins.plugins.datadog.configuration.api.key.DatadogTextApiKey.DatadogTextApiKeyDescriptor.getDefaultKey; import com.thoughtworks.xstream.annotations.XStreamConverter; @@ -44,6 +46,7 @@ of this software and associated documentation files (the "Software"), to deal import hudson.util.XStream2; import java.io.File; import java.io.IOException; +import java.util.*; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -202,7 +205,7 @@ public void loadEnvVariables() { String clientType = System.getenv(REPORT_WITH_PROPERTY); if (DATADOG_AGENT_CLIENT_TYPE.equals(clientType)) { this.datadogClientConfiguration = new DatadogAgentConfiguration( - getDefaultAgentHost(), getDefaultAgentPort(), getDefaultAgentLogCollectionPort(), getDefaultAgentTraceCollectionPort()); + getDefaultAgentHost(), getDefaultAgentPort(), getDefaultAgentLogCollectionPort(), getDefaultAgentTraceCollectionPort(), getSite()); } else { DatadogIntake intake = DatadogIntake.getDefaultIntake(); DatadogTextApiKey apiKey = new DatadogTextApiKey(getDefaultKey()); @@ -1167,7 +1170,7 @@ protected Object readResolve() { this.included = this.whitelist; } if (DATADOG_AGENT_CLIENT_TYPE.equals(reportWith)) { - this.datadogClientConfiguration = new DatadogAgentConfiguration(this.targetHost, this.targetPort, this.targetLogCollectionPort, this.targetTraceCollectionPort); + this.datadogClientConfiguration = new DatadogAgentConfiguration(this.targetHost, this.targetPort, this.targetLogCollectionPort, this.targetTraceCollectionPort, getSite()); } if (DATADOG_API_CLIENT_TYPE.equals(reportWith)) { DatadogIntakeUrls intake = new DatadogIntakeUrls(this.targetApiURL, this.targetLogIntakeURL, this.targetWebhookIntakeURL); diff --git a/src/main/java/org/datadog/jenkins/plugins/datadog/configuration/DatadogAgentConfiguration.java b/src/main/java/org/datadog/jenkins/plugins/datadog/configuration/DatadogAgentConfiguration.java index 273ffcbd..7495fa4a 100644 --- a/src/main/java/org/datadog/jenkins/plugins/datadog/configuration/DatadogAgentConfiguration.java +++ b/src/main/java/org/datadog/jenkins/plugins/datadog/configuration/DatadogAgentConfiguration.java @@ -4,24 +4,27 @@ import hudson.RelativePath; import hudson.model.Descriptor; import hudson.util.FormValidation; -import java.net.MalformedURLException; -import java.net.Socket; -import java.net.URL; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.logging.Logger; -import javax.annotation.Nonnull; +import hudson.util.ListBoxModel; 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.configuration.api.intake.DatadogSite; import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.interceptor.RequirePOST; +import javax.annotation.Nonnull; +import java.net.MalformedURLException; +import java.net.Socket; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.logging.Logger; + @Symbol("datadogAgentConfiguration") public class DatadogAgentConfiguration extends DatadogClientConfiguration { @@ -45,13 +48,19 @@ public class DatadogAgentConfiguration extends DatadogClientConfiguration { private final Integer agentPort; private final Integer agentLogCollectionPort; private final Integer agentTraceCollectionPort; + private final DatadogSite site; @DataBoundConstructor - public DatadogAgentConfiguration(String agentHost, Integer agentPort, Integer agentLogCollectionPort, Integer agentTraceCollectionPort) { + public DatadogAgentConfiguration(String agentHost, Integer agentPort, Integer agentLogCollectionPort, Integer agentTraceCollectionPort, String site) { + this(agentHost, agentPort, agentLogCollectionPort, agentTraceCollectionPort, StringUtils.isNotBlank(site) ? DatadogSite.valueOf(site) : null); + } + + public DatadogAgentConfiguration(String agentHost, Integer agentPort, Integer agentLogCollectionPort, Integer agentTraceCollectionPort, DatadogSite site) { this.agentHost = agentHost; this.agentPort = agentPort; this.agentLogCollectionPort = agentLogCollectionPort; this.agentTraceCollectionPort = agentTraceCollectionPort; + this.site = site; } public String getAgentHost() { @@ -70,6 +79,10 @@ public Integer getAgentTraceCollectionPort() { return agentTraceCollectionPort; } + public DatadogSite getSite() { + return site; + } + @Override public DatadogClient createClient() { return new DatadogAgentClient(agentHost, agentPort, agentLogCollectionPort, agentTraceCollectionPort); @@ -127,6 +140,11 @@ public Map toEnvironmentVariables() { return variables; } + @Override + public String getSiteName() { + return site != null ? site.getSiteName() : null; + } + @Override public Descriptor getDescriptor() { Jenkins jenkins = Jenkins.getInstanceOrNull(); @@ -218,6 +236,17 @@ public FormValidation doCheckTraceConnectivity(@QueryParameter("agentHost") fina return FormValidation.ok("Success!"); } + @RequirePOST + public ListBoxModel doFillSiteItems() { + DatadogSite[] siteValues = DatadogSite.values(); + ListBoxModel.Option[] values = new ListBoxModel.Option[siteValues.length + 1]; + values[0] = new ListBoxModel.Option(""); + for (int i = 0; i < siteValues.length; i++) { + values[i + 1] = new ListBoxModel.Option(siteValues[i].name()); + } + return new ListBoxModel(values); + } + public static String getDefaultAgentHost() { Map envVars = System.getenv(); @@ -331,11 +360,12 @@ public boolean equals(Object o) { return Objects.equals(agentHost, that.agentHost) && Objects.equals(agentPort, that.agentPort) && Objects.equals(agentLogCollectionPort, that.agentLogCollectionPort) - && Objects.equals(agentTraceCollectionPort, that.agentTraceCollectionPort); + && Objects.equals(agentTraceCollectionPort, that.agentTraceCollectionPort) + && Objects.equals(site, that.site); } @Override public int hashCode() { - return Objects.hash(agentHost, agentPort, agentLogCollectionPort, agentTraceCollectionPort); + return Objects.hash(agentHost, agentPort, agentLogCollectionPort, agentTraceCollectionPort, site); } } \ No newline at end of file diff --git a/src/main/java/org/datadog/jenkins/plugins/datadog/configuration/DatadogApiConfiguration.java b/src/main/java/org/datadog/jenkins/plugins/datadog/configuration/DatadogApiConfiguration.java index f205b97d..3fd411d2 100644 --- a/src/main/java/org/datadog/jenkins/plugins/datadog/configuration/DatadogApiConfiguration.java +++ b/src/main/java/org/datadog/jenkins/plugins/datadog/configuration/DatadogApiConfiguration.java @@ -131,6 +131,11 @@ public Map toEnvironmentVariables() { return variables; } + @Override + public String getSiteName() { + return intake.getSiteName(); + } + @Override public Descriptor getDescriptor() { Jenkins jenkins = Jenkins.getInstanceOrNull(); diff --git a/src/main/java/org/datadog/jenkins/plugins/datadog/configuration/DatadogClientConfiguration.java b/src/main/java/org/datadog/jenkins/plugins/datadog/configuration/DatadogClientConfiguration.java index 4db0b3b8..30662200 100644 --- a/src/main/java/org/datadog/jenkins/plugins/datadog/configuration/DatadogClientConfiguration.java +++ b/src/main/java/org/datadog/jenkins/plugins/datadog/configuration/DatadogClientConfiguration.java @@ -2,13 +2,15 @@ import hudson.model.Describable; import hudson.model.Descriptor; +import jenkins.model.Jenkins; +import org.datadog.jenkins.plugins.datadog.DatadogClient; + +import javax.annotation.Nullable; import java.io.Serializable; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.Map; -import jenkins.model.Jenkins; -import org.datadog.jenkins.plugins.datadog.DatadogClient; public abstract class DatadogClientConfiguration implements Describable, Serializable { @@ -20,6 +22,9 @@ public abstract class DatadogClientConfiguration implements Describable toEnvironmentVariables(); + @Nullable + public abstract String getSiteName(); + public static abstract class DatadogClientConfigurationDescriptor extends Descriptor { public static List all() { Jenkins jenkins = Jenkins.getInstanceOrNull(); diff --git a/src/main/java/org/datadog/jenkins/plugins/datadog/configuration/api/intake/DatadogIntakeSite.java b/src/main/java/org/datadog/jenkins/plugins/datadog/configuration/api/intake/DatadogIntakeSite.java index 6cd70ab0..8cc44d0f 100644 --- a/src/main/java/org/datadog/jenkins/plugins/datadog/configuration/api/intake/DatadogIntakeSite.java +++ b/src/main/java/org/datadog/jenkins/plugins/datadog/configuration/api/intake/DatadogIntakeSite.java @@ -7,6 +7,7 @@ import org.kohsuke.stapler.DataBoundConstructor; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.util.Arrays; import java.util.Objects; @@ -74,7 +75,8 @@ public String getHelpFile() { return getHelpFile("siteBlock"); } - public static DatadogSite getDefaultSite() { + @Nullable + public static DatadogSite getSite() { String site = System.getenv().get(DATADOG_SITE_PROPERTY); if (site != null) { try { @@ -84,6 +86,14 @@ public static DatadogSite getDefaultSite() { "Illegal " + DATADOG_SITE_PROPERTY + " environment property value set: " + site + ". Allowed values are " + Arrays.toString(DatadogSite.values()), e); } + } + return null; + } + + public static DatadogSite getDefaultSite() { + DatadogSite site = getSite(); + if (site != null) { + return site; } else { return DEFAULT_DATADOG_SITE_VALUE; } diff --git a/src/main/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogBuildListener.java b/src/main/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogBuildListener.java index 2797523d..c84b1661 100644 --- a/src/main/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogBuildListener.java +++ b/src/main/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogBuildListener.java @@ -41,11 +41,13 @@ of this software and associated documentation files (the "Software"), to deal import java.util.concurrent.TimeUnit; import java.util.logging.Logger; import javax.annotation.Nonnull; +import org.apache.commons.lang.StringUtils; import org.datadog.jenkins.plugins.datadog.DatadogClient; import org.datadog.jenkins.plugins.datadog.DatadogEvent; import org.datadog.jenkins.plugins.datadog.DatadogGlobalConfiguration; import org.datadog.jenkins.plugins.datadog.DatadogUtilities; import org.datadog.jenkins.plugins.datadog.clients.ClientHolder; +import org.datadog.jenkins.plugins.datadog.configuration.DatadogClientConfiguration; import org.datadog.jenkins.plugins.datadog.events.BuildAbortedEventImpl; import org.datadog.jenkins.plugins.datadog.events.BuildFinishedEventImpl; import org.datadog.jenkins.plugins.datadog.events.BuildStartedEventImpl; @@ -414,9 +416,13 @@ public void onFinalized(Run run) { return; } - DatadogGlobalConfiguration datadogGlobalConfiguration = DatadogUtilities.getDatadogGlobalDescriptor(); - if (datadogGlobalConfiguration != null && datadogGlobalConfiguration.getEnableCiVisibility()) { - run.addAction(new DatadogLinkAction(buildData)); + DatadogGlobalConfiguration datadogConfiguration = DatadogUtilities.getDatadogGlobalDescriptor(); + if (datadogConfiguration != null && datadogConfiguration.getEnableCiVisibility()) { + DatadogClientConfiguration clientConfiguration = datadogConfiguration.getDatadogClientConfiguration(); + String siteName = clientConfiguration.getSiteName(); + if (StringUtils.isNotBlank(siteName)) { + run.addAction(new DatadogLinkAction(buildData, siteName)); + } } traceWriter.submitBuild(buildData, run); diff --git a/src/main/java/org/datadog/jenkins/plugins/datadog/model/DatadogLinkAction.java b/src/main/java/org/datadog/jenkins/plugins/datadog/model/DatadogLinkAction.java index be4cb76b..12c4d4ba 100644 --- a/src/main/java/org/datadog/jenkins/plugins/datadog/model/DatadogLinkAction.java +++ b/src/main/java/org/datadog/jenkins/plugins/datadog/model/DatadogLinkAction.java @@ -6,19 +6,22 @@ import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; import hudson.model.Action; +import org.datadog.jenkins.plugins.datadog.util.conversion.DatadogConverter; +import org.datadog.jenkins.plugins.datadog.util.conversion.VersionedConverter; + import java.net.URLEncoder; import java.nio.charset.StandardCharsets; -import org.datadog.jenkins.plugins.datadog.util.conversion.DatadogActionConverter; -import org.datadog.jenkins.plugins.datadog.util.conversion.VersionedConverter; + +import static org.datadog.jenkins.plugins.datadog.util.conversion.VersionedConverter.ignoreOldData; public class DatadogLinkAction implements Action { private final String url; - public DatadogLinkAction(BuildData buildData) { // ci.pipeline.url%3A"https%3A%2F%2Fgoogle.com" + public DatadogLinkAction(BuildData buildData, String siteName) { String query = String.format("ci_level:pipeline @ci.pipeline.name:\"%s\" @ci.pipeline.number:%s", buildData.getJobName(), buildData.getBuildNumber("")); String urlEncodedQuery = URLEncoder.encode(query, StandardCharsets.UTF_8); - this.url = String.format("https://app.datadoghq.com/ci/pipeline-executions?query=%s", urlEncodedQuery); + this.url = String.format("https://app.%s/ci/pipeline-executions?query=%s", siteName, urlEncodedQuery); } private DatadogLinkAction(String url) { @@ -40,9 +43,9 @@ public String getUrlName() { return url; } - public static final class ConverterImpl extends DatadogActionConverter { + public static final class ConverterImpl extends DatadogConverter { public ConverterImpl(XStream xs) { - super(new ConverterV1()); + super(ignoreOldData(), new ConverterV1()); } } diff --git a/src/main/resources/org/datadog/jenkins/plugins/datadog/configuration/DatadogAgentConfiguration/config.jelly b/src/main/resources/org/datadog/jenkins/plugins/datadog/configuration/DatadogAgentConfiguration/config.jelly index 39b64252..20c6e789 100644 --- a/src/main/resources/org/datadog/jenkins/plugins/datadog/configuration/DatadogAgentConfiguration/config.jelly +++ b/src/main/resources/org/datadog/jenkins/plugins/datadog/configuration/DatadogAgentConfiguration/config.jelly @@ -25,4 +25,8 @@ method="checkTraceConnectivity" with="agentHost,agentTraceCollectionPort" /> + + + + diff --git a/src/main/resources/org/datadog/jenkins/plugins/datadog/configuration/DatadogAgentConfiguration/help-site.html b/src/main/resources/org/datadog/jenkins/plugins/datadog/configuration/DatadogAgentConfiguration/help-site.html new file mode 100644 index 00000000..dba2ad97 --- /dev/null +++ b/src/main/resources/org/datadog/jenkins/plugins/datadog/configuration/DatadogAgentConfiguration/help-site.html @@ -0,0 +1,4 @@ +
+ Select your Datadog site. + See Datadog documentation for more information about sites. +
diff --git a/src/test/java/org/datadog/jenkins/plugins/datadog/apm/TracerInjectionIT.java b/src/test/java/org/datadog/jenkins/plugins/datadog/apm/TracerInjectionIT.java index a87fd21a..132c275b 100644 --- a/src/test/java/org/datadog/jenkins/plugins/datadog/apm/TracerInjectionIT.java +++ b/src/test/java/org/datadog/jenkins/plugins/datadog/apm/TracerInjectionIT.java @@ -1,5 +1,6 @@ package org.datadog.jenkins.plugins.datadog.apm; +import static org.datadog.jenkins.plugins.datadog.configuration.DatadogAgentConfiguration.DatadogAgentConfigurationDescriptor.*; import static org.datadog.jenkins.plugins.datadog.configuration.DatadogAgentConfiguration.DatadogAgentConfigurationDescriptor.getDefaultAgentHost; import static org.datadog.jenkins.plugins.datadog.configuration.DatadogAgentConfiguration.DatadogAgentConfigurationDescriptor.getDefaultAgentLogCollectionPort; import static org.datadog.jenkins.plugins.datadog.configuration.DatadogAgentConfiguration.DatadogAgentConfigurationDescriptor.getDefaultAgentPort; @@ -55,7 +56,7 @@ public static void suiteSetUp() throws Exception { // There is no agent and the injected tracers will fail to actually send anything, // but for the purposes of this test this is enough, since it is only asserted that the tracer initialisation was reported in the logs datadogConfig.setDatadogClientConfiguration(new DatadogAgentConfiguration( - getDefaultAgentHost(), getDefaultAgentPort(), getDefaultAgentLogCollectionPort(), getDefaultAgentTraceCollectionPort())); + getDefaultAgentHost(), getDefaultAgentPort(), getDefaultAgentLogCollectionPort(), getDefaultAgentTraceCollectionPort(), "")); agentNode = jenkinsRule.createOnlineSlave(); }