Skip to content

Commit

Permalink
Add validation for manually set Git timestamps (#443)
Browse files Browse the repository at this point in the history
  • Loading branch information
nikita-tkachenko-datadog authored Aug 20, 2024
1 parent 1caef76 commit c7ac69a
Show file tree
Hide file tree
Showing 11 changed files with 235 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ of this software and associated documentation files (the "Software"), to deal
import java.net.Inet4Address;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
Expand Down Expand Up @@ -984,6 +985,19 @@ public static String toISO8601(Date date) {
return sdf.format(date);
}

public static boolean isValidISO8601Date(String date) {
if (StringUtils.isBlank(date)) {
return false;
}
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_ISO8601);
try {
sdf.parse(date);
return true;
} catch (ParseException e) {
return false;
}
}

/**
* Returns a JSON array string based on the set.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@
import hudson.model.Computer;
import hudson.model.Run;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.apache.commons.lang.StringUtils;
import org.datadog.jenkins.plugins.datadog.DatadogUtilities;
import org.datadog.jenkins.plugins.datadog.audit.DatadogAudit;
import org.datadog.jenkins.plugins.datadog.model.BuildData;
Expand Down Expand Up @@ -261,11 +264,6 @@ private static void updateGitData(Run<?, ?> run, Map<String, String> envVars) {
commitAction.setAuthorEmail(ddGitAuthorEmail);
}

final String ddGitAuthorDate = envVars.get(DD_GIT_COMMIT_AUTHOR_DATE);
if(ddGitAuthorDate != null) {
commitAction.setAuthorDate(ddGitAuthorDate);
}

final String ddGitCommitterName = envVars.get(DD_GIT_COMMIT_COMMITTER_NAME);
if(ddGitCommitterName != null) {
commitAction.setCommitterName(ddGitCommitterName);
Expand All @@ -276,9 +274,22 @@ private static void updateGitData(Run<?, ?> run, Map<String, String> envVars) {
commitAction.setCommitterEmail(ddGitCommitterEmail);
}

final String ddGitAuthorDate = envVars.get(DD_GIT_COMMIT_AUTHOR_DATE);
if (StringUtils.isNotBlank(ddGitAuthorDate)) {
if (DatadogUtilities.isValidISO8601Date(ddGitAuthorDate)) {
commitAction.setAuthorDate(ddGitAuthorDate);
} else {
logger.log(Level.WARNING, "Invalid date specified in " + DD_GIT_COMMIT_AUTHOR_DATE + ": expected ISO8601 format (" + DatadogUtilities.toISO8601(new Date()) + "), got " + ddGitAuthorDate);
}
}

final String ddGitCommitterDate = envVars.get(DD_GIT_COMMIT_COMMITTER_DATE);
if(ddGitCommitterDate != null) {
commitAction.setCommitterDate(ddGitCommitterDate);
if (StringUtils.isNotBlank(ddGitCommitterDate)) {
if (DatadogUtilities.isValidISO8601Date(ddGitCommitterDate)) {
commitAction.setCommitterDate(ddGitCommitterDate);
} else {
logger.log(Level.WARNING, "Invalid date specified in " + DD_GIT_COMMIT_COMMITTER_DATE + ": expected ISO8601 format (" + DatadogUtilities.toISO8601(new Date()) + "), got " + ddGitCommitterDate);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ of this software and associated documentation files (the "Software"), to deal
import java.io.IOException;
import java.io.Serializable;
import java.nio.charset.Charset;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -470,10 +471,26 @@ private void populateEnvVariables(EnvVars envVars){
this.gitMessage = envVars.get(DD_GIT_COMMIT_MESSAGE, this.gitMessage);
this.gitAuthorName = envVars.get(DD_GIT_COMMIT_AUTHOR_NAME, this.gitAuthorName);
this.gitAuthorEmail = envVars.get(DD_GIT_COMMIT_AUTHOR_EMAIL, this.gitAuthorEmail);
this.gitAuthorDate = envVars.get(DD_GIT_COMMIT_AUTHOR_DATE, this.gitAuthorDate);
this.gitCommitterName = envVars.get(DD_GIT_COMMIT_COMMITTER_NAME, this.gitCommitterName);
this.gitCommitterEmail = envVars.get(DD_GIT_COMMIT_COMMITTER_EMAIL, this.gitCommitterEmail);
this.gitCommitterDate = envVars.get(DD_GIT_COMMIT_COMMITTER_DATE, this.gitCommitterDate);

String gitAuthorDate = envVars.get(DD_GIT_COMMIT_AUTHOR_DATE, this.gitAuthorDate);
if (StringUtils.isNotBlank(gitAuthorDate)) {
if (DatadogUtilities.isValidISO8601Date(gitAuthorDate)) {
this.gitAuthorDate = gitAuthorDate;
} else {
LOGGER.log(Level.WARNING, "Invalid date specified in " + DD_GIT_COMMIT_AUTHOR_DATE + ": expected ISO8601 format (" + DatadogUtilities.toISO8601(new Date()) + "), got " + gitAuthorDate);
}
}

String gitCommitterDate = envVars.get(DD_GIT_COMMIT_COMMITTER_DATE, this.gitCommitterDate);
if (StringUtils.isNotBlank(gitCommitterDate)) {
if (DatadogUtilities.isValidISO8601Date(gitCommitterDate)) {
this.gitCommitterDate = gitCommitterDate;
} else {
LOGGER.log(Level.WARNING, "Invalid date specified in " + DD_GIT_COMMIT_COMMITTER_DATE + ": expected ISO8601 format (" + DatadogUtilities.toISO8601(new Date()) + "), got " + gitCommitterDate);
}
}

} else if (envVars.get("CVS_BRANCH") != null) {
this.branch = envVars.get("CVS_BRANCH");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class GitCommitAction extends DatadogPluginAction {
public GitCommitAction() {
}

public GitCommitAction(String tag, String commit, String message, String authorName, String authorEmail, String authorDate, String committerName, String committerEmail, String committerDate) {
GitCommitAction(String tag, String commit, String message, String authorName, String authorEmail, String authorDate, String committerName, String committerEmail, String committerDate) {
this.tag = tag;
this.commit = commit;
this.message = message;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -280,10 +280,10 @@ public void testUserSuppliedGitWithCommitInfo() throws Exception {
env.put(DD_GIT_COMMIT_MESSAGE, "hardcoded-message");
env.put(DD_GIT_COMMIT_AUTHOR_NAME, "hardcoded-author-name");
env.put(DD_GIT_COMMIT_AUTHOR_EMAIL, "hardcoded-author-email");
env.put(DD_GIT_COMMIT_AUTHOR_DATE, "hardcoded-author-date");
env.put(DD_GIT_COMMIT_AUTHOR_DATE, "2024-08-14T12:06:04.530Z");
env.put(DD_GIT_COMMIT_COMMITTER_NAME, "hardcoded-committer-name");
env.put(DD_GIT_COMMIT_COMMITTER_EMAIL, "hardcoded-committer-email");
env.put(DD_GIT_COMMIT_COMMITTER_DATE, "hardcoded-committer-date");
env.put(DD_GIT_COMMIT_COMMITTER_DATE, "2024-08-14T12:06:04.529Z");
final String defaultBranch = "refs/heads/hardcoded-master";
env.put(DD_GIT_DEFAULT_BRANCH, defaultBranch);
jenkins.getGlobalNodeProperties().add(prop);
Expand All @@ -304,10 +304,10 @@ public void testUserSuppliedGitWithCommitInfo() throws Exception {
assertEquals("hardcoded-message", meta.get(CITags.GIT_COMMIT_MESSAGE));
assertEquals("hardcoded-author-name", meta.get(CITags.GIT_COMMIT_AUTHOR_NAME));
assertEquals("hardcoded-author-email", meta.get(CITags.GIT_COMMIT_AUTHOR_EMAIL));
assertEquals("hardcoded-author-date", meta.get(CITags.GIT_COMMIT_AUTHOR_DATE));
assertEquals("2024-08-14T12:06:04.530Z", meta.get(CITags.GIT_COMMIT_AUTHOR_DATE));
assertEquals("hardcoded-committer-name", meta.get(CITags.GIT_COMMIT_COMMITTER_NAME));
assertEquals("hardcoded-committer-email", meta.get(CITags.GIT_COMMIT_COMMITTER_EMAIL));
assertEquals("hardcoded-committer-date", meta.get(CITags.GIT_COMMIT_COMMITTER_DATE));
assertEquals("2024-08-14T12:06:04.529Z", meta.get(CITags.GIT_COMMIT_COMMITTER_DATE));
assertEquals("401d997a6eede777602669ccaec059755c98161f", meta.get(CITags.GIT_COMMIT__SHA));
assertEquals("401d997a6eede777602669ccaec059755c98161f", meta.get(CITags.GIT_COMMIT_SHA));
assertEquals("master", meta.get(CITags.GIT_BRANCH));
Expand All @@ -331,10 +331,10 @@ public void testUserSuppliedGitWithCommitInfoWebhook() throws Exception {
env.put(DD_GIT_COMMIT_MESSAGE, "hardcoded-message");
env.put(DD_GIT_COMMIT_AUTHOR_NAME, "hardcoded-author-name");
env.put(DD_GIT_COMMIT_AUTHOR_EMAIL, "hardcoded-author-email");
env.put(DD_GIT_COMMIT_AUTHOR_DATE, "hardcoded-author-date");
env.put(DD_GIT_COMMIT_AUTHOR_DATE, "2024-08-14T12:06:04.530Z");
env.put(DD_GIT_COMMIT_COMMITTER_NAME, "hardcoded-committer-name");
env.put(DD_GIT_COMMIT_COMMITTER_EMAIL, "hardcoded-committer-email");
env.put(DD_GIT_COMMIT_COMMITTER_DATE, "hardcoded-committer-date");
env.put(DD_GIT_COMMIT_COMMITTER_DATE, "2024-08-14T12:06:04.529Z");
final String defaultBranch = "refs/heads/hardcoded-master";
env.put(DD_GIT_DEFAULT_BRANCH, defaultBranch);
jenkins.getGlobalNodeProperties().add(prop);
Expand All @@ -355,10 +355,10 @@ public void testUserSuppliedGitWithCommitInfoWebhook() throws Exception {
assertEquals("hardcoded-message", meta.getString("message"));
assertEquals("hardcoded-author-name", meta.getString("author_name"));
assertEquals("hardcoded-author-email", meta.getString("author_email"));
assertEquals("hardcoded-author-date", meta.getString("author_time"));
assertEquals("2024-08-14T12:06:04.530Z", meta.getString("author_time"));
assertEquals("hardcoded-committer-name", meta.getString("committer_name"));
assertEquals("hardcoded-committer-email", meta.getString("committer_email"));
assertEquals("hardcoded-committer-date", meta.getString("commit_time"));
assertEquals("2024-08-14T12:06:04.529Z", meta.getString("commit_time"));
assertEquals("401d997a6eede777602669ccaec059755c98161f", meta.getString("sha"));
assertEquals("master", meta.getString("branch"));
assertEquals(toUrl(localGitRepoPath.getRemote()), meta.getString("repository_url"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
Expand Down Expand Up @@ -77,7 +78,6 @@
import org.junit.ClassRule;
import org.junit.Test;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.recipes.WithTimeout;

public class DatadogGraphListenerTest extends DatadogTraceAbstractTest {

Expand Down Expand Up @@ -392,6 +392,90 @@ public void testIntegrationGitInfoOverrideCommit() throws Exception {
}
}

@Test
public void testManuallySetCommitterDateIsExtractedFromEnvironmentVariables() throws Exception {
Jenkins jenkins = jenkinsRule.jenkins;

WorkflowJob job = jenkins.createProject(WorkflowJob.class, "testPipelinesManualGitCommitterDate.txt");
String definition = getPipelineDefinition("testPipelinesManualGitCommitterDate.txt");

job.setDefinition(new CpsFlowDefinition(definition, true));
final FilePath ws = jenkins.getWorkspaceFor(job);

job.scheduleBuild2(0).get();

clientStub.waitForTraces(3);
final List<TraceSpan> spans = clientStub.getSpans();
assertEquals(3, spans.size());
for(TraceSpan span : spans) {
if ("jenkins.build".equals(span.getOperationName())) {
assertEquals("2024-08-14T12:06:04.529Z", span.getMeta().get(CITags.GIT_COMMIT_COMMITTER_DATE));
}
}
}

@Test
public void testManuallySetAuthorDateIsExtractedFromEnvironmentVariables() throws Exception {
Jenkins jenkins = jenkinsRule.jenkins;

WorkflowJob job = jenkins.createProject(WorkflowJob.class, "testPipelinesManualGitAuthorDate.txt");
String definition = getPipelineDefinition("testPipelinesManualGitAuthorDate.txt");

job.setDefinition(new CpsFlowDefinition(definition, true));
final FilePath ws = jenkins.getWorkspaceFor(job);

job.scheduleBuild2(0).get();

clientStub.waitForTraces(3);
final List<TraceSpan> spans = clientStub.getSpans();
assertEquals(3, spans.size());
for(TraceSpan span : spans) {
if ("jenkins.build".equals(span.getOperationName())) {
assertEquals("2024-08-14T12:06:04.529Z", span.getMeta().get(CITags.GIT_COMMIT_AUTHOR_DATE));
}
}
}

@Test
public void testInvalidManuallySetCommitterDateIsExtractedFromEnvironmentVariables() throws Exception {
Jenkins jenkins = jenkinsRule.jenkins;

WorkflowJob job = jenkins.createProject(WorkflowJob.class, "testPipelinesInvalidManualGitCommitterDate.txt");
String definition = getPipelineDefinition("testPipelinesInvalidManualGitCommitterDate.txt");

job.setDefinition(new CpsFlowDefinition(definition, true));
final FilePath ws = jenkins.getWorkspaceFor(job);

job.scheduleBuild2(0).get();

clientStub.waitForTraces(3);
final List<TraceSpan> spans = clientStub.getSpans();
assertEquals(3, spans.size());
for(TraceSpan span : spans) {
assertNull(span.getMeta().get(CITags.GIT_COMMIT_COMMITTER_DATE));
}
}

@Test
public void testInvalidManuallySetAuthorDateIsExtractedFromEnvironmentVariables() throws Exception {
Jenkins jenkins = jenkinsRule.jenkins;

WorkflowJob job = jenkins.createProject(WorkflowJob.class, "testPipelinesInvalidManualGitAuthorDate.txt");
String definition = getPipelineDefinition("testPipelinesInvalidManualGitAuthorDate.txt");

job.setDefinition(new CpsFlowDefinition(definition, true));
final FilePath ws = jenkins.getWorkspaceFor(job);

job.scheduleBuild2(0).get();

clientStub.waitForTraces(3);
final List<TraceSpan> spans = clientStub.getSpans();
assertEquals(3, spans.size());
for(TraceSpan span : spans) {
assertNull(span.getMeta().get(CITags.GIT_COMMIT_AUTHOR_DATE));
}
}

private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile("\\$([A-Z_]+)");

private String getPipelineDefinition(String file) throws IOException {
Expand Down Expand Up @@ -560,10 +644,10 @@ public void testUserSuppliedGitWithCommitInfo() throws Exception {
env.put(DD_GIT_COMMIT_MESSAGE, "hardcoded-message");
env.put(DD_GIT_COMMIT_AUTHOR_NAME, "hardcoded-author-name");
env.put(DD_GIT_COMMIT_AUTHOR_EMAIL, "hardcoded-author-email");
env.put(DD_GIT_COMMIT_AUTHOR_DATE, "hardcoded-author-date");
env.put(DD_GIT_COMMIT_AUTHOR_DATE, "2024-08-14T12:06:04.530Z");
env.put(DD_GIT_COMMIT_COMMITTER_NAME, "hardcoded-committer-name");
env.put(DD_GIT_COMMIT_COMMITTER_EMAIL, "hardcoded-committer-email");
env.put(DD_GIT_COMMIT_COMMITTER_DATE, "hardcoded-committer-date");
env.put(DD_GIT_COMMIT_COMMITTER_DATE, "2024-08-14T12:06:04.529Z");
final String defaultBranch = "refs/heads/hardcoded-master";
env.put(DD_GIT_DEFAULT_BRANCH, defaultBranch);
WorkflowJob job = jenkins.createProject(WorkflowJob.class, "pipelineIntegrationUserSuppliedGitWithCommitInfo");
Expand All @@ -587,10 +671,10 @@ public void testUserSuppliedGitWithCommitInfo() throws Exception {
assertEquals("hardcoded-message", meta.get(CITags.GIT_COMMIT_MESSAGE));
assertEquals("hardcoded-author-name", meta.get(CITags.GIT_COMMIT_AUTHOR_NAME));
assertEquals("hardcoded-author-email", meta.get(CITags.GIT_COMMIT_AUTHOR_EMAIL));
assertEquals("hardcoded-author-date", meta.get(CITags.GIT_COMMIT_AUTHOR_DATE));
assertEquals("2024-08-14T12:06:04.530Z", meta.get(CITags.GIT_COMMIT_AUTHOR_DATE));
assertEquals("hardcoded-committer-name", meta.get(CITags.GIT_COMMIT_COMMITTER_NAME));
assertEquals("hardcoded-committer-email", meta.get(CITags.GIT_COMMIT_COMMITTER_EMAIL));
assertEquals("hardcoded-committer-date", meta.get(CITags.GIT_COMMIT_COMMITTER_DATE));
assertEquals("2024-08-14T12:06:04.529Z", meta.get(CITags.GIT_COMMIT_COMMITTER_DATE));
assertEquals("401d997a6eede777602669ccaec059755c98161f", meta.get(CITags.GIT_COMMIT__SHA));
assertEquals("401d997a6eede777602669ccaec059755c98161f", meta.get(CITags.GIT_COMMIT_SHA));
assertEquals("master", meta.get(CITags.GIT_BRANCH));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.datadog.jenkins.plugins.datadog.model;

import static org.datadog.jenkins.plugins.datadog.util.git.GitConstants.DD_GIT_COMMIT_AUTHOR_DATE;
import static org.datadog.jenkins.plugins.datadog.util.git.GitConstants.DD_GIT_COMMIT_COMMITTER_DATE;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
Expand Down Expand Up @@ -146,4 +148,40 @@ private BuildData whenCreatingBuildData(Run run) throws IOException, Interrupted
return new BuildData(run, listener);
}

@Test
public void testCommitAuthorDateIsPopulatedFromEnvVar() throws Exception {
String validISO8601Date = "2024-08-14T12:06:04.529Z";
Map<String, String> buildEnvironment = Collections.singletonMap(DD_GIT_COMMIT_AUTHOR_DATE, validISO8601Date);
FreeStyleBuild build = givenJobRun(FreeStyleBuild.class, "jobName", "jobParentName", mock(Hudson.class), buildEnvironment);
BuildData buildData = whenCreatingBuildData(build);
assertEquals(validISO8601Date, buildData.getGitAuthorDate(""));
}

@Test
public void testCommitCommitterDateIsPopulatedFromEnvVar() throws Exception {
String validISO8601Date = "2024-08-14T12:06:04.529Z";
Map<String, String> buildEnvironment = Collections.singletonMap(DD_GIT_COMMIT_COMMITTER_DATE, validISO8601Date);
FreeStyleBuild build = givenJobRun(FreeStyleBuild.class, "jobName", "jobParentName", mock(Hudson.class), buildEnvironment);
BuildData buildData = whenCreatingBuildData(build);
assertEquals(validISO8601Date, buildData.getGitCommitterDate(""));
}

@Test
public void testCommitAuthorDateIsNotPopulatedWithInvalidValues() throws Exception {
String invalidISO8601Date = "12:06:04.529 14/08/2024";
Map<String, String> buildEnvironment = Collections.singletonMap(DD_GIT_COMMIT_AUTHOR_DATE, invalidISO8601Date);
FreeStyleBuild build = givenJobRun(FreeStyleBuild.class, "jobName", "jobParentName", mock(Hudson.class), buildEnvironment);
BuildData buildData = whenCreatingBuildData(build);
assertEquals("", buildData.getGitAuthorDate(""));
}

@Test
public void testCommitCommitterDateIsNotPopulatedWithInvalidValues() throws Exception {
String invalidISO8601Date = "12:06:04.529 14/08/2024";
Map<String, String> buildEnvironment = Collections.singletonMap(DD_GIT_COMMIT_COMMITTER_DATE, invalidISO8601Date);
FreeStyleBuild build = givenJobRun(FreeStyleBuild.class, "jobName", "jobParentName", mock(Hudson.class), buildEnvironment);
BuildData buildData = whenCreatingBuildData(build);
assertEquals("", buildData.getGitCommitterDate(""));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
pipeline {
agent none
stages {
stage('test'){
steps {
withEnv(["DD_GIT_COMMIT_AUTHOR_DATE=12:06:04.529 2024/08/14"]) {
echo "hello world"
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
pipeline {
agent none
stages {
stage('test'){
steps {
withEnv(["DD_GIT_COMMIT_COMMITTER_DATE=12:06:04.529 2024-08-14"]) {
echo "hello world"
}
}
}
}
}
Loading

0 comments on commit c7ac69a

Please sign in to comment.