Jenkins input pipeline step filled via POST with CSRF - howto?

后端 未结 4 1304
陌清茗
陌清茗 2021-01-12 22:13

I have Jenkins pipeline with an Input step, and I would like to submit this input(single string argument) via a script. So far I am trying with curl, ideally I\'ll be sendi

相关标签:
4条回答
  • 2021-01-12 22:27

    There is an easier way, simply call the proceedEmpty URL for the jobs:

    curl -X POST -H "Jenkins-Crumb:${JENKINS_CRUMB}" http://${JENKINS_URL}/job/${JOB_NAME}/${BUILD_ID}/input/${INPUT_ID}/proceedEmpty
    

    There is no need to pass in body data.

    To abort, use:

    curl -X POST -H "Jenkins-Crumb:${JENKINS_CRUMB}" http://${JENKINS_URL}/job/${JOB_NAME}/${BUILD_ID}/input/${INPUT_ID}/abort
    
    0 讨论(0)
  • 2021-01-12 22:37

    I just downloaded the latest stable release of Jenkins (2.7.2) and tested the csrf mechanism and it seems like it worked as expected.

    For example, the following command successfully kicked off a job called "test".

    curl -X POST -u admin:test --header "Jenkins-Crumb:9c771b9e74d8d1d4b80766b63165c79d" http://localhost:8080/job/test/build
    

    That being said, your command looks like it should work. Could you try the following to narrow down the problem:

    1. Try to kick off a build using the csrf mechanism rather than using the Jenkins input pipeline. This will at least let us know if it's the csrf that's causing the problem or the plugin.
    2. Try a newer version of Jenkins (if you're not on the latest stable).

    Let me know your results.

    0 讨论(0)
  • 2021-01-12 22:37

    For properly using the wfapi I'd like to recommend the following bash script. You need an API user on jenkins. The API user should have the permissions Overall/Read, Job/Read and Job/Build set using Jenkins -> Manage Jenkins -> Manage and Assign Roles.

    Let's assume your build is paused using

    input message: 'Does the build work on the Testserver?', ok: 'Yes'
    

    The following script will continue it. This is a simplified version, without any checks. It assumes that the most recent build is paused waiting for input. You need to change the variables at the top to match your environment.

    #!/bin/bash
    JENKINS_SERVER_URL=https://www.example.com
    JENKINS_URL=${JENKINS_SERVER_URL}/jenkins
    JENKINS_USER=YOUR-API-USER
    JENKINS_API_TOKEN=YOUR-API-TOKEN
    JENKINS_PROJECT=your-project
    JENKINS_WGET_PARAMS="--auth-no-challenge --http-user=${JENKINS_USER} --http-password=${JENKINS_API_TOKEN}"
    
    # Get the ID of the most recent build
    mrBuildInfo=$(wget -q -O - ${JENKINS_WGET_PARAMS} "${JENKINS_URL}/job/${JENKINS_PROJECT}/wfapi/runs" | jq '.[0] | {id: .id, status: .status}')
    # mrBuildInfo is now something like: '{ "id": "13", "status": "PAUSED_PENDING_INPUT" }'
    mrBuildId=$(echo "$mrBuildInfo" | jq --raw-output '.id')
    mrBuildStatus=$(echo "$mrBuildInfo" | jq --raw-output '.status')
    
    # From here on we assume that $mrBuildStatus is PAUSED_PENDING_INPUT
    # Get the first pending input action, assuming there is one
    mrBuildInputActions=$(wget -q -O - ${JENKINS_WGET_PARAMS} "${JENKINS_URL}/job/${JENKINS_PROJECT}/${mrBuildId}/wfapi/pendingInputActions" | jq --raw-output '.[0]')
    mrBuildProceedUrl=$(echo "$mrBuildInputActions" | jq --raw-output '.proceedUrl')
    mrBuildProceedText=$(echo "$mrBuildInputActions" | jq --raw-output '.proceedText')
    # We need to pass json={} and proceed=Yes, the curly braces are already URL encoded here
    wget -q -O - "--post-data=json=%7B%7D&proceed=$mrBuildProceedText" ${JENKINS_WGET_PARAMS} "${JENKINS_SERVER_URL}${mrBuildProceedUrl}"
    

    Which basically boils down to:

    wget -q -O - "--post-data=json=%7B%7D&proceed=Yes" --auth-no-challenge --http-user=${JENKINS_USER} --http-password=${JENKINS_API_TOKEN} "https://www.example.com/jenkins/job/${JENKINS_JOB}/${JOB_NR}/wfapi/inputSubmit?inputId=YOUR-INPUT-ID"
    
    0 讨论(0)
  • 2021-01-12 22:44

    I managed to resolve this issue.

    Hoping that someone else will benefit from my answer, let me explain how I achieved OPs target.

    All that Jenkis Pipeline input step needs is a properly formatted JSON and OK button caption sent to the right URL.

    So, the proper syntax is:

    curl -X POST -H "Jenkins-Crumb:${JENKINS_CRUMB}" -d json='{"parameter": {"name": "${PARAMETER_NAME}", "value": "${PARAMETER_VALUE}"}}' -d proceed='${SUBMIT_CAPTION}' 'http://j${JENKINS_URL}/job/${JOB_NAME}/${BUILD_ID}/input/${INPUT_ID}/submit'
    

    regards

    0 讨论(0)
提交回复
热议问题