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
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!')
/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
You can also install the Jenkins Scriptler plugin and proceed as follow:
changeCredentialPassword.groovy
username
and password
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")
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:
Search engine tip: use keywords 'Jenkins.instance.'
, 'com.cloudbees.plugins.credentials'
and UsernamePasswordCredentialsImpl
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With