Jenkins pipeline credentials for all stages - jenkins-pipeline

I have Jenkins scripted pipeline with multiple stages, all of the stages require the same password for interaction with third-party API.
node {
stage ('stage1') {
sh 'curl --user login:password http://trird-party-api'
}
stage ('stage2') {
sh 'curl --user login:password http://trird-party-api'
}
}
For obvious reasons I want to keep this password safe, e.g. in Jenkins credentials.
The only secure way I've found is to add withCredentials section, but it must be added to each pipeline stage, e.g:
node {
stage ('stage1') {
withCredentials([string(credentialsId: '02647301-e655-4858-a7fb-26b106a81458', variable: 'mypwd')]) {
sh 'curl --user login:$mypwd http://trird-party-api'
}
}
stage ('stage2') {
withCredentials([string(credentialsId: '02647301-e655-4858-a7fb-26b106a81458', variable: 'mypwd')]) {
sh 'curl --user login:$mypwd http://trird-party-api'
}
}
}
This approach is not OK because real pipeline is really complicated.
Any alternatives?

According to this other stackoverflow question and this tutorial, you should be able to specify the needed credentials in a declarative pipeline like so:
environment {
AUTH = credentials('02647301-e655-4858-a7fb-26b106a81458')
}
stages {
stage('stage1') {
sh 'curl --user $AUTH_USR:$AUTH_PSW http://third-party-api'
}
stage('stage2') {
sh 'curl --user $AUTH_USR:$AUTH_PSW http://third-party-api'
}
With a scripted pipeline, you're pretty much relegated to using withCredentials around the things you want to have access to them. Have you tried surrounding the stages with the credentials, as in:
node {
withCredentials([string(credentialsId: '02647301-e655-4858-a7fb-26b106a81458', variable: 'mypwd')]) {
stage ('stage1') {
sh 'curl --user login:password http://trird-party-api'
}
stage ('stage2') {
sh 'curl --user login:password http://trird-party-api'
}
}
}

Related

Pass a value to a shell script from jenkins pipeline

How to pass values to a shell script from jenkins during the runtime of the pipeline job.
I have a shell script and want to pass the values dynamically.
#!/usr/bin/env bash
....
/some code
....
export USER="" // <--- want to pass this value from pipeline
export password="" //<---possibly as a secret
The jenkins pipeline executes the above shell script
node('abc'){
stage('build'){
sh "cd .."
sh "./script.sh"
}
}
You can do something like the following:
pipeline {
agent any
environment {
USER_PASS_CREDS = credentials('user-pass')
}
stages {
stage('build') {
steps {
sh "cd .."
sh('./script.sh ${USER_PASS_CREDS_USR} ${USER_PASS_CREDS_PSW}')
}
}
}
}
The credentials is from using the Credentials API and Credentials plugin. Your other option is Credentials Binding plugin where it allows you to include credentials as part of a build step:
stage('build with creds') {
steps {
withCredentials([usernamePassword(credentialsId: 'user-pass', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
// available as an env variable, but will be masked if you try to print it out any which way
// note: single quotes prevent Groovy interpolation; expansion is by Bourne Shell, which is what you want
sh 'echo $PASSWORD'
// also available as a Groovy variable
echo USERNAME
// or inside double quotes for string interpolation
echo "username is $USERNAME"
sh('./script.sh $USERNAME $PASSWORD')
}
}
}
Hopefully this helps.

Jenkins/ MacOS - dial unix /var/run/docker.sock: connect:permission denied

i am new to using jenkins and docker. Currently I ran into an error where my jenkinsfile doesnt have permission to docker.sock. Is there a way to fix this? Dried out of ideas
things i've tried:
-sudo usermod -aG docker $USER //usermod not found
-sudo setfacl --modify user:******:rw /var/run/docker.sock //setfacl not found
-chmod 777 /var/run/docker.sock //still receiving this error after reboot
-chown -R jenkins:jenkins /var/run/docker.sock //changing ownership of '/var/run/docker.sock': Operation not permitted
error image:
def gv
pipeline {
agent any
environment {
CI = 'true'
VERSION = "$BUILD_NUMBER"
PROJECT = "foodcore"
IMAGE = "$PROJECT:$VERSION"
}
tools {
nodejs "node"
'org.jenkinsci.plugins.docker.commons.tools.DockerTool' 'docker'
}
parameters {
choice(name: 'VERSION', choices: ['1.1.0', '1.2.0', '1.3.0'], description: '')
booleanParam(name: 'executeTests', defaultValue: true, description: '')
}
stages {
stage("init") {
steps {
script {
gv = load "script.groovy"
CODE_CHANGES = gv.getGitChanges()
}
}
}
stage("build frontend") {
steps {
dir("client") {
sh 'npm install'
echo 'building client'
}
}
}
stage("build backend") {
steps {
dir("server") {
sh 'npm install'
echo 'building server...'
}
}
}
stage("build docker image") {
steps {
sh 'docker build -t $IMAGE .'
}
}
// stage("deploy") {
// steps {
// script {
// docker.withRegistry(ECURL, ECRCRED) {
// docker.image(IMAGE).push()
// }
// }
// }
// }
}
// post {
// always {
// sh "docker rmi $IMAGE | true"
// }
// }
}
docker.sock permissions will be lost if you restart system or docker service.
To make it persistence setup a cron to change ownership after each reboot
#reboot chmod 777 /var/run/docker.sock
and When you restart the docker, make sure to run the below command
chmod 777 /var/run/docker.sock
Or you can put a cron for it also, which will execute in each every 5 minutes.

Unable to print credentials set in Jenkins Pipeline

Credentials are configured in Jenkins but there's an error suggesting they are not.
I've followed documentation provided by Jenkins website.
agent {
node {
label 'master'
}
}
environment {
AWS_ACCESS_KEY_ID = credentials('jenkins-aws-secret-key-id')
AWS_SECRET_ACCESS_KEY = credentials('jenkins-aws-secret-access-key')
}
stages {
stage('checkout') {
steps {
git(url: 'git#bitbucket.org:user/bitbucketdemo.git', branch: 'master', credentialsId: 'jenkins')
echo 'hello'
}
}
stage('packer') {
steps {
echo $AWS_ACCESS_KEY_ID
}
}
}
}```
It should print out the value of the environment variable
I used the Cloudbees AWS Credentials plugin. Once installed, I was able to add my AWS credentials (additional selection in Credentials pull-down menu)
enter image description here
Then use the following snippet in my Jenkinsfile
withCredentials(
[[
$class: 'AmazonWebServicesCredentialsBinding',
accessKeyVariable: 'AWS_ACCESS_KEY_ID',
credentialsId: 'AWS',
secretKeyVariable: 'AWS_SECRET_ACCESS_KEY'
]]) {
sh 'packer build -var aws_access_key=${AWS_ACCESS_KEY_ID} -var aws_secret_key=${AWS_SECRET_ACCESS_KEY} example4.json'
}

jenkins pipeline using gcloud is not working

I'm trying to set up jenkins pipeline using gcloud but I'm getting the following error:
gcloud auth activate-service-account --key-file
./service-account-creds.json WARNING: Could not setup log file in
/.config/gcloud/logs, (Error: Could not create directory
[/.config/gcloud/logs/2019.02.07]: Permission denied.
the code:
stages {
stage('build') {
steps {
withCredentials([file(credentialsId: 'google-container-registry', variable: 'GOOGLE_AUTH')]) {
script {
docker.image('google/cloud-sdk:latest').inside {
sh "echo ${GOOGLE_AUTH} > gcp-key.json"
sh 'gcloud auth activate-service-account --key-file ./service-account-creds.json'
}
}
}
}
}
}
Jenkins is running in a container using the imagen jenkins/jenkins
Try this:
withCredentials([file(credentialsId: 'google-container-registry', variable: 'GOOGLE_AUTH')]) {
script {
docker.image('google/cloud-sdk:latest').inside {
sh "echo ${GOOGLE_AUTH} > gcp-key.json"
sh "gcloud auth activate-service-account --key-file=${GOOGLE_AUTH}"
}
}
}

How to re-use pre process jenkins/groovy in each test

Im using the following code to run our voter , currently I’ve one target which is called Run Tests
Which use exactly the same steps as the last (lint) , currently I duplicate it which I think is not a good solution ,
Is there is nice way to avoid this duplication and done it only once as per-requisite process ?
I need all the steps until the cd to the project
The only difference is one target I run
go test ...
and the second
go lint
All steps before are equal
#!/usr/bin/env groovy
try {
parallel(
'Run Tests': {
node {
//————————Here we start
checkout scm
def dockerImage = 'docker.company:50001/crt/deg:0.1.3-09’
setupPipelineEnvironment script: this,
measureDuration(script: this, measurementName: 'build') {
executeDocker(dockerImage: dockerImage, dockerWorkspace: '/go/src') {
sh """
mkdir -p /go/src/github.com/ftr/myGoProj
cp -R $WORKSPACE/* /go/src/github.com/ftr/MyGoProj
cd /go/src/github.com/ftr/MyGoProj
//————————Here we finish and TEST
go test -v ./...
"""
}
}
}
},
‘Lint’: {
node {
//————————Here we start
checkout scm
def dockerImage = 'docker.company:50001/crt/deg:0.1.3-09’
setupPipelineEnvironment script: this,
measureDuration(script: this, measurementName: 'build') {
executeDocker(dockerImage: dockerImage, dockerWorkspace: '/go/src') {
sh """
mkdir -p /go/src/github.com/ftr/myGoProj
cp -R $WORKSPACE/* /go/src/github.com/ftr/MyGoProj
cd /go/src/github.com/ftr/MyGoProj
//————————Here we finish and LINT
go lint
"""
}
}
)
}
}
}
You can use function and pass Go arguments:
try {
parallel(
'Run Tests': {
node {
checkout scm
runTestsInDocker('test -v ./...')
}
},
'Lint': {
node {
checkout scm
runTestsInDocker('lint')
}
}
)
}
def runTestsInDocker(goArgs) {
def dockerImage = 'docker.company:50001/crt/deg:0.1.3-09'
setupPipelineEnvironment script: this,
measureDuration(script: this, measurementName: 'build') {
executeDocker(dockerImage: dockerImage, dockerWorkspace: '/go/src') {
sh """
mkdir -p /go/src/github.com/ftr/myGoProj
cp -R $WORKSPACE/* /go/src/github.com/ftr/MyGoProj
cd /go/src/github.com/ftr/MyGoProj
go ${goArgs}
"""
}
}
}
Update
If some actions can be separated out of runTestsInDocker they probably should be.
For example setupPipelineEnvironment step. I don't know exact logic but maybe it can be run once before running test.
node {
stage('setup') {
setupPipelineEnvironment script: this
}
stage ('Tests') {
parallel(
'Run Tests': {
node {
checkout scm
runTestsInDocker('test -v ./...')
}
},
'Lint': {
node {
checkout scm
runTestsInDocker('lint')
}
}
)
}
}
def runTestsInDocker(goArgs) {
def dockerImage = 'docker.company:50001/crt/deg:0.1.3-09'
measureDuration(script: this, measurementName: 'build') {
executeDocker(dockerImage: dockerImage, dockerWorkspace: '/go/src') {
sh """
mkdir -p /go/src/github.com/ftr/myGoProj
cp -R $WORKSPACE/* /go/src/github.com/ftr/MyGoProj
cd /go/src/github.com/ftr/MyGoProj
go ${goArgs}
"""
}
}
}
Note
If you are running parallel on remote agents you must remember that setup performed on master may be not aviailable on remote slave.

Resources