最近浏览jenkins官方文档时,看到一个有意思的功能,它就是jenkins在启动时可以加载groovy脚本来做初始化工作(●’◡’●),有点意思
对于启动groovy脚本需要放置在jenkins的家录中的init.groovy.d中,jenkins启动时回读取该目录内所有groovy脚本并运行
[root@jenkins-manager jenkins]# mkdir /var/lib/jenkins/init.groovy.d
[root@jenkins-manager jenkins]# chown jenkins.jenkins -R /var/lib/jenkins/init.groovy.d
使用启动groovy脚本重置管理员密码
安装jenkins后第一次打开会提示输入初始密码,此处使用启动脚本提前预设密码来跳过
重置免密多半出现于临时接手其他人项目,他人提供密码错误或者未提供,此时就需要重置下了,以下步骤也可以先在自建的jenkins实例中,jenkins控制台(脚本命令行)执行查看效果
1.获取当前所有用户
import hudson.security.*
import jenkins.model.*
def instance = Jenkins.getInstance()
def hudsonRealm = new HudsonPrivateSecurityRealm(false)
def users = hudsonRealm.getAllUsers()
// 获取用户
users_s = users.collect { it.toString() }
println(users_s)
2.设置用户密码
从上面的脚本输出可以获得用户列表,自行推测寻找可能是管理员的用户,因为它可以是任何值(root/admin/manger/xadocker等,)此处我们假设拥有管理员权限的用户是admin
import hudson.security.*
import jenkins.model.*
def user = hudson.model.User.get('admin')
def password = hudson.security.HudsonPrivateSecurityRealm.Details.fromPlainPassword('admin@password')
user.addProperty(password)
user.save()
println "Updating password successed"
3.将脚本放置需要重置的实例init.groovy.d中
/[root@jenkins-manager init.groovy.d]# pwd
/var/lib/jenkins/init.groovy.d
[root@jenkins-manager init.groovy.d]# cat >resetuserpwd.groovy<<-'EOF'
#!groovy
import hudson.security.*
import jenkins.model.*
def instance = Jenkins.getInstance()
def hudsonRealm = new HudsonPrivateSecurityRealm(false)
def users = hudsonRealm.getAllUsers()
// 获取用户
users_s = users.collect { it.toString() }
println(users_s)
def user = hudson.model.User.get('admin')
def password = hudson.security.HudsonPrivateSecurityRealm.Details.fromPlainPassword('admin@password')
user.addProperty(password)
user.save()
println "Updating password successed"
EOF
[root@jenkins-manager jenkins]# chown jenkins.jenkins -R
4.重启jenkins触发运行init.groovy.d中的脚本
[root@jenkins-manager jenkins]# systemctl restart jenkins
# 查看状态,可以看到已打印用户列表和重置密码成功
[root@jenkins-manager jenkins]# systemctl status jenkins
● jenkins.service - Jenkins Continuous Integration Server
Loaded: loaded (/usr/lib/systemd/system/jenkins.service; enabled; vendor preset: disabled)
Active: active (running) since Sun 2022-11-27 18:59:20 CST; 16s ago
Main PID: 2320 (java)
CGroup: /system.slice/jenkins.service
└─2320 /usr/bin/java -Djava.awt.headless=true -jar /usr/share/java/jenkins.war --webroot=%C/jenkins/war --httpPort=8080
Nov 27 18:59:06 jenkins-manager jenkins[2320]: 2022-11-27 10:59:06.445+0000 [id=32] INFO jenkins.InitReactorRunner$1#onAttained: Configuration for all jobs updated
Nov 27 18:59:06 jenkins-manager jenkins[2320]: 2022-11-27 10:59:06.495+0000 [id=29] INFO j.util.groovy.GroovyHookScript#execute: Executing /var/lib/jenkins/init.groovy.d/resetuserpwd.groovy
Nov 27 18:59:06 jenkins-manager jenkins[2320]: 2022-11-27 10:59:06.497+0000 [id=51] INFO hudson.model.AsyncPeriodicWork#lambda$doRun$1: Started Download metadata
Nov 27 18:59:07 jenkins-manager jenkins[2320]: [admin, user1, user2, xadocker]
Nov 27 18:59:07 jenkins-manager jenkins[2320]: Updating password successed
Nov 27 18:59:08 jenkins-manager jenkins[2320]: 2022-11-27 10:59:08.144+0000 [id=51] WARNING h.m.DownloadService$Downloadable#updateNow: No tool installer metadata found for jenkins.plugins.nodejs.tool...rNodeJSInstaller
Nov 27 18:59:08 jenkins-manager jenkins[2320]: 2022-11-27 10:59:08.148+0000 [id=51] INFO hudson.model.AsyncPeriodicWork#lambda$doRun$1: Finished Download metadata. 1,648 ms
Nov 27 18:59:20 jenkins-manager jenkins[2320]: 2022-11-27 10:59:20.552+0000 [id=33] INFO jenkins.InitReactorRunner$1#onAttained: Completed initialization
Nov 27 18:59:20 jenkins-manager jenkins[2320]: 2022-11-27 10:59:20.629+0000 [id=23] INFO hudson.lifecycle.Lifecycle#onReady: Jenkins is fully up and running
Nov 27 18:59:20 jenkins-manager systemd[1]: Started Jenkins Continuous Integration Server.
Hint: Some lines were ellipsized, use -l to show in full.
执行完后将resetuserpwd.groovy删除,因为在init.groovy.d中的脚本每次启动时都会运行一次,而我们只需要运行一次即可
5.假如连疑似admin用户都没有找到时,可以使用如下方式直接创建管理角色用户
此处直接创建cicd-admin为管理用户,若为已存在用户,则会更新密码
[root@jenkins-manager init.groovy.d]# cat >resetuserpwd.groovy<<-'EOF'
#!groovy
import hudson.security.*
import jenkins.model.*
import org.jenkinsci.plugins.matrixauth.PermissionEntry
import org.jenkinsci.plugins.matrixauth.AuthorizationType
def instance = Jenkins.getInstance()
def hudsonRealm = new HudsonPrivateSecurityRealm(false)
// 创建用户和密码,已有用户则为更新密码
hudsonRealm.createAccount('cicd-admin', 'admin@password')
instance.setSecurityRealm(hudsonRealm)
// 创建新的且空的策略,会覆盖原实例已有策略,谨慎!
// def strategy = new GlobalMatrixAuthorizationStrategy()
// strategy.add(Jenkins.ADMINISTER, "cicd-admin")
// instance.setAuthorizationStrategy(strategy)
// 创建授权入口为user
def permission_entry = new PermissionEntry(AuthorizationType.USER, "cicd-admin")
// 新增ADMINISTER策略
instance.authorizationStrategy.add(Jenkins.ADMINISTER, permission_entry)
instance.save()
println "--> creating admin roles user successed"
EOF
注意事项:上述操作需要有矩阵认证插件
jenkins-plugin-cli --plugins matrix-auth:3.1.5
创建用户时曾出现的问题,在用户矩阵中出现提示:
This table contains rows with ambiguous entries. This means that they apply to both users and groups of the specified name. If the current security realm does not distinguish between user names and group names unambiguously, and if users can either choose their own user name or create new groups, this configuration may allow them to obtain greater permissions. It is recommended that all ambiguous entries are replaced with ones that are either explicitly a user or group.
这是应用创建授权入口时未指定是以用用户为入口类型,此时jenkins就报这个提示。正常情况下,手动创建时需要指定该入口为用户还是用户组,而脚本中则按如下方式指定
// 创建授权入口为user
def permission_entry = new PermissionEntry(AuthorizationType.USER, "cicd-admin")
// 创建授权入口为group
// def permission_entry = new PermissionEntry(AuthorizationType.GROUP, "cicd-admin")
instance.authorizationStrategy.add(Jenkins.ADMINISTER, permission_entry)
// 未指定入口类型
// instance.authorizationStrategy.add(Jenkins.ADMINISTER, 'cicd-admin')
当出现这种未指定类型的账号时,根据提示点击migrate就可以了