Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

update Jenkins credentials by script

I have a Jenkins server running on Windows. It stores a username:password in the credentials plugin. This is a service user that gets its password updated regularly.

I'm looking for a way to run a script, preferably Powershell, that will update that credential in the Jenkins password store so that it's always up to date when I use it in a build job script.

The password is managed by a Thycotic Secret Server install so I should be able to automate the process of keeping this password up to date, but I have found almost no leads for how to accomplish this, even though the blog post by the guy who wrote the credentials api mentions almost exactly this scenario and then proceeds to just link to the credentials plugin's download page that says nothing about how to actually use the api.

Update

The accepted answer works perfectly, but the rest method call example is using curl, which if you're using windows doesn't help much. Especially if you are trying to invoke the REST URL but your Jenkins server is using AD Integration. To achieve this you can use the following script.

Find the userId and API Token by going to People > User > configure > Show API Token.

$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
like image 310
Bill Hurt Avatar asked Aug 25 '15 16:08

Bill Hurt


1 Answers

Jenkins supports scripting with the Groovy language. You can get a scripting console by opening in a browser the URL /script of your Jenkins instance. (i.e: http://localhost:8080/script)

The advantage of the Groovy language (over powershell, or anything else) is that those Groovy scripts are executed within Jenkins and have access to everything (config, plugins, jobs, etc).

Then the following code would change the password for user 'BillHurt' to '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!')

Classic automation (/scriptText)

To automate the execution of this script, you can save it to a file (let's say /tmp/changepassword.groovy) and run the following curl command:

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

which should respond with a HTTP 200 status and text:

found credential 801cf176-3455-4b6d-a461-457a288fd202 for username BillHurt

password changed for BillHurt

Automation with the Scriptler plugin

You can also install the Jenkins Scriptler plugin and proceed as follow:

enter image description here

  • Open the Scriptler tool in side menu

enter image description here

  • fill up the 3 first field taking care to set the Id field to changeCredentialPassword.groovy
  • check the Define script parameters checkbox
  • add 2 parameters: username and password
  • paste the following script:
    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")
  • and click the Submit button

Now you can call the following URL to change the password (replacing the username and password parameter): http://localhost:8080/scriptler/run/changeCredentialPassword.groovy?username=BillHurt&password=s3crEt%21 (notice the need to urlencode the parameters' value)

or with curl:

curl -G http://localhost:8080/scriptler/run/changeCredentialPassword.groovy --data-urlencode 'username=BillHurt' --data-urlencode "password=s3crEt!"

sources:

  • Printing a list of credentials and their IDs
  • Create UserPrivateKeySource Credential via Groovy?
  • credential plugin source code
  • Scriptler plugin

Search engine tip: use keywords 'Jenkins.instance.', 'com.cloudbees.plugins.credentials' and UsernamePasswordCredentialsImpl

like image 144
Thomasleveil Avatar answered Sep 21 '22 12:09

Thomasleveil