-
Notifications
You must be signed in to change notification settings - Fork 49
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
Add configuration validation in clients #59
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know it's still a draft, but I wanted to add a few comments already.
src/main/java/org/datadog/jenkins/plugins/datadog/DatadogGlobalConfiguration.java
Outdated
Show resolved
Hide resolved
src/main/java/org/datadog/jenkins/plugins/datadog/DatadogGlobalConfiguration.java
Outdated
Show resolved
Hide resolved
src/main/java/org/datadog/jenkins/plugins/datadog/DatadogGlobalConfiguration.java
Show resolved
Hide resolved
src/main/java/org/datadog/jenkins/plugins/datadog/DatadogGlobalConfiguration.java
Outdated
Show resolved
Hide resolved
src/main/java/org/datadog/jenkins/plugins/datadog/DatadogGlobalConfiguration.java
Show resolved
Hide resolved
src/main/java/org/datadog/jenkins/plugins/datadog/clients/DatadogHttpClient.java
Outdated
Show resolved
Hide resolved
src/main/java/org/datadog/jenkins/plugins/datadog/clients/DatadogHttpClient.java
Outdated
Show resolved
Hide resolved
instance.setLogIntakeConnectionBroken(true); | ||
logger.severe("Connection broken, please double check both your Log Intake URL and Key"); | ||
} | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So validation will pass even though both the url and the logIntakeUrl are invalid (or the apiKey is invalid).
Maybe we should at least fail it metrics can't be submitted?
Also to come back to the UI part, we should be able to display a FormWarning if the plugin can't connect.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh that's a good idea. I agree there are more validations that can be performed.
@@ -588,4 +612,9 @@ private String getJenkinsVersion(){ | |||
return this.jenkinsVersion; | |||
} | |||
|
|||
private static boolean isCollectBuildLogEnabled(){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like that we need to access the config from here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is also currently in DogstatsdClient. I'm not sure the best way to check for logs being enabled.
src/main/java/org/datadog/jenkins/plugins/datadog/clients/DogStatsDClient.java
Outdated
Show resolved
Hide resolved
src/main/java/org/datadog/jenkins/plugins/datadog/DatadogGlobalConfiguration.java
Show resolved
Hide resolved
|
||
return status; | ||
}catch(Exception e){ | ||
// Intercept all FormException instances. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what the effect of this is. Are we sure the change is safe ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm I'm not completely sure, I know FormExceptions are the most common, and they should be thrown, but maybe unexpected errors should be caught and logged.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added it back- I agree that having this safeguard is more important than the cleanliness of the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In theory java should let you know about all exceptions and force you to catch or rethrow them except if they are unchecked exception like RuntimeExceptions.
So I think you should be able to ensure that all exceptions are caught?
|
||
DatadogUtilities.severe(logger, e, null); | ||
if(client != null) { | ||
// There are no reasons at this point client should be null. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's update the comment here, client
is expected to be null if connection is impossible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And let's reverse the condition:
if(client == null) {
return null
}
client.setDefaultIntakeConnectionBroken(false);
client.setLogIntakeConnectionBroken(false);
// Persist global configuration information
save();
return status;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also think that instead of returning status here we should return true. And at the top of the method do this:
if(!super.configure(req, formData)){
return false
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure!
@@ -54,7 +54,9 @@ of this software and associated documentation files (the "Software"), to deal | |||
*/ | |||
public class DatadogHttpClient implements DatadogClient { | |||
|
|||
private static DatadogClient instance; | |||
private static DatadogClient instance = null; | |||
private static boolean failedLastValidation = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's have a comment to tell why it's useful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure!
DatadogHttpClient newInstance = new DatadogHttpClient(url, logIntakeUrl, apiKey); | ||
DatadogHttpClient httpInstance = (DatadogHttpClient) instance; | ||
if (httpInstance != null && httpInstance.equals(newInstance)) { | ||
if (DatadogHttpClient.failedLastValidation) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We will need a way to retry validation every X minutes. What if failedLastValidation
is true because of a network failure ? You'd require a restart of Jenkins to fix
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm that's true. I will look into a way to do this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We still need this to be addressed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know, I haven't thought of a great approach yet. Do you have any ideas?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, thinking it through, in the case of a network failure, it wouldn't require a restart of jenkins, it would just require entering different credentials (and then entering the correct ones). It isn't the best solution, but I'm not sure how likely this scenario is.
DatadogHttpClient.lastInstance = new DatadogHttpClient(url, logIntakeUrl, apiKey); | ||
if (enableValidations) { | ||
try { | ||
validateCongiguration(url, logIntakeUrl, apiKey); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reopening: this should not be a static method.
DatadogHttpClient.instance = newInstance; | ||
try { | ||
validateCongiguration(url, logIntakeUrl, apiKey); | ||
} catch(RuntimeException e){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's not use unchecked exception for validation.
@@ -124,6 +122,68 @@ private DatadogHttpClient(String url, String logIntakeUrl, Secret apiKey) { | |||
this.logIntakeUrl = logIntakeUrl; | |||
} | |||
|
|||
public static void validateCongiguration(String url, String logIntakeUrl, Secret apiKey) throws RuntimeException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: validateConfiguration*
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should not be static
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use checked exception instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated!
} | ||
|
||
@Override | ||
public int hashCode() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Auto generated ? Let's indicate it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I based it off of the method from our other hashCode
methods; it was recommended to override hashCode
since I overrode equals
@@ -32,6 +32,7 @@ of this software and associated documentation files (the "Software"), to deal | |||
import org.datadog.jenkins.plugins.datadog.DatadogUtilities; | |||
import org.datadog.jenkins.plugins.datadog.util.SuppressFBWarnings; | |||
import org.datadog.jenkins.plugins.datadog.util.TagsUtil; | |||
import org.apache.commons.lang.StringUtils; | |||
|
|||
import java.io.*; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comments as for DatadogHttpClient
if (enableValidations) { | ||
DatadogHttpClient.instance = newInstance; | ||
try { | ||
newInstance.validateConfiguration(url, logIntakeUrl, apiKey); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
newInstance.validateConfiguration(url, logIntakeUrl, apiKey); | |
newInstance.validateConfiguration(); |
You don't need the args because it's not static anymore
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not see how this PR fixes the issue of using the LogLevel.INFO
pom.xml
Outdated
@@ -5,7 +5,7 @@ | |||
<parent> | |||
<groupId>org.jenkins-ci.plugins</groupId> | |||
<artifactId>plugin</artifactId> | |||
<version>3.56</version> <!-- or whatever the newest version available is --> | |||
<version>4.1</version> <!-- or whatever the newest version available is --> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems ill adviced:
https://github.com/jenkinsci/plugin-pom/blob/88cb710c1b7244bf5f885e16fc9f0baef1ef2661/pom.xml#L53
Please at least specify a Jenkins.version
property
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi, @jetersen!
This change was to just update the parent pom version. It was also included in this PR as well, which is ready to be merged: https://github.com/jenkinsci/datadog-plugin/pull/57/files#diff-600376dffeb79835ede4a0b285078036R8 Adding a minimum jenkins version is out of the scope for this PR, but it’s a good idea that we should do in a later PR.
Thanks for the review @jetersen! I agree this PR doesn’t solve the issue of the continuous DatadogCountersPublisher logs- this was only meant to resolve the null api key logs issue. Can we use #63 to address the DatadogCountersPublisher issue? |
return DatadogUtilities.getDatadogGlobalDescriptor() != null && | ||
DatadogUtilities.getDatadogGlobalDescriptor().isCollectBuildLogs(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your doing a lookup twice 😓 and your using an more expensive get in the method called.
You should use:
ExtensionList.lookupSingleton(DatadogGlobalConfiguration.class);
Also the method could be moved to the DatadogGlobalConfiguration
class, basically moving it to where it belongs.
See here for example:
https://github.com/jenkinsci/azure-keyvault-plugin/blob/ef3a5eb4413f7ecd47d6532735604c52fceaaef0/src/main/java/org/jenkinsci/plugins/azurekeyvaultplugin/AzureKeyVaultGlobalConfiguration.java#L241-L243
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds like a good idea, so we should refactor getDatadogGlobalDescriptor()
and move it to DatadogGlobalConfiguration
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is definitely an opportunity to clean this up, but let's cover it in a separate PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sarah-witt I see you never picked up this suggestion 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some changes were implemented here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah you kept DatadogUtilities.getDatadogGlobalDescriptor
😅 Logically I would prefer DatadogGlobalConfiguration.get()
src/main/java/org/datadog/jenkins/plugins/datadog/DatadogGlobalConfiguration.java
Outdated
Show resolved
Hide resolved
src/main/java/org/datadog/jenkins/plugins/datadog/clients/DatadogHttpClient.java
Show resolved
Hide resolved
…into sarah/validate-config
src/main/java/org/datadog/jenkins/plugins/datadog/clients/DatadogHttpClient.java
Outdated
Show resolved
Hide resolved
src/main/java/org/datadog/jenkins/plugins/datadog/clients/DatadogHttpClient.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔥 LGTM - tested this out locally and only see a single log line when the API key is invalid.
* Add configuration validation * Create .equals method and use synchronization * Remove try catch in configure and enforce use of POST * Simplify logic in configure * Don't create instance if config is invalid * Remove IOException * Throw form exception * Remove exception and post * Fiz style * Check for zero as port * Use parseInt instead of Number Utils * Remove zero check * Update pom * Fix style of imports * Add back extra safeguards for exceptions in configuration * Update exception type and use assertThrows in tests * Validation does not need parameters * Reset config for testing * Remove reset * Remove unneeded resetConfig * Remove unneeded validation * Move hostname validation * Style * Refactor validate url * Simplify equals methods * Update equals and remove imports * Update instance type
What does this PR do?
What inspired you to submit this pull request?
#55
Description of the Change
Alternate Designs
Possible Drawbacks
Verification Process
Additional Notes
Release Notes
Review checklist (to be filled by reviewers)
changelog/
label attached. If applicable it should have thebackward-incompatible
label attached.do-not-merge/
label attached.kind/
andseverity/
labels attached at least.