Jenkins REST API to create an agent

Hello,

So I am trying to create a PHP script that allows me to create agents without actually being on Jenkins through the REST API. I’m having a bit of trouble here. Here is the current workflow I am attempting.

  • Authenticates the user using their username and password to the /crumbIssuer/api/json endpoint.
    • Returns issued crumb as JSON object
  • Do a POST request to the /computer/doCreateItem endpoint and supply it with the crumb from the JSON response.

So the odd part is, when I run the script, I keep getting a 403 forbidden response.

ERROR 403 No valid crumb was included in the request

Though when I paste that same exact request to PostMan, it creates the agent just fine.

So here’s an example for instance.

http://localhost:8083/computer/doCreateItem?name=test&nodeDescription=A+test+node&_.numExecutors=5&_.remoteFS=/var/jenkins&_.labelString=&mode=NORMAL&oldCommand=&_.command=&_.host=&includeUser=false&_.credentialsId=&stapler-class=hudson.plugins.sshslaves.verifiers.KnownHostsFileKeyVerificationStrategy&stapler-class=hudson.plugins.sshslaves.verifiers.ManuallyProvidedKeyVerificationStrategy&stapler-class=hudson.plugins.sshslaves.verifiers.ManuallyTrustedKeyVerificationStrategy&stapler-class=hudson.plugins.sshslaves.verifiers.NonVerifyingKeyVerificationStrategy&stapler-class=hudson.slaves.RetentionStrategy$Always&stapler-class=hudson.slaves.SimpleScheduledRetentionStrategy&stapler-class=hudson.slaves.RetentionStrategy$Demand&stapler-class=hudson.slaves.JNLPLauncher&stapler-class=hudson.slaves.CommandLauncher&$class=hudson.plugins.sshslaves.verifiers.KnownHostsFileKeyVerificationStrategy&$class=hudson.plugins.sshslaves.verifiers.ManuallyProvidedKeyVerificationStrategy&$class=hudson.plugins.sshslaves.verifiers.ManuallyTrustedKeyVerificationStrategy&$class=hudson.plugins.sshslaves.verifiers.NonVerifyingKeyVerificationStrategy&$class=hudson.slaves.RetentionStrategy$Always&$class=hudson.slaves.SimpleScheduledRetentionStrategy&$class=hudson.slaves.RetentionStrategy$Demand&$class=hudson.slaves.JNLPLauncher&$class=hudson.slaves.CommandLauncher&$class=hudson.plugins.sshslaves.SSHLauncher&_.port=22&_.javaPath=&_.jvmOptions=&_.prefixStartSlaveCmd=&_.suffixStartSlaveCmd=&launchTimeoutSeconds=&maxNumRetries=&retryWaitTime=&tcpNoDelay=on&workDir=&stapler-class-bag=true&_.freeDiskSpaceThreshold=1GiB&_.freeDiskSpaceWarningThreshold=2GiB&_.freeTempSpaceThreshold=1GiB&_.freeTempSpaceWarningThreshold=2GiB&type=hudson.slaves.DumbSlave&Submit=&stapler-class=hudson.plugins.sshslaves.SSHLauncher&Jenkins-Crumb=f86496w1z38f830ae97891717600ed51ccae58e6c9fffdca26f47df96f54e0eb&json={"name":"test","nodeDescription":"A+test+node","numExecutors":"5","remoteFS":"/var/jenkins","labelString":"","mode":"NORMAL","":["hudson.slaves.JNLPLauncher"],"launcher":{"stapler-class":"hudson.slaves.JNLPLauncher","$class":"hudson.slaves.JNLPLauncher","oldCommand":""},"retentionStrategy":{"stapler-class":"hudson.slaves.RetentionStrategy$Always","$class":"hudson.slaves.RetentionStrategy$Always"},"nodeProperties":{"stapler-class-bag":"true"},"type":"hudson.slaves.DumbSlave","Submit":"","Jenkins-Crumb":"f86496w1z38f830ae97891717600ed51ccae58e6c9fffdca26f47df96f54e0eb"}

I get that as an output after I construct the URL. Though when I take that exact output and put it in PostMan, I get 200 OK and the agent is created. I’m thinking either the first time I submit a POST request via PHP, Jenkins doesn’t like that or there’s a header/form submission I’m sending to Jenkins which it doesn’t like.

I’m sending these cURL requests to it.

  • POST request
  • Headers
    • Content-Type: application/x-www-form-urlencoded
    • Accept: application/x-www-form-urlencoded
  • Body
    • No body content is sent
  • URL parameters
    • All of the URL parameters I sent above in the code snippet.

I’m at a lost for words on what I’m doing wrong. Everything is exactly the same going from the PHP script to PostMan and vice versa.

I have done everything possible with the Jenkins crumb.

  • I have placed the Jenkins crumb in the headers
  • I have placed the Jenkins crumb in the URL query parameters
  • I have placed the Jenkins crumb in Authorization: Bearer
  • I have placed the Jenkins crumb in the headers, URL query parameters, the JSON object inside of the URL query parameters, AND in the Authorization: Bearer

Nothing helped. I kept getting that ERROR 403 No valid crumb was included in the request response.

Found out what the issue was. It’s because of the cookies. Looks like Jenkins requires everything to be the same from username and password to cookies to the same exact things being passed in.

Jenkins was providing me invalid crumbs and when I supply the API with those crumbs, it would give me a 403 response. This is because at the time of request, there is the JSESSIONID cookie. However when I do the POST request to create the node agent, the JSESSIONID cookie is no longer available.

What I ended up doing was creating a temp file, storing the cookies in that file, providing that temp file to Jenkins, allowing Jenkins to use it, then deleting that temp file. After doing it in that workflow, I was able to create the node agent.

This Stack Overflow post nudged me in the right direction.