From 695761bd4ca8cde49bb166f2d43507b296fc3cce Mon Sep 17 00:00:00 2001 From: Pedro Bueno Yerbes Date: Tue, 1 Apr 2025 17:33:14 +0200 Subject: [PATCH 1/5] Using configurator for global props --- .../plugins/casc/GlobalNodePropertiesTest.yml | 2 + .../GlobalNodePropertiesConfigurator.java | 93 +++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 plugin/src/main/java/io/jenkins/plugins/casc/core/GlobalNodePropertiesConfigurator.java diff --git a/integrations/src/test/resources/io/jenkins/plugins/casc/GlobalNodePropertiesTest.yml b/integrations/src/test/resources/io/jenkins/plugins/casc/GlobalNodePropertiesTest.yml index c9eeb3aaf9..411f6908ea 100644 --- a/integrations/src/test/resources/io/jenkins/plugins/casc/GlobalNodePropertiesTest.yml +++ b/integrations/src/test/resources/io/jenkins/plugins/casc/GlobalNodePropertiesTest.yml @@ -4,3 +4,5 @@ jenkins: env: - key: FOO value: BAR + - key: FOO2 + value: "" diff --git a/plugin/src/main/java/io/jenkins/plugins/casc/core/GlobalNodePropertiesConfigurator.java b/plugin/src/main/java/io/jenkins/plugins/casc/core/GlobalNodePropertiesConfigurator.java new file mode 100644 index 0000000000..b8df68732a --- /dev/null +++ b/plugin/src/main/java/io/jenkins/plugins/casc/core/GlobalNodePropertiesConfigurator.java @@ -0,0 +1,93 @@ +package io.jenkins.plugins.casc.core; + +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; +//import hudson.EnvVars; +import hudson.EnvVars; +import hudson.Extension; +import hudson.slaves.EnvironmentVariablesNodeProperty; +import hudson.slaves.EnvironmentVariablesNodeProperty.DescriptorImpl; +import hudson.slaves.EnvironmentVariablesNodeProperty.Entry; +import hudson.util.DescribableList; +import hudson.util.PersistedList; +import io.jenkins.plugins.casc.Attribute; +import io.jenkins.plugins.casc.BaseConfigurator; +import io.jenkins.plugins.casc.ConfigurationContext; +import io.jenkins.plugins.casc.ConfiguratorException; +import io.jenkins.plugins.casc.impl.attributes.MultivaluedAttribute; +import io.jenkins.plugins.casc.model.CNode; +import io.jenkins.plugins.casc.model.Mapping; +import io.jenkins.plugins.casc.model.Sequence; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import org.apache.commons.lang.StringUtils; + +@Extension +public class GlobalNodePropertiesConfigurator extends BaseConfigurator { + + @NonNull + @Override + public String getName() { + return "globalNodeProperties"; + } + + @Override + protected EnvironmentVariablesNodeProperty instance(Mapping mapping, + ConfigurationContext context) throws ConfiguratorException { + List vars = getVarsAsList(mapping); + return new EnvironmentVariablesNodeProperty(vars); + } + + @Override + public Class getTarget() { + return EnvironmentVariablesNodeProperty.class; + } + + @NonNull + @Override + public Set> describe() { + Set> attrs = super.describe(); + attrs.add(new MultivaluedAttribute("env", Entry.class)); + return attrs; + } + + @NonNull + @Override + public EnvironmentVariablesNodeProperty configure(CNode c, ConfigurationContext context) throws ConfiguratorException { + Mapping mapping = c.asMapping(); + List variables = getVarsAsList(mapping); + return new EnvironmentVariablesNodeProperty(variables); + } + + @CheckForNull + public CNode describe(EnvironmentVariablesNodeProperty instance, ConfigurationContext context) throws Exception { + Mapping mapping = new Mapping(); + for (Attribute attribute : getAttributes()) { + CNode value = attribute.describe(instance, context); + // Clean empty vars + Sequence values = new Sequence(); + value.asSequence().stream().filter(entry -> StringUtils.isNotBlank(entry.asMapping().get("value").toString())) + .forEach(values::add); + if (value != null) { + mapping.put(attribute.getName(), values); + } + } + return mapping; + } + + + private List getVarsAsList(Mapping m) { + List result = new ArrayList<>(); + if (m.get("env") != null){ + result = m.get("env").asSequence().stream() + .map(pair -> new Entry(pair.asMapping().get("key").asScalar().getValue(), + pair.asMapping().get("value").asScalar().getValue())) + .toList(); + } + return result; + } +} From 3f5d776060bbd85f2d9f17cc05cb4af8f3ed038b Mon Sep 17 00:00:00 2001 From: Francisco Javier Fernandez Gonzalez Date: Wed, 2 Apr 2025 12:32:26 +0200 Subject: [PATCH 2/5] Accept EnvVars wihtout value --- .../casc/GlobalNodePropertiesTest.java | 15 ++++++- .../plugins/casc/GlobalNodePropertiesTest.yml | 1 + .../casc/GlobalNodePropertiesTestExpected.yml | 2 + .../GlobalNodePropertiesConfigurator.java | 44 +++++++++---------- 4 files changed, 38 insertions(+), 24 deletions(-) diff --git a/integrations/src/test/java/io/jenkins/plugins/casc/GlobalNodePropertiesTest.java b/integrations/src/test/java/io/jenkins/plugins/casc/GlobalNodePropertiesTest.java index ba91c2edea..5c5ad20a4d 100644 --- a/integrations/src/test/java/io/jenkins/plugins/casc/GlobalNodePropertiesTest.java +++ b/integrations/src/test/java/io/jenkins/plugins/casc/GlobalNodePropertiesTest.java @@ -15,7 +15,9 @@ import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithCodeRule; import io.jenkins.plugins.casc.misc.junit.jupiter.WithJenkinsConfiguredWithCode; import io.jenkins.plugins.casc.model.CNode; +import java.util.Iterator; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import jenkins.model.Jenkins; import org.junit.jupiter.api.Test; @@ -33,11 +35,20 @@ void configure(JenkinsConfiguredWithCodeRule j) { Set> entries = ((EnvironmentVariablesNodeProperty) nodeProperties.get(0)) .getEnvVars() .entrySet(); - assertEquals(1, entries.size()); + assertEquals(3, entries.size()); - Map.Entry envVar = entries.iterator().next(); + Iterator> iterator = entries.iterator(); + Map.Entry envVar = iterator.next(); assertEquals("FOO", envVar.getKey()); assertEquals("BAR", envVar.getValue()); + + envVar = iterator.next(); + assertEquals("FOO2", envVar.getKey()); + assertEquals("", envVar.getValue()); + + envVar = iterator.next(); + assertEquals("FOO3", envVar.getKey()); + assertEquals("", envVar.getValue()); } @Test diff --git a/integrations/src/test/resources/io/jenkins/plugins/casc/GlobalNodePropertiesTest.yml b/integrations/src/test/resources/io/jenkins/plugins/casc/GlobalNodePropertiesTest.yml index 411f6908ea..e76e751e4f 100644 --- a/integrations/src/test/resources/io/jenkins/plugins/casc/GlobalNodePropertiesTest.yml +++ b/integrations/src/test/resources/io/jenkins/plugins/casc/GlobalNodePropertiesTest.yml @@ -6,3 +6,4 @@ jenkins: value: BAR - key: FOO2 value: "" + - key: FOO3 \ No newline at end of file diff --git a/integrations/src/test/resources/io/jenkins/plugins/casc/GlobalNodePropertiesTestExpected.yml b/integrations/src/test/resources/io/jenkins/plugins/casc/GlobalNodePropertiesTestExpected.yml index e02c4d039a..bf79b322c9 100644 --- a/integrations/src/test/resources/io/jenkins/plugins/casc/GlobalNodePropertiesTestExpected.yml +++ b/integrations/src/test/resources/io/jenkins/plugins/casc/GlobalNodePropertiesTestExpected.yml @@ -2,3 +2,5 @@ env: - key: "FOO" value: "BAR" + - key: "FOO2" + - key: "FOO3" diff --git a/plugin/src/main/java/io/jenkins/plugins/casc/core/GlobalNodePropertiesConfigurator.java b/plugin/src/main/java/io/jenkins/plugins/casc/core/GlobalNodePropertiesConfigurator.java index b8df68732a..35033dbcbc 100644 --- a/plugin/src/main/java/io/jenkins/plugins/casc/core/GlobalNodePropertiesConfigurator.java +++ b/plugin/src/main/java/io/jenkins/plugins/casc/core/GlobalNodePropertiesConfigurator.java @@ -2,14 +2,9 @@ import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; -//import hudson.EnvVars; -import hudson.EnvVars; import hudson.Extension; import hudson.slaves.EnvironmentVariablesNodeProperty; -import hudson.slaves.EnvironmentVariablesNodeProperty.DescriptorImpl; import hudson.slaves.EnvironmentVariablesNodeProperty.Entry; -import hudson.util.DescribableList; -import hudson.util.PersistedList; import io.jenkins.plugins.casc.Attribute; import io.jenkins.plugins.casc.BaseConfigurator; import io.jenkins.plugins.casc.ConfigurationContext; @@ -19,12 +14,8 @@ import io.jenkins.plugins.casc.model.Mapping; import io.jenkins.plugins.casc.model.Sequence; import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; import java.util.List; import java.util.Set; -import java.util.stream.Collectors; -import org.apache.commons.lang.StringUtils; @Extension public class GlobalNodePropertiesConfigurator extends BaseConfigurator { @@ -36,8 +27,8 @@ public String getName() { } @Override - protected EnvironmentVariablesNodeProperty instance(Mapping mapping, - ConfigurationContext context) throws ConfiguratorException { + protected EnvironmentVariablesNodeProperty instance(Mapping mapping, ConfigurationContext context) + throws ConfiguratorException { List vars = getVarsAsList(mapping); return new EnvironmentVariablesNodeProperty(vars); } @@ -51,13 +42,15 @@ public Class getTarget() { @Override public Set> describe() { Set> attrs = super.describe(); - attrs.add(new MultivaluedAttribute("env", Entry.class)); + attrs.add(new MultivaluedAttribute( + "env", Entry.class)); return attrs; } @NonNull @Override - public EnvironmentVariablesNodeProperty configure(CNode c, ConfigurationContext context) throws ConfiguratorException { + public EnvironmentVariablesNodeProperty configure(CNode c, ConfigurationContext context) + throws ConfiguratorException { Mapping mapping = c.asMapping(); List variables = getVarsAsList(mapping); return new EnvironmentVariablesNodeProperty(variables); @@ -68,25 +61,32 @@ public CNode describe(EnvironmentVariablesNodeProperty instance, ConfigurationCo Mapping mapping = new Mapping(); for (Attribute attribute : getAttributes()) { CNode value = attribute.describe(instance, context); - // Clean empty vars - Sequence values = new Sequence(); - value.asSequence().stream().filter(entry -> StringUtils.isNotBlank(entry.asMapping().get("value").toString())) - .forEach(values::add); if (value != null) { + Sequence values = new Sequence(); + value.asSequence().stream().forEach(values::add); mapping.put(attribute.getName(), values); } } return mapping; } - private List getVarsAsList(Mapping m) { List result = new ArrayList<>(); - if (m.get("env") != null){ + if (m.get("env") != null) { result = m.get("env").asSequence().stream() - .map(pair -> new Entry(pair.asMapping().get("key").asScalar().getValue(), - pair.asMapping().get("value").asScalar().getValue())) - .toList(); + .map(pair -> { + if (pair.asMapping().get("key") == null) { + return null; + } + final String key = + pair.asMapping().get("key").asScalar().getValue(); + final String value = pair.asMapping().get("value") == null + ? "" + : pair.asMapping().get("value").asScalar().getValue(); + + return new Entry(key, value); + }) + .toList(); } return result; } From be60c5ab2bcab5df2b58344365848bcbabe9a9e5 Mon Sep 17 00:00:00 2001 From: Pedro Bueno Yerbes Date: Wed, 2 Apr 2025 18:21:16 +0200 Subject: [PATCH 3/5] Testing additional global props --- .../casc/GlobalNodePropertiesTest.java | 22 ++++++++++++++++--- .../plugins/casc/GlobalNodePropertiesTest.yml | 11 +++++++++- .../casc/GlobalNodePropertiesTestExpected.yml | 9 ++++++++ 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/integrations/src/test/java/io/jenkins/plugins/casc/GlobalNodePropertiesTest.java b/integrations/src/test/java/io/jenkins/plugins/casc/GlobalNodePropertiesTest.java index 5c5ad20a4d..c59a115e32 100644 --- a/integrations/src/test/java/io/jenkins/plugins/casc/GlobalNodePropertiesTest.java +++ b/integrations/src/test/java/io/jenkins/plugins/casc/GlobalNodePropertiesTest.java @@ -7,9 +7,11 @@ import static org.hamcrest.core.Is.is; import static org.junit.jupiter.api.Assertions.assertEquals; +import hudson.node_monitors.DiskSpaceMonitorNodeProperty; import hudson.slaves.EnvironmentVariablesNodeProperty; import hudson.slaves.NodeProperty; import hudson.slaves.NodePropertyDescriptor; +import hudson.tools.ToolLocationNodeProperty; import hudson.util.DescribableList; import io.jenkins.plugins.casc.misc.ConfiguredWithCode; import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithCodeRule; @@ -32,12 +34,15 @@ void configure(JenkinsConfiguredWithCodeRule j) { DescribableList, NodePropertyDescriptor> nodeProperties = jenkins.getGlobalNodeProperties(); - Set> entries = ((EnvironmentVariablesNodeProperty) nodeProperties.get(0)) + assertEquals(3, nodeProperties.size()); + + Set> envVars = ((EnvironmentVariablesNodeProperty) + nodeProperties.get(EnvironmentVariablesNodeProperty.class)) .getEnvVars() .entrySet(); - assertEquals(3, entries.size()); + assertEquals(3, envVars.size()); - Iterator> iterator = entries.iterator(); + Iterator> iterator = envVars.iterator(); Map.Entry envVar = iterator.next(); assertEquals("FOO", envVar.getKey()); assertEquals("BAR", envVar.getValue()); @@ -49,6 +54,17 @@ void configure(JenkinsConfiguredWithCodeRule j) { envVar = iterator.next(); assertEquals("FOO3", envVar.getKey()); assertEquals("", envVar.getValue()); + + DiskSpaceMonitorNodeProperty diskSpace = nodeProperties.get(DiskSpaceMonitorNodeProperty.class); + assertEquals("1GiB", diskSpace.getFreeDiskSpaceThreshold()); + assertEquals("2GiB", diskSpace.getFreeDiskSpaceWarningThreshold()); + assertEquals("1GiB", diskSpace.getFreeTempSpaceThreshold()); + assertEquals("2GiB", diskSpace.getFreeTempSpaceWarningThreshold()); + + ToolLocationNodeProperty toolLocations = nodeProperties.get(ToolLocationNodeProperty.class); + assertEquals(1, toolLocations.getLocations().size()); + assertEquals("Default", toolLocations.getLocations().get(0).getName()); + assertEquals("/home/user/bin/git", toolLocations.getLocations().get(0).getHome()); } @Test diff --git a/integrations/src/test/resources/io/jenkins/plugins/casc/GlobalNodePropertiesTest.yml b/integrations/src/test/resources/io/jenkins/plugins/casc/GlobalNodePropertiesTest.yml index e76e751e4f..35ae547e9c 100644 --- a/integrations/src/test/resources/io/jenkins/plugins/casc/GlobalNodePropertiesTest.yml +++ b/integrations/src/test/resources/io/jenkins/plugins/casc/GlobalNodePropertiesTest.yml @@ -1,9 +1,18 @@ jenkins: globalNodeProperties: + - diskSpaceMonitor: + freeDiskSpaceThreshold: "1GiB" + freeDiskSpaceWarningThreshold: "2GiB" + freeTempSpaceThreshold: "1GiB" + freeTempSpaceWarningThreshold: "2GiB" - envVars: env: - key: FOO value: BAR - key: FOO2 value: "" - - key: FOO3 \ No newline at end of file + - key: FOO3 + - toolLocation: + locations: + - home: "/home/user/bin/git" + key: "hudson.plugins.git.GitTool$DescriptorImpl@Default" \ No newline at end of file diff --git a/integrations/src/test/resources/io/jenkins/plugins/casc/GlobalNodePropertiesTestExpected.yml b/integrations/src/test/resources/io/jenkins/plugins/casc/GlobalNodePropertiesTestExpected.yml index bf79b322c9..b34a3b8583 100644 --- a/integrations/src/test/resources/io/jenkins/plugins/casc/GlobalNodePropertiesTestExpected.yml +++ b/integrations/src/test/resources/io/jenkins/plugins/casc/GlobalNodePropertiesTestExpected.yml @@ -1,6 +1,15 @@ +- diskSpaceMonitor: + freeDiskSpaceThreshold: "1GiB" + freeDiskSpaceWarningThreshold: "2GiB" + freeTempSpaceThreshold: "1GiB" + freeTempSpaceWarningThreshold: "2GiB" - envVars: env: - key: "FOO" value: "BAR" - key: "FOO2" - key: "FOO3" +- toolLocation: + locations: + - home: "/home/user/bin/git" + key: "hudson.plugins.git.GitTool$DescriptorImpl@Default" From e7055abd38b073a7b7142d3aef888a56812d3360 Mon Sep 17 00:00:00 2001 From: Pedro Bueno Yerbes Date: Wed, 2 Apr 2025 18:30:26 +0200 Subject: [PATCH 4/5] Removing not used describe --- .../core/GlobalNodePropertiesConfigurator.java | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/plugin/src/main/java/io/jenkins/plugins/casc/core/GlobalNodePropertiesConfigurator.java b/plugin/src/main/java/io/jenkins/plugins/casc/core/GlobalNodePropertiesConfigurator.java index 35033dbcbc..9ac3c25c5b 100644 --- a/plugin/src/main/java/io/jenkins/plugins/casc/core/GlobalNodePropertiesConfigurator.java +++ b/plugin/src/main/java/io/jenkins/plugins/casc/core/GlobalNodePropertiesConfigurator.java @@ -1,6 +1,5 @@ package io.jenkins.plugins.casc.core; -import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; import hudson.Extension; import hudson.slaves.EnvironmentVariablesNodeProperty; @@ -12,7 +11,6 @@ import io.jenkins.plugins.casc.impl.attributes.MultivaluedAttribute; import io.jenkins.plugins.casc.model.CNode; import io.jenkins.plugins.casc.model.Mapping; -import io.jenkins.plugins.casc.model.Sequence; import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -56,20 +54,6 @@ public EnvironmentVariablesNodeProperty configure(CNode c, ConfigurationContext return new EnvironmentVariablesNodeProperty(variables); } - @CheckForNull - public CNode describe(EnvironmentVariablesNodeProperty instance, ConfigurationContext context) throws Exception { - Mapping mapping = new Mapping(); - for (Attribute attribute : getAttributes()) { - CNode value = attribute.describe(instance, context); - if (value != null) { - Sequence values = new Sequence(); - value.asSequence().stream().forEach(values::add); - mapping.put(attribute.getName(), values); - } - } - return mapping; - } - private List getVarsAsList(Mapping m) { List result = new ArrayList<>(); if (m.get("env") != null) { From d1c08d9f15a9a6962e64c78bfe85d18a3f3bc77c Mon Sep 17 00:00:00 2001 From: Pedro Bueno Yerbes Date: Thu, 3 Apr 2025 18:09:08 +0200 Subject: [PATCH 5/5] Switching to use DataBoundConstructor --- .../GlobalNodePropertiesConfigurator.java | 32 +++++-------------- 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/plugin/src/main/java/io/jenkins/plugins/casc/core/GlobalNodePropertiesConfigurator.java b/plugin/src/main/java/io/jenkins/plugins/casc/core/GlobalNodePropertiesConfigurator.java index 9ac3c25c5b..b3ab3ce0e0 100644 --- a/plugin/src/main/java/io/jenkins/plugins/casc/core/GlobalNodePropertiesConfigurator.java +++ b/plugin/src/main/java/io/jenkins/plugins/casc/core/GlobalNodePropertiesConfigurator.java @@ -4,45 +4,29 @@ import hudson.Extension; import hudson.slaves.EnvironmentVariablesNodeProperty; import hudson.slaves.EnvironmentVariablesNodeProperty.Entry; -import io.jenkins.plugins.casc.Attribute; -import io.jenkins.plugins.casc.BaseConfigurator; import io.jenkins.plugins.casc.ConfigurationContext; import io.jenkins.plugins.casc.ConfiguratorException; -import io.jenkins.plugins.casc.impl.attributes.MultivaluedAttribute; +import io.jenkins.plugins.casc.impl.configurators.DataBoundConfigurator; import io.jenkins.plugins.casc.model.CNode; import io.jenkins.plugins.casc.model.Mapping; import java.util.ArrayList; import java.util.List; -import java.util.Set; @Extension -public class GlobalNodePropertiesConfigurator extends BaseConfigurator { +public class GlobalNodePropertiesConfigurator extends DataBoundConfigurator { - @NonNull - @Override - public String getName() { - return "globalNodeProperties"; + public GlobalNodePropertiesConfigurator() { + this(EnvironmentVariablesNodeProperty.class); } - @Override - protected EnvironmentVariablesNodeProperty instance(Mapping mapping, ConfigurationContext context) - throws ConfiguratorException { - List vars = getVarsAsList(mapping); - return new EnvironmentVariablesNodeProperty(vars); - } - - @Override - public Class getTarget() { - return EnvironmentVariablesNodeProperty.class; + public GlobalNodePropertiesConfigurator(Class clazz) { + super(EnvironmentVariablesNodeProperty.class); } @NonNull @Override - public Set> describe() { - Set> attrs = super.describe(); - attrs.add(new MultivaluedAttribute( - "env", Entry.class)); - return attrs; + public String getName() { + return "globalNodeProperties"; } @NonNull