How to set Active choice parameter default value as None - jenkins

In Jenkins, Now I'm getting the list of all the available values as List using the Active choice parameter.
I want to get None as the default value but the user can get the list from the dropdown along with None. Is there any way I can add None at the top of the list?
How can I achieve this??
My Groovy script -
// Construct The TypeCast Based On URL Encoder
def gitURL = 'https://test.com/avs-bitbucket/rest/api/1.0/projects/abc/repos?limit=10000'
// Setup Commands
proc1 = ['/bin/bash', '-c', 'rm -rf /product/jenkins/Repo_list'].execute()
proc2 = ['/bin/bash', '-c', 'mkdir -p /product/jenkins/Repo_list'].execute()
proc3 = ['/bin/bash', '-c', "curl -s -k --request GET -H 'Authorization: Bearer test' ${gitURL}"].execute()
proc4 = ['/bin/bash', '-c', "jq '.values|.[]|.name'"].execute()
proc5 = ['/bin/bash', '-c', "sed 's/\"//g'"].execute()
// Execute All The Steps In Unix Pipe Format
all = proc1 | proc2 | proc3 | proc4 |proc5
// Store The Result In A File
String result = all.text
String filename = '/product/jenkins/Repo_list/repo.txt'
boolean success = new File(filename).write(result)
// Call Return List Of The Function
def multiline = 'cat product/jenkins/Repo_list/repo.txt'.execute().text
def list = multiline.readLines()
return list

Related

Jenkins scripted pipeline environment variable

I'm using the Jenkins scripted pipeline and since the last update I get a new warning, which I want to silence, here is an MWE:
// FROM https://jenkins.io/doc/pipeline/examples/#parallel-multiple-nodes
def labels = []
if (Host == 'true') {
labels.add('<host-slavename>')
}
def builders = [:]
for (x in labels) {
def label = x
builders[label] = {
ansiColor('xterm') {
node(label) {
stage('cleanup') {
deleteDir()
}
stage('build') {
def timestamp = sh (script: 'echo -n `(date +%Y%m%d%H%M%S)`', returnStdout: true)
withCredentials([string(credentialsId: 'TEST_PASSWORD', variable: 'PASSWORD')]){
sh """
logger \
TEST_1 "${PASSWORD}" TEST_2 \
TEST_3 $timestamp TEST_4
"""
sh '''
logger \
TEST_1 "$PASSWORD" TEST_2 \
TEST_3 $timestamp TEST_4
'''
}
}
}
}
}
}
parallel builders
the first sh block returns
Warning: A secret was passed to "sh" using Groovy String interpolation, which is insecure.
Affected argument(s) used the following variable(s): [PASSWORD]
See https://jenkins.io/redirect/groovy-string-interpolation for details.
+ logger TEST_1 **** TEST_2 TEST_3 20211029074911 TEST_4
which at least prints the timestamp and the password (it's censored, but works), but raises the warning.
the second sh block returns
+ logger TEST_1 **** TEST_2 TEST_3 TEST_4
So no warning, but also no timestamp.
Is there a way to write a scripted pipeline that shows no warning, but still the timestamp?
The warning occurs when you use Groovy string interpolation in the first sh step like "${PASSWORD}" for the reasons explained in Interpolation of Sensitive Environment Variables.
That's why you should always let the shell resolve environment variables as you correctly do in the 2nd sh step.
To use non-environment variables like timestamp, convert them to environment variables by wrapping the sh step in withEnv step:
withEnv(["timestamp=$timestamp"]) {
sh '''
logger \
TEST_1 "$PASSWORD" TEST_2 \
TEST_3 $timestamp TEST_4
'''
}
This limits the scope of the environment variable to the withEnv block.
Alternatively you could add a member to the env map:
env.timestamp = sh (script: 'echo -n `(date +%Y%m%d%H%M%S)`', returnStdout: true)
sh '''
logger \
TEST_1 "$PASSWORD" TEST_2 \
TEST_3 $timestamp TEST_4
'''

Export of a variable from a bash script

I've got to some variables which will be done with kubenetes command so I thought it best to put these in a bash script. I've managed to do that and called on it and see that variables get created but when it comes out of the bash script they are not assigned.
Within the Jenkinsfile script I have
steps {
sh '''
./bin/kube.sh
echo "Kube2 = ${SCRET}"
.....
and within the kube.sh file I have
#!/bin/bash
export SCRET=`kubectl -n keycloak get secret auser -o yaml | grep password | awk '{print $2}'`
echo "Kube2 = ${SCRET}"
I get the following results
+ ./bin/kube.sh
Kube1 = XXXXXXXX
+ echo 'SCRET = XXXXXXXX'
Kube2 =
Why is it that it gets unset again? What am I missing
Variables set in a subshell evaporate with that shell, and are not exported to the parent.
To set variables in the current environment using a script, you must source the code into the current context.
$: cat x
foo=bar
$: ./x && echo $foo # runs in a subshell - foo ends with ./x
$: . x && echo $foo # runs in current shell - foo is set
bar

Jenkins pass variable out of script section

I'm trying to create a pipeline that creates EC2 instances and I want to execute some shell commands on it.
After the Terraform applies the plan, AWS create new instances:
Build [no info about public IP yet]
Staging [no info about public IP yet]
It's impossible to retrieve public ipv4 information at the plan stage, therefore I created that construction:
stage ('Running command on a Build server') {
steps {
script {
BUILD_INSTANCE_IP = sh (
script: """
aws --region eu-central-1 ec2 describe-instances --filter \
"Name=instance-state-name,Values=running" --query \
"Reservations[*].Instances[*].[PublicIpAddress, Tags[?Key=='Name'].Value|[0]]" \
--output text | grep Build | cut -f1 //retrieve 'Build' instance IP
""", returnStdout: true
).trim()
sleep time: 3, unit: 'MINUTES' // wait 3 minutes until instance will be available to connect
sh ( script: """ssh -i ${AWS_KEY} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ubuntu#${BUILD_INSTANCE_IP} touch /home/ubuntu/test.txt""", returnStdout: true ).trim()
So, here I need to connect to the instance via sshagent {} directive, but after Jenkins moves to a new section, the data of variable 1 is reset to zero.
How do I make a variable that won't change?
I am sure this example will help you, How to use or re-use a variable across the stage throughout the pipeline
def x
node() {
stage('shell') {
x = sh(script: "echo 10", returnStdout: true) as int // needed to convert from String to int
print x // result = 10
}
stage('groovy') {
x = x + 10
print x // result = 20
}
}

How to hide sensitive data from pipeline for sh commands

I have Jenkinsfile that creates mt object and passes vaultToken to psl library:
Jenkinsfile:
#Library('shared-library#psl')
Maintenance mt = new Maintenance()
mt.setVaultToken(config.vaultToken)
mt.setApiUrl(config.apiUrl)
pslService.createMaintenance(mt)
pslService:
String createMaintenance(Maintenance mt){
dockerBuildHelper.getDockerImage(dockerBuildHelper.getWdBuildDockerImageName()).inside('-u root'){
String cmd = "curl -X POST '${mt.getApiUrl()}'" +
" -H 'Content-Type: application/json'" +
" -H 'Authorization: Api-Token ${mt.getVaultToken()}'" +
" -d ${mt.getPayload()} | jq -r '.id'"
return sh(script: cmd, returnStdout: true).trim()
}
}
But this prints curl command and exposes vault token in the pipeline.
Does anyone know how I can hide the sensitive info and/or entire curl command?
I do not want to store this in credentials store, unless I have no choice.
I heard I can use set +x. But I am not sure how to use it and if it helps. Any thoughts?
Try to use mask password plugin. Or create secrets in jenkins and call them in environment block of pipeline.
I went with set +x
String cmd = """set +x
curl -X POST '${mt.getApiUrl()}' -H 'Content-Type: application/json' -H 'Authorization: Api-Token ${mt.getVaultToken()}' -d ${mt.getPayload()} | jq -r '.id'
"""
return sh(script: cmd, returnStdout: true).trim()

How to get curl exit status from sh step command?

I'm trying to get the result of a command into a boolean variable in my Jenkinsfile. The command is: curl -o/dev/null -sfI "$url", which can be used in sh like this:
if ( curl -o/dev/null -sfI "$url" ); then
echo "URL exists"
else
echo "URL does not exist"
fi
So, I need this condition in my jenkinsfile but I don't know how to recreate it. This is what I've tried:
def fileAlreadyExists = sh(
script: "curl -o/dev/null -sfI \"$url\"",
returnStdout: true
)
But seems to return false always.
Your command does not return any output due to -o /dev/null switch. If you want to catch exit code you would have to set returnStatus and not returnStdout option, like:
def fileAlreadyExists = sh(
script: "curl -o/dev/null -sfI \"$url\"",
returnStatus: true
)
Alternatively you could extend your Bash command to do echo $? after the curl command to echo last command exit code:
def fileAlreadyExists = sh(
script: "curl -o/dev/null -sfI \"$url\"; echo \\\$?",
returnStdout: true
) as Integer // explicit casting needed, because it returns String
The variable fileAlreadyExists stores an integer value, so you can use it in if () statement (Groovy evalutes if (0) to false, so if you expect 0 exit code then it is good idea to make this comparison explicit like:
if (fileAlreadyExists == 0) { /* exists */ } else { /* not exist */ }
As a side note: remember to escape \ if you want to pass it to the sh command - Jenkins strips single escape character, so if you want to pass e.g. double quote the underlying script then you have to escape it in the following way: \\\".

Resources