jenkins DSL dynamic parameters - jenkins

This is my configure block to generate dynamic parameters. But it is not working. Can someone help?
configure { project ->
def paramDefs = project / 'properties' / 'hudson.model.ParametersDefinitionProperty' / 'parameterDefinitions'
paramDefs << 'com.seitenbau.jenkins.plugins.dynamicparameter.scriptler.ScriptlerStringParameterDefinition' {
name('BUILD_VERSION')
description('Overall Build version')
__remote(false)
__scriptlerScriptId('**/build_versions.groovy')
}
}

Short answer: Don't use the plugin anymore, just use normal groovy code in combination with the default jenkins parameters
Full answer: Please have a look at this answer https://stackoverflow.com/a/42230455/4486169

The answer to this question didn't help so here is an example with StringParameterDefinition (just replace with sriptler.ScriptlerStringParameterDefinition if you're using the Scriptler alternative), you can find node names by opening a configured job xml:
configure { root ->
def paramDefs = root / 'properties' / 'hudson.model.ParametersDefinitionProperty' / 'parameterDefinitions'
paramDefs << 'com.seitenbau.jenkins.plugins.dynamicparameter.StringParameterDefinition' {
delegate.createNode('name', 'FirstParam')
delegate.createNode('__script', 'someScriptString')
__localBaseDirectory(serialization: 'custom') {
'hudson.FilePath' {
'default' {
delegate.createNode('remote', "${JENKINS_HOME}/dynamic_parameter/classpath")
}
delegate.createNode('boolean', true)
}
}
delegate.createNode('__remoteBaseDirectory', 'dynamic_parameter_classpath')
delegate.createNode('__classPath', '')
}
paramDefs << 'com.seitenbau.jenkins.plugins.dynamicparameter.StringParameterDefinition' {
delegate.createNode('name', 'SecondParam')
delegate.createNode('__script', 'someScriptString')
__localBaseDirectory(serialization: 'custom') {
'hudson.FilePath' {
'default' {
delegate.createNode('remote', "${JENKINS_HOME}/dynamic_parameter/classpath")
}
delegate.createNode('boolean', true)
}
}
delegate.createNode('__remoteBaseDirectory', 'dynamic_parameter_classpath')
delegate.createNode('__classPath', '')
}
...
}

Related

Jenkins Job DSL: unknown return statement

some days ago I bumped into a code snippet used to override the default configuration of the Jenkins plugin "GitHub SCM Source" (unknown author):
Closure configOverride(String repo, int id, String cred) {
return {
it / sources / 'data' / 'jenkins.branch.BranchSource' << {
source(class: 'org.jenkinsci.plugins.github_branch_source.GitHubSCMSource') {
id(id)
scanCredentialsId(cred)
checkoutCredentialsId('SAME')
repoOwner('owner')
repository(repo)
includes('*')
buildOriginBranch('true')
buildOriginBranchWithPR('true')
buildOriginPRMerge('false')
buildOriginPRHead('false')
buildForkPRMerge('true')
buildForkPRHead('false')
}
}
}
}
All it's good except that I can't understand the following line:
it / sources / 'data' / 'jenkins.branch.BranchSource' << { ... }
I tried to find some explanation about the use of '/' in groovy but no luck. Maybe I don't know what exactly to search.
Could someone help me please with a link to the docs or a short explanation.
This is overloading of
operators
Groovy allows you to overload the various operators so that they can be used with your own classes. Consider this simple class:
class Bucket {
int size
Bucket(int size) { this.size = size }
Bucket plus(Bucket other) {
return new Bucket(this.size + other.size)
}
}
Just by implementing the plus() method, the Bucket class can now be used with the + operator like so:
def b1 = new Bucket(4)
def b2 = new Bucket(11)
assert (b1 + b2).size == 15
For / one would override T div(T x)
This code snippet is used in Jenkins DSL for the "multibranchPipelineJob". The closure configOverride is used to generate an XML object which replace the default configuration in config.xml on the following path "sources/data/jenkins.branch.BranchSource".

How to Set multiple credentials using withcredentials in jenkins pipeline groovy file

I need to set two or more credentials to a job, my plan is to use it separately like below, so that it can be used in multiple jobs
static void _artifactoryCredentialBinding(Job job) {
job.with {
wrappers {
credentialsBinding {
usernamePassword('USERNAME', 'PASSWORD', 'xxxxx')
}
}
}
}
static void _jasyptCredentialBinding(Job job) {
return job.with {
wrappers {
credentialsBinding {
usernamePassword('', 'PASSWORD', 'jasypt-credentials')
}
}
}
}
When I do this the first credential is getting over ridden by the second credential.
I will be calling these two methods as a helper method in where ever necessary in my groovy file.
I would require to add multiple credentials in few jobs and only one credential in a job.
Adding the credentials under one wrapper will work - multiple-credentials, but I will not be able to reuse if I add multiple under the same.
I tried returning the Job in the above methods and used the same methods to set the creds but getting the error while building -
ERROR: (CredentialBindingUtil.groovy, line 28) No signature of method: xxxx.CredentialBindingUtil$__pfJasyptCredentialBinding_closure3.wrappers() is applicable for argument types: (xxx.CredentialBindingUtil$__pfJasyptCredentialBinding_closure3$_closure9) values: [xxxx.CredentialBindingUtil$__pfJasyptCredentialBinding_closure3$_closure9#11b4d391]
[Office365connector] No webhooks to notify
How do I make the credentials to be appended with the existing ones ?
As discussed in the comments, it's possible to achieve this through the Configure Block.
static void _artifactoryCredentialBinding(def job) {
job.with {
configure { node ->
node / 'buildWrappers' / 'org.jenkinsci.plugins.credentialsbinding.impl.SecretBuildWrapper' / 'bindings' << 'org.jenkinsci.plugins.credentialsbinding.impl.UsernamePasswordMultiBinding' {
usernameVariable 'some-credential-id'
credentialsId PASS1
passwordVariable USER1
}
}
}
}
static void _jasyptCredentialBinding(def job) {
job.with {
configure { node ->
node / 'buildWrappers' / 'org.jenkinsci.plugins.credentialsbinding.impl.SecretBuildWrapper' / 'bindings' << 'org.jenkinsci.plugins.credentialsbinding.impl.UsernamePasswordMultiBinding' {
usernameVariable 'some-credential-id'
credentialsId PASS2
passwordVariable USER2
}
}
}
}
def a_job = job('a-temporaryjob')
_artifactoryCredentialBinding(a_job)
_jasyptCredentialBinding(a_job)
To understand how the Configure Block works I highly suggest reading the wiki page and an older blog post which explains step by step how to configure an unsupported plugin.

Groovy code works, Then in Jenkins it doesn't. How can I make this work?

I am trying to augment the 'load' pipeline step function and I keep getting an error. I have found the code it executes based on the stack trace but I can't for the life of me figure out why it wouldn't just call the code as written.
I have written lots-and-lots of Java code so I know what it's trying to do. I just don't understand why it's trying to do it or how to convince it to stop! The groovy sample works perfectly! BTW: if there is an idiomatic way to do this in groovy/jenkins, I am all in.
Jenkins version: 2.176.1
Groovy plugin: 2.2
test.groovy
def someFunction(def params){
println("someFunction ${params}")
}
def someFunction2(def params){
println("someFunction2 ${params}")
}
def mainFunc(def stuff){
}
def somemainThingrunFunmain(){
}
def ___cps___21685(){
}
def ___cps___21688(){
}
this
main.groovy
def loaded = evaluate('test.groovy' as File)
def toAugment = loaded.class.declaredMethods*.name.findAll { !(it =~ '^(main|run)$|^[$]|^(___cps___)') }
def proxy = new Script(this.binding) {
#Override
Object run() {
monad.run()
}
}
toAugment.each {
proxy.metaClass."${it}" = { "logging ${it}".tap { println(it)} } >> loaded.&"${it}"
}
proxy.someFunction('hello world1')
proxy.someFunction2('hello world2')
outputs:
called
someFunction hello world1
called
someFunction2 hello world2
Now in Jenkins:
Jenkinsfile:
library 'common-libraries#chb0'
node('java') {
stage('SCM') {
checkout scm
}
def loaded = load('test.groovy')
stage('experiment') {
loaded.someFunction('hello world1')
loaded.someFunction2('hello world2')
}
}
adapted library (in common-library:vars/load.groovy):
def call(String path) {
def loaded = steps.load(path)
def proxy = new Script(this.getBinding()) { // error here
#Override
Object run() {
loaded.run()
}
}
// remove groovy and jenkins generated functions. Don't touch those
def toAugment = loaded.class.declaredMethods*.name.findAll { !(it =~ '^(main|run)$|^[$]|^(___cps___)') }
toAugment.each {
proxy.metaClass."${it}" = { "logging ${it}".tap { println(it) } } >> loaded.&"${it}"
}
}
exception:
groovy.lang.GroovyRuntimeException: Could not find matching constructor for: load$1(load, Script1, groovy.lang.Binding)
at groovy.lang.MetaClassImpl.invokeConstructor(MetaClassImpl.java:1732)
at groovy.lang.MetaClassImpl.invokeConstructor(MetaClassImpl.java:1532)
at org.codehaus.groovy.runtime.callsite.MetaClassConstructorSite.callConstructor(MetaClassConstructorSite.java:49)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:60)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:235)
at com.cloudbees.groovy.cps.sandbox.DefaultInvoker.constructorCall(DefaultInvoker.java:25)

Adding Suppress automatic scm triggering except for named branches in Jenkins Job DSL?

How do I add default Suppress automatic scm triggering except for named branch - development in Job DSL?
I tried docs
https://jenkinsci.github.io/job-dsl-plugin/#path/multibranchPipelineJob . It doesn't say much. Seems like it is not supported.
So I guess my only way is adding custom properties directly to XML via configure block.
What I want:
<strategy class="jenkins.branch.NamedExceptionsBranchPropertyStrategy">
<defaultProperties class="java.util.Arrays$ArrayList">
<a class="jenkins.branch.BranchProperty-array">
<jenkins.branch.NoTriggerBranchProperty/>
</a>
</defaultProperties>
<namedExceptions class="java.util.Arrays$ArrayList">
<a class="jenkins.branch.NamedExceptionsBranchPropertyStrategy$Named-array">
<jenkins.branch.NamedExceptionsBranchPropertyStrategy_-Named>
<props class="empty-list"/>
<name>development</name>
</jenkins.branch.NamedExceptionsBranchPropertyStrategy_-Named>
</a>
</namedExceptions>
</strategy>
What I've tried:
multibranchPipelineJob(jobName) {
branchSources {
git {
remote(gitRepo)
credentialsId(credentials)
includes('*')
configure {
it / "sources class='jenkins.branch.MultiBranchProject$BranchSourceList'" / 'data' / 'jenkins.branch.BranchSource' / "strategy class='jenkins.branch.DefaultBranchPropertyStrategy'" << name('development')
}
}
}
}
This is useful, but keeps crashing http://job-dsl.herokuapp.com/
This is not so useful https://github.com/jenkinsci/job-dsl-plugin/blob/master/docs/The-Configure-Block.md
I have no idea what I'm doing and the docs, manuals and tutorials are not helpful at all.
EDIT:
Now I have this. It works, sort of...
I'm able to generate the job, but Jenkins throws an error when I try to resave the job. The output XML is somehow different.
multibranchPipelineJob(jobName) {
configure {
it / sources(class: 'jenkins.branch.MultiBranchProject$BranchSourceList') / 'data' / 'jenkins.branch.BranchSource' << {
source(class: 'jenkins.plugins.git.GitSCMSource') {
id(randomId)
remote(gitRepo)
credentialsId(credentials)
}
strategy(class: "jenkins.branch.NamedExceptionsBranchPropertyStrategy") {
defaultProperties(class: "java.util.Arrays\$ArrayList") {
a(class: "jenkins.branch.BranchProperty-array") {
'jenkins.branch.NoTriggerBranchProperty'()
}
}
namedExceptions(class: "java.util.Arrays\$ArrayList") {
a(class: "jenkins.branch.NamedExceptionsBranchPropertyStrategy\$Named-array") {
'jenkins.branch.NamedExceptionsBranchPropertyStrategy_-Named'() {
props(class: "empty-list")
name('development')
}
}
}
}
}
}
}
As you might have noticed, it is extremely ugly. Hopefully someone will fix the plugin in the future.
So the code which is working is the following:
UUID uuid = UUID.randomUUID()
println('Random UUID: ' + uuid)
multibranchPipelineJob('test') {
configure {
it / sources / 'data' / 'jenkins.branch.BranchSource' << {
source(class: 'jenkins.plugins.git.GitSCMSource') {
id(uuid)
remote('...')
credentialsId('...')
includes('*')
excludes('')
ignoreOnPushNotifications('false')
traits {
'jenkins.plugins.git.traits.BranchDiscoveryTrait'()
}
}
strategy(class: 'jenkins.branch.NamedExceptionsBranchPropertyStrategy') {
defaultProperties(class: 'empty-list')
namedExceptions(class: 'java.util.Arrays\$ArrayList') {
a(class: 'jenkins.branch.NamedExceptionsBranchPropertyStrategy\$Named-array') {
'jenkins.branch.NamedExceptionsBranchPropertyStrategy_-Named'() {
props(class: 'java.util.Arrays\$ArrayList') {
a(class: 'jenkins.branch.BranchProperty-array') {
'jenkins.branch.NoTriggerBranchProperty'()
}
}
name('master')
}
}
}
}
}
}
}
You can achieve this in two ways
Configuring in UI as explained here, which you said you do not want to do.
Using conditional statements in DSL as explained here

grails kickstart plugin KickstartFilters how to prevent password information on logs

I am using Grails version 2.2.4 and I have installed kickstart plugin as compile ":kickstart-with-bootstrap:0.9.6".
BuildConfig.groovy
plugins {
runtime ":hibernate:$grailsVersion"
runtime ":jquery:1.8.3"
runtime ":resources:1.1.6"
compile ":kickstart-with-bootstrap:0.9.6"
build ":tomcat:$grailsVersion"
runtime ":database-migration:1.3.2"
compile ':cache:1.0.1'
}
I found "KickstartFilters.groovy" filter with following directory structure
plugin
-> kickstart-with-bootstrap:0.9.6
-> conf
-> kickstart
-> KickstartFilters.groovy
my "KickstartFilters.groovy" file contains following information
package kickstart
class KickstartFilters {
def filters = {
all() {
before = {
// Small "logging" filter for controller & actions
log.info(!params.controller ? '/: ' + params : params.controller +"."+(params.action ?: "index")+": "+params)
}
after = {
}
afterView = {
}
}
}
}
while log.info are printed in logs at that time if password is passed as params then password information are visible on log so how can I prevent only password Information?
I have a work around for this...
https://github.com/joergrech/KickstartWithBootstrap/issues/84
Basically create your filter under conf/kickstart/YourAppFilters.groovy
package kickstart
class YourAppFilters extends KickstartFilters {
def filters = {
kickstartLogger() {
before = {
// Small "logging" filter for controller & actions
if (log.infoEnabled) {
if (!params.controller.equals('chat')) {
if (!params.password ) {
log.info(!params.controller ? '/: ' + params : params.controller +"."+(params.action ?: "index")+": "+params)
}else{
log.info (params.controller+","+params.action+":"+params?.username)
}
}
}
}
}
}
}
Now under conf/spring/resources.groovy under beans add:
yourAppFilters(KickstartFilters)
This should now override kickstarts filter

Resources