Jenkins : saltstack-plugin

Plugin Information

View SaltStack on the plugin site for more information.

Older versions of this plugin may not be safe to use. Please review the following warnings before using an older version:

This plugin sends a SaltStack API message as a build step

Basic usage

Components

Installing this plugin contributes following:

  • Send a message to Salt API - Build step

There are a few options for how to run a salt job:

local

This is the standard way to run a salt command. If command returns quickly, the results will be returned. Otherwise, if the command is long running, jenkins will not wait.
If you wish to have jenkins wait for a long running command to finish, check the "Wait for completion" checkbox.

Salt syntax: "salt -N nodegroup webservers state.sls apache test=True"

local_batch

Similar to the local operation, but allows for only running the command on a few minions at a time. Jenkins will always wait for all minions to return before finishing, so long running commands will always block the build until finished.

Salt syntax: "salt -b '25%' -N nodegroup webservers state.sls deploy.websites test=True"

subset

Also similar to the local operation, but allows for only running the command on a subset of the target match. Jenkins will always wait for all minions to return before finishing, so long running commands will always block the build until finished.

Salt syntax: salt --subset=4 '*' service.stop zabbix-agent

runner

This allows you to run salt-run commands. It was intended to be used to kick off salt orchestration jobs

Salt syntax: salt-run state.orchestrate orchestration.refresh-apache pillar='{"target":testserver1.domain.com}'

hook

This publishes a message to the salt event bus. Useful for integrating with reactors from Jenkins

Curl syntax: curl -sS localhost:8000/hook/jenkins/notify/slack \
    -H 'Content-type: application/json' \
    -d '{"message": "Build ran"}'

Pipeline

As of the 2.0 release, Jenkins pipeline is supported

import groovy.json.*

node() {
  saltresult = salt authtype: 'pam', clientInterface: local(arguments: '"ls -la"', blockbuild: true,
    function: 'cmd.run', jobPollTime: 16, target: '*', targettype: 'glob'),
    credentialsId: 'a3d814c2-84ed-4752-94a8-271791bb5375', servername: 'http://localhost:8000'
  def prettyJson = JsonOutput.prettyPrint(saltresult)
  println(prettyJson)
}

Declarative Pipeline

Declarative pipelines are supported and function with the blueocean pipeline editor. As of blueocean 1.3 the pipeline editor does not fully render the input fields and requires some adjustments.

Add a step "Send a message to the SaltAPI"

 

Servernamehttp://master.local:8000
Authtypepam
ClientInterface${local(arguments: '"sleep 3; ls -la"', blockbuild: true, function: 'cmd.run', jobPollTime: 6, target: '*', targettype: 'glob')}
CredentialsIdb5f40401-01b9-4b27-a4e8-8ae94bc90250
CheckboxesSaveFile

Add a second step "Run arbitrary Pipeline script" to print results 

env.WORKSPACE = pwd()
def output = readFile "${env.WORKSPACE}/saltOutput.json"
echo output


All together this will create a declarative pipeline Jenkinsfile that looks something like:

JenkinsFile
pipeline {
  agent {
    node {
      label 'agent1'
    }
    
  }
  stages {
    stage('saltcommand') {
      steps {
        salt(authtype: 'pam', clientInterface: local(arguments: '"sleep 3; ls -la"', blockbuild: true, function: 'cmd.run', jobPollTime: 6, target: '*', targettype: 'glob'), credentialsId: 'b5f40401-01b9-4b27-a4e8-8ae94bc90250', saveFile: true, servername: 'http://master.local:8000')
        script {
          env.WORKSPACE = pwd()
          def output = readFile "${env.WORKSPACE}/saltOutput.json"
          echo output
        }
        
      }
    }
  }
}


Configuration

Jenkins

Simply fill out the connection details on the build page.

If using the wait for long commands to finish option, then you may want to adjust either the poll interval or the minion timeout. The default for both options are set on in the Jenkins configuration page or the default can be overwritten from on the individual job.

  • poll interval - controls how often jenkins will check in with the saltapi during a long running job. This can be set to something short (like 5 seconds) if you have a job that completes somewhat quickly. If you have a job that you know will run for an hour, checking every 5 seconds is a bit too frequent.
  • minion timeout - If you have a job that should be run on multiple minions but only some minions return, the minion timeout will set how long to wait for the remaining minions to come back before assuming them offline and marking the build as a failure. This is helpful as without the timeout, the jenkins salt plugin will wait forever for the possibly non-existent minions to return.

Allow the user accessing the salt api to have permission to the necessary salt modules. Also grant access for the @runner returner.

external_auth:
  pam:
    jenkins:
      - test.*
      - pkg.*
      - cmd.*
      - state.*
      - '@runner'

This jenkins module was written to use SaltStack's cherrypy api and tornado (as of 3.0.0). You will need to add something like the following to your salt master's configuration

rest_cherrypy:
  port: 8000
  ssl_crt: /etc/pki/tls/certs/localhost.crt
  ssl_key: /etc/pki/tls/certs/localhost.key
  expire_responses: False

rest_timeout: 7200

Note: some long running jobs may require increasing the rest_timeout or setting the expire_responses options.

You can test if you can access the API with the following command (changing the user and password to the right values).

$ curl -sSk https://<salt-master>:8000/login \
     -H 'Accept: application/x-yaml' \
     -d username=jenkins \
     -d password=jenkins \
     -d eauth=pam

Which would give you something similar to the following output.

return:
- eauth: pam
  expire: 1458563520.558709
  perms:
  - .*
  - test.*
  - pkg.*
  - cmd.*
  - state.*
  - '@runner'
  start: 1458520320.558709
  token: 634c66d581806e5e9dacefbdc721cba45b78f63c
  user: jenkins

Logging Configuration

To see what is sent/received from the salt-api create a jenkins logger:

Name: salt logs
Logger: com.waytta.saltstack
Log level: ALL

To see what http requests are being sent:

Name: http
Logger: sun.net.www.protocol.http.HttpURLConnection
log level: ALL

To get any output from http, you may also need to add a default FINEST Jenkins logger on /jenkins/log/levels

Changelog

Version 3.2.1 (December 14, 2018)

  • Fix github issue 131: ignore non-boolean "success" keys

Version 3.2.0 (August 7, 2018)

  • Add file and auto auth types. Note: As mentioned in upstream documentation, auto is only for testing and not to be used in production!
  • Define global configuration option to specify saltapi version used. This enables:
    • Support tgt_type updates from 2017.7
    • Add full_return to cmd.* modules

    • Validate "success" key if it exists

  • Support batch_wait option
  • Only pass arg or kwarg when not empty (corrects issues with some modules such as saltutil.refresh_grains)

Version 3.1.7 (July 30, 2018)

Version 3.1.6 (March 16, 2018)

  • Runner mods key will only be passed to salt-api when not empty

Version 3.1.5 (Feb 1, 2018)

  • Add option to skip validation of salt return

Version 3.1.4 (Jan 16, 2018)

  • Fix for JEP-200

Version 3.1.3 (Oct 14, 2017)

  • Increase timeout for saltapi response, which improves detection of large results
  • Better error message when minion target matches no minions

Version 3.1.2 (Aug 20, 2017)

  • Don't force = inside of quotes to be kwargs

Version 3.1.1 (July 24, 2017)

  • Correct an issue with hook pipeline jobs

Version 3.1.0 (June 20, 2017)

  • Fix runner jobs with recent SaltAPI
  • Correct Jenkins timeout on long running jobs
  • Support pre 2.0 job import
    • Due to human error, there is a manual step necessary to fully import pre 2.0 build configs. If the Jenkins migrate old data page at administrativeMonitor/OldData/manage shows the error ConversionException: Cannot construct com.waytta.clientinterface.BasicClient then delete the <clientInterface>*</clientInterface> line from the config. This can be done with:
      sed -i'.bak' '/<clientInterface>.*<\/clientInterface>/d' jenkinshome/jobs/jobname/config.xml

      At this point reloading configs should restore the job data.

Version 3.0.0 (April 28, 2017)

  • Supports the Tornado SaltAPI
    • Version bump due to the changes in the return
      Former Cherrypy results
      "return": [{
        "minionid": "Results and output"
      }]

      Tornado and Cherrypy as of this release

      "Result": {
        "minionid": {
          "return": "Results and output"
        }
      }
  • Support setting a minion timeout that does not fail the build
  • Display http errors from SaltAPI rather than showing a parsing problem
  • Add ability to save SaltAPI return to a file - useful for large output or declarative pipeline syntax
  • Retry http connections on timeout
  • Only raise exceptions on errors, don't mark build as failed. This allows for try/catch blocks in pipeline

Version 2.1.0 (March 30, 2017)

  • Support running from Jenkins agents
  • Allow minion timeout to be configured per job

Version 2.0.1 (March 11, 2017)

  • Correct issue where build always waits for minion timeout

Version 2.0.0 (Feb 11, 2017)

  • Support Jenkins pipeline
  • Support folder level credentials
  • Simplify args and kwargs to single input
  • Split on spaces rather than commas in args input to closer match salt cli syntax
  • Salt subset support
  • Salt hook support
  • Detect minion timeouts in order to fail build
  • Allow parameterized batch size

Version 1.7.1 (May 6, 2016)

  • Properly handle missing environment variables
  • Use jenkins logging to record messages to/from salt-api (see above)

Version 1.7.0 (February 29, 2016)

  • Convert from username/password fields to using jenkins credentials
  • Detect additional salt failures
  • Support saving salt return into SALTBUILDOUTPUT environment variable
  • Support JSON pillar data in orchestrate calls

Version 1.6.1 (February 1, 2016)

  • Properly detect salt runners that only return a boolean (fileserver.update)
  • Display a proper error message for runners that return a string (failure of fileserver.update (wink) )

Version 1.6.0 (January 5, 2016)

  • Correct quote handling of arguments and keyword arguments to support both single and double quotes.
  • Add configuration option to output yaml or json to console
  • Improve failure detection
  • Allow paramoized servername

Version 1.5.0 (July 10, 2015)

  • Break out salt kwargs into a separate text input. Resolves issues detecting args including "=" as kwargs.

Version 1.4.0 (Nov 24, 2014)

  • Support SaltStack batch jobs
  • Reconfigure GUI to support both "local" and "local_batch"
  • Support arguments containing python lists

Version 1.3.0 (Nov 7, 2014)

  • Now use JSON when speaking to SaltAPI instead of URL encoding. This fixes some issues with kwarg handling.
  • Improve error detection

Version 1.2.1 (Oct 30, 2014)

  • Clean up space detection around argument separator. Fixes problem of too aggressively removing whitespace in arguments list.

Version 1.2 (Oct 4, 2014)

  • Allow comma separated arguments

Version 1.1 (Sep 7, 2014)

  • Include blocking support

Version 1.0 (Sep 4, 2014)

  • Initial Version

Attachments:

local.png (image/png)
batch.png (image/png)
batch1.png (image/png)
orchestration1.png (image/png)
jenkins.png (image/png)
local.png (image/png)
local_batch.png (image/png)
runner.png (image/png)
runner.png (image/png)
hook.png (image/png)
subset.png (image/png)
Screen Shot 2017-10-14 at 7.33.15 PM.png (image/png)