I've been searching the whole web for a snippet on how to create GitLab API credential with groovy. and creating Gitlab connection using that API credential for 'Build merge request' purposes, It would be really helpful. Thanks in advance
UPDATE:
I found a solution anyway. I created the GitlabAPI creds manually and took its XML and parsed it with jinja2 to make it dynamic. then I've passed it to the Jenkins CLI create creds by xml
cat /tmp/gitlab-credential.xml | \
java -jar {{ cli_jar_location }} \
-s http://{{ jenkins_hostname }}:{{ http_port }} \
create-credentials-by-xml "SystemCredentialsProvider::SystemContextResolver::jenkins" "(global)"
I encountered similar need to create the gitlab api credential via groovy. Below is the solution I managed to figure out, adapted from https://gist.github.com/iocanel/9de5c976cc0bd5011653
import jenkins.model.*
import com.cloudbees.plugins.credentials.*
import com.cloudbees.plugins.credentials.common.*
import com.cloudbees.plugins.credentials.domains.*
import com.cloudbees.plugins.credentials.impl.*
import com.dabsquared.gitlabjenkins.connection.*
import hudson.util.Secret
domain = Domain.global()
store = Jenkins.instance.getExtensionList('com.cloudbees.plugins.credentials.SystemCredentialsProvider')[0].getStore()
token = new Secret("my-token")
gitlabToken = new GitLabApiTokenImpl(
CredentialsScope.GLOBAL,
"gitlab-token",
"token for gitlab",
token
)
store.addCredentials(domain, gitlabToken)
Related
below error pops when I try to target a CDK pipeline using events targets.
jsii.errors.JavaScriptError:
Error: Resolution error: Supplied properties not correct for "CfnRuleProps"
targets: element 0: supplied properties not correct for "TargetProperty"
arn: required but missing.
code is below
from aws_cdk import (
core,
aws_codecommit as codecommit,
aws_codepipeline as codepipeline,
aws_events as events,
aws_events_targets as targets
)
from aws_cdk import pipelines
from aws_cdk.pipelines import CodePipeline, CodePipelineSource, ShellStep
class BootStrappingStack(core.Stack):
def __init__(self, scope: core.Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs
repo = codecommit.Repository(
self, 'Repository',
repository_name='Repository'
)
source_artifact = codepipeline.Artifact()
cloud_assembly_artifact = codepipeline.Artifact()
pipeline = CodePipeline(self, 'Pipeline',
synth=ShellStep("Synth",
input=CodePipelineSource.code_commit(
repository=repo,
branch='master'),
commands=[
'pip install -r requirements',
'npm install -g aws-cdk',
'cdk synth']
)
)
rule = events.Rule(self, 'TriggerPipeline',
schedule=events.Schedule.expression('rate(1 hour)')
)
rule.add_target(targets.CodePipeline(pipeline))
The documentation for aws_cdk.events_targets works with codepipeline construct, however doesn't work as documented for cdk pipelines.
This needs to be addressed in the documentation, once I get to know what's the fix. Please help.
As mentioned by #Otavio, you need to use the codepipeline.IPipeline.
You can use the pipeline property from CDK CodePipeline construct but in order to use that first you need to construct the pipeline using build_pipeline() method:
pipeline = CodePipeline(self, 'Pipeline',
synth=ShellStep("Synth",
input=CodePipelineSource.code_commit(
repository=repo,
branch='master'),
commands=[
'pip install -r requirements',
'npm install -g aws-cdk',
'cdk synth']
)
)
# You need to construct the pipeline before passing it as a target in rule
pipeline.build_pipeline()
rule = events.Rule(self, 'TriggerPipeline',
schedule=events.Schedule.expression('rate(1 hour)')
)
# Using the pipeline property from CDK Codepipeline
rule.add_target(targets.CodePipeline(pipeline.pipeline))
The problem is that targets.CodePipeline receives a codepipeline.IPipeline as a parameter. But what you are using instead is a pipelines.CodePipeline, which is a different thing. CodePipeline is more abstract construct, built on top of the codepipeline module.
You can try this:
const pipeline = new CodePipeline(self, 'Pipeline' ....
Then:
rule.addTarget(new targets.CodePipeline(pipeline))
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
I am using jenkins with Jobdsl to create jenkins jobs. I am trying to build a parameterized job by adding a groovy script in active choice parameter. The script uses a credential stored in jenkins credential, I am trying to fetch it in my script by using the code
import jenkins.model.*
import jenkins.*
import jenkins.model.*
import hudson.*
import hudson.model.*
credentialsId = '1672622gjj'
def jenkinsCredentials = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
com.cloudbees.plugins.credentials.Credentials.class,
Jenkins.instance,
null,
null
).find{it.id == credentialsId};
def creds = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
com.cloudbees.plugins.credentials.common.StandardUsernameCredentials.class, Jenkins.instance, null, null ).find{
it.id == credentialsId}
println(creds.username)
println(creds.password)
This code gives me the credential name and password but the result of the branches is blank. I am using `creds.password` as the authorization token.
What I am doing wrong?
You can replace the string there the same way, you do already with your script name (+ the strings), yet this not groovy at all.
So this should work:
... "curl ... 'Authorization: token ${creds.password}' ...
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()
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 }}"