Now you can cancel jobs via API! This endpoint will take in a JobID and cancel the specified job. Use this endpoint for easy troubleshooting or while developing and testing workflows in InsightConnect.
Cancel All Running Jobs Associated with a Workflow. This script uses the Get All Jobs API to grab all running jobs associated to a workflowID. It then iterates over the list of jobs and cancels them using the cancel jobs endpoint.
import requests, json, re, math
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
import maskpass
# extractJobIds returns total number of jobs and extracts all the jobIds from the GetAllJobs response to use in the
# CancelJob endpoint
def extractJobIds(body, checkMeta):
ids = []
total = 0
for _, data in body.items():
# Check the meta for number of jobs returned from Get All Jobs
if checkMeta:
meta = data["meta"]
if meta["total"] == 0:
print("You have no running/waiting jobs to cancel. Exiting...")
return
else:
total = meta["total"]
jobs = data["jobs"]
for i in range(len(jobs)):
for key in jobs[i]:
if key == "id":
ids.append(jobs[i][key])
return total, ids
def main():
# Parse command line arguments
parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter)
required = parser.add_argument_group('required arguments')
required.add_argument("-i", "--id", help="The id of the workflow wanted to export", required=True)
args = vars(parser.parse_args())
# Set up User API key
userKey = maskpass.askpass(prompt="X-API-KEY:", mask="*")
headers = {'X-API-KEY': userKey}
# Build URL
workflowId = args["id"]
regionInput = input("What region?\n1) eu\n2) us\n3) ap\n4) ca\n5) au\n6) us2\n7) us3\nEnter a number 1-7: ")
if regionInput == "1":
region = "eu"
elif regionInput == "2":
region = "us"
elif regionInput == "3":
region = "ap"
elif regionInput == "4":
region = "ca"
elif regionInput == "5":
region = "au"
elif regionInput == "6":
region = "us2"
elif regionInput == "7":
region = "us3"
else:
print("A region must be provided. Please try again.")
return
numOfJobsCanceled = 0
failedCanceledJobs = []
getAllJobsUrl = "https://{0}.api.insight.rapid7.com/connect/v1/jobs?workflowId={1}&status=running&status=waiting".format(region, workflowId)
r = requests.get(getAllJobsUrl, headers=headers)
print("Print the url to check the URL has been correctly encoded or not!")
print("URL: ", r.url)
print("Status Code: ", r.status_code)
body = r.json()
getAllJobsResponse = json.dumps(body, indent=4, ensure_ascii=False)
print(getAllJobsResponse)
# Bail out if Get All Jobs returns anything besides a 200
if r.status_code != 200:
return
total, jobIds = extractJobIds(body, True)
response = input("Do you want to cancel all {0} running/waiting jobs related to worfklowId: {1}?\n Y or N? ".format(total, workflowId)).upper()
if response == "Y":
# Call GetAllJobs X number of times to get the next set of 30 jobs
# 30 is the limit of jobs returned
times = math.ceil(total / 30)
for i in range(1, times):
getAllJobsUrl = "https://{0}.api.insight.rapid7.com/connect/v1/jobs?workflowId={1}&status=running&status=waiting&offset=30".format(region, workflowId)
r = requests.get(getAllJobsUrl, headers=headers)
body = r.json()
jobIds.extend(extractJobIds(body, False))
print("\nStarting to cancel " + str(len(jobIds)) + " jobs...\n")
# Loop through each jobId to cancel the associated job
for jobId in jobIds:
cancelJobUrl = "https://{0}.api.insight.rapid7.com/connect/v1/jobs/{1}/events/cancel".format(region, jobId)
r = requests.post(cancelJobUrl, headers=headers)
body = r.json()
cancelJobResponse = json.dumps(body, indent=4, ensure_ascii=False)
if r.status_code == 200:
numOfJobsCanceled += 1
else:
failedCanceledJobs.append(jobId)
print("Number of jobs successfully canceled: " + str(numOfJobsCanceled))
if len(failedCanceledJobs) > 0:
print("Failed to cancel " + str(len(failedCanceledJobs)) + " jobs.\n Failed jobIds: " + str(failedCanceledJobs))
main()