Unable to see Jenkins Credentials values - jenkins

I'm trying to leverage the Jenkins credentials plugin to store sensitive data which I want to inject into Secrets within my Kubernetes cluster. I have a JenkinsFile which is used in my project to define the steps and I've added the following code to pull a username/password from a credential and pass to shell script to replace a placeholder in a file with the actual file:
stages {
stage('Build') {
steps {
withCredentials([usernamePassword(credentialsId: 'creds-test', passwordVariable: 'PASSWORD', usernameVariable: 'USERNAME')]) {
sh '''
echo $USERNAME
echo $PASSWORD
chmod +x secrets-replace.sh
./secrets-replace.sh USERNAME_PLACEHOLDER $USERNAME
./secrets-replace.sh PASSWORD_PLACEHOLDER $PASSWORD
'''
}
echo 'Building...'
sh './gradlew build --refresh-dependencies'
}
}
...
}
However whenever this runs all I ever get is the masked **** value back, even when I pass it to the shell script. Here is part of the build log:
Is there something I need to configure to get access to the unmasked value?

Write the variable to a file in jenkins. Go to the jenkins workspace and look inside the file. The token will be present in plain text there.
UPDATE
Further easy way will be to print the base64 encoded value of the credential and then decode it.

Like the others added above, you could actually write it to a file and then cat the file outside of the withCredentials. You should be fine with this. As below..
withCredentials([usernamePassword(credentialsId: 'creds-test', passwordVariable: 'PASSWORD', usernameVariable: 'USERNAME')]) {
sh '''
echo $USERNAME > tmp
echo $PASSWORD >> tmp
'''
}
sh 'cat tmp'
This prints the actual credential values

Echoing straight from file didnt work for me so I tricked Jenkins like this to see the secret during debugging: Obviously, remove it right after debugging!
stage('Build') {
azureKeyVault(
credentialID: 'my-sp',
keyVaultURL: 'https://my-kv.vault.azure.net',
secrets: [
[envVariable: 'MY_SECRET', name: 'my-secret-name-in-azure-kv', secretType: 'Secret']
]
) {
sh '''
echo -n $MY_SECRET | base64 > tmpp
cat tmpp
'''
}
}

Consider manipulating the string
echo env.PASSWORD.toCharArray().join(' ');
like
stages {
stage('Build') {
steps {
withCredentials([usernamePassword(credentialsId: 'creds-test', passwordVariable: 'PASSWORD', usernameVariable: 'USERNAME')]) {
script {
echo env.USERNAME.toCharArray().join(' ');
echo env.PASSWORD.toCharArray().join(' ');
}
sh '''
chmod +x secrets-replace.sh
./secrets-replace.sh USERNAME_PLACEHOLDER $USERNAME
./secrets-replace.sh PASSWORD_PLACEHOLDER $PASSWORD
'''
}
echo 'Building...'
sh './gradlew build --refresh-dependencies'
}
}
...
}

Related

How to pass jenkins passwords into ansible playbook via pipeline

How to inject passwords to the build as environment variables(these are job passwords) for deployment through ansible via pipeline or dsl script
First, those job passwords should be registered as credentials inside Jenkins.
Second, you can use said file when calling your ansible-playbook command, through the Credentials Binding plugin.
See "How to use multiple credentials in withCredentials in Jenkins Pipeline"
node {
withCredentials([
usernamePassword(credentialsId: credsId1, usernameVariable: 'USER1', passwordVariable: 'PASS1'),
usernamePassword(credentialsId: credsId2, usernameVariable: 'USER2', passwordVariable: 'PASS2')
...
]) {
sh '''
set +x
ansible-playbook /path/to/ansible-playbook.yml -i /path/to/hosts_list -u AUTO_USER --private-key=/path/to/private-key \
-e $USER1=$PASS1 -e $USER2=$PASS2
'''
}
}
Note: the file should have a JSON content, with your

Some Variables not getting rendered in jenkins pipeline inside single quotes

I am using below code in CASE 1 in my jenkins library , it is able to render the artifactory password and username inside the sh block but not able to render the variable docker_repo , if I replace it with code in CASE 2 it works fine but it is an unsafe practice , Any idea why it is happening ? and how to overcome it ?
CASE 1
def dockerAuth(String creds = 'mysecret',String docker_repo = ARTF_URL) {
withCredentials([usernamePassword(credentialsId: creds,
usernameVariable: 'ARTIFACTORY_USER',
passwordVariable: 'ARTIFACTORY_PASSWORD')]) {
//opts = '-u $ARTIFACTORY_USER -p $ARTIFACTORY_PASSWORD'
sh 'sudo docker login -u $ARTIFACTORY_USER -p $ARTIFACTORY_PASSWORD $docker_repo'
}
}
CASE 2
def dockerAuth(String creds = 'mysecret',String docker_repo = ARTF_URL) {
withCredentials([usernamePassword(credentialsId: creds,
usernameVariable: 'ARTIFACTORY_USER',
passwordVariable: 'ARTIFACTORY_PASSWORD')]) {
//opts = '-u $ARTIFACTORY_USER -p $ARTIFACTORY_PASSWORD'
sh "sudo docker login -u ${ARTIFACTORY_USER} -p ${ARTIFACTORY_PASSWORD} ${docker_repo}"
}
}
I solved it using below code ,
converted docker_repo into a env variable and then used inside single quotes.
Reason for using single quotes in sh is in this link https://docs.cloudbees.com/docs/admin-resources/latest/automating-with-jenkinsfile/string-interpolation
If anyone has a better answer please post
def dockerAuth(String creds = 'jenkins-artifactory',String docker_repo = "${ARTF_SECURE_DOCKER_URL}") {
withCredentials([usernamePassword(credentialsId: creds,
usernameVariable: 'ARTIFACTORY_USER',
passwordVariable: 'ARTIFACTORY_PASSWORD')]) {
withEnv(["repo=${docker_repo}"]) {
sh 'sudo docker login -u $ARTIFACTORY_USER -p $ARTIFACTORY_PASSWORD $repo'
}
}
}
You need "CASE 3", where you use double quotes (as case 2) but escape the dollar on environment variables, but leave it for templating groovy variables
sh "sudo docker login -u \${ARTIFACTORY_USER} -p \${ARTIFACTORY_PASSWORD} ${docker_repo}"
Also you can try this
def dockerAuth(String creds = 'mysecret',String docker_repo = ARTF_URL) {
withCredentials([usernamePassword(credentialsId: creds,
usernameVariable: 'ARTIFACTORY_USER',
passwordVariable: 'ARTIFACTORY_PASSWORD')]) {
//opts = '-u $ARTIFACTORY_USER -p $ARTIFACTORY_PASSWORD'
sh 'sudo docker login -u $ARTIFACTORY_USER -p $ARTIFACTORY_PASSWORD' + " ${docker_repo}"
}
}

how to create global variable inside a stage So that i can use it into the other stage as well in pipeline script

In the below code I am fetching the version inside the script block, but I can not use it in the sh block and even not in the post block. Can someone please help. I am able to print the value in the println function. Variable is generating at the run time so I can not define inside the global environment block of Jenkinsfile. Can someone please help and tell me what am missing here?
stage('test build') {
steps {
script{
version = sh (
script: "cat ${WORKSPACE}/version.txt | grep var | awk -F ':' '{print \$2}'",
returnStdout: true
).trim()
}
println(version)
sh '''
echo "${version}"
'''
}
post {
success {
sh '''
echo "${version}"
'''
}
}
}

wget: command not found in Jenkins Pipeline

in my Mac, wget command working. How to fix this issue?
Error Message
wget
https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip
/Users/don/.jenkins/workspace/demo#tmp/durable-2702e009/script.sh:
line 1: wget: command not found
Full Pipeline Script
node('master') {
def home = sh(script: "echo $ANDROID_HOME",returnStdout: true).trim()
def SDKPath = "$home/Android/sdk"
stage("Preparing SDK"){
// Check SDK Downloaded
def isSDKDownloaded = sh(script: "test -e sdk-tools-linux-4333796.zip && echo true || echo false",returnStdout: true).trim()
if(isSDKDownloaded == "false"){
// Download SDK
sh "wget 'https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip'"
}
// Check if SDK is Extracted
def isExtracted = sh(script: "test -e $SDKPath/tools && echo true || echo false",returnStdout: true).trim()
if(isExtracted == "false"){
sh "mkdir -p $SDKPath"
//Unzip SDK
sh "unzip sdk-tools-linux-4333796.zip -d $SDKPath"
}
// Install SDK Tools
sh "yes | $SDKPath/tools/bin/sdkmanager 'build-tools;28.0.3' 'platform-tools' 'platforms;android-27'"
sh "ls $SDKPath/licenses"
// See installed And Available SDK
sh "$SDKPath/tools/bin/sdkmanager --list"
// Accept All SDK Licences
sh "yes | $SDKPath/tools/bin/sdkmanager --licenses"
}
def selectedBranch = SELECTED_RELEASE_BRANCH
stage('Checkout') {
git branch: selectedBranch, url: 'git#gitlab.com:o-apps/demo.git'
// Remove Existing local properties
sh 'rm local.properties ||:'
// Write sdk.dir Path into local properties file
sh "echo 'sdk.dir=$SDKPath' >> local.properties"
}
stage('Setup Tools') {
withCredentials([file(credentialsId: 'android_keystore', variable: 'KEYFILE')]) {
sh "cp \$KEYFILE app/key.jks"
}
}
stage('Build Release APK') {
sh "./gradlew clean assembleRelease"
}
stage('Upload to Play Store') {
androidApkUpload googleCredentialsId: 'key', apkFilesPattern: '**/*-release.apk', trackName: 'alpha'
}
stage('Cleanup Credential') {
sh "rm app/key.jks"
}
}
This is probably due to the $PATH environment variable which is different between your user and the user running Jenkins. Your user may be altering its $PATH by expanding it in the shell resource file (~/.bashrc, ~/.zshrc).
Not to worry, you can use the full path.
To find out the full path to wget, run this on the machine that runs the pipeline (the one labelled master):
% which wget
/usr/local/bin/wget
(Your path may naturally be different.)
Now use the full path:
// Download SDK
sh "/usr/local/bin/wget 'https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip'"

Access a Groovy variable from within shell step in Jenkins pipeline

Using the Pipeline plugin in Jenkins 2.x, how can I access a Groovy variable that is defined somewhere at stage- or node-level from within a sh step?
Simple example:
node {
stage('Test Stage') {
some_var = 'Hello World' // this is Groovy
echo some_var // printing via Groovy works
sh 'echo $some_var' // printing in shell does not work
}
}
gives the following on the Jenkins output page:
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Test Stage)
[Pipeline] echo
Hello World
[Pipeline] sh
[test] Running shell script
+ echo
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
As one can see, echo in the sh step prints an empty string.
A work-around would be to define the variable in the environment scope via
env.some_var = 'Hello World'
and print it via
sh 'echo ${env.some_var}'
However, this kind of abuses the environmental scope for this task.
To use a templatable string, where variables are substituted into a string, use double quotes.
sh "echo $some_var"
I am adding the comment from #Pedro as an answer because I think it is important.
For sh env vars we must use
sh "echo \$some_var"
You need to do something like below if a bash script is required :
Set this variable at global or local(function) level where from these can be accessible to sh script:
def stageOneWorkSpace = "/path/test1"
def stageTwoWorkSpace = "/path/test2"
In shell script call them like below
sh '''
echo ''' +stageOneWorkSpace+ '''
echo ''' +stageTwoWorkSpace+ '''
cp -r ''' +stageOneWorkSpace+'''/qa/folder1/* ''' +stageOneWorkSpace+'''/qa/folder2
'''
Make sure you start and end sh with three quotes like '''
I would like to add another scenario to this discussion.
I was using shell environment variables and groovy variables in the same script.
format='html'
for file in *.txt;
do mv -- "\$file" "\${file%.txt}.$format";
done
So here, What I have done is use \$ only for shell environment variables and use $ for groovy variables.
This is extension to #Dave Bacher's answer. I'm running multiple shell command in Groovy file & want to use output of one shell command to the next command as groovy variable. Using double quotes in shell command, groovy passes variable from one to another command but using single quotes it does not work, it returns null.
So use shell command like this in double quotes: sh "echo ${FOLDER_NAME}"
FOLDER_NAME = sh(script: $/
awk -F '=' '/CODE_COVERAGE_FOLDER/ {gsub("\"","");print$2}' ${WORKSPACE}/test.cfg
/$, returnStdout: true).trim()
echo "Folder: ${FOLDER_NAME}" // print folder name in groovy console
sh "mkdir -p ${WORKSPACE}/${FOLDER_NAME} && chmod 777 ${WORKSPACE}/${FOLDER_NAME}"

Resources