Search code examples
pycurlrundeck

Rundeck API to upload job using python pycurl fails to upload file


I'm trying to implement rundeck job import functionality using pycurl in python, fails to find the file. Curl version of the same works fine.

    def importRundeckJOB(jobConfigFilePath):
        responseObject = BytesIO()
        rd = pycurl.Curl()

        rd.setopt(rd.URL, RUNDECK_API_END_POINT)
        rd.setopt(rd.HTTPHEADER, ['X-Rundeck-Auth-Token: '+RUNDECK_TOKEN,
                                  "Accept: application/json"])
        rd.setopt(rd.HTTPPOST, [("dupeOption", "update"),
                                ("fileformat", "yaml"),
                                ("xmlBatch",  jobConfigFilePath )])
        rd.setopt(rd.WRITEFUNCTION, responseObject.write)
        rd.perform()
        responseCode = rd.getinfo(rd.HTTP_CODE)
        rd.close()

Error ::

{'error': True, 'apiversion': 17, 'errorCode': 'api.error.jobs.import.missing-file', 'message': 'No file was uploaded'}

Working curl

curl --header X-Rundeck-Auth-Token:<TOKEN> -F xmlBatch=@"<FILE_PATH>"  -F dupeOption=update -F fileformat=yaml <RUNDECK_API_END_POINT>/import

{
  "succeeded": [
    {
      "index": 1,
      "id": "deploy-job",
      "name": "deploy-job",
      "group": "DEV",
      "project": "SOF",
      "permalink": "<RUNDECK_URL>/job/show/deploy-job"
    }
  ],
  "failed": [],
  "skipped": []
}

Solution

  • i've found a solution, i need to an additional parameter to handle files.

    http://pycurl.io/docs/latest/quickstart.html#file-upload-multipart-post

    c.FORM_FILE
    

    Working solution

        def importRundeckJOB(jobConfigFilePath):
            responseObject = BytesIO()
            rd = pycurl.Curl()
    
            rd.setopt(rd.URL, RUNDECK_API_END_POINT)
            rd.setopt(rd.HTTPHEADER, ['X-Rundeck-Auth-Token: '+RUNDECK_TOKEN,
                                      "Accept: application/json"])
            rd.setopt(rd.HTTPPOST, [("dupeOption", "update"),
                                    ("fileformat", "yaml"),
                                    ("xmlBatch",  (rd.FORM_FILE, jobConfigFile))])
            rd.setopt(rd.WRITEFUNCTION, responseObject.write)
            rd.perform()
            responseCode = rd.getinfo(rd.HTTP_CODE)
            rd.close()