Groovy Script - Active Choices Jenkins Plugin - variable reference from inside "script:" section - jenkins

I'm using the "Active Choices Jenkins Plugin" in order to realize a pipeline.
I've defined my parameters.
[$class: 'DynamicReferenceParameter',
choiceType: 'ET_FORMATTED_HTML',
description: '_description',
name: '_name',
referencedParameters: '**customer**',
script:
[$class: 'GroovyScript',
script: [
sandbox: true,
script: **MUST INSERT SCRIPT**
]
]
Now i go a pretty big script to be processed, that need to evaluate:
A static variabile defined before execution
def customer_dictionary = [
"customer1": ["a", "b", "c"],
"customer2": ["a", "b", "c", "d"],
]
A runtime variabile passed through the referencedParameters, "customer" ) .
customer.each { service->
html_to_be_rendered += "<tr><td>"
configuration = configuration_dictionary[service]
I've to pass to "script:" a string.
But even if i use string interpolation ( """ script """ ) i can't manage to make him resolve this reference ( configuration_dictionary[service] ).
Someone can help me?
Thx

Related

Accessing global variables from an Active Choice parameter's script block in a declarative pipeline

I have the following code in my Jenkinsfile:
def testList = ['a','b','c']
properties([[
[$class: 'CascadeChoiceParameter',
choiceType: 'PT_SINGLE_SELECT',
description: 'Some description',
filterLength: 1,
filterable: true,
name: 'TestParameter',
randomName: 'choice-parameter-47114921421532360',
script: [
$class: 'GroovyScript',
fallbackScript: [
classpath: [],
sandbox: false,
script: 'return [\'ERROR\']'
],
script: [
classpath: [],
sandbox: false,
script: 'return testList'
]
]]
]])
How can I get the value of testList to the script block here without string interpolation?
I do not want to use string interpolation because in production, testList will be dynamically populated. This has the nasty side effect of having to reapprove the script block in Jenkins via Script Approval every time testList is modified. I also do not want to expose an additional parameter to the user here (I could use a Choice parameter to get testList and then use "param.myChoiceParameter" to get the Active Choice working). And finally, I don't know if it would solve my issue, but I don't want the effort of creating a shared library at this time.
Things I've tried and either didn't work or had side effects.
String interpolation with inspect ("return $testList.Inspect()}" in the script block)
Adding #field to testList
Some other SO question said to add an ArrayList object to Parameters, which throws an an exception saying an ArrayList type is not recognized as a parameter type.

Export build parameters into shared library

This is an example of my Jenkinsfile:
properties([
parameters([
booleanParam(defaultValue: false, name: 'BuildAll', description: ''),
// lots of params here, some of them are Active Choice Plugin params...
])
])
pipeline {
agent any
stages {
stage ('Initialize') {
// code...
}
}
}
Now, is it posslible to export those parameters (that are enclosed inside "properties" section) into shared library?
Jenkins shared library: https://www.jenkins.io/doc/book/pipeline/shared-libraries/
I have lots of params and many similar projects and I would like simply to define parameters on one place and include them everywhere (DRY).
create deriveJobParams.groovy in vars folder with following code in shared library project.
def call() {
properties([
parameters([
booleanParam(defaultValue: false, name: 'BuildAll', description: ''),
[$class: 'ChoiceParameter', choiceType: 'PT_CHECKBOX',
description: 'Choose environment category.',
name: 'ENVIRONMENT',
script: [
$class: 'GroovyScript',
script: [sandbox: true, script: 'return ["QA", "DEV", "PROD"]']
]
]
])
])
}
In job Jenkinsfile, import the share library and call deriveJobParams()
#Library('my-library#branch or tag') _
// call deriveJobParams at beginning
deriveJobParams()
pipeline {
stages {
}
}

Accessing jenkins env params from inside a GroovyScript in properties

I have a jenkins job:
properties([
parameters([
[$class: 'ChoiceParameter', choiceType: 'PT_CHECKBOX', description: '''The name of the image to be used.''', filterLength: 1, filterable: true, name: 'OS', randomName: 'choice-parameter-15413073438404172', script: [$class: 'GroovyScript', fallbackScript: [classpath: [], sandbox: true, script: ''], script: [classpath: [], sandbox: true, script: '''templates = [
"BB-Win7-x32-SP1",
"BB-Win7-x64-SP1",
"BB-Win10-x64-RS1",
"BB-Win10-x64-RS2",
"BB-Win10-x32-RS5"]
return templates''']]]])
])
....
....
Which is working and generates the checkbox property for the GUI as expected.
Now, I want to generate those options dynamically, based on a file in my workspace. For this, I need the workspace environment variable inside the groovy script. How can I do that?
Jenkins needs to figure out all the parameters before it runs a pipeline. So your problem, basically, boils down to "How can I run an (arbitrary) groovy script before I run a pipeline?"
There are two options for this:
As I mentioned, ActiveChoice plugin allows you to define a parameter that returns a script. Jenkins will then run the script (don't forget to approve it) in order to show you your "Build with parameters" page. Debugging this is notoriously hard, but this can go to great lengths.
Alternatively, you may want to run a scripted pipeline before you run the Declarative (main) one, as outlined e.g. in this answer. This may look a bit like this:
def my_choices_list = []
node('master') {
stage('prepare choices') {
// read the file contents
def my_choices = sh script: "cat ${WORKSPACE}/file.txt", returnStdout:true
// make a list out of it - I haven't tested this!
my_choices_list = my_choices.trim().split("\n")
}
}
pipeline {
parameters {
choiceParam('OPTION', my_choices_list)

Required $class definition for all the Jenkins parameters

How do I get to know all the $class definitions for all the parameters available in the Jenkins.
For an example, I have $class definitions for NodeParameter & String Parameter. Likewise, I want for all the available Jenkins parameters. Pls do share.
[
$class: 'NodeParameterValue', name: 'HOST', labels: ["${env.HOSTNAME}"], nodeEligibility: [$class: 'AllNodeEligibility']
],
[
$class: 'StringParameterValue', name: 'RELEASE_VERSION', value: "main" ],

How to send referencedParameters value in Jenkins pipeline for CascadeChoiceParameter to ScriptlerScript

I'm declaring 2 parameters in properties section of a Jenkins pipeline:
a data center (can have multiple environment types)
an environment type
The data center is of type ChoiceParameter; the list is retrieved from a database; when the data center changes in the drop-down list, the environment types should populate accordingly, also from the database, through a ScriptlerScript.
The problem is that when changing selection on data center, nothing happens for environment types list, which is a CascadeChoiceParameter with referencedParameters: 'DataCenter'.
How should I link the referenced parameter to the scriptlet script I'm using - what do I have to send ?
The issue is with [name:'DataCenter', value: '$DataCenter'] for second parameter - the value is not sent to the ScriptletScript when first drop-down value changes.
If I define the 2 parameters from the Jenkins interface - so not through the DSL pipeline - under Configure section, everything works as expected.
It's not working for me to use something other than properties section - I've tried using activeChoiceParameter inside pipeline section, but I get an error 'Build parameters definitions cannot have blocks # line (...)', which is a known issue (see first example link below).
Examples I've used:
Jenkinsfile Active Choice Parameter
Active Choices Reactive Reference Parameter in jenkins pipeline
properties([
parameters([
[
$class: 'ChoiceParameter',
choiceType: 'PT_SINGLE_SELECT',
name: 'DataCenter',
script: [
$class: 'ScriptlerScript',
scriptlerScriptId:'getdatacenters.groovy',
parameters: [
[name:'StatusId', value:'']
]
]
],
[
$class: 'CascadeChoiceParameter',
choiceType: 'PT_SINGLE_SELECT',
name: 'EnvironmentType',
script: [
$class: 'ScriptlerScript',
scriptlerScriptId:'getenvtypesbydatacenter.groovy',
referencedParameters: 'DataCenter',
parameters: [
[name:'DataCenter', value: '$DataCenter']
]
]
]
])
])
pipeline {
...
Expected result: Second drop-down list populates when data center changes
Actual result: Nothing happens when data center changes
Pipeline with params configured in UI - behaves ok (environment types loading on data center change):
One thing to keep in mind: Scriptlers are not secure, you should not use them: https://wiki.jenkins.io/display/JENKINS/Scriptler+Plugin !.
That being said, if you still want to go on and use Scriptler plugin and CascadeChoiceParameter, the code might look like this:
properties([
parameters([
[
$class: 'ChoiceParameter',
choiceType: 'PT_SINGLE_SELECT',
name: 'DataCenter',
randomName: 'datacenter-choice-parameter-102102304304506506',
script: [
$class: 'ScriptlerScript',
scriptlerScriptId:'getdatacenters.groovy',
fallbackScript: [ classpath: [], script: 'return ["N/A"]']
]
],
[
$class: 'CascadeChoiceParameter',
choiceType: 'PT_SINGLE_SELECT',
name: 'EnvironmentType',
randomName: 'envtype-choice-parameter-101012020230303404',
referencedParameters: 'DataCenter',
script: [
$class: 'ScriptlerScript',
scriptlerScriptId:'getenvtypesbydatacenter.groovy',
fallbackScript: [ classpath: [], script: 'return ["N/A"]'],
]
]
])
])
The groovy code for getdatacenters.groovy for demo purposes is (but might be retrieved from a DB, as an alternative):
return["Dev","Prod"]
The groovy code for getenvtypesbydatacenter.groovy might look like this:
import groovy.sql.Sql
import jenkins.model.*
nodes = Jenkins.instance.globalNodeProperties
nodes.getAll(hudson.slaves.EnvironmentVariablesNodeProperty.class)
sql = Sql.newInstance("jdbc:sqlserver://SQLServerHere;connectionDataHere", "com.microsoft.sqlserver.jdbc.SQLServerDriver")
envTypes = sql.rows("exec [DbHere].[schema].[GetEnvTypes] #DataCenter = $DataCenter").collect({ query -> query.EnvTypeName})
envTypes.add(0,'')
return envTypes
The most important thing to note here is that referencedParameters: 'DataCenter' was not inside the script block, but at the "root" level. If you need more parameters, you can separate them with comma.
Because DataCenter is a referenced parameter and automatically transmitted to the scriptler, $DataCenter variable from inside the SQL query will be mapped with its value. As a note, DataCenter should be added as parameter of the scriptler, in the UI Parameters section.
Credits for the solution go to CloudBees.

Resources