TLDR;
How to configure jenkins
in a non-interactive way so people can use my shared library without me needing to go click on the approve button for the in-process script.
long story...
I have created a shared Library in Jenkins which looks something like this (simplified version):
def call(body) {
// evaluate the body block, and collect configuration into the object
def pipelineParams= [:]
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = pipelineParams
body()
pipeline { stages { stage { steps { script {
pipelineParams.test()
}
}
This way a user can just call my library like this:
@Library('my-shared-library@master') _
MyPipeline {
test = {
sh "./gradlew test"
}
}
The library is also configured under jenkins/configure.
Trouble is jenkins is alway asking for in-process scrip approval for the signature:
signature : staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods invokeMethod java.lang.Object java.lang.String java.lang.Object
However in the documentation it says that shared-libraries are supposed to be trusted: https://jenkins.io/doc/book/pipeline/shared-libraries/#global-shared-libraries...
This is what I tried:
1. disable in-process script approval completely
this seems impossible: see How can I disable security checks for Jenkins pipeline builds and open jenkins
ticket: https://issues.jenkins-ci.org/browse/JENKINS-28178
2. use Configuration As Code to pre-configure jenkins to allow this specific method
This is currently not yet possible... work seems mostly ready, but still needs to be merged into master as of today: https://github.com/jenkinsci/script-security-plugin/pull/250
3. GET and POST on jenkins/scriptApproval
I used the browser debugger to see what calls were made. A GET on the page got me the correct ID, and then a POST would have sufficed, but since both requests are made separately, the ID changes inbetween, and I get a 404 error...
import requests
id = [line for line in requests.get("http://localhost:8080/scriptApproval/").text.strip().split() if 'makeStaplerProxy' in line][0].split("'")[1]
postUrl = "http://localhost:8080" + id + "/approveSignature"
print(postUrl)
r = requests.post(postUrl)
print(r.status_code)
will give:
http://localhost:8080/$stapler/bound/8488d0c2-9fce-4091-8b9f-747ae0016421/approveSignature
404
4. load library implicitly
I load the library implicitly, and removed the
@Library('my-shared-library@master') _
from the Jenkinsfile. Approval is still required.
out of ideas
I'm quite out of ideas. Normally a shared-pipeline is supposed to be trusted, so I don't really get why he is still asking for approval for these external calls... or am I doing something wrong in the implementation of my shared-library?