Some Variables not getting rendered in jenkins pipeline inside single quotes - jenkins

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}"
}
}

Related

Jenkins - "sh" splits my command and tries to execute it separatly

I am trying to run a linux command in a jenkins pipeline using sh, but for some reason my command get's spited in 2 and tries to execute them sparely.
The result of the pipeline is:
curl --insecure -u ':' --upload-file ./file.ear
curl: no URL specified!
Please see the image.
pipeline {
agent any
stages {
stage('use curl'){
steps{
script{
withCredentials([
usernamePassword(credentialsId: 'CREDENTIALS', usernameVariable: 'USER', passwordVariable: 'PWD')
]) {
sh(script:"curl --insecure -u ${USER}:${PWD} --upload-file ./" + Artifact + " " + REPO_URL + Artifact.substring(0, Artifact.length() - 5) + "/", returnStdout: false)
} //withCredentials
} // scripts
} //steps
} //stage
}
}
Using Artifact.trim() did not fix it. But using Artrifact.substring(0, Artifact.length() - 1) instead did the trick.

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

How To Auto-Tag A Docker Image with Git Commit Hash through a Jenkinsfile Pipeline

So I have a Jenkins instance that I need to automatically tag a Docker Image with using a Jenkinsfile Pipeline that automatically tags the image with the commit hash and then pushes it to the Docker Repository. Jenkins is configured correctly, but my pipeline is still failing. At first, I tried using the following command, which returns the current commit hash of my repository.
git rev-parse --short=10 HEAD
Then I noticed this was returning more than one line, so I started using this:
git rev-parse --short=10 HEAD | tail -n +2
Which returns a commit hash similar to this:
338fcaa318b17c40dacf81dcf7a5826e3e3f0160
My goal is to tag my docker images with this hash using a Jenkinsfile:
pipeline {
agent any
environment {
tag = sh(returnStdout: true, script: "git rev-parse -short=10 HEAD | tail -n +2")
}
stages {
stage('Build core lodestone image') {
steps {
// TODO: proper tagging
sh "docker build -f Dockerfile.lodestone -t mirantiseng/lodestone:${var.tag} ."
withCredentials([usernamePassword(credentialsId: 'common-dockerhub-up', usernameVariable: 'HUB_USER', passwordVariable: 'HUB_PASS')]) {
sh "docker login -u ${HUB_USER} -p ${HUB_PASS} && docker push mirantiseng/lodestone:${var.tag}"
}
}
}
stage('Build core lodestone-comment image') {
steps {
// TODO: proper tagging
sh "docker build -f Dockerfile -t mirantiseng/lodestone-comment:${var.tag} ."
withCredentials([usernamePassword(credentialsId: 'common-dockerhub-up', usernameVariable: 'HUB_USER', passwordVariable: 'HUB_PASS')]) {
sh "docker login -u ${HUB_USER} -p ${HUB_PASS} && docker push mirantiseng/lodestone-comment:${var.tag}"
}
}
}
stage('Build core lodestone-mover image') {
steps {
// TODO: proper tagging
sh "docker build -f Dockerfile.mover -t mirantiseng/lodestone-mover:${var.tag} ."
withCredentials([usernamePassword(credentialsId: 'common-dockerhub-up', usernameVariable: 'HUB_USER', passwordVariable: 'HUB_PASS')]) {
sh "docker login -u ${HUB_USER} -p ${HUB_PASS} && docker push mirantiseng/lodestone-mover:${var.tag}"
}
}
}
}
}
The build works if I take out the :${var.tag} and the following block, but it just pushes latest. This leaves the working file looking like this:
pipeline {
agent any
stages {
stage('Build core lodestone image') {
steps {
// TODO: proper tagging
sh "docker build -f Dockerfile.lodestone -t mirantiseng/lodestone ."
withCredentials([usernamePassword(credentialsId: 'common-dockerhub-up', usernameVariable: 'HUB_USER', passwordVariable: 'HUB_PASS')]) {
sh "docker login -u ${HUB_USER} -p ${HUB_PASS} && docker push mirantiseng/lodestone"
}
}
}
stage('Build core lodestone-comment image') {
steps {
// TODO: proper tagging
sh "docker build -f Dockerfile -t mirantiseng/lodestone-comment ."
withCredentials([usernamePassword(credentialsId: 'common-dockerhub-up', usernameVariable: 'HUB_USER', passwordVariable: 'HUB_PASS')]) {
sh "docker login -u ${HUB_USER} -p ${HUB_PASS} && docker push mirantiseng/lodestone-comment"
}
}
}
stage('Build core lodestone-mover image') {
steps {
// TODO: proper tagging
sh "docker build -f Dockerfile.mover -t mirantiseng/lodestone-mover ."
withCredentials([usernamePassword(credentialsId: 'common-dockerhub-up', usernameVariable: 'HUB_USER', passwordVariable: 'HUB_PASS')]) {
sh "docker login -u ${HUB_USER} -p ${HUB_PASS} && docker push mirantiseng/lodestone-mover"
}
}
}
}
}
But I need the docker images to be tagged. I read up on the Jenkinsfile and it said I could make an environmental variable using environment {<something>} to set global variables. I have a variable called tag that I would like to implement that tags the docker images with the commit hash. How can I accomplish this?
You could have used is just $GIT_COMMIT like this
sh "docker build -f Dockerfile.mover -t mirantiseng/lodestone-mover:${GIT_COMMIT} ."
So all I had to do was change the way tag was defined:
pipeline {
agent any
environment {
tag = sh(returnStdout: true, script: "git rev-parse --short=10 HEAD").trim()
}
stages {
stage('Build core lodestone image') {
steps {
// TODO: proper tagging
sh "docker build -f Dockerfile.lodestone -t mirantiseng/lodestone:${tag} ."
withCredentials([usernamePassword(credentialsId: 'common-dockerhub-up', usernameVariable: 'HUB_USER', passwordVariable: 'HUB_PASS')]) {
sh "docker login -u ${HUB_USER} -p ${HUB_PASS} && docker push mirantiseng/lodestone:${tag}"
}
}
}
stage('Build core lodestone-comment image') {
steps {
// TODO: proper tagging
sh "docker build -f Dockerfile -t mirantiseng/lodestone-comment:${tag} ."
withCredentials([usernamePassword(credentialsId: 'common-dockerhub-up', usernameVariable: 'HUB_USER', passwordVariable: 'HUB_PASS')]) {
sh "docker login -u ${HUB_USER} -p ${HUB_PASS} && docker push mirantiseng/lodestone-comment:${tag}"
}
}
}
stage('Build core lodestone-mover image') {
steps {
// TODO: proper tagging
sh "docker build -f Dockerfile.mover -t mirantiseng/lodestone-mover:${tag} ."
withCredentials([usernamePassword(credentialsId: 'common-dockerhub-up', usernameVariable: 'HUB_USER', passwordVariable: 'HUB_PASS')]) {
sh "docker login -u ${HUB_USER} -p ${HUB_PASS} && docker push mirantiseng/lodestone-mover:${tag}"
}
}
}
}
}
The main change was this
tag = sh(returnStdout: true, script: "git rev-parse --short=10 HEAD").trim()`

Unable to see Jenkins Credentials values

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'
}
}
...
}

How to get username password stored in Jenkins credentials separately in jenkinsfile

I've stored username and password as credentials in jenkins. Now I would like to use them in my Jenkinsfile.
I am using withCredentials DSL, however, I'm not sure how to get the username password as separate variables so I can use them in my command.
This is what I'm doing:
withCredentials([usernameColonPassword(credentialsId: 'mycreds', variable: 'MYCREDS')]) {
sh 'cf login some.awesome.url -u <user> -p password'
}
How can I the username and passwork separately? I tried doing ${MYCREDS.split(":")[0]} but that doesn't seem to work.
Here is a tiny bit simpler version of StephenKing's answer
withCredentials([usernamePassword(credentialsId: 'mycreds', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
sh 'cf login some.awesome.url -u $USERNAME -p $PASSWORD'
}
You can use the UsernamePasswordMultiBinding to get credential data in separate values:
withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId:'mycreds',
usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD']
])
So the following should work in your case:
withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId:'mycreds', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD']]) {
sh 'cf login some.awesome.url -u $USERNAME -p $PASSWORD'
}

Resources