How to automate the activation of role-based strategy plugin in jenkins - jenkins

I am working to automate the installation and use of the role-based strategy plugin in Jenkins using ansible. At the moment I can easily install the plugin using the API. However, in order to use the plugin, it is necessary to activate it through the Jenkins UI by clicking 'Manage Jenkins, then Configure System and selecting a role-based strategy.
I am having difficulty automating the activation process since it seems an API does not exist in Jenkins for that. This is my relevant ansible code
- name: Install a role based plugin if it does not exist
uri:
url: "http://localhost:8080/pluginManager/installNecessaryPlugins"
method: POST
user: admin
password: bd7afbedc842418fb7fc27fdf8b3d2e4
force_basic_auth: yes
body: '<jenkins><install plugin="role-strategy#2.9.0" /></jenkins>'
headers:
Content-Type: "text/xml"
follow_redirects: all
when: "'Role-based Authorization Strategy' not in plugins_output_list.content"
ignore_errors: yes
After installing the plugin, is there a way I can activate it without using the UI? I really can't see any API for that purpose.

Your answer is here.
Configure ALL Jenkins initial setup
Fully working Jenkins master with:
no hands on keyboard
no click on UI

Related

How can I install a plugin using jenkinsfile?

Problem Statement
I am using Jenkins for CI/CD automation. I installed the GitHub Pull Request Builder through Jenkin's Plugin Manager.
However I cannot figure out how to do this with a Jenkins Pipeline
Attempts/Documentation
I have skimmed through this exhaustive list of pipeline steps and declarative documentation but cannot find any documentation on how to accomplish this?
Installing Plugin via Jenkinsfile
Firstly, I would question why exactly you want to do this. This is a fairly odd requirement that I have not seen in my 10 years of Jenkins & Hudson experience. With that said, anything that can be done in the Jenkins web interface, and a billion other things that cannot, can be done in either a Pipeline or in the Script Console because these two constructs have access to the entire SDK.
node {
// 'ghprb' is this plugins short name value
GITHUB_PULL_REQUEST_BUILDER = 'ghprb'
for (plugin in [GITHUB_PULL_REQUEST_BUILDER]) {
e = Hudson.instance.updateCenter.getPlugin(plugin).deploy().get().getError()
if (e != null)
println e.message
}
}
Security
Anything you see on the Jenkins GUI can be done in the script console or a pipeline via the Jenkins SDK. Jenkins has implemented a Sandbox to prevent nefarious actors from executing malicious scripts. Your requirement must use the Jenkins/Hudson SDK and therefore you have two options:
Disable the Sandbox for this pipeline
Authorize the scripts and/or methods being used
If you try and run the aforementioned script without solving these security constraints the following exception will be thrown:
org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use method jenkins.model.Jenkins getUpdateCenter
Sandbox
To disable the Sandbox simply uncheck the "Use Groovy Sandbox" checkbox. This is the easiest solution.
Script Approval
If your administrator does not authorize you to outright disable the Sandbox for that job then you can approve the method signatures used in your script or approve the script itself.
The following message signatures would need to be approved for this script
staticMethod hudson.model.Hudson getInstance
method jenkins.model.Jenkins getUpdateCenter
method hudson.model.UpdateSite$Plugin deploy
method java.util.concurrent.Future get
method hudson.model.UpdateCenter$UpdateCenterJob getError
Additional Information
Most likely the plugin will not be available until a restart has occurred. You can automate a restart a variety of ways. You can hit the following endpoints
http://<jenkins.server>/restart
http://<jenkins.server>/safeRestart
You could invoke the jenkins-cli.jar tool. If you're feeling exceptionally risky you could even do something like Jenkins.instance.restart()
Note: don't use the SDK to restart unless you really know what you're doing

How to notify Github after merge job is finished? [duplicate]

Is there a way to show the Jenkins build status on my project's GitHub Readme.md?
I use Jenkins to run continuous integration builds. After each commit it ensures that everything compiles, as well as executes unit and integration tests, before finally producing documentation and release bundles.
There's still a risk of inadvertently committing something that breaks the build. It would be good for users visiting the GitHub project page to know the current master is in that state.
Ok, here's how you can set up Jenkins to set GitHub build statuses. This assumes you've already got Jenkins with the GitHub plugin configured to do builds on every push.
Go to GitHub, log in, go to Settings, Developer Settings, Personal access tokens and click on Generate new token.
Check repo:status (I'm not sure this is necessary, but I did it, and it worked for me).
Generate the token, copy it.
Make sure the GitHub user you're going to use is a repository collaborator (for private repos) or is a member of a team with push and pull access (for organization repos) to the repositories you want to build.
Go to your Jenkins server, log in.
Manage Jenkins → Configure System
Under GitHub Web Hook select Let Jenkins auto-manage hook URLs, then specify your GitHub username and the OAuth token you got in step 3.
Verify that it works with the Test Credential button. Save the settings.
Find the Jenkins job and add Set build status on GitHub commit to the post-build steps
That's it. Now do a test build and go to GitHub repository to see if it worked. Click on Branches in the main repository page to see build statuses.
You should see green checkmarks:
In the meanwhile the UI of Jenkins and GitHub has changed a bit and it took me a while to figure out how to configure Jenkins now correctly. The explanation here is based on Jenkins version 2.121.1.
I also assume that you have already configured your Jenkins Job be triggered by a webhook or by polling.
Those are the steps that I have taken to get it working:
Configure Github: Create Personal Access Token with OAuth Scope repo:status
Configure Jenkins: Configure System and add the OAuth Secret as a GitHub Server - use Secret Text as an authentication method to put the OAuth Secret in there.
Configure your Jenkins Job: Add Set GitHub commit status as Post-build action. Set the Status Result to One of the default messages and statuses.
Check your result on GitHub: Check if you get the build status and build execution duration on your GitHub commit.
Configure Github
Configure Jenkins
Configure Jenkins Job
Result
You will now see the status for your commits and branches:
What I did is quite simple:
Install the Hudson Post Task Plugin
Create a Personal Access Token here : https://github.com/settings/tokens
Add a Post Task Plugin that always put success
curl -XPOST -H "Authorization: token OAUTH TOKEN" https://api.github.com/repos/:organization/:repos/statuses/$(git rev-parse HEAD) -d "{
\"state\": \"success\",
\"target_url\": \"${BUILD_URL}\",
\"description\": \"The build has succeeded!\"
}"
Add a Post Task Plugin that will put failure if "marked build as failure"
curl -XPOST -H "Authorization: token OAUTH TOKEN" https://api.github.com/repos/:organization/:repos/statuses/$(git rev-parse HEAD) -d "{
\"state\": \"failure\",
\"target_url\": \"${BUILD_URL}\",
\"description\": \"The build has failed!\"
}"
You can also add a call to pending at the beginning of tests
curl -XPOST -H "Authorization: token OAUTH TOKEN" https://api.github.com/repos/:organization/:repos/statuses/$(git rev-parse HEAD) -d "{
\"state\": \"pending\",
\"target_url\": \"${BUILD_URL}\",
\"description\": \"The build is pending!\"
}"
This plugin should work: https://wiki.jenkins-ci.org/display/JENKINS/Embeddable+Build+Status+Plugin
You should be able to embed badges like this into your README.md file:
The Commit Status API allows you to see the "Repo Statuses API".
And since April 26th 2013, you now can see the build status on your GitHub repo branch page:
That means it is another way, by visiting the GitHub project page, to see those statuses instead of having only Jenkins.
Starting April 30th, 2013, the API endpoint for commit statuses has been extended to allow branch and tag names, as well as commit SHAs.
There's also the plugin Embeddable Build Status that will give you a badge URL that you can post in your README.md file, and it looks like this:
If you have the GitHub plugin installed on your Jenkins, you can do it in the Post build actions like this:
Add the below line in your README.md file and change both URLs according to your Jenkins project.
[![Build Status](https://jenkins../..project/lastBuild/buildStatus)](https://jenkins../..project/lastBuild/)
In regards with setting up Jenkins and GitHub's protected branch. I'm using Jenkins 2.6, and these are the steps I did to make it work:
On your repository's GitHub webpage:
Navigate to Settings > Branches.
Under Protect branches, click on
the Choose a branch drown down menu and select the branch you want
to set as a Protected branch.
Enable the options as needed.
On the Jenkins Server:
(Make sure you have the Git and GitHub Plugin installed)
Navigate to Manage Jenkins > Configure System.
Under GitHub, set the API URL to https://api.github.com. Though this is the default value.
Select your generated token for the Credentials. If you haven't generated a token yet, click on Advanced... then on Additional actions, you can convert your login and password to token and use it as your credential.
Also, make sure the GitHub account that your Jenkins is using is a collaborator for the repository. I've set it with write permission level.
Hope this helps.
I followed the directions from Alex and it worked.
But, for GitHub Enterprise you need to modify the API URL when adding the server to Jenkins.
For example, if your company is creditcard.com, your URL would be
https://github.creditcard.com/api/v3/
Edit:
I'm no longer using this approach, please use one of the other answers.
Update: what I ended up doing, for our specific case: (above answers were great - thanks!)
Because our build server is not on the internet, we have a script to publish the build status to the gh-pages branch in github.
Start of build stamps failing
End of build stamps success
Project runs after main project to publish results -> build-status, API docs, test reports and test coverage.
GitHub caches images, so we created .htaccess file, that instructs a short cache timeout for the build-status image.
Put this in the directory with the build-status image:
ExpiresByType image/png "access plus 2 minutes"
Here's the build script. The target that publishes to gh-pages is '--publish.site.dry.run'
With less than 400 lines of config, we have:
Compile checks
unit & integration tests
Test Reports
Code Coverage Reports
API Docs
Publishing to Github
. . and this script can be run in or outside of Jenkins, so that:
Developers can run this script before commit, reducing the chance of a broken build that impacts others.
A failure is easy to reproduce locally.
The Results:
Project main page has the build status, updated after each build, along with latest API Docs, test results and test coverage.
Jently updates your GitHub commit status (as described by vonc), but unfortunately they have yet to implement the Repo Status API.
For pipeline projects, you can use the post section like so:
void setBuildStatus(String message, String state) {
step([
$class: "GitHubCommitStatusSetter",
reposSource: [$class: "ManuallyEnteredRepositorySource", url: "https://github.com/my-user/my-repo"],
contextSource: [$class: "ManuallyEnteredCommitContextSource", context: "ci/jenkins/build-status"],
errorHandlers: [[$class: "ChangingBuildStatusErrorHandler", result: "UNSTABLE"]],
statusResultSource: [ $class: "ConditionalStatusResultSource", results: [[$class: "AnyBuildResult", message: message, state: state]] ]
]);
}
pipeline {
agent any
triggers {
githubPush()
}
stages {
stage('Hello') {
steps {
echo 'Hello World'
}
}
}
post {
success {
setBuildStatus("Build succeeded", "SUCCESS");
}
failure {
setBuildStatus("Build failed", "FAILURE");
}
}
}
Just change "https://github.com/my-user/my-repo" to meet your GitHub repository.
Reference: How to set GitHub commit status with Jenkinsfile NOT using a pull request builder
I am adding to this answer, and also to this one. They have answered the question, but they didn't give us a proper intuition about the problem
So, here are my intuitions:
We need to add status to our GitHub commit. This status is based upon the results of our Jenkins build.
To do this, we need to give Jenkins access to the GitHub API, not to the repo. We do this through OAuth, and we can create the token going to the GitHub settings → Developer settings → Personal access tokens. Then for a public GitHub repository just check repo:status, and for a private repository, check the whole repository section
After creating your access token you need to add it to your Jenkins server:
Copy and paste the access token to the GitHub plugin section settings, under your Jenkins configurations
Create a GitHub server. It defaults to api.github.com. And add the access token as a secret text credentials.
The last step is to add a post build settings when you create your pipeline.
Resources:
Here is a section of a YouTube video in which he goes over the above steps.
Read about OAuth

How to configure new BitBucket webhook for Jenkins

Since BitBucket 5.4 it's not necessary anymore to install some plugin to enable webhooks to jenkins (push to bitbucket -> trigger jenkins build).
I'm now trying to configure this on our BitBucket 5.9.1.
I've clicked create webhook on my repo:
Name: test-webhook
URL: https://ourjenkins/
secret: MyToken
In my jenkins job I've configured: Trigger builds remotely (e.g., from scripts) and also added the same token: MyToken.
When I test the setup I got a 403:
Authentication required
<!--
You are authenticated as: anonymous
Groups that you are in:
Permission you need to have (but didn't): hudson.model.Hudson.Read
... which is implied by: hudson.security.Permission.GenericRead
... which is implied by: hudson.model.Hudson.Administer
-->
What am I missing to authenticate? I hoped the token would be used to authenticate but it seems not to work.
Go to Jenkins --> Manage Jenkins --> Configure Global Security
Select Project-based Matrix Authorization Strategy under Authorization
Set permission for Anonymous User to Read / Write Jenkins Jobs. Check for overall Read should work in your case. You can also try other options.

How to configure jenkins slack plugin?

I tried to configure jenkins slack plugin to send a notification to slack channel. But it doesn't work. I followed below instruction:
1. Get a Slack account: https://slack.com/
2. Configure the Jenkins integration: https://my.slack.com/services/new/jenkins-ci
3. Install this plugin on your Jenkins server.
4. Configure it in your Jenkins job (and optionally as global configuration) and add it as a Post-build action.
After I install jenkins on slack app there is a instruction about how to configure jenkins. But the configuration fields mentioned on the instruction is a little different than my jenkins configuration.
Below is the configuration screenshot from the instruction:
the configuration for my jenkins server looks like below:
how can I fill in the Base URL in my configuration? I have tried to fill in my jenkins url but it doesn't work. The test connection failed.
I get below error in jenkins system log:
Slack post may have failed. Response: <html><head><meta http-equiv='refresh' content='1;url=/login?from=%2FOPRc9G4zB2JX289VOnTvfeey'/><script>window.location.replace('/login?from=%2FOPRc9G4zB2JX289VOnTvfeey');</script></head><body style='background-color:white; color:white;'>
Authentication required
<!--
You are authenticated as: anonymous
Groups that you are in:
Permission you need to have (but didn't): hudson.model.Hudson.Read
... which is implied by: hudson.security.Permission.GenericRead
... which is implied by: hudson.model.Hudson.Administer
-->
I have tried to leave base url empty but still doesn't work
After a lot of testing, I figured out the problem. The issue relates to the configuration panel for slack. When I change the slack configuration and hit the test button, it doesn't take the current configuration, instead, it takes the previously saved configuration. I have to save the configuration first then test the connection.
Base URL doesn't need to be filled. Try from Specific Project. Only supply Team SubDomain in Global setting.
You have to provide these info separately for every project:
Team Domain/Sub-Domain
Integration Token(Taken from the Browse Apps > Jenkins CI)
Channel Name
For each Project that you would like receive notifications for, choose Configure from the project's menu in Jenkins.
You'll also need to add Slack Notifications to the Post-build Actions for this project.
Provide the Channel name, Team Subdomain and Integration Token there.
Test the connection.
you can directly run a POST build shell script per project basis or per slack channel
#!/bin/bash
curl -X POST --data-urlencode 'payload={"text": "'"$SLACK_MSG"'"}' $SLACK_WEB_HOOK_URL
where $SLACK_WEB_HOOK_URL and $SLACK_MSG can be exported as env variables or hardcode it for each project
Hay,
you have to add you integration Token to your Jenkins(I would recommend to add a Credential ID but its not necessary), that should sole your Problem. Keep in mind that your Jenkins just can send Messages to channels, the Account which generated the token has access to.
As said previously, you dont have to add a Team-Domain and your Subdomain has to be the following part of your Slack link:
www.EXAMPLE.slack.com
Hopefully i was able to help

How to build with parameters in Jenkins from Gitlab push?

I have GitLab Community Edition 8.15.2 successfully trigger pipeline projects in Jenkins 2.32.1 using a webhook. I want the gitlab push to trigger a build with parameters but the parameter value is null when it comes through so the build fails.
The gitlab webhook looks like:
http://jenkins.server:8080/project/project-a/buildWithParameters?MYPARAM=foo
In my pipeline project I echo the parameter value out with
echo "MYPARAM: ${MYPARAM}"
and it's not set to anything. Any ideas on where I've gone wrong?
UPDATE
The actual code I'm using in the pipeline is:
node {
try {
echo "VM_HOST: ${VM_HOST}"
echo "VM_NAME: ${VM_NAME}"
stage('checkout') {
deleteDir()
git 'http://git-server/project/automated-build.git'
}
stage('build') {
bat 'powershell -nologo -file Remove-MyVM.ps1 -VMHostName %VM_HOST% -VMName "%VM_NAME%" -Verbose'
}
...
}
}
The parameter VM_HOST has a default value but VM_NAME doesn't. In my Console output in Jenkins I can see:
[Pipeline] echo
VM_HOST: HyperVHost
[Pipeline] echo
VM_NAME:
I have been struggling with this for weeks. I had it working once, but I couldn't get it to work again, untill today. And the solution was mindblowingly obvious ofcourse...
Automatically for each pipeline job I ticked the following box:
Build when a change is pushed to GitLab. GitLab CI Service URL:
http://jenkins.dev:8080/project/MyProject
Then from GitLab I used the webhook to trigger the above.
Like you I tried to add /buildWithParameters and tried many other things that didn't work.
The problem was, I ticked the wrong checkbox!
Since I trigger the build from a GitLab webhook, the above checkbox (build when a...) does not have to be checked at all.
What needs to be checked is:
Trigger builds remotely (e.g., from scripts)
That checkbox provides you with a new URL:
Use the following URL to trigger build remotely:
JENKINS_URL/job/MyProject/build?token=TOKEN_NAME or
/buildWithParameters?token=TOKEN_NAME
Like all the documentation I came along states and as you can see, the URL now no longer starts with /project, but with /job instead!
So tick that box and change your URL accordingly:
http://jenkins.server:8080/**job**/project-a/buildWithParameters?token=TOKEN_NAME&MYPARAM=foo
Least I want to mention the token:
In the GitLab webhook there is a seperate field for "token", which states:
Use this token to validate received payloads. It will be sent with the request in the X-Gitlab-Token HTTP header.
So, the token provided there will be sent along the request as a HTTP header.
This is the token which can be provided globally in the Jenkins setup.
The token you must provide in the Jenkins job when ticking the box Use the following URL to trigger build remotely must be send in the URL as GET parameter, just like the example shows.
Final note: personally I have never got this working completely, because I don't get the Jenkins CSRF protection off my back. Disabling it gives me another error. However, hopefully the above does fix the problem for you and others.
GitLab plugin does not allow you to pass arbitrary parameters. In their project there is an open issue for it that deserves to be upvoted.
My convoluted solution was to use the desired values for the push trigger as the default parameters of the job. Then I used the Parameterized Scheduler plugin to use other values in the scheduled executions.
The problem is that I got a bad usability for the job when it was manually run, since the default parameters were appropriate for the push hook.
I found the solution here https://www.jittagornp.me/blog/jenkins-gitlab-webhook/
I verified it with Jenkins 2.263.1 and GitLab Community Edition 13.6.1
Your webhook url will look like
https://hunter:11a403302a4f01b9b4975c0ac27441a5cc#jenkinsservername.com/job/yourjenkinsproject/buildWithParameters?token=Aju9ryHUu6t7W8wLSeCWtY2bWjzQduYNPyY7B3gs&yourparam=yourvalue
"hunter" ist your username in Jenkins.
The following is the Jenkins API Token you have to create in your Jenkins User Managment independent of the project.
The last Token is the one you specify in the jenkins project options under "Trigger builds remotely (e.g., from scripts)"
The last thing is to add your Parameter and value to the url with &param=value

Resources