Skip to content

Instantly share code, notes, and snippets.

@fishi0x01
Last active May 17, 2024 17:38
Show Gist options
  • Save fishi0x01/7c2d29afbaa0f16126eb4d4b35942f76 to your computer and use it in GitHub Desktop.
Save fishi0x01/7c2d29afbaa0f16126eb4d4b35942f76 to your computer and use it in GitHub Desktop.
This is a collection of groovy scripts I gathered and use for bootstrapping Jenkins. Most of this can also be achieved with the CasC Plugin https://github.com/jenkinsci/configuration-as-code-plugin
#!groovy
/*
* This script configures the Jenkins base URL.
*/
import jenkins.model.JenkinsLocationConfiguration
JenkinsLocationConfiguration location = Jenkins.instance.getExtensionList('jenkins.model.JenkinsLocationConfiguration')[0]
location.url = 'https://jenkins-as-code-poc.devtail.io/'
location.save()
#!groovy
/*
* This script loads different kinds
* of credentials from files into the
* Jenkins credential store.
*/
import jenkins.model.*
import com.cloudbees.plugins.credentials.*
import com.cloudbees.plugins.credentials.common.*
import com.cloudbees.plugins.credentials.domains.*
import com.cloudbees.plugins.credentials.impl.*
import com.cloudbees.jenkins.plugins.sshcredentials.impl.*
import org.jenkinsci.plugins.plaincredentials.*
import org.jenkinsci.plugins.plaincredentials.impl.*
import hudson.util.Secret
///////////////////
// Helper functions
///////////////////
def getStore() {
return Jenkins.instance.getExtensionList('com.cloudbees.plugins.credentials.SystemCredentialsProvider')[0].getStore()
}
def getContent(filePath) {
return new File(filePath).text
}
// This function reads the contents of a key file and returns
// a Jenkins SSH private key object with the given user as owner
def getSSHKeyCredential(id, path, user) {
return new BasicSSHUserPrivateKey(
CredentialsScope.GLOBAL,
id,
user,
new BasicSSHUserPrivateKey.DirectEntryPrivateKeySource(getContent(path)),
"",
"SSH key ${id}"
)
}
// Get master credential store
domain = Domain.global()
//////////////////////////////
// Add username/password pairs
//////////////////////////////
userPasswords = [
[id: 'docker-registry', description: 'Docker Registry Credentials', userNameFile: '/var/jenkins_home/secrets/dockerUserName', userPasswordFile: '/var/jenkins_home/secrets/dockerUserPassword'],
[id: 'github-ci-user', description: 'GitHub CI User Credentials', userNameFile: '/var/jenkins_home/secrets/githubCIUserName', userPasswordFile: '/var/jenkins_home/secrets/githubCIUserToken'],
]
for(userPassword in userPasswords) {
Credentials cred = (Credentials) new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, userPassword.id, userPassword.description, getContent(userPassword.userNameFile), getContent(userPassword.userPasswordFile))
getStore().addCredentials(domain, cred)
}
/////////////
// Add tokens
/////////////
secretTokens = [
[id: 'slack-token', description: 'Slack Token', tokenFile: '/var/jenkins_home/secrets/slackToken'],
[id: 'vault-approle-secret', description: 'Vault AppRole Secret', tokenFile: '/var/jenkins_home/secrets/vaultAppRoleSecret'],
[id: 'vault-approle-id', description: 'Vault AppRole ID', tokenFile: '/var/jenkins_home/secrets/vaultAppRoleID'],
[id: 'github-ci-user-token', description: 'Github CI User Token', tokenFile: '/var/jenkins_home/secrets/githubCIUserToken']
]
for(secretToken in secretTokens) {
Credentials token = (Credentials) new StringCredentialsImpl(CredentialsScope.GLOBAL, secretToken.id, secretToken.description, Secret.fromString(getContent(secretToken.tokenFile)))
getStore().addCredentials(domain, token)
}
///////////////
// Add ssh keys
///////////////
sshKeys = [
[id: 'ssh-deploy-key-service-a', path: '/var/jenkins_home/.ssh/deploy-key-service-a', user: 'root'],
[id: 'ssh-slave-access', path: '/var/jenkins_home/.ssh/slave-access', user: 'jenkins'],
[id: 'ssh-global-shared-library', path: '/var/jenkins_home/.ssh/global-shared-library', user: 'root'],
]
for(sshKey in sshKeys) {
getStore().addCredentials(domain, getSSHKeyCredential(sshKey.id, sshKey.path, sshKey.user))
}
#!groovy
/*
* This script configures the GitHub Plugin.
* Requires the GitHub Plugin to be installed.
* Tested with github:1.29.3
*/
import jenkins.model.Jenkins
import org.jenkinsci.plugins.github.config.GitHubPluginConfig
import org.jenkinsci.plugins.github.config.GitHubServerConfig
def githubConfig = new GitHubServerConfig("github-ci-user-token") // credential ID for our user token for the GitHub CI User
githubConfig.setManageHooks(true)
githubConfig.setName("GitHub")
def github = Jenkins.instance.getExtensionList(GitHubPluginConfig.class)[0]
github.setConfigs([
githubConfig,
])
github.save()
#!groovy
/*
* This script configures Github OAuth access
* in Jenkins. It uses a global authorization
* Matrix strategy as authorization configurtion.
* This script requires the Gibhub Authentication
* plugin (github-oauth) to be installed. It is
* tested with github-oauth:0.29
*/
import hudson.security.SecurityRealm
import org.jenkinsci.plugins.GithubSecurityRealm
import jenkins.model.*
import hudson.security.*
// Setup OAUTH Realm
String githubWebUri = GithubSecurityRealm.DEFAULT_WEB_URI
String githubApiUri = GithubSecurityRealm.DEFAULT_API_URI
String oauthScopes = 'read:org,user:email' //GithubSecurityRealm.DEFAULT_OAUTH_SCOPES
String clientID = System.getenv()['GITHUB_OAUTH_CLIENT_ID'] // TODO: get from credential store
String clientSecret = System.getenv()['GITHUB_OAUTH_CLIENT_SECRET'] // TODO: get from credential store
SecurityRealm github_realm = new GithubSecurityRealm(githubWebUri, githubApiUri, clientID, clientSecret, oauthScopes)
Jenkins.instance.setSecurityRealm(github_realm)
// Create global authorization matrix
def strategy = new GlobalMatrixAuthorizationStrategy()
// Give admin access to fishi0x01 user
strategy.add(Jenkins.ADMINISTER, "fishi0x01")
// Give admin access to my_team_name
strategy.add(Jenkins.ADMINISTER, "my_company_id*my_team_name")
// wrap up
Jenkins.instance.setAuthorizationStrategy(strategy)
Jenkins.instance.save()
#!groovy
/*
* This script configures global environment variables in Jenkins
*/
import jenkins.model.Jenkins
import hudson.EnvVars;
import hudson.slaves.EnvironmentVariablesNodeProperty;
import hudson.slaves.NodeProperty;
import hudson.slaves.NodePropertyDescriptor;
import hudson.util.DescribableList;
def createGlobalEnvironmentVariables(String key, String value){
Jenkins instance = Jenkins.getInstance();
DescribableList<NodeProperty<?>, NodePropertyDescriptor> globalNodeProperties = instance.getGlobalNodeProperties();
List<EnvironmentVariablesNodeProperty> envVarsNodePropertyList = globalNodeProperties.getAll(EnvironmentVariablesNodeProperty.class);
EnvironmentVariablesNodeProperty newEnvVarsNodeProperty = null;
EnvVars envVars = null;
if ( envVarsNodePropertyList == null || envVarsNodePropertyList.size() == 0 ) {
newEnvVarsNodeProperty = new hudson.slaves.EnvironmentVariablesNodeProperty();
globalNodeProperties.add(newEnvVarsNodeProperty);
envVars = newEnvVarsNodeProperty.getEnvVars();
} else {
envVars = envVarsNodePropertyList.get(0).getEnvVars();
}
envVars.put(key, value)
instance.save()
}
createGlobalEnvironmentVariables('MY_ENV_VAR_A', 'A')
createGlobalEnvironmentVariables('MY_ENV_VAR_B', 'B')
#!groovy
/*
* Configure pipeline shared libraries in the global Jenkins configuration.
* This will safely compare configured libraries and only overwrite the global
* shared library config if changes have been made.
* workflow-cps-global-lib 2.9
*
* Source: https://github.com/thbkrkr/jks/blob/master/init.groovy.d/11-configure-pipeline-global-shared.groovy
*/
import jenkins.model.Jenkins
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
List libraries = [] as ArrayList
def remote = '[email protected]:<my-org>/<my-shared-library>.git'
def credentialsId = 'ssh-global-shared-library'
name = 'lib-name'
defaultVersion = 'master'
if (remote != null) {
def scm = new GitSCMSource(remote)
if (credentialsId != null) {
scm.credentialsId = credentialsId
}
scm.traits = [new BranchDiscoveryTrait()]
def retriever = new SCMSourceRetriever(scm)
def library = new LibraryConfiguration(name, retriever)
library.defaultVersion = defaultVersion
library.implicit = false
library.allowVersionOverride = true
library.includeInChangesets = false
libraries << library
def global_settings = Jenkins.instance.getExtensionList(GlobalLibraries.class)[0]
global_settings.libraries = libraries
global_settings.save()
println 'Configured Pipeline Global Shared Libraries:\n ' + global_settings.libraries.collect { it.name }.join('\n ')
}
#!groovy
/*
* This script is designated for the init.groovy.d
* directory to be executed at startup time of the
* Jenkins instance. This script requires the jobDSL
* Plugin. Tested with job-dsl:1.70
*/
import javaposse.jobdsl.dsl.DslScriptLoader
import javaposse.jobdsl.plugin.JenkinsJobManagement
import jenkins.model.Jenkins
import com.cloudbees.plugins.credentials.domains.Domain
import com.cloudbees.jenkins.plugins.sshcredentials.impl.BasicSSHUserPrivateKey
import com.cloudbees.plugins.credentials.CredentialsScope
import hudson.security.FullControlOnceLoggedInAuthorizationStrategy
import hudson.security.HudsonPrivateSecurityRealm
// Add deploy key for the centrally shared pipeline and configuration repository
def domain = Domain.global()
def store = Jenkins.instance.getExtensionList('com.cloudbees.plugins.credentials.SystemCredentialsProvider')[0].getStore()
def keyFileContents = new File("/var/jenkins_home/.ssh/shared-libraries-deploy-key").text
def privateKey = new BasicSSHUserPrivateKey(
CredentialsScope.GLOBAL,
"shared-libraries-deploy-key",
"root",
new BasicSSHUserPrivateKey.DirectEntryPrivateKeySource(keyFileContents),
"",
"SSH key for shared-library"
)
store.addCredentials(domain, privateKey)
// Create the configuration job interface from a jobDSL script
def jobDslScript = new File('/var/jenkins_home/init-dsl/ConfigurationAndSeedingPipelineDSL.groovy')
def workspace = new File('.')
def jobManagement = new JenkinsJobManagement(System.out, [:], workspace)
new DslScriptLoader(jobManagement).runScript(jobDslScript.text)
// Disable Setup Wizards
if(Jenkins.instance.getSecurityRealm().getClass().getSimpleName() == 'None') {
def instance = Jenkins.getInstance()
// Those files should be mounted into the jenkins master container
def setupUser = new File("/var/jenkins_home/jenkins-basic-auth-credentials/default-setup-user").text.trim()
def setupPass = new File("/var/jenkins_home/jenkins-basic-auth-credentials/default-setup-password").text.trim()
def hudsonRealm = new HudsonPrivateSecurityRealm(false)
instance.setSecurityRealm(hudsonRealm)
def user = instance.getSecurityRealm().createAccount(setupUser, setupPass)
user.save()
def strategy = new FullControlOnceLoggedInAuthorizationStrategy()
strategy.setAllowAnonymousRead(false)
instance.setAuthorizationStrategy(strategy)
instance.save()
println("SetupWizard Disabled")
}
#!groovy
/*
* This script makes the maven tool available on all Jenkins nodes.
* Requires the maven plugin to be installed.
*/
import hudson.tasks.Maven.MavenInstallation;
import hudson.tools.InstallSourceProperty;
import hudson.tools.ToolProperty;
import hudson.tools.ToolPropertyDescriptor;
import hudson.util.DescribableList;
// Install maven tool
def mavenDesc = jenkins.model.Jenkins.instance.getExtensionList(hudson.tasks.Maven.DescriptorImpl.class)[0]
def isp = new InstallSourceProperty()
def autoInstaller = new hudson.tasks.Maven.MavenInstaller("3.3.9")
isp.installers.add(autoInstaller)
def proplist = new DescribableList<ToolProperty<?>, ToolPropertyDescriptor>()
proplist.add(isp)
def installation = new MavenInstallation("M3", "", proplist)
mavenDesc.setInstallations(installation)
mavenDesc.save()
#!groovy
/*
* This script configures the Jenkins Slack Plugin.
* Requires the installation of the Slack Plugin.
* Tested with slack:2.3
*/
import jenkins.model.Jenkins
def slack = Jenkins.instance.getExtensionList('jenkins.plugins.slack.SlackNotifier$DescriptorImpl')[0]
slack.tokenCredentialId = 'slack-token'
slack.teamDomain = 'my-slack-team-domain'
slack.baseUrl = 'https://my-slack-team-domain.slack.com/services/hooks/jenkins-ci/'
slack.save()
#!groovy
import jenkins.model.*
import hudson.model.*
import hudson.slaves.*
import hudson.plugins.sshslaves.*
import java.util.ArrayList;
import hudson.slaves.EnvironmentVariablesNodeProperty.Entry;
// Prepare env vars for slave node
List<Entry> env = new ArrayList<Entry>();
env.add(new Entry("key1","value1"))
env.add(new Entry("key2","value2"))
EnvironmentVariablesNodeProperty envPro = new EnvironmentVariablesNodeProperty(env);
// Define slave to be bootstrapped by master
Slave slave = new DumbSlave(
"my-slave-id",
"My slave description",
"/path/to/slave/workdir",
"4", // # of executors
Node.Mode.EXCLUSIVE,
"slave-label",
new SSHLauncher(System.getenv()['MY_SLAVE_ADDRESS'], 22, SSHLauncher.lookupSystemCredentials("my-slave-ssh-key-credential-id"), "", null, null, "", "", 60, 3, 15),
new RetentionStrategy.Always(),
new LinkedList()
)
// Add env vars to slave
slave.getNodeProperties().add(envPro)
// Save slave
Jenkins.instance.addNode(slave)
#!groovy
/*
* This script configures the Jenkins SSHD Port.
*/
import jenkins.model.Jenkins
def sshDesc = Jenkins.instance.getDescriptor("org.jenkinsci.main.modules.sshd.SSHD")
sshDesc.setPort(6666)
sshDesc.getActualPort()
sshDesc.save()
#!groovy
/*
* This script configures the simple theme plugin.
* Requires the simple theme plugin to be installed.
* Tested with simple-theme-plugin:0.5.1
*
* Use http://afonsof.com/jenkins-material-theme/ to generate a new jenkins theme.
* Upload the theme to a CDN or place it directly at the userContent directory of
* Jenkins to be publicly available.
*/
import jenkins.model.Jenkins
import org.jenkinsci.plugins.simpletheme.CssUrlThemeElement
def themeDecorator = Jenkins.instance.getExtensionList(org.codefirst.SimpleThemeDecorator.class).first()
themeDecorator.setElements([
new CssUrlThemeElement('https://fishi.devtail.io/content-images/jenkins-devtail-theme.css')
])
Jenkins.instance.save()
#! groovy
/*
* This script configures the timezone in Jenkins
*/
System.setProperty('org.apache.commons.jelly.tags.fmt.timeZone', 'Europe/Berlin')
#! groovy
import jenkins.model.Jenkins
// trigger configuration as code plugin
def jcacPlugin = Jenkins.instance.getExtensionList(io.jenkins.plugins.casc.ConfigurationAsCode.class).first()
jcacPlugin.configure()
#! groovy
def getFileContent(filePath) {
return new File(filePath).text
}
def user = hudson.model.User.get('admin')
def pubKey = new org.jenkinsci.main.modules.cli.auth.ssh.UserPropertyImpl(getFileContent('/var/jenkins_home/jenkins-ssh-keys/ssh-jenkins-cli.pub'))
user.addProperty(pubKey)
user.save()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment