def lookup_remotelink(options, jira_id): data = shared.jiraquery(options, "/rest/api/latest/issue/" + jira_id + "/remotelink") if (data and len(data) >=1): # print "[INFO] Found remotelink for " + jira return data[0] else: return
def lookup_remotelink(options, jira_id): data = shared.jiraquery( options, "/rest/api/latest/issue/" + jira_id + "/remotelink") if (data and len(data) >= 1): # print "[INFO] Found remotelink for " + jira return data[0] else: return
def lookup_proxy(options, bug): #TODO should keep a local cache from BZ->JIRA to avoid constant querying payload = {'jql': 'project = ' + ECLIPSE_PROJECT + ' and summary ~ \'EBZ#' + str(bug.id) +'\'', 'maxResults' : 5} data = shared.jiraquery(options, "/rest/api/latest/search?" + urllib.urlencode(payload)) count = len(data['issues']) if (count == 0): return elif (count == 1): return data['issues'][0] else: print "[WARN] Multiple issues found for " + str(bug.id) print data['issues'] return
def fetch_email(username, fallback, email_addresses): if username in email_addresses: return email_addresses[username] else: found = None payload = {'username': username} user_data = shared.jiraquery(options, "/rest/api/2/user?" + urllib.urlencode(payload)) if 'emailAddress' in user_data: found = str(user_data['emailAddress']) email_addresses[username]=found else: print 'No email found for ' + username + ' using ' + str(fallback) found = fallback # don't cache if not found return found
def fetch_email(username, fallback, email_addresses): if username in email_addresses: return email_addresses[username] else: found = None payload = {'username': username} user_data = shared.jiraquery(options, "/rest/api/2/user?" + urllib.urlencode(payload)) if 'emailAddress' in user_data: found = str(user_data['emailAddress']) email_addresses[username]=found else: print 'No email found for ' + username + ' using ' + str(fallback) found = fallback # don't cache if not found return found
def lookup_proxy(options, bug): #TODO should keep a local cache from BZ->JIRA to avoid constant querying payload = { 'jql': 'project = ' + ECLIPSE_PROJECT + ' and summary ~ \'EBZ#' + str(bug.id) + '\'', 'maxResults': 5 } data = shared.jiraquery( options, "/rest/api/latest/search?" + urllib.urlencode(payload)) count = len(data['issues']) if (count == 0): return elif (count == 1): return data['issues'][0] else: print "[WARN] Multiple issues found for " + str(bug.id) print data['issues'] return
def listVersions(project, pattern=".*", released=None, hasReleaseDate=None, archived=None, hasStartDate=None, codefrozen=None, lowerLimit=None, upperLimit=None, index=None): """Return list of versions for a specific project matching a pattern and a list of optional filters. arguments: project -- the jira project key (i.e. 'JBIDE') (required) pattern -- regular expression that the version name should match (i.e. '4.2.*') (default=.*) released -- boolean to state if the version should be released or not. (default=None) archived -- boolean to state if the version should be archived or not. (default=None) hasStartDate -- boolean to state if the version should have a start date. (default=None) hasReleaseDate -- boolean to state if the version should have a released date. (default=None) codefrozen -- boolean if description of version contains (codefreeze: <date>) and date has occurred true will include it otherwise exclude it. upperLimit -- upper limit (default=None) lowerLimit -- lower limit (default=None) index -- integer to state which index to get (supports negative indexing too, -1=last element), if index out of range nothing is returned. (default=None) examples: listVersions("JBIDE", "4.2.*") -- versions in JBIDE starting with "4.2." listVersions("JBIDE", "4.2.*", upperLimit=2) -- first two version of 4.2.* listVersions("JBIDE", "4.2.*", released=False, upperLimit=2) -- first two version that are released in 4.2.* listVersions("JBIDE", "4.2.*", released=False) -- non-released 4.2.* versions listVersions("JBIDE", "4.2.*|4.3.*", released=False, hasReleaseDate=True) -- non-released that has release date in either 4.2 or 4.3 streams listVersions("JBIDE", "4.2.*|4.3.*", released=False, hasStartDate=True) -- non-released that has start date in either 4.2 or 4.3 streams listVersions("JBIDE", ".*", archived=True, hasReleaseDate=True, lowerLimit=2, lowerLimit=4) """ versions = shared.jiraquery( options, "/rest/api/latest/project/" + project + "/versions") if options.verbose: print(pattern) #print codefrozen versionmatch = re.compile(pattern) foundversions = [] for version in versions: if versionmatch.match(version['name']): foundversions.append(version) print "after versionmatch: " + dumpVersions(foundversions) if released is not None: foundversions = filter(lambda v: released == v['released'], foundversions) #print "after released: " + dumpVersions(foundversions) if hasReleaseDate is not None: foundversions = filter( lambda v: hasFieldOrNot('releaseDate', hasReleaseDate, v), foundversions) #print "after hasReleaseDate: " + dumpVersions(foundversions) if hasStartDate is not None: foundversions = filter( lambda v: hasFieldOrNot('startDate', hasStartDate, v), foundversions) #print "after hasStartDate: " + dumpVersions(foundversions) if archived is not None: foundversions = filter(lambda v: archived == v['archived'], foundversions) #print "after archived: " + dumpVersions(foundversions) if codefrozen is not None: foundversions = filter(lambda v: isCodefrozenToday(v, codefrozen), foundversions) #print "after codefrozen: " + dumpVersions(foundversions) if upperLimit or lowerLimit: foundversions = foundversions[lowerLimit:upperLimit] #print "after limits: " + dumpVersions(foundversions) if index is not None: try: foundversions = [foundversions[index]] except IndexError: foundversions = [] #print "after index: " + dumpVersions(foundversions) foundversions = map(lambda v: v['name'], foundversions) return ", ".join(foundversions)
def listVersions(project, pattern=".*", released=None, hasReleaseDate=None, archived=None, hasStartDate=None, codefrozen=None, lowerLimit=None, upperLimit=None, index=None): """Return list of versions for a specific project matching a pattern and a list of optional filters. arguments: project -- the jira project key (i.e. 'JBIDE') (required) pattern -- regular expression that the version name should match (i.e. '4.2.*') (default=.*) released -- boolean to state if the version should be released or not. (default=None) archived -- boolean to state if the version should be archived or not. (default=None) hasStartDate -- boolean to state if the version should have a start date. (default=None) hasReleaseDate -- boolean to state if the version should have a released date. (default=None) codefrozen -- boolean if description of version contains (codefreeze: <date>) and date has occurred true will include it otherwise exclude it. upperLimit -- upper limit (default=None) lowerLimit -- lower limit (default=None) index -- integer to state which index to get (supports negative indexing too, -1=last element), if index out of range nothing is returned. (default=None) examples: listVersions("JBIDE", "4.2.*") -- versions in JBIDE starting with "4.2." listVersions("JBIDE", "4.2.*", upperLimit=2) -- first two version of 4.2.* listVersions("JBIDE", "4.2.*", released=False, upperLimit=2) -- first two version that are released in 4.2.* listVersions("JBIDE", "4.2.*", released=False) -- non-released 4.2.* versions listVersions("JBIDE", "4.2.*|4.3.*", released=False, hasReleaseDate=True) -- non-released that has release date in either 4.2 or 4.3 streams listVersions("JBIDE", "4.2.*|4.3.*", released=False, hasStartDate=True) -- non-released that has start date in either 4.2 or 4.3 streams listVersions("JBIDE", ".*", archived=True, hasReleaseDate=True, lowerLimit=2, lowerLimit=4) """ versions = shared.jiraquery(options,"/rest/api/latest/project/" + project + "/versions") if options.verbose: print(pattern) #print codefrozen versionmatch = re.compile(pattern) foundversions = [] for version in versions: if versionmatch.match(version['name']): foundversions.append(version) print "after versionmatch: " + dumpVersions(foundversions) if released is not None: foundversions = filter(lambda v: released == v['released'], foundversions) #print "after released: " + dumpVersions(foundversions) if hasReleaseDate is not None: foundversions = filter(lambda v: hasFieldOrNot('releaseDate', hasReleaseDate, v), foundversions) #print "after hasReleaseDate: " + dumpVersions(foundversions) if hasStartDate is not None: foundversions = filter(lambda v: hasFieldOrNot('startDate', hasStartDate, v), foundversions) #print "after hasStartDate: " + dumpVersions(foundversions) if archived is not None: foundversions = filter(lambda v: archived == v['archived'], foundversions) #print "after archived: " + dumpVersions(foundversions) if codefrozen is not None: foundversions = filter(lambda v: isCodefrozenToday(v, codefrozen), foundversions) #print "after codefrozen: " + dumpVersions(foundversions) if upperLimit or lowerLimit: foundversions = foundversions[lowerLimit:upperLimit] #print "after limits: " + dumpVersions(foundversions) if index is not None: try: foundversions = [foundversions[index]] except IndexError: foundversions = [] #print "after index: " + dumpVersions(foundversions) foundversions = map(lambda v: v['name'], foundversions) return ", ".join(foundversions)
def render(issue_type, issue_description, jira_env, issues, jql, options, email_addresses, components): doc = Document() testsuite = doc.createElement("testsuite") doc.appendChild(testsuite) emails_to_send = {} if len(issues) > 0: for i, v in enumerate(issues): fields = v['fields'] jira_key = v['key'] # For available field names, see the variables in # src/java/com/atlassian/jira/rpc/soap/beans/RemoteIssue.java #logger.info('%s\t%s\t%s' % (v['key'], v['assignee'], v['summary'])) # print fields['components'] component_details = [] component_lead_name = "" component_lead_email = "" component_lead_names = "" for component in fields['components']: # print component['id'] # https://issues.jboss.org/rest/api/2/component/12311294 if component['id'] in components: component_data = components[component['id']] else: # print 'Query ' + component['name'] + ' component lead' component_data = shared.jiraquery( options, "/rest/api/2/component/" + component['id']) components[component['id']] = component_data component_name = str(component_data['name']) if not 'lead' in component_data.keys(): raise Exception( '[ERROR] No component lead set for component = ' + component_name + ' on issue ' + jira_key + '.\n\n[ERROR] Contact an administrator to update https://issues.jboss.org/plugins/servlet/project-config/CRW/components' ) component_lead_name = str(component_data['lead']['name']) component_lead_names += "-" + xstr(component_lead_name) component_lead_email = fetch_email(component_lead_name, options.unassignedjiraemail, email_addresses) component_details.append({ 'name': component_name, 'lead': component_lead_name, 'email': component_lead_email }) fix_version = "" for version in fields['fixVersions']: fix_version += '_' + version['name'] fix_version = fix_version[1:] if fix_version == "": if issue_type == "No fix version": fix_version = "" else: fix_version = ".nofixversion" else: fix_version = "." + xstr(fix_version) recipients = {} assignees = {} assignee_name = "Nobody" assignee_email = str(options.unassignedjiraemail) if fields['assignee']: assignee_name = str(fields['assignee']['name']) if 'emailAddress' in fields['assignee']: assignee_email = str(fields['assignee']['emailAddress']) else: assignee_email = fetch_email(assignee_name, None, email_addresses) if not assignee_email: print 'No email found for assignee: ' + assignee_name assignees[assignee_name] = assignee_email recipients[assignee_name] = assignee_email if not assignee_name in email_addresses: email_addresses[assignee_name] = assignee_email # TODO handle array of components elif component_details: for component_detail in component_details: # print component_detail recipients[ component_detail['lead']] = component_detail['email'] else: # default assignee - send to mailing list if no component set recipients["Nobody"] = str(options.unassignedjiraemail) # print recipients testcase = doc.createElement("testcase") testcase.setAttribute("classname", jira_key) testcase.setAttribute( "name", issue_type.lower().replace(" ", "") + xstr(fix_version) + "." + assignee_name + xstr(component_lead_names)) o = urlparse(v['self']) url = o.scheme + "://" + o.netloc + "/browse/" + jira_key error = doc.createElement("error") lastupdate = datetime.datetime.now() - datetime.datetime.strptime( fields['updated'][:-5], "%Y-%m-%dT%H:%M:%S.%f").replace(tzinfo=None) error.setAttribute( "message", "\n* [" + assignee_email + "] " + issue_type + " for " + jira_key) component_name = "" lead_info = "" assignee_info = "" if component_details: for component_detail in component_details: component_name = component_name + ( ", " if component_name else "") + component_detail['name'] lead_info = lead_info + ( ", " if lead_info else "") + component_detail[ 'lead'] + " <" + component_detail['email'] + ">" assignee_info = email_array_to_string(assignees) # print assignee_info error_text = "\n" + url + "\n" + \ "Summary: " + fields['summary'] + "\n\n" + \ ("Assignee(s): " + assignee_info if assignee_info else "Assignee: None set.") + "\n" + \ ("Lead(s): " + lead_info + "\n" if lead_info else "") + \ ("Component(s): " + component_name if component_name else "Component: None set - please fix.") + "\n" + \ "Problem: " + issue_type + " - " + issue_description + "\n" + \ "Last Update: " + str(lastupdate) + "\n\n----------------------------\n\n" error_text_node = doc.createTextNode(error_text) error.appendChild(error_text_node) testcase.appendChild(error) testsuite.appendChild(testcase) subject = "\n* " + issue_type + " for " + jira_key # load email content into a dict(), indexed by email recipient & JIRA; for issues w/ more than one component, each component lead will get an email for name in recipients: if not recipients[name] in emails_to_send: emails_to_send[recipients[name]] = {} emails_to_send[recipients[name]][jira_key] = { 'message': subject + '\n' + error_text, 'recipients': name + " <" + recipients[name] + ">" } #print emails_to_send[recipients[name]][jira_key] else: testcase = doc.createElement("testcase") testcase.setAttribute("classname", issue_type) testcase.setAttribute("name", "found.noissues") testsuite.appendChild(testcase) print('Write to ' + issue_type.lower().replace(" ", "") + "-test.xml") output = open(issue_type.lower().replace(" ", "") + "-test.xml", 'w') output.write(doc.toprettyxml(indent=" ").encode('utf8', 'replace')) # send emails & log to file log = '' if options.fromemail: if len(emails_to_send) > 0: for i, assignee_email in enumerate(emails_to_send): problem_count = str(len(emails_to_send[assignee_email])) # note: python uses `value if condition else otherValue`, which is NOT the same as `condition ? value : otherValue` entry = ("Prepare (but do not send)" if options.dryrun else "Send") + " email with " + problem_count + \ " issue(s) to: " + (options.toemail + " (not " + assignee_email + ")" if options.toemail else assignee_email) print entry log = log + entry + "\n\n" message = '' o = urlparse(v['self']) url = o.scheme + "://" + o.netloc + "/browse/" for j, jira_key in enumerate(emails_to_send[assignee_email]): print " * " + url + jira_key message = message + emails_to_send[assignee_email][ jira_key]['message'] log = log + emails_to_send[assignee_email][jira_key][ 'message'] # print emails_to_send[assignee_email][jira_key]['recipients'] # wrap generated message w/ header and footer message = "This email is the result of a query to locate stalled/invalid jiras. Please fix them. Thanks!" + \ "\n\nGlobal Query: " + options.jiraserver + "/issues/?jql=" + urllib.quote_plus(jql) + \ "\n\nPersonal Query: " + options.jiraserver + "/issues/?jql=" + urllib.quote_plus(jql + " AND assignee = currentUser()") + \ "\n\n----------------------------\n\n" + message # send to yourself w/ --toemail override, or else send to actual recipient # note: python uses `value if condition else otherValue`, which is NOT the same as `condition ? value : otherValue` mailsend( options.smtphost, options.fromemail, (options.toemail if options.toemail else assignee_email), problem_count + ' issue' + ('s' if len(emails_to_send[assignee_email]) > 1 else '') + ' with ' + issue_type.lower(), message.encode('utf8', 'replace'), emails_to_send[assignee_email][jira_key]['recipients'], options) if log: output = open(issue_type.lower().replace(" ", "") + ".log", 'w') output.write(log.encode('utf8', 'replace')) return email_addresses
"Need to specify both --unassignedjiraemail and --smpthost to send mail" ) # store an array of username : email_address and componentid: component data we can use as a lookup table email_addresses = {} components = {} if options.reportfile: print "Using reports defined in " + options.reportfile reports = json.load(open(options.reportfile, 'r')) for report in reports: for issue_type, fields in report.items(): print("Check for '" + issue_type.lower() + "'") payload = {'jql': fields['jql'], 'maxResults': options.maxresults} data = shared.jiraquery( options, "/rest/api/2/search?" + urllib.urlencode(payload)) print( str(len(data['issues'])) + " issues found with '" + issue_type.lower() + "'") if options.verbose: print data print options email_addresses = render( issue_type, fields['description'].encode('utf8', 'replace'), data, data['issues'], fields['jql'], options, email_addresses, components) else: print "Generating based on .json found on standard in" data = json.load(sys.stdin) email_addresses = render('stdin', 'Query from standard in.', data, data['issues'], None, options, email_addresses,
def render(issue_type, issue_description, jira_env, issues, jql, options, email_addresses, components): doc = Document() testsuite = doc.createElement("testsuite") doc.appendChild(testsuite) emails_to_send = {} if len(issues) > 0: for i, v in enumerate(issues): fields = v['fields'] jira_key = v['key'] # For available field names, see the variables in # src/java/com/atlassian/jira/rpc/soap/beans/RemoteIssue.java #logger.info('%s\t%s\t%s' % (v['key'], v['assignee'], v['summary'])) # print fields['components'] component_details = [] component_lead_name = "" component_lead_email = "" component_lead_names = "" for component in fields['components']: # print component['id'] # https://issues.jboss.org/rest/api/2/component/12311294 if component['id'] in components: component_data = components[component['id']] else: # print 'Query ' + component['name'] + ' component lead' component_data = shared.jiraquery(options, "/rest/api/2/component/" + component['id']) components[component['id']] = component_data component_name = str(component_data['name']) component_lead_name = str(component_data['lead']['name']) component_lead_names += "-" + xstr(component_lead_name) component_lead_email = fetch_email(component_lead_name, options.unassignedjiraemail, email_addresses) component_details.append({'name': component_name, 'lead': component_lead_name, 'email': component_lead_email}) fix_version = "" for version in fields['fixVersions']: fix_version += '_' + version['name'] fix_version = fix_version[1:] if fix_version == "": if issue_type == "No fix version": fix_version = "" else: fix_version=".nofixversion" else: fix_version = "." + xstr(fix_version) recipients = {} assignees = {} assignee_name = "Nobody" assignee_email = str(options.unassignedjiraemail) if fields['assignee']: assignee_name = str(fields['assignee']['name']) if 'emailAddress' in fields['assignee']: assignee_email = str(fields['assignee']['emailAddress']) else: assignee_email = fetch_email(assignee_name, None, email_addresses) if not assignee_email: print 'No email found for assignee: ' + assignee_name assignees[assignee_name] = assignee_email recipients[assignee_name] = assignee_email if not assignee_name in email_addresses: email_addresses[assignee_name] = assignee_email # TODO handle array of components elif component_details: for component_detail in component_details: # print component_detail recipients[component_detail['lead']] = component_detail['email'] else: # default assignee - send to mailing list if no component set recipients["Nobody"] = str(options.unassignedjiraemail) # print recipients testcase = doc.createElement("testcase") testcase.setAttribute("classname", jira_key) testcase.setAttribute("name", issue_type.lower().replace(" ","") + xstr(fix_version) + "." + assignee_name + xstr(component_lead_names)) o = urlparse(v['self']) url = o.scheme + "://" + o.netloc + "/browse/" + jira_key error = doc.createElement("error") lastupdate = datetime.datetime.now() - datetime.datetime.strptime(fields['updated'][:-5], "%Y-%m-%dT%H:%M:%S.%f" ).replace(tzinfo=None) error.setAttribute("message", "\n* [" + assignee_email + "] " + issue_type + " for " + jira_key) component_name = "" lead_info = "" assignee_info = "" if component_details: for component_detail in component_details: component_name = component_name + (", " if component_name else "") + component_detail['name'] lead_info = lead_info + (", " if lead_info else "") + component_detail['lead'] + " <" + component_detail['email'] + ">" assignee_info = email_array_to_string(assignees) # print assignee_info error_text = "\n" + url + "\n" + \ "Summary: " + fields['summary'] + "\n\n" + \ ("Assignee(s): " + assignee_info if assignee_info else "Assignee: None set.") + "\n" + \ ("Lead(s): " + lead_info + "\n" if lead_info else "") + \ ("Component(s): " + component_name if component_name else "Component: None set - please fix.") + "\n" + \ "Problem: " + issue_type + " - " + issue_description + "\n" + \ "Last Update: " + str(lastupdate) + "\n\n----------------------------\n\n" error_text_node = doc.createTextNode(error_text) error.appendChild(error_text_node) testcase.appendChild(error) testsuite.appendChild(testcase) subject = "\n* " + issue_type + " for " + jira_key # load email content into a dict(), indexed by email recipient & JIRA; for issues w/ more than one component, each component lead will get an email for name in recipients: if not recipients[name] in emails_to_send: emails_to_send[recipients[name]] = {} emails_to_send[recipients[name]][jira_key] = {'message': subject + '\n' + error_text, 'recipients': name + " <" + recipients[name] + ">"} #print emails_to_send[recipients[name]][jira_key] else: testcase = doc.createElement("testcase") testcase.setAttribute("classname", issue_type) testcase.setAttribute("name", "found.noissues") testsuite.appendChild(testcase) print('Write to ' + issue_type.lower().replace(" ","") + "-test.xml") output = open(issue_type.lower().replace(" ","") + "-test.xml", 'w') output.write(doc.toprettyxml(indent=" ").encode('utf8', 'replace')) # send emails & log to file log = '' if options.fromemail: if len(emails_to_send) > 0: for i, assignee_email in enumerate(emails_to_send): problem_count = str(len(emails_to_send[assignee_email])) # note: python uses `value if condition else otherValue`, which is NOT the same as `condition ? value : otherValue` entry = ("Prepare (but do not send)" if options.dryrun else "Send") + " email with " + problem_count + " issue(s) to: " + (options.toemail + " (not " + assignee_email + ")" if options.toemail else assignee_email) print entry log = log + entry + "\n\n" message = '' for j, jira_key in enumerate(emails_to_send[assignee_email]): message = message + emails_to_send[assignee_email][jira_key]['message'] log = log + emails_to_send[assignee_email][jira_key]['message'] # print emails_to_send[assignee_email][jira_key]['recipients'] # wrap generated message w/ header and footer message = "This email is the result of a query to locate stalled/invalid jiras. Please fix them. Thanks!\n\n " + message message = message + "\n\nQuery used: " + options.jiraserver + "/issues/?jql=" + urllib.quote_plus(jql) + "\n" # send to yourself w/ --toemail override, or else send to actual recipient # note: python uses `value if condition else otherValue`, which is NOT the same as `condition ? value : otherValue` mailsend (options.smtphost, options.fromemail, (options.toemail if options.toemail else assignee_email), problem_count + ' issue' + ('s' if len(emails_to_send[assignee_email]) > 1 else '') + ' with ' + issue_type.lower(), message.encode('utf8','replace'), emails_to_send[assignee_email][jira_key]['recipients'], options) if log: output = open(issue_type.lower().replace(" ","") + ".log", 'w') output.write(log.encode('utf8', 'replace')) return email_addresses
(options, args) = parser.parse_args() if not options.username or not options.password: parser.error("Missing username or password") if options.fromemail and (not options.unassignedjiraemail or not options.smtphost): parser.error("Need to specify both --unassignedjiraemail and --smpthost to send mail") # store an array of username : email_address and componentid: component data we can use as a lookup table email_addresses = {} components = {} if options.reportfile: print "Using reports defined in " + options.reportfile reports = json.load(open(options.reportfile, 'r')) for report in reports: for issue_type,fields in report.items(): print("Check for '" + issue_type.lower() + "'") payload = {'jql': fields['jql'], 'maxResults' : options.maxresults} data = shared.jiraquery(options, "/rest/api/2/search?" + urllib.urlencode(payload)) print(str(len(data['issues'])) + " issues found with '" + issue_type.lower() + "'") email_addresses = render(issue_type, fields['description'].encode('utf8','replace'), data, data['issues'], fields['jql'], options, email_addresses, components) else: print "Generating based on .json found on standard in" data = json.load(sys.stdin) email_addresses = render('stdin', 'Query from standard in.', data, data['issues'], None, options, email_addresses, components)
for filterfile in filterfiles: print "Processing filters found in " + filterfile filters = json.load(open(filterfile, 'r')) newfilters = filters.copy() for name, fields in filters.items(): try: print "filter " + name data = [{ 'type': 'project', 'projectId': 10020 }, { 'type': 'project', 'projectId': 12310500 }] if 'id' in fields: print 'Checking filter ' + name filter = shared.jiraquery( options, "/rest/api/latest/filter/" + fields['id']) if len(filter['sharePermissions']) == 0: print 'Updating filter ' + name for permission in data: shared.jirapost( options, "/rest/api/latest/filter/" + fields['id'] + "/permission", permission) else: print 'Filter ' + name + ' already has some permissions' except urllib2.HTTPError, e: print "Problem with setting up filter %s" % (name)