Last active
July 25, 2023 21:20
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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