本文首发于:Jenkins 中文社区git
了解到行业内有些团队是基于 Jenkins 开发 DevOps 平台。而基于 Jenkins 实现的 DevOps 平台,就不得不考虑凭证的管理问题。安全
本文就此问题进行讨论,尝试找出相对合理的管理凭证的方案。闭包
一开始咱们想到的方案多是这样的:用户在 DevOps 平台增长凭证后,DevOps 再将凭证同步到 Jenkins 上。Jenkins 任务在使用凭证时,使用的是存储在 Jenkins 上的凭证,而不是 DevOps 平台上的。ssh
可是,仔细想一想,这样作会存在如下问题:curl
那么,有没有更好的办法呢?加密
先定咱们以为更合理的目标,而后讨论如何实现。如下是笔者以为合理的目标:url
用户仍是在 DevOps 管理本身的凭证。可是 DevOps 不须要将本身凭证同步到 Jenkins 上。Jenkins 任务在使用凭证时,从 DevOps 上取。插件
Jenkins 有一个 Credentials Binding Plugin 插件,在 Jenkins pipeline 中的用法以下:命令行
withCredentials([usernameColonPassword(credentialsId: 'mylogin', variable: 'USERPASS')]) { sh ''' curl -u "$USERPASS" https://private.server/ > output ''' }
withCredentials
方法作的事情就是从 Jenkins 的凭证列表中取出 id 为 mylogin 的凭证,并将值赋到变量名为 USERPASS 的变量中。接下来,你就能够在闭包中使用该变量了。设计
说到这里,不知道读者朋友是否已经有思路了?
思路就是实现一个和 Credentials Binding Plugin 插件相似功能的方法,好比叫 zWithCredentials
(后文还会提到)。与 withCredentials
不一样的是,zWithCredentials
根据凭证 id 获取凭证时,不是从 Jenkins 上获取,而是从 DevOps 平台获取。
withCredentials
方法是将凭证的内容存到变量中,这能够知足一大部分场景。可是有一种场景是没法知足的。就是某些 Jenkins 插件的步骤接收参数时,参数值必须是 Jenkins 凭证管理系统中的 id。好比 git 步骤中 credentialsId 参数:
git branch: 'master', credentialsId: '12345-1234-4696-af25-123455', url: 'ssh://git@bitbucket.org:company/repo.git'
这种状况,咱们不可能修改现有的插件。由于那样作的成本过高了。
那怎么办呢?
笔者想到的办法是在 zWithCredentials
中作一些 hack 操做。也就是 zWithCredentials
除了从 DevOps 平台获取凭证,还在 Jenkins 中建立一个 Jenkins 凭证。在 Jenkins 任务执行完成后,再将这个临时凭证删除。这样就能够适配那些只认 Jenkins 凭证 id 的插件了。
DevOps 平台在存储凭证、传输凭证给 Jenkins 时,都须要对凭证进行加密。至于使用何种加密方式,交给读者思考了。
以上解决方案对 Jenkins 自己的改造几乎没有,咱们只经过一个插件就解耦了 Jenkins 的凭证管理和 DevOps 平台的凭证管理。
思路已经有了。具体怎么实现,因为一些缘由不能开源,虽然实现起来不算难。还请读者见谅。
最后,但愿能和遇到一样问题的同窗进行交流。看看是否还能够有更好的设计思路。
做者:翟志军