I want to create jenkins credentials via ansible - jenkins

I am putting together a developer machine using ansible. In that machine i am installing jenkins.
I have created the jobs for jenkins with ansible:
- shell: "java -jar {{ jenkins.cli_jar }} -s {{ jenkins.server }} create-job \
{{ item.name }} < {{ jenkins.jobs_dir }}/{{ item.xml_file }}"
with_items: "jenkins.jobs"
And installed the plugins, via cli etc.
But now i am missing the ssh credentials for the jobs; i just want a ssh credential with user "jenkins" and that uses "From the Jenkins master ~/.ssh".
This type of credentials are the ones i am talking about:
Maybe is a groovy script but i haven't find a lot of information about it. Thanks for the help.

You can use the jenkins client from command line on the machine where the jenkins runs like:
java -jar jenkins-cli.jar -s http://localhost:8080/ groovy create-credential.groovy
with create-credential.groovy:
import jenkins.model.*
import com.cloudbees.plugins.credentials.CredentialsScope
import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl
def addPassword = { 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}"
} else {
def credentials_store = Jenkins.instance.getExtensionList(
'com.cloudbees.plugins.credentials.SystemCredentialsProvider'
)[0].getStore()
def scope = CredentialsScope.GLOBAL
def description = ""
def result = credentials_store.addCredentials(
com.cloudbees.plugins.credentials.domains.Domain.global(),
new UsernamePasswordCredentialsImpl(scope, null, description, username, new_password)
)
if (result) {
println "credential added for ${username}"
} else {
println "failed to add credential for ${username}"
}
}
}
addPassword('pinky', 'narf')
This will add the global credential for user 'pinky' with password 'narf'

As of version 2.1.1 of the plugin (June 2016) this is possible through the CLI or the REST API:
https://github.com/jenkinsci/credentials-plugin/blob/master/docs/user.adoc#creating-a-credentials
from that page:
$ cat > credential.xml <<EOF
<com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>
<scope>GLOBAL</scope>
<id>deploy-key</id>
<username>wecoyote</username>
<password>secret123</password>
</com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>
EOF
$ curl -X POST -H content-type:application/xml -d #credential.xml \
https://jenkins.example.com/job/example-folder/credentials/store/folder/\
domain/testing/createCredentials

Jenkins credentials plugin doesn't allow credentials creation using API (https://issues.jenkins-ci.org/browse/JENKINS-28407).
A viable solution would be recording a credential creation using your prefered browser and JMeter proxy or Selenium IDE. and replaying it using JMeter CLI or saving the Selenium recorded test as a groovy script.
You may also take a look at https://github.com/jenkinsci/credentials-plugin/pull/33

Here is an example ansible task that uses "jenkins_script" instead of directly specifying the CLI or calling the REST API, and it adds the benefit of updating existing credentials.
- name: establish credentials
jenkins_script:
script: |
import jenkins.model.*
import com.cloudbees.plugins.credentials.CredentialsProvider
import com.cloudbees.plugins.credentials.CredentialsScope
import com.cloudbees.plugins.credentials.common.StandardUsernameCredentials
import com.cloudbees.plugins.credentials.domains.Domain
import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl
def domain = Domain.global()
def instance = Jenkins.instance
def credstore = instance.getExtensionList(
'com.cloudbees.plugins.credentials.SystemCredentialsProvider'
)[0].getStore()
def existingCreds = CredentialsProvider.lookupCredentials(
StandardUsernameCredentials.class, instance).findResult {
it.username == '${username}' ? it : null
}
def newCreds = new UsernamePasswordCredentialsImpl(
CredentialsScope.GLOBAL, null,
'${description}', '${username}', '${password}')
if (existingCreds) {
credstore.updateCredentials(domain, existingCreds, newCreds)
} else {
credstore.addCredentials(domain, newCreds)
}
args:
description: "entrada credential"
username: "{{ item.username }}"
password: "{{ item.password }}"
user: "{{ entrada_user_name }}"
password: "{{ entrada_user_password }}"
with_items: "{{ entrada_cicd_credentials }}"

Related

Edit user in Jenkins via groovy script

I am wondering if I can change password, username, email in Jenkins user. Because I am able to create user via groovy script like this:
import hudson.model.*
def user = instance.securityRealm.createAccount(userId, password)
user.addProperty(new Mailer.UserProperty(email));
instance.save()
Jenkins interface allows me to manage user credentials, but script which allow to change password/email/username would be very helpfull. I didnt find examples.
I tried many times with script like this, but It didnt work
import hudson.model.*
User user = User.getAll().get(1)
user.setProperty(newPassword)
Here's a simple code that works :
import jenkins.model.*
import hudson.security.*
import hudson.tasks.Mailer
def env = System.getenv()
def jenkins = Jenkins.getInstance()
if(!(jenkins.getSecurityRealm() instanceof HudsonPrivateSecurityRealm))
jenkins.setSecurityRealm(new HudsonPrivateSecurityRealm(false))
if(!(jenkins.getAuthorizationStrategy() instanceof GlobalMatrixAuthorizationStrategy))
jenkins.setAuthorizationStrategy(new GlobalMatrixAuthorizationStrategy())
// update admin Jenkins user account
def user = jenkins.getSecurityRealm().getUser('admin')
email= 'jenkins-admin#gmail.com'
user.addProperty(new Mailer.UserProperty(email));
For Jenkins Jenkins 2.361.1, I have used such Jenkins groovy script to update user's password:
User.getById("userName",false).addProperty(hudson.security.HudsonPrivateSecurityRealm.Details.fromPlainPassword("new-password"));
You can also easily run it from bash script or similar, given $USERNAME and $PASSWORD are set:
echo "script=User.getById(\"$USERNAME\",false).addProperty(hudson.security.HudsonPrivateSecurityRealm.Details.fromPlainPassword(\"$PASSWORD\"));" | \
curl -d #- --user admin:access_token http://<ip>:8080/scriptText

Jenkins - Hide sensitive data from pipeline steps page (flowGraphTable)

I am writing a sensitive data to a .yml file as a string in my Jenkins groovy file. I have attached the .groovy file which would show what I am trying to achieve but it reveals the data in Pipeline steps which is also attached. Nothing shows in the console log. Value from AWS Parameter store is retrieved and passed as a string to a .yml file and this string value is shown in the pipeline steps. I am looking for a way to hide this from being shown in the Pipeline steps. I have tried using set +x but it is not hiding the string value in the pipeline steps. Any thoughts on how this can be achieved would be of great help.Screenshot
#!/usr/bin/env groovy
properties([
parameters([
string(name:'NODE_NAME', defaultValue: 'node', description: 'Node Name')
])
])
nodeName = params.NODE_NAME
node("${nodeName}") {
def AWS_REGION = "eu-west-2"
def paramPath = "path"
def paramName = "PASSWORD"
stage("Data from SSM") {
param = sh (script: "aws ssm get-parameter --name ${paramPath} --with-decryption --region ${AWS_REGION} | /var/jenkins_home/tools/jq .Parameter.Value | tr -d '\"'", returnStdout: true).trim()
sh('#!/bin/sh -e\n' + "echo '${paramName}: ${param}' >> vars.yml")
}
}
You can make use of credentials in jenkins. Go to Jenkins -> credentials -> global -> add credentials
Select either 'Username with password'/'secret text' depending on your need
This will generate a secret in jenkins
Then in your groovy file you can use the credentials as env variables which will not be printed by jenkins
withCredentials([usernamePassword(credentialsId: 'Your-Credential-ID', passwordVariable: 'pwdToken', usernameVariable: 'userToken')]){
//Use pwdToken as a variable here which will not be printed
}

How to use jenkins plugin for username with password in dsl?

I'm new to jenkins and I'm trying to use the credentials in a dsl using the credentials plugin
template.xml
<com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>
<scope>GLOBAL</scope>
<id>PROD</id>
<description>prod credentials</description>
<username>prod</username>
<password>{{ encrypted_password_prod }}</password
</com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>
I have defined the credentials in jenkins as username with password . the above encrypted value is saved in ansible.
My question is how should i call them in my dsl
Map credentials = [:]
credentialsBinding {
credentials.each { key, value ->
string("${key}", "${value}")
}
.credentials(["TF_VAR_username": "PROD" ,"TF_VAR_password" : "password_prod"])
Error:
22:11:16 FATAL: Credentials 'PROD' is of type 'Username with password'
where 'org.jenkinsci.plugins.plaincredentials.StringCredentials' was
expected
You can put credentials in Jenkins keystore (Jenkins -> Credentials -> System -> Global credentials -> Add Credentials), and then refer to them in your pipeline using withCredentials block like this:
node {
withCredentials([usernameColonPassword(credentialsId: 'mylogin', variable: 'USERPASS')]) {
sh '''
set +x
curl -u "$USERPASS" https://private.server/ > output
'''
}
}
More info here: https://jenkins.io/doc/pipeline/steps/credentials-binding/

Automate Jenkins Keycloak plugin with groovy script

i try to 100% automating the deployment of Jenkins with Keycloak plugin with Docker-compose. The objectiv is that we do not want to do anything but run a single command.
To automate Jenkins, I tried to use the Jenkins API but the Groovy script seems to be the best and easiest solution. The problem is that I am not a developper ...
I try something like this, but it's failed at Keycloak conf :
Failed to run script file:/var/jenkins_home/init.groovy.d/init.groovy groovy.lang.GroovyRuntimeException: Could not find matching constructor for: org.jenkinsci.plugins.KeycloakSecurityRealm(java.lang.Boolean)
import jenkins.model.*
import hudson.security.*
import org.jenkinsci.plugins.*
def instance = Jenkins.getInstance()
def env = System.getenv()
def hudsonRealm = new HudsonPrivateSecurityRealm(false)
String password = env.JENKINS_PASSWORD
hudsonRealm.createAccount("admin", password)
instance.setSecurityRealm(hudsonRealm)
instance.save()
def keycloak_realm = new KeycloakSecurityRealm(true)
instance.setSecurityRealm(keycloak_realm)
instance.setAuthorizationStrategy(new FullControlOnceLoggedInAuthorizationStrategy())
instance.save()
In the end, i want to
create an admin user
configure the Keycloak plugin
set the users autorisations.
Thanks you in advance for your help :)
A possibly outdated issue, but I would like to share that I also had problems using Groovy scripts in the init.groovy.d to maintain the configurations in Jenkins, including Keycloak configurations. And the best way to solve it was through a declarative model using the Jenkins Configuration as Code (JCasC) plugin.
Examples:
Keycloak
jenkins:
securityRealm: keycloak
unclassified:
keycloakSecurityRealm:
keycloakJson: |-
{
"realm": "my-realm",
"auth-server-url": "https://my-keycloak-url/auth",
"ssl-required": "all",
"resource": "jenkins",
"public-client": true,
"confidential-port": 0
}
source: https://github.com/jenkinsci/configuration-as-code-plugin/tree/master/demos/keycloak
Credentials
credentials:
system:
domainCredentials:
- domain:
name: "test.com"
description: "test.com domain"
specifications:
- hostnameSpecification:
includes: "*.test.com"
credentials:
- usernamePassword:
scope: SYSTEM
id: sudo_password
username: root
password: ${SUDO_PASSWORD}
source: https://github.com/jenkinsci/configuration-as-code-plugin/tree/master/demos/credentials
Following solution works for me.
#!/usr/bin/env groovy
import jenkins.model.Jenkins
import hudson.security.*
import org.jenkinsci.plugins.KeycloakSecurityRealm
Jenkins jenkins = Jenkins.get()
def desc = jenkins.getDescriptor("org.jenkinsci.plugins.KeycloakSecurityRealm")
// JSON based on the keycloak configuration
desc.setKeycloakJson( "{\n" +
" \"realm\": \"myRealm\",\n" +
" \"auth-server-url\": \"https://keycloak/auth/\",\n" +
" \"ssl-required\": \"external\",\n" +
" \"resource\": \"jenkins\",\n" +
" \"public-client\": true,\n" +
" \"confidential-port\": 0\n" +
"}")
desc.save()
jenkins.setSecurityRealm(new KeycloakSecurityRealm())
def strategy = new FullControlOnceLoggedInAuthorizationStrategy()
strategy.setAllowAnonymousRead(false)
jenkins.setAuthorizationStrategy(strategy)
jenkins.save()

Jenkins mask passwords use in "Execute system Groovy script"

im trying to undeploy/deploy an application to a Tomcat via jenkins using "system Groovy script".
For the undeploy/deploy i need credentials.
These i masked in the jenkins job via "mask passwords" (user and password)
Im not able to use these variables in my "system Groovy script" properly.
when i use the credentials in the script directly it works fine.
This is my "system Groovy script":
def ant = new AntBuilder()
//def user = build.getEnvVars()['user']
//def password = build.getEnvVars()['password']
ant.taskdef( name: 'deploy', classname: 'org.apache.catalina.ant.DeployTask' )
ant.taskdef( name: 'undeploy', classname: 'org.apache.catalina.ant.UndeployTask' )
ant.undeploy(
url:deployURL,
username:"${user}",
password:"${password}",
path:deployPath,
failonerror:true)
ant.deploy(
url:deployURL,
username:"${user}",
password:"${password}",
path:deployPath
war:warfile)
Jenkins Credentials Store Access via Groovy
I used the solution from the link above in the following way:
def credentials_store = jenkins.model.Jenkins.instance.getExtensionList(
'com.cloudbees.plugins.credentials.SystemCredentialsProvider')
credentials_store[0].credentials.each { ThisJenkins ->
if (ThisJenkins instanceof com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl) {
if (ThisJenkins.username == "MyUser") {
user = ThisJenkins.username
password = ThisJenkins.password
}
}
}
later on i used the "user" and "password" for my deployment:
ant.undeploy(
url:'MyServer',
username: user,
password: password,
path:'/MyTool',
failonerror:false)

Resources