Search code examples
jenkinsgroovyjenkins-pipeline

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):

screenshot


Solution

  • 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.