├── README.md ├── get_creds.groovy ├── init.groovy ├── set_git_global_config.groovy ├── sonar-artifactory-settings.groovy └── useful_groovy_snippets.groovy /README.md: -------------------------------------------------------------------------------- 1 | # Useful Jenkins groovy init Scripts 2 | 3 | Jenkins allows adding groovy scripts for initialization, which means these scripts will run every time Jenkins starts. 4 | 5 | ## How this works? 6 | 7 | The jenkins server automatically looks for `groovy.d` folder under the home dir of where Jenkins run from e.g. `/var/lib/jenkins/groovy.d` or `/root/.jenkins/groovy.d` if running in a container, and any groovy script in folder get executed anytime jenkins starts. 8 | 9 | ## Why use the scripts? 10 | 11 | Its a pretty handy way of automating Jenkins installation; lets say you want your CI setup to be automated, like everytime you 12 | install your jenkins environment, it should be pre-configured with certain user accounts created, have LDAP configured automatically or some global properties set. 13 | 14 | Groovy is an easy way of calling Jenkins base classes of Java without getting to know much of Java itself ;) 15 | 16 | ## What scripts are in this repo? 17 | 18 | I have scripts for : 19 | 1. Creating user accounts. 20 | 2. Creating global credentials (for ssh , username/password etc). 21 | 3. Getting the API key of a user ( this is pretty useful because if you use (Jenkins Job Builder )[https://github.com/openstack-infra/jenkins-job-builder.git] for setting up 22 | your CI , for the credential .ini file , you will need the API key so why not get it from a groovy script :) ) 23 | 4. Setting the global security , either LDAP , or jenkins own database etc. 24 | 5. Setting global authorization matrix for groups like `anonymous`, `authenticated` or any specific user. 25 | 6. Get a credential ID of a global credential, again extremely useful when you use *Jenkins Job BUilder* and in git SCM, you need 26 | to specify (Credential ID of ssh key for git to use in cloning some private repos)[http://docs.openstack.org/infra/jenkins-job-builder/scm.html], 27 | this script will do it for you . 28 | 29 | Cheers :) 30 | -------------------------------------------------------------------------------- /get_creds.groovy: -------------------------------------------------------------------------------- 1 | def creds = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials( 2 | com.cloudbees.plugins.credentials.common.StandardUsernameCredentials.class, 3 | Jenkins.instance, 4 | null, 5 | null 6 | ); 7 | for (c in creds) { 8 | println(c.id + ": " + c.description) 9 | } 10 | -------------------------------------------------------------------------------- /init.groovy: -------------------------------------------------------------------------------- 1 | import jenkins.* 2 | import hudson.* 3 | import com.cloudbees.plugins.credentials.* 4 | import com.cloudbees.plugins.credentials.common.* 5 | import com.cloudbees.plugins.credentials.domains.* 6 | import com.cloudbees.jenkins.plugins.sshcredentials.impl.* 7 | import hudson.plugins.sshslaves.*; 8 | import hudson.model.* 9 | import jenkins.model.* 10 | import hudson.security.* 11 | 12 | 13 | // SET SLAVE PORT AND NUMBER OF EXECUTORS AT MASTER NODE( im setting it to 5, you may declare it after you know you have enough RAM) 14 | // Jenkins eats a lot of RAM :D 15 | def instance = Jenkins.getInstance() 16 | instance.setNumExecutors(5) 17 | instance.setSlaveAgentPort([55000]) 18 | 19 | // Create a SSH key based global credential , the key is stored in master, here i assume my key already exists on master at 20 | // location `/root/.ssh/id_rsa` 21 | String keyfile = "/root/.ssh/id_rsa" 22 | global_domain = Domain.global() 23 | credentials_store = 24 | Jenkins.instance.getExtensionList( 25 | 'com.cloudbees.plugins.credentials.SystemCredentialsProvider' 26 | )[0].getStore() 27 | credentials = new BasicSSHUserPrivateKey( 28 | CredentialsScope.GLOBAL, 29 | null, 30 | "root", 31 | new BasicSSHUserPrivateKey.FileOnMasterPrivateKeySource(keyfile), 32 | "", 33 | "") 34 | credentials_store.addCredentials(global_domain, credentials) 35 | // Create a global credential to work with git, this is needed to access the git related jobs. 36 | // which means all the jobs, since all our jobs are somewhat working with git :) 37 | // This assumes there is a ssh private key in /root/.ssh/ which i actually added in dockerfile , no need to worry 38 | global_domain = Domain.global() 39 | credentials_store = 40 | Jenkins.instance.getExtensionList( 41 | 'com.cloudbees.plugins.credentials.SystemCredentialsProvider' 42 | )[0].getStore() 43 | credentials = new BasicSSHUserPrivateKey( 44 | CredentialsScope.GLOBAL, 45 | null, 46 | "root", 47 | new BasicSSHUserPrivateKey.UsersPrivateKeySource(), 48 | "", 49 | "") 50 | credentials_store.addCredentials(global_domain, credentials) 51 | 52 | 53 | // NOW TIME TO CONFIGURE GLOBAL SECURITY 54 | def hudsonRealm = new HudsonPrivateSecurityRealm(false) 55 | // sample LDAP setup 56 | String server = 'ldap://mycompany.com' 57 | String rootDN = 'dc=company,dc=com' 58 | String userSearchBase = '' 59 | String userSearch = 'uid={0}' 60 | String groupSearchBase = '' 61 | String managerDN = 'cn=System,ou=people,dc=company,dc=com' 62 | String passcode = 'passwordofSystem' 63 | boolean inhibitInferRootDN = true 64 | SecurityRealm ldap_realm = new LDAPSecurityRealm(server, rootDN, userSearchBase, userSearch, groupSearchBase, managerDN, passcode, inhibitInferRootDN) 65 | instance.setSecurityRealm(ldap_realm) 66 | instance.save() 67 | 68 | //FOLLOWING IS THE ACTUAL SETUP NEEDED FOR JJB AND SWARM SLAVES 69 | hudsonRealm.createAccount("swarm-slave","boguspassword") 70 | hudsonRealm.createAccount("jenkins-job-builder","boguspassword") 71 | instance.setSecurityRealm(hudsonRealm) 72 | instance.save() 73 | def strategy = new GlobalMatrixAuthorizationStrategy() 74 | strategy.add(Jenkins.READ,'authenticated') 75 | strategy.add(Item.READ,'authenticated') 76 | strategy.add(Item.DISCOVER,'authenticated') 77 | strategy.add(Item.CANCEL,'authenticated') 78 | strategy.add(Item.CONFIGURE,'jenkins-job-builder') 79 | strategy.add(Item.READ,'jenkins-job-builder') 80 | strategy.add(Item.READ,'anonymous') 81 | strategy.add(Item.DISCOVER,'jenkins-job-builder') 82 | strategy.add(Item.CREATE,'jenkins-job-builder') 83 | strategy.add(Item.DELETE,'jenkins-job-builder') 84 | strategy.add(Jenkins.ADMINISTER, "swarm-slave") 85 | strategy.add(Jenkins.ADMINISTER, "jenkins-job-builder") 86 | // declare who can launch a slave (using awarm client ) and configure the slaves 87 | // add slave launch permissions to svc 88 | // info found from http://javadoc.jenkins-ci.org/hudson/security/class-use/Permission.html#jenkins.slaves 89 | strategy.add(Computer.BUILD,'swarm-slave') 90 | strategy.add(Computer.CONFIGURE,'swarm-slave') 91 | strategy.add(Computer.CONNECT,'swarm-slave') 92 | strategy.add(Computer.CREATE,'swarm-slave') 93 | strategy.add(Computer.DISCONNECT,'swarm-slave') 94 | instance.setAuthorizationStrategy(strategy) 95 | instance.save() 96 | 97 | 98 | 99 | //// HOW TO GET CREDENTIAL ID OF A GLOBAL CREDENTIAL - PETTY USEFUL IF YOU NEED TO WORK WITH private 100 | // github repos , and jenkins need a cred id so that the git scm works properly 101 | // i really need it since i use jenkins-job-builder to define my jobs, some jobs need access to private github repos, 102 | // i createed creds in start of this file (see above), but jenkins-job-builder need to cred id for git scm dfinition. 103 | // iget it using follwing code, store in a file.. 104 | 105 | // Normal way of creating file objects.We get the creds to be used by jobs who need access to private github repos 106 | // Above we created global creds , we get their ID, which will then be passed to `git` section of each job 107 | // under `credentials-id` ..so in short, jenkins git needs a cred ID, and knows the corresponding ssh key it relates to. 108 | def file1 = new File('/tmp/creds.txt') 109 | def file2 = new File('/tmp/jjb.txt') 110 | def creds = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials( 111 | com.cloudbees.plugins.credentials.common.StandardUsernameCredentials.class, 112 | Jenkins.instance, 113 | null, 114 | null 115 | ); 116 | for (c in creds) { 117 | // println(c.id + ": " + c.description) 118 | // Writing to the files with the write method: 119 | file1 << "${c.id}" 120 | } 121 | // here im getting API token of a user , pretty col huh, since JJB needs API token , not the normal password, to talk to jenkins and update/modify jobs 122 | 123 | //j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); 124 | // this assumes user jenkins-job-builder has already been created...as i have done above in same file.. 125 | // to get api token of user foo , do it as " User.get('foo') 126 | // cheers :) 127 | User u = User.get("jenkins-job-builder") 128 | ApiTokenProperty t = u.getProperty(ApiTokenProperty.class) 129 | // use admin account to retrieve API token of any user 130 | // NOTE: jenkins has changed the way to get api token , only a user logged in as itself will be able to retrieve its token 131 | // refer : http://stackoverflow.com/questions/37035319/as-a-jenkins-administrator-how-do-i-get-a-users-api-token-without-logging-in-a 132 | def token = t.getApiToken() 133 | // token.getClass() 134 | file2 << "${token}" 135 | -------------------------------------------------------------------------------- /set_git_global_config.groovy: -------------------------------------------------------------------------------- 1 | import jenkins.model.* 2 | 3 | def inst = Jenkins.getInstance() 4 | 5 | def desc = inst.getDescriptor("hudson.plugins.git.GitSCM") 6 | 7 | desc.setGlobalConfigName("[name to use with git commits]") 8 | desc.setGlobalConfigEmail("[email to use with git commits]") 9 | 10 | desc.save() 11 | -------------------------------------------------------------------------------- /sonar-artifactory-settings.groovy: -------------------------------------------------------------------------------- 1 | //Source of scripts: https://groups.google.com/forum/#!topic/jenkinsci-users/U9HLBVB5_CM 2 | //=========================== 3 | //Sonar Script 4 | //========================== 5 | import jenkins.model.* 6 | import hudson.plugins.sonar.* 7 | import hudson.plugins.sonar.model.* 8 | 9 | def inst = Jenkins.getInstance() 10 | 11 | def desc = inst.getDescriptor("hudson.plugins.sonar.SonarPublisher") 12 | 13 | def sinst = new SonarInstallation( 14 | "sonar4.5.1", 15 | false, 16 | "http://localhost:9000/", 17 | "jdbc:mysql://localhost:3306/sonar", 18 | "com.mysql.jdbc.Driver", 19 | "sonar", 20 | "sonar", 21 | "", 22 | "-Dsonar.sourceEncoding=\"UTF-8\"", 23 | new TriggersConfig(), 24 | "admin", 25 | "admin" 26 | ) 27 | desc.setInstallations(sinst) 28 | 29 | desc.save() 30 | 31 | 32 | //================================================== 33 | //Artifactory Script 34 | //================================================== 35 | import jenkins.model.* 36 | import org.jfrog.* 37 | import org.jfrog.hudson.* 38 | import org.jfrog.hudson.util.Credentials; 39 | 40 | def inst = Jenkins.getInstance() 41 | 42 | def desc = inst.getDescriptor("org.jfrog.hudson.ArtifactoryBuilder") 43 | 44 | def deployerCredentials = new Credentials("admin", "password") 45 | def resolverCredentials = new Credentials("", "") 46 | 47 | def sinst = [new ArtifactoryServer( 48 | "server-id", 49 | "http://localhost:8081/artifactory", 50 | deployerCredentials, 51 | resolverCredentials, 52 | 300, 53 | false ) 54 | ] 55 | 56 | desc.setArtifactoryServers(sinst) 57 | 58 | desc.save() 59 | -------------------------------------------------------------------------------- /useful_groovy_snippets.groovy: -------------------------------------------------------------------------------- 1 | 2 | import com.cloudbees.jenkins.plugins.sshcredentials.impl.* 3 | import com.cloudbees.jenkins.plugins.sshcredentials.impl.*; 4 | import com.cloudbees.plugins.credentials.* 5 | import com.cloudbees.plugins.credentials.*; 6 | import com.cloudbees.plugins.credentials.common.* 7 | import com.cloudbees.plugins.credentials.domains.* 8 | import com.cloudbees.plugins.credentials.domains.*; 9 | import com.cloudbees.plugins.credentials.impl.* 10 | import com.cloudbees.plugins.credentials.impl.*; 11 | import hudson.plugins.sshslaves.*; 12 | import jenkins.model.*; 13 | 14 | private credentials_for_username(String username) { 15 | def username_matcher = CredentialsMatchers.withUsername(username) 16 | def available_credentials = 17 | CredentialsProvider.lookupCredentials( 18 | StandardUsernameCredentials.class, 19 | Jenkins.getInstance(), 20 | hudson.security.ACL.SYSTEM, 21 | new SchemeRequirement("ssh") 22 | ) 23 | 24 | return CredentialsMatchers.firstOrNull( 25 | available_credentials, 26 | username_matcher 27 | ) 28 | } 29 | 30 | ///////////////////////// 31 | // create or update user 32 | ///////////////////////// 33 | void create_or_update_user(String user_name, String email, String password="", String full_name="", String public_keys="") { 34 | def user = hudson.model.User.get(user_name) 35 | user.setFullName(full_name) 36 | 37 | def email_param = new hudson.tasks.Mailer.UserProperty(email) 38 | user.addProperty(email_param) 39 | 40 | def pw_param = hudson.security.HudsonPrivateSecurityRealm.Details.fromPlainPassword(password) 41 | user.addProperty(pw_param) 42 | 43 | if ( public_keys != "" ) { 44 | def keys_param = new org.jenkinsci.main.modules.cli.auth.ssh.UserPropertyImpl(public_keys) 45 | user.addProperty(keys_param) 46 | } 47 | 48 | user.save() 49 | } 50 | 51 | ///////////////////////// 52 | // delete user 53 | ///////////////////////// 54 | void delete_user(String user_name) { 55 | def user = hudson.model.User.get(user_name, false) 56 | if (user != null) { 57 | user.delete() 58 | } 59 | } 60 | 61 | ///////////////////////// 62 | // current user 63 | ///////////////////////// 64 | void user_info(String user_name) { 65 | def user = hudson.model.User.get(user_name, false) 66 | 67 | if(user == null) { 68 | return null 69 | } 70 | 71 | def user_id = user.getId() 72 | def name = user.getFullName() 73 | 74 | def email_address = null 75 | def emailProperty = user.getProperty(hudson.tasks.Mailer.UserProperty) 76 | if(emailProperty != null) { 77 | email_address = emailProperty.getAddress() 78 | } 79 | 80 | def keys = null 81 | def keysProperty = user.getProperty(org.jenkinsci.main.modules.cli.auth.ssh.UserPropertyImpl) 82 | if(keysProperty != null) { 83 | keys = keysProperty.authorizedKeys.split('\\s+') 84 | } 85 | 86 | def token = null 87 | def tokenProperty = user.getProperty(jenkins.security.ApiTokenProperty.class) 88 | if (tokenProperty != null) { 89 | token = tokenProperty.getApiTokenInsecure() 90 | } 91 | 92 | def builder = new groovy.json.JsonBuilder() 93 | builder { 94 | id user_id 95 | full_name name 96 | email email_address 97 | api_token token 98 | public_keys keys 99 | } 100 | 101 | out.println(builder) 102 | } 103 | 104 | ///////////////////////// 105 | // create credentials 106 | ///////////////////////// 107 | void create_or_update_credentials(String username, String password, String description="", String private_key="") { 108 | def global_domain = Domain.global() 109 | def credentials_store = 110 | Jenkins.instance.getExtensionList( 111 | 'com.cloudbees.plugins.credentials.SystemCredentialsProvider' 112 | )[0].getStore() 113 | 114 | def credentials 115 | if (private_key == "" ) { 116 | credentials = new UsernamePasswordCredentialsImpl( 117 | CredentialsScope.GLOBAL, 118 | null, 119 | description, 120 | username, 121 | password 122 | ) 123 | } else { 124 | def key_source 125 | if (private_key.startsWith('-----BEGIN')) { 126 | key_source = new BasicSSHUserPrivateKey.DirectEntryPrivateKeySource(private_key) 127 | } else { 128 | key_source = new BasicSSHUserPrivateKey.FileOnMasterPrivateKeySource(private_key) 129 | } 130 | credentials = new BasicSSHUserPrivateKey( 131 | CredentialsScope.GLOBAL, 132 | null, 133 | username, 134 | key_source, 135 | password, 136 | description 137 | ) 138 | } 139 | 140 | // Create or update the credentials in the Jenkins instance 141 | def existing_credentials = credentials_for_username(username) 142 | 143 | if(existing_credentials != null) { 144 | credentials_store.updateCredentials( 145 | global_domain, 146 | existing_credentials, 147 | credentials 148 | ) 149 | } else { 150 | credentials_store.addCredentials(global_domain, credentials) 151 | } 152 | } 153 | 154 | ////////////////////////// 155 | // delete credentials 156 | ////////////////////////// 157 | void delete_credentials(String username) { 158 | def existing_credentials = credentials_for_username(username) 159 | 160 | if(existing_credentials != null) { 161 | def global_domain = com.cloudbees.plugins.credentials.domains.Domain.global() 162 | def credentials_store = 163 | Jenkins.instance.getExtensionList( 164 | 'com.cloudbees.plugins.credentials.SystemCredentialsProvider' 165 | )[0].getStore() 166 | credentials_store.removeCredentials( 167 | global_domain, 168 | existing_credentials 169 | ) 170 | } 171 | } 172 | 173 | //////////////////////// 174 | // current credentials 175 | //////////////////////// 176 | void credential_info(String username) { 177 | def credentials = credentials_for_username(username) 178 | 179 | if(credentials == null) { 180 | return null 181 | } 182 | 183 | def current_credentials = [ 184 | id:credentials.id, 185 | description:credentials.description, 186 | username:credentials.username 187 | ] 188 | 189 | if ( credentials.hasProperty('password') ) { 190 | current_credentials['password'] = credentials.password.plainText 191 | } else { 192 | current_credentials['private_key'] = credentials.privateKey 193 | current_credentials['passphrase'] = credentials.passphrase.plainText 194 | } 195 | 196 | def builder = new groovy.json.JsonBuilder(current_credentials) 197 | out.println(builder) 198 | } 199 | 200 | //////////////////////// 201 | // set_security 202 | //////////////////////// 203 | /* 204 | * Set up security for the Jenkins instance. This currently supports 205 | * only a small number of configurations. If authentication is enabled, it 206 | * uses the internal user database. 207 | */ 208 | void set_security(String security_model) { 209 | def instance = Jenkins.getInstance() 210 | 211 | if (security_model == 'disabled') { 212 | instance.disableSecurity() 213 | return null 214 | } 215 | 216 | def strategy 217 | def realm 218 | switch (security_model) { 219 | case 'full_control': 220 | strategy = new hudson.security.FullControlOnceLoggedInAuthorizationStrategy() 221 | realm = new hudson.security.HudsonPrivateSecurityRealm(false, false, null) 222 | break 223 | case 'unsecured': 224 | strategy = new hudson.security.AuthorizationStrategy.Unsecured() 225 | realm = new hudson.security.HudsonPrivateSecurityRealm(false, false, null) 226 | break 227 | default: 228 | throw new InvalidAuthenticationStrategy() 229 | } 230 | instance.setAuthorizationStrategy(strategy) 231 | instance.setSecurityRealm(realm) 232 | } 233 | --------------------------------------------------------------------------------