通过脚本更新Jenkins凭据

Bil*_*urt 13 scripting jenkins

我在Windows上运行Jenkins服务器.它在凭证插件中存储用户名:密码.这是一个定期更新其密码的服务用户.

我正在寻找一种方法来运行一个脚本,最好是Powershell,它将更新Jenkins密码存储区中的凭证,以便在构建作业脚本中使用它时始终保持最新状态.

密码是由Thycotic Secret Server安装管理的,所以我应该能够自动保持这个密码最新的过程,但我发现几乎没有任何线索如何实现这一点,即使写的人的博客帖子凭证几乎完全提到了这种情况,然后继续链接到凭证插件的下载页面,该页面没有说明如何实际使用api.

更新

接受的答案完美无缺,但其余的方法调用示例使用curl,如果您使用的是Windows,则无济于事.特别是如果您尝试调用REST URL但Jenkins服务器正在使用AD Integration.要实现此目的,您可以使用以下脚本.

通过转到人员>用户>配置>显示API令牌来查找userId和API令牌.

$user = "UserID"
$pass = "APIToken"
$pair = "${user}:${pass}"

$bytes = [System.Text.Encoding]::ASCII.GetBytes($pair)
$base64 = [System.Convert]::ToBase64String($bytes)

$basicAuthValue = "Basic $base64"

$headers = @{ Authorization = $basicAuthValue }



Invoke-WebRequest `
    -uri "http://YourJenkinsServer:8080/scriptler/run/changeCredentialPassword.groovy?username=UrlEncodedTargetusername&password=URLEncodedNewPassword" `
    -method Get `
    -Headers $headers
Run Code Online (Sandbox Code Playgroud)

Tho*_*eil 19

Jenkins支持使用Groovy语言编写脚本.您可以通过在浏览器中打开Jenkins实例的URL 来获取脚本控制台/script.(即:http:// localhost:8080/script)

Groovy语言(在powershell或其他任何方面)的优点是那些Groovy脚本在Jenkins中执行并且可以访问所有内容(配置,插件,作业等).

然后,以下代码将用户'BillHurt'的密码更改为's3crEt!':

import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl

def changePassword = { username, new_password ->
    def creds = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
        com.cloudbees.plugins.credentials.common.StandardUsernameCredentials.class,
        Jenkins.instance
    )

    def c = creds.findResult { it.username == username ? it : null }

    if ( c ) {
        println "found credential ${c.id} for username ${c.username}"

        def credentials_store = Jenkins.instance.getExtensionList(
            'com.cloudbees.plugins.credentials.SystemCredentialsProvider'
            )[0].getStore()

        def result = credentials_store.updateCredentials(
            com.cloudbees.plugins.credentials.domains.Domain.global(), 
            c, 
            new UsernamePasswordCredentialsImpl(c.scope, c.id, c.description, c.username, new_password)
            )

        if (result) {
            println "password changed for ${username}" 
        } else {
            println "failed to change password for ${username}"
        }
    } else {
      println "could not find credential for ${username}"
    }
}

changePassword('BillHurt', 's3crEt!')
Run Code Online (Sandbox Code Playgroud)

经典自动化(/scriptText)

要自动执行此脚本,可以将其保存到文件中(比方说/tmp/changepassword.groovy)并运行以下curl命令:

curl -d "script=$(cat /tmp/changepassword.groovy)" http://localhost:8080/scriptText
Run Code Online (Sandbox Code Playgroud)

哪个应该回复HTTP 200状态和文字:

找到用户名BillHurt的凭证801cf176-3455-4b6d-a461-457a288fd202

BillHurt的密码已更改

使用Scriptler插件自动化

您还可以安装Jenkins Scriptler插件并按以下步骤操作:

在此输入图像描述

  • 在侧边菜单中打开Scriptler工具

在此输入图像描述

  • 填写3个第一个字段,注意将Id字段设置为changeCredentialPassword.groovy
  • 选中Define script parameters复选框
  • 添加2个参数:usernamepassword
  • 粘贴以下脚本:
    import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl

    def changePassword = { username, new_password ->
        def creds = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
            com.cloudbees.plugins.credentials.common.StandardUsernameCredentials.class,
            jenkins.model.Jenkins.instance
        )

        def c = creds.findResult { it.username == username ? it : null }

        if ( c ) {
            println "found credential ${c.id} for username ${c.username}"

            def credentials_store = jenkins.model.Jenkins.instance.getExtensionList(
                'com.cloudbees.plugins.credentials.SystemCredentialsProvider'
                )[0].getStore()

            def result = credentials_store.updateCredentials(
                com.cloudbees.plugins.credentials.domains.Domain.global(), 
                c, 
                new UsernamePasswordCredentialsImpl(c.scope, null, c.description, c.username, new_password)
                )

            if (result) {
                println "password changed for ${username}" 
            } else {
                println "failed to change password for ${username}"
            }
        } else {
          println "could not find credential for ${username}"
        }
    }

    changePassword("$username", "$password")
Run Code Online (Sandbox Code Playgroud)
  • 然后单击Submit按钮

现在您可以调用以下URL来更改密码(替换usernamepassword参数):http:// localhost:8080/scriptler/run/changeCredentialPassword.groovy?username = BillHurt&password = s3crEt%21(注意需要对参数进行urlencode '值)

或卷曲:

curl -G http://localhost:8080/scriptler/run/changeCredentialPassword.groovy --data-urlencode 'username=BillHurt' --data-urlencode "password=s3crEt!"
Run Code Online (Sandbox Code Playgroud)

来源:

搜索引擎提示:使用关键字'Jenkins.instance.','com.cloudbees.plugins.credentials'UsernamePasswordCredentialsImpl


ako*_*nov 5

决定写一个新答案,尽管它基本上是对 @Tomasleveil 答案的一些更新:

  • 删除已弃用的调用(感谢jenkins wiki,有关其他列表选项,请参阅插件消费者指南
  • 添加一些评论
  • 保留凭据 ID 以避免破坏现有作业
  • 通过描述查找凭据,因为用户名很少如此独特(读者可以轻松地将其更改为 ID 查找)

事情是这样的:

credentialsDescription = "my credentials description"
newPassword = "hello"

// list credentials
def creds = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
    // com.cloudbees.plugins.credentials.common.StandardUsernameCredentials to catch all types
    com.cloudbees.plugins.credentials.common.UsernamePasswordCredentials.class,
    Jenkins.instance,
    null,
    null
);

// select based on description (based on ID might be even better)
cred = creds.find { it.description == credentialsDescription}
println "current values: ${cred.username}:${cred.password} / ${cred.id}"

// not sure what the other stores would be useful for, but you can list more stores by
// com.cloudbees.plugins.credentials.CredentialsProvider.all()
credentials_store = jenkins.model.Jenkins.instance.getExtensionList(
                'com.cloudbees.plugins.credentials.SystemCredentialsProvider'
                )[0].getStore()

// replace existing credentials with a new instance
updated = credentials_store.updateCredentials(
                com.cloudbees.plugins.credentials.domains.Domain.global(), 
                cred,
                // make sure you create an instance from the correct type
                new com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl(cred.scope, cred.id, cred.description, cred.username, newPassword)
                )

if (updated) {
  println "password changed for '${cred.description}'" 
} else {
  println "failed to change password for '${cred.description}'"
}
Run Code Online (Sandbox Code Playgroud)