How to get Jenkins node configurations from groovy - jenkins

I would like to use a groovy script in a job to read all the node configurations as viewed in the Node configuration in the Jenkins GUI. I know that it is possible to use the REST API to fetch node configurations, but I would like to know how to do this using the available library methods, e.g. from a system Groovy script.
I envision something like this pseudo-code to print the Host as it is configured in the "Launch method" setting, if launch method is set to SSH:
jenkins.getNodes().each { node ->
println(node.getLaunchMethod().getHost())
}
The answers to Accessing Jenkins global property in Groovy seems possibly to be relevant?

Related

Unable to determine what the withEnv is doing in Jenkinsfile

I have just started writing Jenkinsfile. I was viewing the following two URLs to learn how to build a Java application, push it to Nexus and then invoke Ansible to deploy.
Redhat Jenkinsfile description
Actual Jenkinsfile
In the second link the following is mentioned several times whose function I am unable to understand:
withEnv(["PATH+MAVEN=${tool 'm3'}/bin"])
What I can find from net is that withEnv is used to create/override a environment variables. But what is ${tool 'm3'}/bin doing? Normally the syntax of withEnv is VARIABLE_NAME=value/expression.
The ${} is substituting a command/variable into the GString. See groovy docs on string Interpolation
From the looks of it, it would be safe to assume tool 'm3' is returning the install path which then gets /bin appended.
So the end result would be
PATH+MAVEN=/my/path/to/m3/etc/bin
Additionally to #metalisticpain's answer, there's some background configuration to the tools directive on the Jenkins server itself that configures the installation paths to be used.
Let's say you have jdk-1.8.0 installed as a tool name on the Jenkins server, then it can be used in the Jenkinsfile as such in your example:
withEnv(["PATH+JDK=${tool 'jdk-1.8.0'}/bin"])
Taken from the documentation linked above:
The tool name must be pre-configured in Jenkins under Manage Jenkins → Global Tool → Configuration.

Securing Jenkins multibranch pipeline for open source projects

How to properly secure Jenkins multibranch pipeline for open source projects?
I work on an open source projects, with community contributions made
using pull requests. I want to build those PR, but if I do so, there
is a risk that those parts get modified and host malicious code or
steal credentials :
the pipeline
the pipeline's dependencies
the test suite
...
For what it worth, I did researches, and my beginner point of view is this:
1/ Find a way to prevent modified code to be executed for :
pipeline
pipeline's dependencies
=> is it even possible?
2/ execute build only on agent never on master
3/ find a way to properly block agents to access secrets (like github/slack tokens)
4/ Find a way to mitigated what a malicious test code can do
the agent's should use a subnet with only this agent and the master
the agent should run on a separate VM/container
2/ execute build only on agent never on master
:- Never use "Agent Any" instead use Agent labels on your pipeline. you can switch your node on pipeline execution by mentioning Agent at stage level.
3/ find a way to properly block agents to access secrets (like github/slack tokens)
:- Use Credentials method and declare it in environment section.
environment {
YOUR_PASSWORD = credentials('<CREDENTIAL_ID>')
}

Extending the Jenkins Groovy DSL

How can I add/edit new code to my Jenkins instance that would be accesible in a DSL script? Context follows
I've inherited a Jenkins instance. Part of this inheritance includes spending the night in a haunted house writing some new automation in groovy via the Jobs DSL plugin. Since I'm fearful of ruining our jenkins instance, my first step is setting up a local development instance.
I'm having trouble running one of our existing DSL Scripts on my local development instance -- my builds on the local server fail with the following in the Jenkins error console.
Processing DSL script jobs.groovy
ERROR: startup failed:
jobs.groovy: 1: unable to resolve class thecompanysname.jenkins.extensions
The script in question starts off like this.
import thecompanysname.jenkins.extensions
use(extensions) {
def org = 'project-name'
def project = 'test-jenkins-repo'
def _email = 'foo#example.com'
So, as near I can tell, it seems like a predecesor has written some custom Groovy code that they're importing
import thecompanysname.jenkins.extensions
What's not clear to me is
Where this code lives
How I can find it in our real Jenkins instance
How I can add to to my local instance
Specific answers are welcome, as our here's how you can learn to fish answers.
While there may be other ways to accomplish this, after a bit of poking around I discovered
The Jenkins instance I've installed has an older version of the Jobs DSL plugin installed.
This version of the Jobs DSL plugin allowed you to set an additional classpath in your Process DSL Builds job section that pointed to additional jar files.
These jar files can give you access to additional classes in your groovy scripts (i.e. thecompanysname.jenkins.extensions)
Unfortunately, more recent versions of the Jobs DSL plugin have removed this option, and it's not clear if it's possible to add it back. That, however, is another question.
Configure Global Security -> uncheck "Enable script security for Job DSL
scripts".
works for me

Environment variable in Jenkins Pipeline

Is there any environment variable available for getting the Jenkins Pipeline Title?
I know we can use $JOB_NAME to get title for a freestyle job,
but is there anything that can be used for getting Pipeline name?
You can access the same environment variables from groovy using the same names (e.g. JOB_NAME or env.JOB_NAME).
From the documentation:
Environment variables are accessible from Groovy code as env.VARNAME or simply as VARNAME. You can write to such properties as well (only using the env. prefix):
env.MYTOOL_VERSION = '1.33'
node {
sh '/usr/local/mytool-$MYTOOL_VERSION/bin/start'
}
These definitions will also be available via the REST API during the build or after its completion, and from upstream Pipeline builds using the build step.
For the rest of the documentation, click the "Pipeline Syntax" link from any Pipeline job
To avoid problems of side effects after changing env, especially using multiple nodes, it is better to set a temporary context.
One safe way to alter the environment is:
withEnv(['MYTOOL_HOME=/usr/local/mytool']) {
sh '$MYTOOL_HOME/bin/start'
}
This approach does not poison the env after the command execution.

Using parameterized credentials in Jenkins

Say I've got dev, qa, and stable server environments for some web app, with corresponding git branches. Each environment should be continuously integrated. Each of these environments has a separate username/password pair used to publish the app. I would like to make a Jenkins multiconfiguration (matrix) job to publish to all of these environments. The publishing almost certainly must be done with a shell script.
My failed attempt consisted of using the Jenkins Credentials and Credentials Binding plugins. Credentials Binding provides a way to inject credentials as environment variables using a parameter. However, setting this parameter dynamically (i.e., something like if ENV == dev: CREDS = CREDS_dev) doesn't appear to be possible. Build scripts happen afterwards, and even using the Environment Script plugin doesn't work.
Is there any way for this to happen?
Had similar situation and used groovy script with parameterized build (https://wiki.jenkins-ci.org/display/JENKINS/EnvInject+Plugin). In my case I had a choice parameter defined as "DEPLOY" and had different values, like "Test", "Release", then in the following groovy script (Evaluated Groovy script):
if ("Test".equals(DEPLOY)) {def map = [DEPLOY_URL: "http://someurl", DEPLOY_STORAGE: "testaccount"]; return map }
You should be able to specify your credentials in here or copy env variables. After that you can access these variables in windows batch command using:
echo %DEPLOY_URL%
echo %DEPLOY_STORAGE%
I also had another choice parameter defined "Deploy.Branch", with values of "dev" and "master". And used it as a parameter to Branches to Build, the value was set to (if you want to dynamically specify branch based on parameters):
*/${Deploy.Branch}
Hope this helps.
Here's what I ended up doing. It's kind of a workaround for what I would argue is a flawed design or missing use case in Jenkins.
Redid my creds so they have standard IDs (this is in the Advanced part and you can't set it after creation)
Matrix job runs a trivial script to figure out what env maps to what creds ID, then triggers...
The main job that does the deployment

Resources