Skip to content

Commit

Permalink
Merge 66f7641 into af67c78
Browse files Browse the repository at this point in the history
  • Loading branch information
abaiken committed Feb 23, 2018
2 parents af67c78 + 66f7641 commit 0d88f9c
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 35 deletions.
6 changes: 3 additions & 3 deletions docs/source/man.rst
Original file line number Diff line number Diff line change
Expand Up @@ -381,15 +381,15 @@ Viewing Scans jobs

The ``qpc scan job`` command returns the the list of scan jobs or a single scan job associated with a scan object. The output of this command includes the scan job identifiers as well as the status of each job and the results.

**qpc scan job --name** *scan_name* **--id=** *scan_job_identifier* **--status=** *(created | pending | running | paused | canceled | completed | failed)*
**qpc scan job (--name** *scan_name* | **--id=** *scan_job_identifier*) **--status=** *(created | pending | running | paused | canceled | completed | failed)*

``--name=name``

Required. Contains the name of the scan object of which to display the scan jobs.
Optional. Contains the name of the scan object of which to display the scan jobs. Mutually exclusive with the ``--id`` option.

``--id=scan_job_identifier``

Optional. Contains the identifier of a specified scan job to show.
Optional. Contains the identifier of a specified scan job to display. Mutually exclusive with the ``--name`` option.

``--status=status``

Expand Down
5 changes: 5 additions & 0 deletions qpc/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,11 @@
'information, see the server log file.'
SCAN_CLEAR_ALL_SUCCESS = 'All scans were removed.'
SCAN_EDIT_NO_ARGS = 'No arguments were provided to edit scan %s.'
SCAN_JOB_NO_ARGS = 'No scan name or job id was provided to the job command.'
SCAN_JOB_NAME_ID = 'Provide either a scan name to list all related jobs, or '\
'a scan job identifier to list a specific job.'
SCAN_JOB_ID_STATUS = 'Provide the "--status" filter with a scan name to '\
'filter the list of related scan jobs.'
SCAN_EDIT_SOURCES_NOT_FOUND = 'An error occurred while processing the '\
'"--sources" input values. References for the following sources '\
'could not be found: %s. Failed to edit scan "%s". For more '\
Expand Down
50 changes: 27 additions & 23 deletions qpc/scan/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

from __future__ import print_function
import sys
import urllib.parse as urlparse
from requests import codes
from qpc.utils import pretty_print
from qpc.clicommand import CliCommand
Expand Down Expand Up @@ -42,7 +41,7 @@ def __init__(self, subparsers):
scan.SCAN_URI, [codes.ok])
self.parser.add_argument('--name', dest='name', metavar='NAME',
help=_(messages.SCAN_NAME_HELP),
required=True)
required=False)
self.parser.add_argument('--id', dest='id',
metavar='ID',
help=_(messages.SCAN_JOB_ID_HELP),
Expand All @@ -59,16 +58,36 @@ def __init__(self, subparsers):
help=_(messages.SCAN_STATUS_FILTER_HELP),
required=False)

def _validate_args(self):
"""Validate the scan job arguments."""
CliCommand._validate_args(self)
# Check to see if args were provided
error = False
if not(self.args.name or self.args.id):
print(_(messages.SCAN_JOB_NO_ARGS))
error = True
elif self.args.name and self.args.id:
print(_(messages.SCAN_JOB_NAME_ID))
error = True
elif self.args.id and self.args.status:
print(_(messages.SCAN_JOB_ID_STATUS))
error = True
if error:
self.parser.print_usage()
sys.exit(1)

def _build_req_params(self):
"""Add filter by scan_type/state query param."""
found, scan_object_id = _get_scan_object_id(self.parser,
self.args.name)
if not found:
sys.exit(1)
if 'name' in self.args and self.args.name:
found, scan_object_id = _get_scan_object_id(self.parser,
self.args.name)
if found:
self.req_path += scan_object_id + 'jobs/'
else:
sys.exit(1)
if 'id' in self.args and self.args.id:
self.req_path = scan.SCAN_JOB_URI + self.args.id + '/'
else:
self.req_path += scan_object_id + 'jobs/'

if 'status' in self.args and self.args.status:
self.req_params = {'status': self.args.status}

Expand All @@ -84,27 +103,12 @@ def _handle_response_success(self):
if 'id' in self.args and self.args.id:
data = pretty_print(json_data)
print(data)
elif 'status' in self.args \
and self.args.status \
and (results != []):
data = pretty_print(json_data)
print(data)
else:
print(_(messages.SCAN_LIST_NO_SCANS))
sys.exit(1)
else:
data = pretty_print(results)
print(data)
if json_data.get('next'):
next_link = json_data.get('next')
params = urlparse.parse_qs(urlparse.urlparse(next_link).query)
page = params.get('page', ['1'])[0]
if self.req_params:
self.req_params['page'] = page
else:
self.req_params = {'page': page}
input(_(messages.NEXT_RESULTS))
self._do_command()
else:
print(_(messages.SCAN_LIST_NO_SCANS))
sys.exit(1)
83 changes: 74 additions & 9 deletions qpc/scan/tests_scan_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ def tearDown(self):
sys.stderr = self.orig_stderr

def test_scan_job_ssl_err(self):
"""Testing the scan job command with a connection error."""
"""Testing the scan job command with an ssl error."""
scan_out = StringIO()
url = get_server_location() + SCAN_URI
with requests_mock.Mocker() as mocker:
mocker.get(url, exc=requests.exceptions.SSLError)
sjc = ScanJobCommand(SUBPARSER)
args = Namespace(name='scan1')
args = Namespace(name='scan1', id=None)
with self.assertRaises(SystemExit):
with redirect_stdout(scan_out):
sjc.main(args)
Expand All @@ -63,7 +63,7 @@ def test_scan_job_conn_err(self):
with requests_mock.Mocker() as mocker:
mocker.get(url, exc=requests.exceptions.ConnectTimeout)
sjc = ScanJobCommand(SUBPARSER)
args = Namespace(name='scan1')
args = Namespace(name='scan1', id=None)
with self.assertRaises(SystemExit):
with redirect_stdout(scan_out):
sjc.main(args)
Expand All @@ -77,7 +77,7 @@ def test_scan_job_internal_err(self):
with requests_mock.Mocker() as mocker:
mocker.get(url, status_code=500, json={'error': ['Server Error']})
sjc = ScanJobCommand(SUBPARSER)
args = Namespace(name='scan1')
args = Namespace(name='scan1', id=None)
with self.assertRaises(SystemExit):
with redirect_stdout(scan_out):
sjc.main(args)
Expand All @@ -90,7 +90,7 @@ def test_scan_job_empty(self):
with requests_mock.Mocker() as mocker:
mocker.get(url, status_code=200, json={'count': 0})
sjc = ScanJobCommand(SUBPARSER)
args = Namespace(name='scan1')
args = Namespace(name='scan1', id=None)
with self.assertRaises(SystemExit):
with redirect_stdout(scan_out):
sjc.main(args)
Expand Down Expand Up @@ -123,7 +123,7 @@ def test_scan_job_filter_id(self):
mocker.get(url, status_code=200, json=data)
mocker.get(urlscanjob, status_code=200, json=scan_job)
sjc = ScanJobCommand(SUBPARSER)
args = Namespace(name='scan1', id='1')
args = Namespace(name=None, id='1', status=None)
with redirect_stdout(scan_out):
sjc.main(args)
expected = '{"id":1,"scan":"scan1","status":"completed"}'
Expand Down Expand Up @@ -160,7 +160,7 @@ def test_scan_job_filter_status(self):
mocker.get(url, status_code=200, json=data)
mocker.get(urlscanjob, status_code=200, json=scan_job)
sjc = ScanJobCommand(SUBPARSER)
args = Namespace(name='scan1', status='completed')
args = Namespace(name='scan1', status='completed', id=None)
with redirect_stdout(scan_out):
sjc.main(args)
expected = '[{"id":1,"scan":"scan1","status":"completed"},' \
Expand All @@ -187,7 +187,7 @@ def test_scan_job_no_filter(self):
}
# set up scan jobs
urlscanjob = get_server_location() + SCAN_URI + '1/jobs/'
scan_job = {'count': 3,
scan_job = {'count': 2,
'results': [{'id': 1,
'status': 'completed',
'scan': 'scan1'},
Expand All @@ -198,10 +198,75 @@ def test_scan_job_no_filter(self):
mocker.get(url, status_code=200, json=data)
mocker.get(urlscanjob, status_code=200, json=scan_job)
sjc = ScanJobCommand(SUBPARSER)
args = Namespace(name='scan1')
args = Namespace(name='scan1', id=None)
with redirect_stdout(scan_out):
sjc.main(args)
expected = '[{"id":1,"scan":"scan1","status":"completed"},' \
'{"id":2,"scan":"scan1","status":"running"}]'
self.assertEqual(scan_out.getvalue().replace('\n', '')
.replace(' ', '').strip(), expected)

def test_scan_job_name_and_id(self):
"""Testing the scan job with name & id."""
scan_out = StringIO()
sjc = ScanJobCommand(SUBPARSER)
args = Namespace(name='scan1', id=1)
with self.assertRaises(SystemExit):
with redirect_stdout(scan_out):
sjc.main(args)
self.assertEqual(scan_out.getvalue(),
messages.SCAN_JOB_NAME_ID + '\n')

def test_scan_job_no_name_or_id(self):
"""Testing the scan job with no name or id."""
scan_out = StringIO()
sjc = ScanJobCommand(SUBPARSER)
args = Namespace(name=None, id=None)
with self.assertRaises(SystemExit):
with redirect_stdout(scan_out):
sjc.main(args)
self.assertEqual(scan_out.getvalue(),
messages.SCAN_JOB_NO_ARGS + '\n')

def test_scan_job_id_and_status(self):
"""Testing the scan job with id and status filter."""
scan_out = StringIO()
sjc = ScanJobCommand(SUBPARSER)
args = Namespace(name=None, id=1, status='completed')
with self.assertRaises(SystemExit):
with redirect_stdout(scan_out):
sjc.main(args)
self.assertEqual(scan_out.getvalue(),
messages.SCAN_JOB_ID_STATUS + '\n')

def test_scan_job_no_jobs(self):
"""Testing the scan job with no jobs."""
scan_out = StringIO()
url = get_server_location() + SCAN_URI
# set up scan object
scan_entry = {'id': 1,
'name': 'scan1',
'scan_type': 'inspect',
'source': {
'id': 1,
'name': 'scan1'}}
results = [scan_entry]
data = {
'count': 1,
'next': None,
'results': results
}
# set up no scan jobs
urlscanjob = get_server_location() + SCAN_URI + '1/jobs/'
scan_job = {'count': 0,
'results': []}
with requests_mock.Mocker() as mocker:
mocker.get(url, status_code=200, json=data)
mocker.get(urlscanjob, status_code=200, json=scan_job)
sjc = ScanJobCommand(SUBPARSER)
args = Namespace(name='scan1', id=None)
with self.assertRaises(SystemExit):
with redirect_stdout(scan_out):
sjc.main(args)
self.assertEqual(scan_out.getvalue(),
messages.SCAN_LIST_NO_SCANS)

0 comments on commit 0d88f9c

Please sign in to comment.