Jenkins ActiveDirectorySecurityRealm插件Groovy配置bindName缺失问题求助
我之前在自动化配置Jenkins AD插件时也碰到过一模一样的问题——照着官方文档用构造函数初始化后,重启Jenkins发现bindName节点直接从config.xml里消失了,只能手动补全。后来翻了插件源码才搞明白是构造函数的坑:
你用的那个ActiveDirectorySecurityRealm多参数构造函数,并没有把bindName赋值给对应的ActiveDirectoryDomain对象,而是存在了Realm的全局属性里,但插件序列化到config.xml时,只会从每个Domain节点读取bindName配置,全局的bindName根本不会被写入。
修复后的Groovy代码
直接手动创建ActiveDirectoryDomain实例,显式设置所有必填属性,再添加到Realm的domains列表里,就能解决这个问题:
import hudson.plugins.active_directory.ActiveDirectorySecurityRealm import hudson.plugins.active_directory.ActiveDirectoryDomain String _domain = 'my-primary-ad-server-running.acme.org' String _site = 'jenkins.acme.org' String _bindName = 'ad-bind-user' String _bindPassword = 'ad-bind-password-super-secret-123' String _server = 'my-primary-ad-server-running.acme.org' // 手动创建Domain对象并绑定所有必填参数 def adDomain = new ActiveDirectoryDomain(_domain, _server, _bindName, _bindPassword) adDomain.site = _site // 初始化Realm并添加配置好的Domain def hudsonActiveDirectoryRealm = new ActiveDirectorySecurityRealm() hudsonActiveDirectoryRealm.domains = [adDomain] // 按需设置其他默认属性(和你之前生成的config.xml保持一致) hudsonActiveDirectoryRealm.startTls = true hudsonActiveDirectoryRealm.groupLookupStrategy = ActiveDirectorySecurityRealm.GroupLookupStrategy.AUTO hudsonActiveDirectoryRealm.removeIrrelevantGroups = false hudsonActiveDirectoryRealm.tlsConfiguration = ActiveDirectorySecurityRealm.TlsConfiguration.TRUST_ALL_CERTIFICATES def instance = Jenkins.getInstance() instance.setSecurityRealm(hudsonActiveDirectoryRealm) instance.save()
为什么原来的代码不行?
查看v2.6版本的ActiveDirectorySecurityRealm源码,那个构造函数的实现简化后是这样的:
public ActiveDirectorySecurityRealm(String domain, String site, String bindName, String bindPassword, String server) { this.domains = Collections.singletonList(new ActiveDirectoryDomain(domain, server)); this.site = site; this.bindName = bindName; this.bindPassword = bindPassword; }
看到没?它创建ActiveDirectoryDomain的时候只传了domain和server,bindName和bindPassword被存在了Realm的全局变量里,并没有关联到Domain对象。但当Jenkins把Realm序列化到config.xml时,只会遍历domains列表里的Domain对象,读取每个Domain自己的bindName,全局的bindName自然不会出现在配置里。
验证结果
用修复后的代码配置后,生成的config.xml会正确包含bindName节点,重启Jenkins后也不会丢失,完全符合你的期望配置。
内容的提问来源于stack exchange,提问作者Patrick Paechnatz

