Skip to content

Commit e5cc7d6

Browse files
Merge pull request #92 from veracode/reportingapi-deletedscans
Fix for #91 - new reporting api scan type
2 parents 9b8b988 + 24b53ba commit e5cc7d6

File tree

7 files changed

+89
-20
lines changed

7 files changed

+89
-20
lines changed

docs/analytics.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,25 @@ The following methods call Veracode REST APIs and return JSON.
66

77
1. The Reporting API is available to Veracode customers by request. More information about the API is available in the [Veracode Docs](https://docs.veracode.com/r/Reporting_REST_API).
88

9-
- `Analytics().create_report(report_type ('findings'),last_updated_start_date, last_updated_end_date (opt), scan_type (opt), finding_status(opt), passed_policy(opt), policy_sandbox(opt), application_id(opt), rawjson(opt))`: set up a request for a report. By default this command returns the GUID of the report request; specify `rawjson=True` to get the full response. Dates should be specified as `YYYY-MM-DD HH:MM:SS` with the timestamp optional. Options include:
10-
- `report_type`: required, currently supports `findings` and `scans`.
11-
- `last_updated_start_date`: required, beginning of date range for new or changed findings
12-
- `last_updated_end_date`: optional, end of date range for new or changed findings
13-
- `scan_type`: optional, one or more of 'Static Analysis', 'Dynamic Analysis', 'Manual', 'Software Composition Analysis', 'SCA'
9+
- `Analytics().create_report(report_type ('findings'),last_updated_start_date(opt), last_updated_end_date (opt), scan_type (opt), finding_status(opt), passed_policy(opt), policy_sandbox(opt), application_id(opt), rawjson(opt), deletion_start_date(opt), deletion_end_date(opt))`: set up a request for a report. By default this command returns the GUID of the report request; specify `rawjson=True` to get the full response. Dates should be specified as `YYYY-MM-DD HH:MM:SS` with the timestamp optional. Options include:
10+
- `report_type`: required, currently supports `findings`, `scans`, and `deletedscans`.
11+
- `last_updated_start_date`: required for `findings` report type, beginning of date range for new or changed findings or scans
12+
- `last_updated_end_date`: optional, end of date range for new or changed findings or scans
13+
- `scan_type`: optional, one or more of 'Static Analysis', 'Dynamic Analysis', 'Manual', 'Software Composition Analysis', 'SCA'. `SCA` is only supported for the `findings` report type.
1414
- `finding_status`: optional, 'Open' or 'Closed'. Applies only to the `findings` report.
1515
- `passed_policy`: optional, boolean. Applies only to the `findings` report.
1616
- `policy_sandbox`: optional, 'Policy' or 'Sandbox'
1717
- `application_id`: optional, application ID for which to return results
1818
- `rawjson`: optional, defaults to False. Returns full response if True, the GUID of the request if false
19+
- `deletion_start_date`: required for `deletedscans` report type, beginning of date range for deleted scans.
20+
- `deletion_end_date`: optional, end of date range for deleted scans.
1921

2022
- `Analytics().get(guid, report_type(findings))`: check the status of the report request and return the report contents when ready. Note that this method returns a tuple of `status` (string) and `results` (list); when `status` is `COMPLETED`, the `results` list will populate with results. Also, you need to specify the type of data expected by the GUID with `report_type`; this defaults to `findings`.
2123

2224
- `Analytics().get_findings(guid)`: check the status of a findings report request specified by `guid` and return the report contents when ready. Note that this method returns a tuple of `status` (string) and `results` (list); when `status` is `COMPLETED`, the `results` list will populate with results.
2325

2426
- `Analytics().get_scans(guid)`: check the status of a scans report request specified by `guid` and return the report contents when ready. Note that this method returns a tuple of `status` (string) and `results` (list); when `status` is `COMPLETED`, the `results` list will populate with results.
2527

28+
- `Analytics().get_deletedscans(guid)`: check the status of a deleted scans report request specified by `guid` and return the report contents when ready. Note that this method returns a tuple of `status` (string) and `results` (list); when `status` is `COMPLETED`, the `results` list will populate with results.
29+
2630
[All docs](docs.md)

docs/api.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,14 @@ As an alternative to importing individual objects into your library, you can acc
2626

2727
### Analytics Reporting
2828

29-
1. *Accessing*: The Reporting API is available to Veracode customers by request.
3029
1. *More information*: See the [Veracode Docs](https://docs.veracode.com/r/Reporting_REST_API).
3130
1. *See Also*: You can also access these methods from the [Analytics class](analytics.md).
3231

3332
- `create_analytics_report(report_type ('findings'),last_updated_start_date, last_updated_end_date (opt), scan_type (opt), finding_status(opt), passed_policy(opt), policy_sandbox(opt), application_id(opt), rawjson(opt))`: set up a request for a report. By default this command returns the GUID of the report request; specify `rawjson=True` to get the full response. Dates should be specified as `YYYY-MM-DD HH:MM:SS` with the timestamp optional. Options include:
34-
- `report_type`: required, currently only supports `findings`
33+
- `report_type`: required, currently only supports `findings`, `scans` and `deletedscans`
3534
- `last_updated_start_date`: required, beginning of date range for new or changed findings
3635
- `last_updated_end_date`: optional, end of date range for new or changed findings
37-
- `scan_type`: optional, one or more of 'Static Analysis', 'Dynamic Analysis', 'Manual', 'Software Composition Analysis', 'SCA'
36+
- `scan_type`: optional, one or more of 'Static Analysis', 'Dynamic Analysis', 'Manual', 'Software Composition Analysis', 'SCA'. `SCA` is only supported for the `findings` type
3837
- `finding_status`: optional, 'Open' or 'Closed'
3938
- `passed_policy`: optional, boolean
4039
- `policy_sandbox`: optional, 'Policy' or 'Sandbox'

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = 'veracode_api_py'
3-
version = '0.9.55'
3+
version = '0.9.56'
44
authors = [ {name = "Tim Jarrett", email="[email protected]"} ]
55
description = 'Python helper library for working with the Veracode APIs. Handles retries, pagination, and other features of the modern Veracode REST APIs.'
66
readme = 'README.md'
@@ -22,4 +22,4 @@ dependencies = {file = ["requirements.txt"]}
2222
[project.urls]
2323
"Homepage" = "https://github.com/veracode/veracode-api-py"
2424
"Bug Tracker" = "https://github.com/veracode/veracode-api-py/issues"
25-
"Download" = "https://github.com/veracode/veracode-api-py/archive/v_0955.tar.gz"
25+
"Download" = "https://github.com/veracode/veracode-api-py/archive/v_0956.tar.gz"
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import time
2+
import sys
3+
import json
4+
import datetime
5+
from veracode_api_py import Analytics
6+
7+
wait_seconds = 15
8+
9+
print('Generating deleted scans report...')
10+
theguid = Analytics().create_report(report_type="deletedscans",deletion_start_date='2024-07-01',deletion_end_date='2024-12-31')
11+
12+
print('Checking status for report {}...'.format(theguid))
13+
thestatus,thescans=Analytics().get_deleted_scans(theguid)
14+
15+
while thestatus != 'COMPLETED':
16+
print('Waiting {} seconds before we try again...'.format(wait_seconds))
17+
time.sleep(wait_seconds)
18+
print('Checking status for report {}...'.format(theguid))
19+
thestatus,thescans=Analytics().get_deleted_scans(theguid)
20+
21+
recordcount = len(thescans)
22+
23+
print('Retrieved {} scans'.format(recordcount))
24+
25+
if recordcount > 0:
26+
now = datetime.datetime.now().astimezone()
27+
filename = 'report-{}'.format(now)
28+
with open('{}.json'.format(filename), 'w') as outfile:
29+
json.dump(thescans,outfile)
30+
outfile.close()
31+
32+
print('Wrote {} findings to {}.json'.format(recordcount,filename))

setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@
77
setup(
88
name = 'veracode_api_py',
99
packages = ['veracode_api_py'],
10-
version = '0.9.54',
10+
version = '0.9.56',
1111
license='MIT',
1212
description = 'Python helper library for working with the Veracode APIs. Handles retries, pagination, and other features of the modern Veracode REST APIs.',
1313
long_description = long_description,
1414
long_description_content_type="text/markdown",
1515
author = 'Tim Jarrett',
1616
author_email = '[email protected]',
1717
url = 'https://github.com/tjarrettveracode',
18-
download_url = 'https://github.com/veracode/veracode-api-py/archive/v_0955.tar.gz',
18+
download_url = 'https://github.com/veracode/veracode-api-py/archive/v_0956.tar.gz',
1919
keywords = ['veracode', 'veracode-api'],
2020
install_requires=[
2121
'veracode-api-signing'

veracode_api_py/analytics.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,46 @@
66
from .apihelper import APIHelper
77

88
class Analytics():
9-
report_types = [ "findings", "scans" ]
9+
report_types = [ "findings", "scans", "deletedscans" ]
1010

1111
findings_scan_types = ["Static Analysis", "Dynamic Analysis", "Manual", "SCA", "Software Composition Analysis" ]
1212
scan_scan_types = ["Static Analysis", "Dynamic Analysis", "Manual" ]
1313

1414
base_url = 'appsec/v1/analytics/report'
1515

1616
#public methods
17-
def create_report(self,report_type,last_updated_start_date,last_updated_end_date=None,
17+
def create_report(self,report_type,last_updated_start_date=None,last_updated_end_date=None,
1818
scan_type:list = [], finding_status=None,passed_policy=None,
19-
policy_sandbox=None,application_id=None,rawjson=False):
19+
policy_sandbox=None,application_id=None,rawjson=False, deletion_start_date=None,
20+
deletion_end_date=None):
2021

2122
if report_type not in self.report_types:
2223
raise ValueError("{} is not in the list of valid report types ({})".format(report_type,self.report_types))
2324

24-
report_def = { "report_type": report_type,"last_updated_start_date": last_updated_start_date }
25+
report_def = { 'report_type': report_type }
26+
27+
if last_updated_start_date:
28+
report_def['last_updated_start_date'] = last_updated_start_date
29+
else:
30+
if report_type in ['findings','scans']:
31+
raise ValueError("{} report type requires a last updated start date.").format(report_type)
2532

2633
if last_updated_end_date:
2734
report_def['last_updated_end_date'] = last_updated_end_date
2835

36+
if deletion_end_date:
37+
report_def['deletion_end_date'] = deletion_end_date
38+
39+
if deletion_start_date:
40+
report_def['deletion_start_date'] = deletion_start_date
41+
else:
42+
if report_type == 'deletedscans':
43+
raise ValueError("{} report type requires a deleteion start date.").format(report_type)
44+
2945
if len(scan_type) > 0:
3046
if report_type == 'findings':
3147
valid_scan_types = self.findings_scan_types
32-
elif report_type == 'scans':
48+
elif report_type in [ 'scans', 'deletedscans' ]:
3349
valid_scan_types = self.scan_scan_types
3450
if not(self._case_insensitive_list_compare(scan_type,valid_scan_types)):
3551
raise ValueError("{} is not in the list of valid scan types ({})".format(report_type,valid_scan_types))
@@ -62,6 +78,10 @@ def get_findings(self, guid: UUID):
6278
def get_scans(self, guid: UUID):
6379
thestatus, thescans = self.get(guid=guid,report_type='scans')
6480
return thestatus, thescans
81+
82+
def get_deleted_scans(self, guid: UUID):
83+
thestatus, thescans = self.get(guid=guid,report_type='deletedscans')
84+
return thestatus, thescans
6585

6686
def get(self,guid: UUID,report_type='findings'):
6787
# handle multiple scan types

veracode_api_py/api.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -641,15 +641,29 @@ def dyn_start_scan(self, length, unit):
641641
return DynUtils().start_scan(length,unit)
642642

643643
# analytics apis
644-
def create_analytics_report(self,report_type,last_updated_start_date,last_updated_end_date=None,
644+
def create_analytics_report(self,report_type,last_updated_start_date=None,last_updated_end_date=None,
645645
scan_type:list = [], finding_status=None,passed_policy=None,
646-
policy_sandbox=None,application_id=None,rawjson=False):
646+
policy_sandbox=None,application_id=None,rawjson=False,deletion_start_date=None,
647+
deletion_end_date=None):
647648
return Analytics().create_report(report_type=report_type,last_updated_start_date=last_updated_start_date,
648649
last_updated_end_date=last_updated_end_date,scan_type=scan_type,
649650
finding_status=finding_status,passed_policy=passed_policy,
650651
policy_sandbox=policy_sandbox,application_id=application_id,
651-
rawjson=rawjson)
652+
rawjson=rawjson, deletion_start_date=deletion_start_date,
653+
deletion_end_date=deletion_end_date)
652654

653655
def get_analytics_report(self,guid: UUID):
654656
status, findings = Analytics().get(guid=guid)
657+
return status, findings
658+
659+
def get_analytics_findings_report(self,guid:UUID):
660+
status, findings = Analytics().get_findings(guid=guid)
661+
return status, findings
662+
663+
def get_analytics_scans(self,guid:UUID):
664+
status, findings = Analytics().get_scans(guid=guid)
665+
return status, findings
666+
667+
def get_analytics_deleted_scans(self,guid:UUID):
668+
status, findings = Analytics().get_deleted_scans(guid=guid)
655669
return status, findings

0 commit comments

Comments
 (0)