Need help to read a json file using groovy and Jenkins - jenkins

I am facing some issues reading a JSON file.
I am using Jenkins Active Choice Parameter to read value from a JSON file via groovy script. This is how my JSON file look.
{
"smoke": "Test1.js",
"default": "Test2.js"
}
I want my groovy script to print out smoke and default. Below is what my groovy code look like.
import groovy.json.JsonSlurper
def inputFile = new File(".\TestSuitesJ.json")
def InputJSON = new JsonSlurper().parseText(inputFile)
InputJson.each
{
return[
key
]
}
Above code is not working for me. Can someone please suggest a better groovy way?

Anyone in similar situation as me trying to import a JSON file at runtime. I used Active Choice parameter to solve my problem. There is an option to write groovy script in Active Choice Parameter plugin of Jenkins. There i have written below code to import a JSON file to achieve desired results.
import groovy.json.JsonSlurper
def inputFile = new File('.//TestSuitesJ.json')
def inputJSON = new JsonSlurper().parse(inputFile)
def keys = inputJSON.keySet() as List
Thanks #sensei to help me learn groovy.

You really should read the groovy dev kit page, and this in particular.
Because in your case parseText() returns a LazyMap instance, the it variable you're getting in your each closure represents a Map.Entry instance. So you could println it.key to get what you want.
A more groovy way would be:
inputJson.each { k, v ->
println k
}
In which case groovy passes your closure the key (k) and the value (v) for every element in the map.

Related

Not that kind of Map exception with Jenkins and Groovy

I have a string in groovy that I want to convert into a map. When I run the code on my local computer through a groovy script for testing, I have no issues and a lazy map is returned. I can then convert that to a regular map and life goes on. When I try the same code through my Jenkins DSL pipeline, I run into the exception
groovy.json.internal.Exceptions$JsonInternalException: Not that kind of map
Here is the code chunk in question:
import groovy.json.*
String string1 = "{value1={blue green=true, red pink=true, gold silver=true}, value2={red gold=false}, value3={silver brown=false}}"
def stringToMapConverter(String stringToBeConverted){
formattedString = stringToBeConverted.replace("=", ":")
def jsonSlurper = new JsonSlurper().setType(JsonParserType.LAX)
def mapOfString = jsonSlurper.parseText(formattedString)
return mapOfString
}
def returnedValue = stringToMapConverter(string1)
println(returnedValue)
returned value:
[value2:[red gold:false], value1:[red pink:true, gold silver:true, blue green:true], value3:[silver brown:false]]
I know that Jenkins and Groovy differ in various ways, but from searches online others suggest that I should be able to use the LAX JsonSlurper library within my groovy pipeline. I am trying to avoid hand rolling my own string to map converter and would prefer to use a library if it's out there. What could be the difference here that would cause this behavior?
Try to use
import groovy.json.*
//#NonCPS
def parseJson(jsonString) {
// Would like to use readJSON step, but it requires a context, even for parsing just text.
def lazyMap = new JsonSlurper().setType(JsonParserType.LAX).parseText(jsonString.replace("=", ":").normalize())
// JsonSlurper returns a non-serializable LazyMap, so copy it into a regular map before returning
def m = [:]
m.putAll(lazyMap)
return m
}
String string1 = "{value1={blue green=true, red pink=true, gold silver=true}, value2={red gold=false}, value3={silver brown=false}}"
def returnedValue = parseJson(string1)
println(returnedValue)
println(JsonOutput.toJson(returnedValue))
You can find information about normalize here.

Jenkins Groovy Pipeline org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: No such field found: field groovy.util.Node

I am retrieving an XML file from a remote host and parsing it using XmlParser. The content of the file is as follows:
<?xml version="1.0" encoding="utf-8"?><Metrics> <Safety> <score>81.00</score> <Percentrules>98.00</Percentrules> </Safety> </Metrics>
I am able to retrieve the score value in the following way when I execute the script outside the Groovy sandbox.
def report = readFile(file: 'Qualitycheck.xml')
def metrics = new XmlParser().parseText(report)
println metrics
double score = Double.parseDouble(metrics.Safety.score[0].value()[0])
However, when I execute the script using SCM I get the following:
org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: No such field found: field groovy.util.Node
The issue persist even though I have installed the Permissive-Script-Security-Plugin and enabled the plugin using the -Dpermissive-script-security.enabled=no_securityJVM option. Is there something different about this method? No other method is causing issues. Why?
Edit
I decided to use XmlSlurper(), and retrieved the value 81.00. However the result was type groovy.util.slurpersupport.NodeChildren
def metrics2 = new XmlSlurper().parseText(report)
def score = metrics2.Safety.score
print score
print score.getClass()
=> 81.0098.00
=> groovy.util.slurpersupport.NodeChildren
How do I use XmlSlurper to extract the value 81.00 and cast it as double? Will that be a good alternative?
There seems to be some issues with the script sandbox with Node and NodeList field access. You can work around this like the following, its not nice but works at least.
node() {
def xml = readFile "${env.WORKSPACE}/Qualitycheck.xml"
def rootNode = new XmlParser().parseText(xml)
print Double.parseDouble(rootNode.value()[0].value()[0].value()[0])
// Next line if position isnt fixed, can return an array
// if theres more than 1 with structure "Safety.score", [0] at the end takes the first.
print Double.parseDouble(rootNode.find{it.name() == "Safety"}.value().find{it.name() == "score"}.value()[0])
}
You also need to approve following signatures in the In-process Script Approval section in Manage Jenkins menu.
method groovy.util.Node name
method groovy.util.Node value
method groovy.util.XmlParser parseText java.lang.String
new groovy.util.XmlParser
staticMethod java.lang.Double parseDouble java.lang.String
staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods find java.lang.Object groovy.lang.Closure

How to add string parameter to a freestyle jenkins job via groovy?

I am new to Groovy and trying to add a string parameter to a Jenkins job via Groovy (not using plugins)
I found similar set of examples for Workflow job and not for FreeStyleProject
https://www.programcreek.com/java-api-examples/index.php?api=hudson.model.FreeStyleProject
If anyone could help me it would be great
After searching for days, the following solution worked
ParameterDefinition paramDef = new StringParameterDefinition("CUSTOM_BUILD_PARAM", "Test", "");
ParametersDefinitionProperty paramsDef = new ParametersDefinitionProperty(paramDef);
job.addProperty(paramsDef);
where 'job' is of type 'FreeStyleProject'
You can use String Parameter Definition
It accepts 3 parameters
new StringParameterDefinition(parameterName, defaultValue, description)
Also, be sure to import it!
import hudson.model.*

How to get parameters of another build?

I use parameterized builds in a lot of places. I'd like a pipeline's input to be a build number of a different job. I haven't found a clean way to query Jenkins from within groovy to get the other job's build parameters. Does anybody have a snippet to share?
This works for me in script console
import hudson.model.ParametersAction
def getParams(String project, String buildNumber){
def params=[]
Jenkins.instance.getItem(project).getBuild(buildNumber).getActions(ParametersAction)
.each { action ->
action.getParameters().each {
params << it
}
}
return params
}

Way to change Jenkins' project variable value with script

Is there a way to change project variable values in Jenkins automatically when build is done?
In my case i got a variable VERSION, default value is 1. And i need to increment this default value every build done. Assuming build stars by cron in this case. Any plugins can help me?
Now i have something like this: My build steps.
It is a single working way to get project variable in my groovy script that i found. Now how can i set new value for variable?
I read some similar question on SO, but didn't found a working way for me.
P.S. I can't use $BUILD_NUMBER var, because i need a possibility to set VERSION manually when i start build.
First, of all, install the plugins Global Variable String Parameter Plugin and Groovy Postbuild Plugin. Under Manage Jenkins -> Configure System you should now have a part, called Global Properties. There you add a new variable. In my tests, I called it SOME_VER.
At your job, you now add a Groovy postbuild part with this code adjusted to your variable:
import jenkins.*;
import jenkins.model.*;
import hudson.*;
import hudson.model.*;
import java.lang.*;
instance = Jenkins.getInstance();
globalNodeProperties = instance.getGlobalNodeProperties();
envVarsNodePropertyList = globalNodeProperties.getAll(hudson.slaves.EnvironmentVariablesNodeProperty.class);
envVars = null
if (envVarsNodePropertyList != null && envVarsNodePropertyList.size() > 0)
{
envVars = envVarsNodePropertyList.get(0).getEnvVars()
String value = envVars.get("SOME_VER", "0")
int NEW_VER = Integer.parseInt(value)
NEW_VER = NEW_VER + 1
envVars.override("SOME_VER", NEW_VER.toString());
}
instance.save()
Parts of this code are taken from here. This code does nothing else than retrieving the value of the global variable, change it and save the new value of the variable.

Resources