aboutsummaryrefslogtreecommitdiffstats
path: root/bin/acme
diff options
context:
space:
mode:
Diffstat (limited to 'bin/acme')
-rwxr-xr-xbin/acme/patcher.json20
-rwxr-xr-xbin/acme/srtool_jira_acme.py (renamed from bin/acme/srtool_jira.py)375
2 files changed, 224 insertions, 171 deletions
diff --git a/bin/acme/patcher.json b/bin/acme/patcher.json
new file mode 100755
index 00000000..365990fa
--- /dev/null
+++ b/bin/acme/patcher.json
@@ -0,0 +1,20 @@
+{
+ "_comments_" : "Blank values indicate defaults",
+ "label" : "ACME",
+ "patcher_dir" : "bin/acme/patcher",
+ "patch_set" : [
+ {
+ "_comments_" : "The ACME custom version of the Jira integration script",
+ "original" : "bin/common/srtool_jira_template.py",
+ "custom" : "bin/acme/srtool_jira_acme.py",
+ "patch" : "",
+ "options" : ""
+ },
+ {
+ "original" : "bin/srt",
+ "custom" : "bin/srt",
+ "patch" : "",
+ "options" : "DISABLE"
+ }
+ ]
+}
diff --git a/bin/acme/srtool_jira.py b/bin/acme/srtool_jira_acme.py
index f9b8103b..d7ef0507 100755
--- a/bin/acme/srtool_jira.py
+++ b/bin/acme/srtool_jira_acme.py
@@ -5,7 +5,7 @@
#
# Security Response Tool Commandline Tool
#
-# Copyright (C) 2018 Wind River Systems
+# Copyright (C) 2018-2019 Wind River Systems
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
@@ -21,33 +21,41 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
### Usage Examples (run from top level directory)
-# Updating Jira Issues: ./bin/srtool_jira.py -U
-
-
-###
-### THIS IS A SAMPLE JIRA INTEGRATION SCRIPT FOR
-### MANAGING AN ORGANIZATION'S SRTOOL INTEGRATION
-###
-### INSTALLATION INSTRUCTIONS AND DOCUMENATION OF THE JIRA PYTHON
-### LIBRARIES CAN BE FOUND HERE:
-### https://jira.readthedocs.io
-###
-
+# Updating Jira Issues: ./bin/<app>/srtool_jira<_app>.py -u
+
+##
+## THIS IS A JIRA INTEGRATION SCRIPT FOR
+## MANAGING AN ORGANIZATION'S SRTOOL INTEGRATION
+##
+## You can use the "bin/common/srtool_patcher.py" to extend this template
+## with your custom changes yet keep in sync with the shared upstream file.
+##
+## See the example: "bin/acme/srtool_jira_acme.py"
+##
+## INSTALLATION INSTRUCTIONS AND DOCUMENATION OF THE JIRA PYTHON
+## LIBRARIES CAN BE FOUND HERE:
+## https://jira.readthedocs.io
+##
+
+### ACME_EXTENSION_BEGIN ###
+#
+# This is the ACME 'patcher' extension of:
+# 'bin/common/srtool_jira_template.py'
+#
+# To merge edits in common areas to upstream, run:
+# $ ./bin/common/srtool_patcher.py -j bin/acme/patcher.json --merge-custom
+# To merge upstream into this custom extension, run:
+# $ ./bin/common/srtool_patcher.py -j bin/acme/patcher.json --merge-original
+#
+### ACME_EXTENSION_END ###
import os
import sys
import re
-import csv
-import xml.etree.ElementTree as ET
import argparse
import sqlite3
-import subprocess
import json
-from jira import JIRA
-from time import sleep
from datetime import datetime, date
-from urllib.request import urlopen, URLError
-from urllib.parse import urlparse
# load the srt.sqlite schema indexes
dir_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
@@ -55,37 +63,66 @@ sys.path.insert(0, dir_path)
from common.srt_schema import ORM
# Setup:
+master_log = ''
+srt_user = ''
+srt_passwd = ''
+force_update = False
+
srtDbName = 'srt.sqlite'
srtErrorLog = 'srt_errors.txt'
-###
-### THESE ARE SAMPLE JIRA INTEGRATION LINKS:
-### The 'production' link is to the main Jira server
-### The 'test' link is to a test Jira server, for example to pre-test defect creation
-### The 'browse' link is how to format the Jira defect lookup link that is passed to the SRTool users
-###
+#
+# Load Jira test
+#
-# Jira constants
-JIRA_PRODUCTION_LINK = 'https://jira.acme.com'
-JIRA_BROWSE_LINK_FORMAT = 'http://jira.acme.com/browse/%s'
-JIRA_TESTSERVER_LINK = 'https://jira.acmetest.com'
+try:
+ from jira import JIRA
+except:
+ # could be SRTDBG_SKIP_DEFECT_IMPORT
+ pass
-###
-### THESE ARE SAMPLE JIRA CUSTOM FIELD LINKS:
-### These are example links that you can use to define and populate the respective fields for the SRTool
-### These are not defined in the standard Jira schema, and would presumably be custom added
-### You can extend and cusomize the Jira integration to SRTool by added additional custom fields using this model
-### The two indicated fields below are part of the SRTool design. They can be present as empty strings if they
-### do not exist in your schema:
-### The 'PUBLISHED' field is used to indicate if and when a Jira defect has been published to the customers
-### The 'FIX_VERSION' field is used to indicate which version/release/update/service pack of the product has the fix
-###
+##
+## THESE ARE JIRA INTEGRATION LINKS:
+## The 'production' link is to the main Jira server
+## The 'test' link is to a test Jira server, for example to pre-test defect creation
+## The 'browse' link is how to format the Jira defect lookup link that is passed to the SRTool users
+##
+
+# Jira constants: examples
+JIRA_PRODUCTION_LINK = 'https://jira.sample.com'
+JIRA_BROWSE_LINK_FORMAT = 'http://jira.sample.com/browse/%s'
+JIRA_TESTSERVER_LINK = 'https://jira.sampletest.com'
+JIRA_NEW_ASSIGNEE = 'kilroy'
+
+### ACME_EXTENSION_BEGIN ###
+JIRA_PRODUCTION_LINK = 'https://jira.wrs.com'
+JIRA_BROWSE_LINK_FORMAT = 'http://jira.wrs.com/browse/%s'
+JIRA_TESTSERVER_LINK = 'http://jiratest.wrs.com'
+JIRA_NEW_ASSIGNEE = 'dreyna'
+### ACME_EXTENSION_END ###
+
+##
+## THESE ARE SAMPLE JIRA CUSTOM FIELD LINKS:
+## These are example links that you can use to define and populate the respective fields for the SRTool
+## These are not defined in the standard Jira schema, and would presumably be custom added
+## You can extend and cusomize the Jira integration to SRTool by added additional custom fields using this model
+## The two indicated fields below are part of the SRTool design. They can be present as empty strings if they
+## do not exist in your schema:
+## The 'PUBLISHED' field is used to indicate if and when a Jira defect has been published to the customers
+## The 'FIX_VERSION' field is used to indicate which version/release/update/service pack of the product has the fix
+##
# Custom Jira fields
-JIRA_PUBLISHED_FIELD = 'customfield_10010' ### REPLACE WITH YOUR CUSTOM FIELD VALUE
-JIRA_FIX_VERSION_FIELD = 'customfield_10011' ### REPLACE WITH YOUR CUSTOM FIELD VALUE
+# Custom Jira fields
+JIRA_PUBLISHED_FIELD = 'customfield_10001' ### REPLACE WITH YOUR CUSTOM FIELD VALUE
+JIRA_FIX_VERSION_FIELD = 'customfield_10002' ### REPLACE WITH YOUR CUSTOM FIELD VALUE
# ...
+### ACME_EXTENSION_BEGIN ###
+JIRA_PUBLISHED_FIELD = 'customfield_10010'
+JIRA_FIX_VERSION_FIELD = 'customfield_11002'
+### ACME_EXTENSION_END ###
+
#################################
# Helper methods
#
@@ -98,14 +135,14 @@ def debugMsg(msg):
overrides = {}
-def set_override(key,value=None):
+def set_override(key,value=None,quite=False):
if not value is None:
overrides[key] = value
elif key in os.environ.keys():
overrides[key] = 'yes' if os.environ[key].startswith('1') else 'no'
else:
overrides[key] = 'no'
- if 'yes' == overrides[key]:
+ if 'yes' == overrides[key] and not quite:
print("OVERRIDE: %s = %s" % (key,overrides[key]))
def get_override(key):
@@ -126,47 +163,38 @@ def get_tag_key(tag,key):
# class to hold fields of a Jira issues
#
-class Defect:
+class Defect():
project = ''
product_id = ''
-
- def __init__(self,*args, **kwargs):
- self.reset()
-
- # reset all but persistent project info
- def reset(self):
- self.id = -1
- self.name = ''
- self.summary = ''
- self.url = ''
- self.priority = -1
- self.status = ''
- self.resolution = 'Unresolved'
- self.publish = ''
-
- # RCPL
- self.release_version = ''
-
- self.date_created = ''
- self.date_updated = ''
-
- # extra fields
- self.cve_status = ''
- self.vi_status = ''
- self.vi_outcome = ''
+ id = -1
+ name = ''
+ summary = ''
+ url = ''
+ priority = -1
+ status = ''
+ resolution = 'Unresolved'
+ publish = ''
+ # RCPL
+ release_version = ''
+ date_created = ''
+ date_updated = ''
+ # extra fields
+ cve_status = ''
+ vi_status = ''
+ vi_outcome = ''
#################################
-# Import Jira states
+# import Jira states
#
-# if too slow, change to check update times and ignore those that need nothing
-# can also move parsing JSON so that it doesnt happen if record is up to date
+#if too slow, change to check update times and ignore those that need nothing (should do anyway to be honest...)
+#can also move parsing JSON so that it doesnt happen if record is up to date
def do_update_jira():
try:
jira = JIRA(JIRA_PRODUCTION_LINK, auth=(srt_user, srt_passwd))
except Exception as e:
print("CONNECTION TO JIRA FAILED")
- return
+ return 1
conn = sqlite3.connect(srtDbName)
c = conn.cursor()
@@ -175,14 +203,14 @@ def do_update_jira():
weeknum = today.strftime("%W")
weekday = today.isoweekday()
- log = open("./update_logs/update_jira_log_%s_%s.txt" % (weeknum, weekday), "a")
+ update_log = open("./update_logs/update_jira_log_%s_%s.txt" % (weeknum, weekday), "a")
- log.write("BEGINNING JIRA UPDATES\n")
+ update_log.write("BEGINNING JIRA UPDATES\n")
pre_update_time = datetime.now()
products = c.execute('''SELECT * FROM orm_product''').fetchall()
for i,product in enumerate(products):
-# print("FOO1:%s,%s" % (product[ORM.PRODUCT_DEFECT_TAGS],get_tag_key(product[ORM.PRODUCT_DEFECT_TAGS],'key')))
+# print("JIRA_PRODUCT_SCAN:%s,%s" % (product[ORM.PRODUCT_DEFECT_TAGS],get_tag_key(product[ORM.PRODUCT_DEFECT_TAGS],'key')))
product_defect_prefix = get_tag_key(product[ORM.PRODUCT_DEFECT_TAGS],'key')
if get_override('SRTDBG_MINIMAL_DB') and (i > 1):
@@ -190,14 +218,13 @@ def do_update_jira():
#specify which fields to get in order to speed up request!
#print("\tupdating ... " + product[ORM.PRODUCT_NAME] + " " + product[ORM.PRODUCT_VERSION] + " " + product[ORM.PRODUCT_PROFILE] + "\tloading " + spinner[block_num % 3], end='\r', flush=True)
- log.write("\tUPDATING ... " + product[ORM.PRODUCT_NAME] + " " + product[ORM.PRODUCT_VERSION] + " " + product[ORM.PRODUCT_PROFILE] + "\n")
+ update_log.write("\tUPDATING ... " + product[ORM.PRODUCT_NAME] + " " + product[ORM.PRODUCT_VERSION] + " " + product[ORM.PRODUCT_PROFILE] + "\n")
block_size = 500
block_num = 0
spinner = [' ', '. ', '.. ', '...']
while True:
print("\tloading" + spinner[block_num % 4] + "\t" + product[ORM.PRODUCT_NAME] + " " + product[ORM.PRODUCT_VERSION] + " " + product[ORM.PRODUCT_PROFILE], end='\r', flush=True)
-# print("\tloading" + spinner[block_num % 4] + "\t" + product[ORM.PRODUCT_NAME] + " " + product[ORM.PRODUCT_VERSION] + " " + product[ORM.PRODUCT_PROFILE], flush=True)
start_idx = block_num*block_size
#searches current project's bug issues that contain "cve" in their text
issues = jira.search_issues('project=%s AND text ~ "cve*" AND type = Bug' % product_defect_prefix, start_idx, block_size, False, fields='key,summary,priority,status,resolution,project,updated,created,%s,%s' % (JIRA_PUBLISHED_FIELD, JIRA_FIX_VERSION_FIELD))
@@ -206,26 +233,28 @@ def do_update_jira():
break
# Development support
block_num += 1
- update_project_issues(product, issues, conn, log)
+ update_project_issues(product, issues, conn, update_log)
+# sleep(1.0) # give time for Sqlite to sync
conn.commit() #commit to db after each block
+# sleep(1.0) # give time for Sqlite to sync
+# conn.commit() #commit to db after each product
print("\tfinished \t" + product[ORM.PRODUCT_NAME] + " " + product[ORM.PRODUCT_VERSION] + " " + product[ORM.PRODUCT_PROFILE], flush=True)
conn.commit()
- log.write("began updates: %s\n" % str(pre_update_time))
- log.write("finished updates: %s\n" % str(datetime.now()))
- log.write("=============================================================================\n")
- log.write("\n")
+ update_log.write("began updates: %s\n" % str(pre_update_time))
+ update_log.write("finished updates: %s\n" % str(datetime.now()))
+ update_log.write("=============================================================================\n")
+ update_log.write("\n")
# Reset datasource's lastModifiedDate as today
sql = "UPDATE orm_datasource SET lastModifiedDate=? WHERE name='Jira'"
date_string = datetime.now().strftime(ORM.DATASOURCE_DATETIME_FORMAT)
- c.execute(sql, (date_string,) )
+ ret = c.execute(sql, (date_string,) )
conn.commit()
c.close()
conn.close()
#############################################################################3
-### Update the defect status from the Jira database
###
def new_vulnerability_name(cur):
@@ -254,10 +283,6 @@ def new_investigation_name(cur):
cur.execute(sql, (index, cvi[ORM.SRTSETTING_ID]))
return "INV-%05d" % index
-#
-# Translate Jira values to SRTool values
-#
-
def translate_priority(j,p):
NONE = 0
MINOR = 1
@@ -279,6 +304,21 @@ def translate_priority(j,p):
srt_error_log("ERROR: unknown priority string '%s=%s'" % (j,p))
return '0'
+def translate_priority_srt_to_jira(s):
+ Priority = (
+ ('Undefined', 'None'),
+ ('Minor', 'P4'),
+ ('Low', 'P3'),
+ ('Medium', 'P2'),
+ ('High', 'P1'),
+ )
+ for i in range(len(Priority)):
+ if s == Priority[i][0]:
+ return str(Priority[i][1])
+ print("ERROR: unknown priority string '%s'" % (s))
+ srt_error_log("ERROR: unknown priority string '%s'" % (s))
+ return 'None'
+
def translate_status(j,s):
OPEN = 0
IN_PROGRESS = 1
@@ -301,7 +341,7 @@ def translate_status(j,s):
srt_error_log("ERROR: unknown status string '%s=%s'" % (j,s))
return '0'
-def translate_resolution(j,r):
+def translate_resolution(j,r,log):
Resolution = (
(ORM.DEFECT_UNRESOLVED, 'Unresolved', ORM.STATUS_VULNERABLE,ORM.STATUS_NOT_VULNERABLE,ORM.OUTCOME_OPEN),
(ORM.DEFECT_RESOLVED, 'Resolved', ORM.STATUS_VULNERABLE,ORM.STATUS_NOT_VULNERABLE,ORM.OUTCOME_FIXED),
@@ -322,10 +362,6 @@ def translate_resolution(j,r):
log.write("ERROR: unknown resolution string '%s=%s'" % (j,r))
return 0,0,0,0
-#
-# Update the defect status from the Jira database
-#
-
#handles updating a list of issues for a single product/project
#DOES NOT CALL COMMIT (should change this?)
def update_project_issues(project, issues, conn, log):
@@ -347,11 +383,10 @@ def update_project_issues(project, issues, conn, log):
USER_SRTOOL_ID = "SRTool"
- d = Defect()
- d.project = project[ORM.PRODUCT_NAME] + " " + project[ORM.PRODUCT_VERSION] + " " + project[ORM.PRODUCT_PROFILE]
- d.product_id = project[ORM.PRODUCT_ID]
+ project_str = project[ORM.PRODUCT_NAME] + " " + project[ORM.PRODUCT_VERSION] + " " + project[ORM.PRODUCT_PROFILE]
+ product_id = project[ORM.PRODUCT_ID]
- cve_regex = re.compile("CVE-\d+-\d+")
+ cve_regex = re.compile(r"CVE-\d+-\d+")
srtool_today = datetime.today().strftime('%Y-%m-%d')
c = conn.cursor()
@@ -362,7 +397,11 @@ def update_project_issues(project, issues, conn, log):
break
issue_json = issue.raw
- d.reset()
+
+ d = Defect()
+ d.project = project_str
+ d.product_id = product_id
+
d.name = issue_json['key']
d.date_updated = issue_json['fields']['updated']
d.date_created = issue_json['fields']['created']
@@ -372,17 +411,13 @@ def update_project_issues(project, issues, conn, log):
d.status = translate_status(d.name,issue_json['fields']['status']['name'])
if issue_json['fields']['resolution'] is not None:
- d.resolution,cve_status,vi_status,vi_outcome = translate_resolution(d.name,issue_json['fields']['resolution']['name'])
+ d.resolution,cve_status,vi_status,vi_outcome = translate_resolution(d.name,issue_json['fields']['resolution']['name'],log)
else:
- d.resolution,cve_status,vi_status,vi_outcome = translate_resolution(d.name,'Unresolved')
+ d.resolution,cve_status,vi_status,vi_outcome = translate_resolution(d.name,'Unresolved',log)
if JIRA_PUBLISHED_FIELD in issue_json['fields'] and issue_json['fields'][JIRA_PUBLISHED_FIELD] is not None:
d.publish = issue_json['fields'][JIRA_PUBLISHED_FIELD]['value']
- else:
- d.publish = ''
if JIRA_FIX_VERSION_FIELD in issue_json['fields'] and issue_json['fields'][JIRA_FIX_VERSION_FIELD] is not None:
d.release_version = issue_json['fields'][JIRA_FIX_VERSION_FIELD]['name']
- else:
- d.release_version = ''
sql = "SELECT * FROM orm_defect WHERE name='%s'" % d.name
defect = c.execute(sql).fetchone()
@@ -444,6 +479,7 @@ def update_project_issues(project, issues, conn, log):
# Also create CVE history entry
sql = '''INSERT INTO orm_cvehistory (cve_id, comment, date, author) VALUES (?,?,?,?)'''
c.execute(sql, (c_id,'Created from defect %s' % d.name,srtool_today,USER_SRTOOL_ID))
+# sleep(0.1)
else:
c_id = cve[ORM.CVE_ID]
@@ -467,6 +503,7 @@ def update_project_issues(project, issues, conn, log):
# Also create Vulnerability history entry
sql = '''INSERT INTO orm_vulnerabilityhistory (vulnerability_id, comment, date, author) VALUES (?,?,?,?)'''
c.execute(sql, (v_id,'Created from defect %s' % d.name,srtool_today,USER_SRTOOL_ID))
+# sleep(0.1)
else:
print("FOUND VULNERABILITY ID for %s" % (cve_name))
v_id = c2v[ORM.CVETOVULNERABLILITY_VULNERABILITY_ID]
@@ -493,6 +530,7 @@ def update_project_issues(project, issues, conn, log):
# Also create Investigation history entry
sql = '''INSERT INTO orm_investigationhistory (investigation_id, comment, date, author) VALUES (?,?,?,?)'''
c.execute(sql, (i_id,'Created from defect %s' % d.name,srtool_today,USER_SRTOOL_ID))
+# sleep(0.1)
else:
print("FOUND INVESTIGATION ID for %s" % (cve_name))
i_id = investigation[ORM.INVESTIGATION_ID]
@@ -506,6 +544,7 @@ def update_project_issues(project, issues, conn, log):
log.write("\tINSERTING INVESTIGATION to DEFECT for %s\n" % i_name)
sql = '''INSERT INTO orm_investigationtodefect (investigation_id, product_id, defect_id) VALUES (?,?,?)'''
c.execute(sql, (i_id,d.product_id,defect_id))
+# sleep(0.1)
#print("=========================================================================================\n")
#print("\n")
@@ -520,13 +559,13 @@ def jira_update_list(jira_list):
jira = JIRA(JIRA_PRODUCTION_LINK, auth=(srt_user, srt_passwd))
except Exception as e:
print("CONNECTION TO JIRA FAILED")
- return
+ return 1
conn = sqlite3.connect(srtDbName)
c = conn.cursor()
products = c.execute('''SELECT * FROM orm_product''').fetchall()
- log = sys.stdout # open("./update_logs/update_jira_log_%s_%s.txt" % (weeknum, weekday), "a")
+ log = sys.stdout
for jira_name in jira_list.split(','):
print("Updating:\t" + jira_name, flush=True)
@@ -546,6 +585,7 @@ def jira_update_list(jira_list):
# Development support
block_num += 1
update_project_issues(product, issues, conn, log)
+# sleep(1.0) # give time for Sqlite to sync
conn.commit() #commit to db after each block
#################################
@@ -554,20 +594,19 @@ def jira_update_list(jira_list):
#Gets all JIRA Enhancement Requests for the specified project
def get_jira_er(project_prefix):
- #log.write("GETTING ENHANCEMENT REQUESTS FOR " + project_prefix)
print ("GETTING ENHANCEMENT REQUESTS FOR " + project_prefix)
try:
jira = JIRA(JIRA_PRODUCTION_LINK, auth=(srt_user, srt_passwd))
except Exception as e:
print("CONNECTION TO JIRA FAILED")
- return
+ return 1
block_size = 100
block_num = 0
while True:
start_idx = block_num*block_size
#searches current project's bug issues that contain "cve" in their text
- issues = jira.search_issues('project=%s AND type = "Enhancement Request"' % project_prefix, start_idx, block_size, False) #project argument could be better written I guess :)
+ issues = jira.search_issues('project=%s AND type = "Enhancement Request"' % project_prefix, start_idx, block_size, False)
if len(issues) == 0:
# Retrieve issues until there are no more to come
break
@@ -583,6 +622,9 @@ def jira_add_to_defect_db(jira_name):
print("Jira_name=%s" % (jira_name))
jira_name = jira_name.strip().upper()
+ # Just error errors to terminal
+ log = sys.stdout
+
#try connecting to jira
try:
jira = JIRA(JIRA_PRODUCTION_LINK, auth=(srt_user, srt_passwd))
@@ -610,11 +652,10 @@ def jira_add_to_defect_db(jira_name):
d.priority = translate_priority(d.name,issue_json['fields']['priority']['name'])
d.status = translate_status(d.name,issue_json['fields']['status']['name'])
-
if issue_json['fields']['resolution'] is not None:
- d.resolution,d.cve_status,d.vi_status,d.vi_outcome = translate_resolution(d.name,issue_json['fields']['resolution']['name'])
+ d.resolution,d.cve_status,d.vi_status,d.vi_outcome = translate_resolution(d.name,issue_json['fields']['resolution']['name'],log)
else:
- d.resolution,d.cve_status,d.vi_status,d.vi_outcome = translate_resolution(d.name,'Unresolved')
+ d.resolution,d.cve_status,d.vi_status,d.vi_outcome = translate_resolution(d.name,'Unresolved',log)
if JIRA_PUBLISHED_FIELD in issue_json['fields'] and issue_json['fields'][JIRA_PUBLISHED_FIELD] is not None:
d.publish = issue_json['fields'][JIRA_PUBLISHED_FIELD]['value']
else:
@@ -632,7 +673,7 @@ def jira_add_to_defect_db(jira_name):
d.product_id = product[ORM.PRODUCT_ID]
break
- #log.write("\tINSERTING %s\n" % d.name)
+ #_log("\tINSERTING %s\n" % d.name)
sql = '''INSERT INTO orm_defect (name, summary, url, priority, status, resolution, publish, release_version, product_id, date_created, date_updated) VALUES (?,?,?,?,?,?,?,?,?,?,?)'''
c.execute(sql, (d.name, d.summary, d.url, d.priority, d.status, d.resolution, str(d.publish), d.release_version, d.product_id, d.date_created, d.date_updated))
conn.commit()
@@ -648,20 +689,15 @@ def jira_add_to_defect_db(jira_name):
# Not yet implemented
def jira_del_from_defect_db(jira_name):
- pass
+ return 1
#################################
# New defect
#
-###
-### You will need to fill in any required custom fields required
-### to create new organization defects in Jira
-###
-
# Use "jiratest" for development testing
-IS_TEST = True
-IS_SIMULATE = True
+JIRA_IS_TEST = True
+JIRA_IS_SIMULATE = True
def simulate_new_defect_name(product_prefix):
conn = sqlite3.connect(srtDbName)
@@ -688,32 +724,17 @@ def simulate_new_defect(product_defect_tags,summary,cve_list,description,reason,
defect_name = simulate_new_defect_name(product_defect_prefix)
print("CREATED:%s,%s/browse/%s" % (defect_name,jira_url,defect_name))
-def translate_priority_srt_to_jira(s):
- Priority = (
- ('Undefined', 'None'),
- ('Minor', 'P4'),
- ('Low', 'P3'),
- ('Medium', 'P2'),
- ('High', 'P1'),
- )
- for i in range(len(Priority)):
- if s == Priority[i][0]:
- return str(Priority[i][1])
- print("ERROR: unknown priority string '%s'" % (s))
- srt_error_log("ERROR: unknown priority string '%s'" % (s))
- return 'None'
-
-def jira_new_defect(product_defect_tags,summary,description,priority,components,link):
- #srt_error_log("NEW DEFECT:%s|%s|%s|%s|%s|%s|%s|%s" % (product_defect_tags,summary,cve_list,description,reason,priority,components,link))
+def jira_new_defect(product_defect_tags,summary,cve_list,description,reason,priority,components,link):
+ srt_error_log("NEW DEFECT:%s|%s|%s|%s|%s|%s|%s|%s" % (product_defect_tags,summary,cve_list,description,reason,priority,components,link))
- if IS_TEST:
+ if JIRA_IS_TEST:
# Test URL
jira_url = JIRA_TESTSERVER_LINK
else:
# Production URL
jira_url = JIRA_PRODUCTION_LINK
- if IS_SIMULATE:
+ if JIRA_IS_SIMULATE:
return simulate_new_defect(product_defect_tags,summary,cve_list,description,reason,priority,components,link,jira_url)
# Connect to Jira server
@@ -721,7 +742,8 @@ def jira_new_defect(product_defect_tags,summary,description,priority,components,
jira = JIRA(jira_url, auth=(srt_user, srt_passwd))
except Exception as e:
print("CONNECTION TO JIRA FAILED")
- return
+ return 1
+ #srt_error_log("Jira connection made")
conn = sqlite3.connect(srtDbName)
c = conn.cursor()
@@ -734,7 +756,7 @@ def jira_new_defect(product_defect_tags,summary,description,priority,components,
# Translate the SRTool priority to Jira priority
priority = translate_priority_srt_to_jira(priority)
- #print("JIRA_NEW_DEFECT:%s,%s,%s" % (product_defect_prefix,summary,description))
+ #print("FOO1:%s,%s,%s" % (product_defect_prefix,summary,description))
jira_components=list()
for component in components.split(' '):
@@ -745,19 +767,24 @@ def jira_new_defect(product_defect_tags,summary,description,priority,components,
'summary': summary,
'description': description,
'issuetype': {'name': 'Bug'},
-
'priority': {'name': priority},
- 'components': jira_components, # Components by name
- 'assignee': {"name":SRT_USER }, # assign to the SRTool developer Jira account
-### 'customfield_11000': 'unknown', # EXAMPLE: "Found In Versions" = "unknown"
-### 'customfield_11001': {"value":"Review"}, # EXAMPLE: "Where Found" = "Review"
+ 'components': jira_components, # Components by name
+ 'assignee': {"name":JIRA_NEW_ASSIGNEE}, # assign to the SRTool developer for now
}
- if True:
- new_issue = jira.create_issue(fields=issue_dict)
- else:
- print("CREATE:%s" % issue_dict)
- new_issue = '%s-%s' % (product_defect_prefix,datetime.now().strftime('%H%M%S'))
+##
+## Add custom fields here, using the format...
+## issue_dict['custom_field_10001'] = value
+##
+
+ ### ACME_EXTENSION_BEGIN ###
+ ## HERE IS AN EXAMPLE OF ADJUSTMENTS TO THE JIRA QUERY
+ issue_dict['customfield_13304'] = {"value":"Review"} # "Where Found" = "Review"
+ ### ACME_EXTENSION_END ###
+
+ new_issue = jira.create_issue(fields=issue_dict)
+ #print("CREATE:%s" % issue_dict)
+ #new_issue = '%s-%s' % (product_defect_prefix,datetime.now().strftime('%H%M%S'))
new_issue = str(new_issue.key)
if not new_issue.startswith(product_defect_prefix):
@@ -767,12 +794,11 @@ def jira_new_defect(product_defect_tags,summary,description,priority,components,
def get_projects():
-
try:
jira = JIRA(JIRA_PRODUCTION_LINK, auth=(srt_user, srt_passwd))
except Exception as e:
print("CONNECTION TO JIRA FAILED")
- return
+ return 1
# Get all projects viewable by anonymous users.
projects = jira.projects()
@@ -784,9 +810,6 @@ def get_projects():
#
def update_jira(is_init):
- if get_override('SRTDBG_SKIP_DEFECT_IMPORT'):
- print("...Skipping Defect import")
- exit(0)
try:
print("BEGINNING JIRA UPDATES PLEASE WAIT ... this can take some time")
do_update_jira()
@@ -795,6 +818,8 @@ def update_jira(is_init):
except Exception as e:
master_log.write("SRTOOL:%s:DEFECT TABLE & JIRA ISSUES:\t\t\t...\t\t\tFAILED ... %s\n" % (date.today(), e))
print("DATABASE UPDATES FAILED ... %s" % e)
+ return(1)
+ return(0)
#################################
# main loop
@@ -820,13 +845,17 @@ def main(argv):
parser.add_argument('--add', nargs=1, help='Add an existing defect to SRTool defect database')
parser.add_argument('--delete', nargs=1, help='Delete an existing defect from SRTool defect database')
parser.add_argument('--new', action='store_const', const='new', dest='command', help='Create a new defect "--new --product-tags --summary --cve --description --reason --priority --components --link"')
- parser.add_argument('--jira-projects', '-P', action='store_const', const='jira-projects', dest='command', help='Jira projects')
+ parser.add_argument('--jira-projects', '-j', action='store_const', const='jira-projects', dest='command', help='Jira projects')
# Be flexible with arguments to support sub-parse trees
args, argv = parser.parse_known_args()
master_log = open("./update_logs/master_log.txt", "a")
+ if get_override('SRTDBG_SKIP_DEFECT_IMPORT'):
+ print("...Skipping Defect import")
+ exit(0)
+
# Authorization
if args.user:
srt_user = args.user
@@ -854,12 +883,13 @@ def main(argv):
if None != args.jira_update_list:
jira_list = args.jira_update_list
+ ret = 0
if args.jira_er:
- get_jira_er(args.jira_er[0])
+ ret = get_jira_er(args.jira_er[0])
elif args.add:
- jira_add_to_defect_db(args.add[0])
+ ret = jira_add_to_defect_db(args.add[0])
elif args.delete:
- jira_del_from_defect_db(args.add[0])
+ ret = jira_del_from_defect_db(args.add[0])
elif 'new' == args.command:
# Instantiate a sub-parse tree for "new" specific arguments
# Example:
@@ -877,7 +907,7 @@ def main(argv):
new_parser.add_argument('--link','-L', help='Link to upstream CVE')
args, argv = new_parser.parse_known_args()
if verbose:
- srt_error_log("SRTool_Jira_New: NOTE unprocessed arguments: %s" % argv)
+ srt_error_log("SRTool_Jira:NEW: NOTE unprocessed arguments: %s" % argv)
jira_new_defect(
args.tags if args.tags else '{}',
args.summary if args.summary else '',
@@ -889,23 +919,26 @@ def main(argv):
args.link if args.link else '',
)
elif 'init_jira' == args.command:
- update_jira(True)
+ ret = update_jira(True)
elif 'update_jira' == args.command:
- update_jira(False)
+ ret = update_jira(False)
elif jira_list:
- jira_update_list(jira_list)
+ ret = jira_update_list(jira_list)
elif 'jira-projects' == args.command:
- get_projects()
+ ret = get_projects()
else:
print("Command not found")
-if __name__ == '__main__':
- global srtool_basepath
+ if 0 != ret:
+ exit(ret)
+
+if __name__ == '__main__':
if verbose: print("srtool_jira(%s)" % sys.argv[1:])
# fetch any environment overrides
- #set_override('SRTDBG_MINIMAL_DB')
+ set_override('SRTDBG_SKIP_DEFECT_IMPORT')
+ set_override('SRTDBG_MINIMAL_DB')
srtool_basepath = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0]))))
main(sys.argv[1:])