Skip to content

Instantly share code, notes, and snippets.

@InfoSec812
Last active July 25, 2023 21:20
Show Gist options
  • Save InfoSec812/079f80147bcc34f0a9544e1d5567a05c to your computer and use it in GitHub Desktop.
Save InfoSec812/079f80147bcc34f0a9544e1d5567a05c to your computer and use it in GitHub Desktop.
A script which can configure global pipeline libraries in Jenkins using configmaps from Kubernetes/OpenShift
import groovy.json.JsonSlurper
import groovy.json.JsonOutput
import jenkins.plugins.git.GitSCMSource
import jenkins.plugins.git.traits.BranchDiscoveryTrait
import org.jenkinsci.plugins.workflow.libs.GlobalLibraries
import org.jenkinsci.plugins.workflow.libs.LibraryConfiguration
import org.jenkinsci.plugins.workflow.libs.SCMSourceRetriever
import net.sf.json.JSONObject
/*
Attempt to load ConfigMap objects labeled with "jenkins.io/pipeline-library" in the format of:
data:
allowVersionOverride: 'false'
defaultVersion: v1.5
implicit: 'true'
includeInChangesets: 'true'
scm: 'https://github.com/redhat-cop/pipeline-library.git'
*/
def token = new File("/run/secrets/kubernetes.io/serviceaccount/token").text.trim()
def namespace = new File("/run/secrets/kubernetes.io/serviceaccount/namespace").text.trim()
def k8sMaster = System.env.KUBERNETES_MASTER
def caCert = "/run/secrets/kubernetes.io/serviceaccount/ca.crt"
def apiPath = "/api/v1/namespaces/${namespace}/configmaps"
def labelSelector = java.net.URLEncoder.encode("jenkins.io/pipeline-library==true")
def queryParams = "?labelSelector=${labelSelector}"
def command = [
"curl",
"--cacert",
"${caCert}",
"${k8sMaster}${apiPath}${queryParams}",
"-H",
"Authorization: Bearer ${token}",
]
def sout = new StringBuilder()
def serr = new StringBuilder()
def proc = command.execute()
proc.consumeProcessOutput(sout, serr)
proc.waitForOrKill(5000)
def parser = new JsonSlurper()
def data = parser.parseText(sout.toString())
def pipelineLibraries = [] as HashMap
data.items.each {
def pipelineLibrary = [
defaultVersion: it.data.defaultVersion,
implicit: it.data.implicit,
allowVersionOveride: it.data.allowVersionOverride,
includeInChangesets: it.data.includeInChangesets,
scm: [
remote: it.data.scm
]
]
pipelineLibraries.put(it.metadata.name, pipelineLibrary)
}
/**
Function to compare if the two global shared libraries are equal.
*/
boolean isLibrariesEqual(List lib1, List lib2) {
//compare returns true or false
lib1.size() == lib2.size() &&
!(
false in [lib1, lib2].transpose().collect { l1, l2 ->
def s1 = l1.retriever.scm
def s2 = l2.retriever.scm
l1.retriever.class == l2.retriever.class &&
l1.name == l2.name &&
l1.defaultVersion == l2.defaultVersion &&
l1.implicit == l2.implicit &&
l1.allowVersionOverride == l2.allowVersionOverride &&
l1.includeInChangesets == l2.includeInChangesets &&
s1.remote == s2.remote &&
s1.credentialsId == s2.credentialsId &&
s1.traits.size() == s2.traits.size() &&
!(
false in [s1.traits, s2.traits].transpose().collect { t1, t2 ->
t1.class == t2.class
}
)
}
)
}
if(!binding.hasVariable('pipeline_shared_libraries')) {
pipeline_shared_libraries = [:]
}
if(!pipeline_shared_libraries in Map) {
throw new Exception("pipeline_shared_libraries must be an instance of Map but instead is instance of: ${pipeline_shared_libraries.getClass()}")
}
pipeline_shared_libraries = pipeline_shared_libraries as JSONObject
List libraries = [] as ArrayList
pipeline_shared_libraries.each { name, config ->
if(name && config && config in Map && 'scm' in config && config['scm'] in Map && 'remote' in config['scm'] && config['scm'].optString('remote')) {
def scm = new GitSCMSource(config['scm'].optString('remote'))
scm.credentialsId = config['scm'].optString('credentialsId')
scm.traits = [new BranchDiscoveryTrait()]
def retriever = new SCMSourceRetriever(scm)
def library = new LibraryConfiguration(name, retriever)
library.defaultVersion = config.optString('defaultVersion')
library.implicit = config.optBoolean('implicit', false)
library.allowVersionOverride = config.optBoolean('allowVersionOverride', true)
library.includeInChangesets = config.optBoolean('includeInChangesets', true)
libraries << library
}
}
def global_settings = Jenkins.instance.getExtensionList(GlobalLibraries.class)[0]
if(libraries && !isLibrariesEqual(global_settings.libraries, libraries)) {
global_settings.libraries = libraries
global_settings.save()
println 'Configured Pipeline Global Shared Libraries:\n ' + global_settings.libraries.collect { it.name }.join('\n ')
}
else {
if(pipeline_shared_libraries) {
println 'Nothing changed. Pipeline Global Shared Libraries already configured.'
}
else {
println 'Nothing changed. Skipped configuring Pipeline Global Shared Libraries because settings are empty.'
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment