Skip to content

Commit

Permalink
Add filtering by type/status to CLI list scans
Browse files Browse the repository at this point in the history
  • Loading branch information
kholdaway committed Dec 15, 2017
1 parent 8a61add commit 418f7c0
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 5 deletions.
9 changes: 8 additions & 1 deletion docs/source/man.rst
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,15 @@ Listing and Showing Scans

The ``qpc scan list`` command returns the details for all executed scans. The output of this command includes the identifier, the source, and the status of the scan.

**qpc scan list**
**qpc scan list** **--type=** *(connect | inspect)* **--type=** *(created | pending | running | paused | canceled | completed | failed)*

``--state=state``

Optional. Filter list by scan state. Must be ``created``, ``pending``, ``running``, ``paused``, ``canceled``, ``completed`` or ``failed``.

``--type=type``

Optional. Filter list by scan type. Must be ``connect`` or ``inspect``.

The ``qpc scan show`` command is the same as the ``qpc scan list`` command, except that it returns details for a single specified scan.

Expand Down
6 changes: 5 additions & 1 deletion qpc/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,13 @@


SCAN_ID_HELP = 'scan identifier'
SCAN_TYPE_FILTER_HELP = 'type filter for listing scan jobs. Valid '\
'values: connect, inspect'
SCAN_STATUS_FILTER_HELP = 'status filter for listing scan jobs. Valid '\
'values: created, pending, running, paused, canceled, completed, failed'
SCAN_MAX_CONCURRENCY_HELP = 'number of concurrent scans; default=50'
SCAN_DOES_NOT_EXIST = 'Scan "%s" does not exist'
SCAN_LIST_NO_SCANS = 'No scans exist yet.'
SCAN_LIST_NO_SCANS = 'No scans found.'
SCAN_STARTED = 'Scan "%s" started'
SCAN_PAUSED = 'Scan "%s" paused'
SCAN_RESTARTED = 'Scan "%s" restarted'
Expand Down
9 changes: 9 additions & 0 deletions qpc/scan/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@
CANCEL = 'cancel'
RESTART = 'restart'

# Status values
SCAN_STATUS_CREATED = 'created'
SCAN_STATUS_PENDING = 'pending'
SCAN_STATUS_RUNNING = 'running'
SCAN_STATUS_PAUSED = 'paused'
SCAN_STATUS_CANCELED = 'canceled'
SCAN_STATUS_COMPLETED = 'completed'
SCAN_STATUS_FAILED = 'failed'


SCAN_URI = '/api/v1/scans/'

Expand Down
24 changes: 24 additions & 0 deletions qpc/scan/list.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,30 @@ def __init__(self, subparsers):
CliCommand.__init__(self, self.SUBCOMMAND, self.ACTION,
subparsers.add_parser(self.ACTION), GET,
scan.SCAN_URI, [codes.ok])
self.parser.add_argument('--type', dest='type',
choices=[scan.SCAN_TYPE_CONNECT,
scan.SCAN_TYPE_INSPECT],
metavar='TYPE',
help=_(messages.SCAN_TYPE_FILTER_HELP),
required=False)
self.parser.add_argument('--status', dest='status',
choices=[scan.SCAN_STATUS_CREATED,
scan.SCAN_STATUS_PENDING,
scan.SCAN_STATUS_RUNNING,
scan.SCAN_STATUS_PAUSED,
scan.SCAN_STATUS_CANCELED,
scan.SCAN_STATUS_COMPLETED,
scan.SCAN_STATUS_FAILED],
metavar='STATUS',
help=_(messages.SCAN_STATUS_FILTER_HELP),
required=False)

def _build_req_params(self):
"""Add filter by scan_type/state query param."""
if 'type' in self.args and self.args.type:
self.req_params = {'scan_type': self.args.type}
if 'status' in self.args and self.args.status:
self.req_params = {'status': self.args.status}

def _handle_response_success(self):
json_data = self.response.json()
Expand Down
53 changes: 50 additions & 3 deletions qpc/scan/tests_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from qpc.scan import SCAN_URI
from qpc.scan.list import ScanListCommand
from qpc.utils import get_server_location, write_server_config
from qpc import messages

PARSER = ArgumentParser()
SUBPARSER = PARSER.add_subparsers(dest='subcommand')
Expand Down Expand Up @@ -95,14 +96,14 @@ def test_list_scan_empty(self):
with redirect_stdout(scan_out):
slc.main(args)
self.assertEqual(scan_out.getvalue(),
'No scans exist yet.\n')
messages.SCAN_LIST_NO_SCANS + '\n')

def test_list_scan_data(self):
"""Testing the list scan command successfully with stubbed data."""
scan_out = StringIO()
url = BASE_URL + SCAN_URI
scan_entry = {'id': 1,
'scan_type': 'host',
'scan_type': 'inspect',
'source': {
'id': 1,
'name': 'scan1'},
Expand All @@ -114,7 +115,53 @@ def test_list_scan_data(self):
args = Namespace()
with redirect_stdout(scan_out):
slc.main(args)
expected = '[{"id":1,"scan_type":"host"' \
expected = '[{"id":1,"scan_type":"inspect"' \
',"source":{"id":1,"name":"scan1"},'\
'"status":"completed"}]'
self.assertEqual(scan_out.getvalue().replace('\n', '')
.replace(' ', '').strip(), expected)

def test_list_filter_type(self):
"""Testing the list scan with filter by type."""
scan_out = StringIO()
url = BASE_URL + SCAN_URI
scan_entry = {'id': 1,
'scan_type': 'inspect',
'source': {
'id': 1,
'name': 'scan1'},
'status': 'completed'}
data = [scan_entry]
with requests_mock.Mocker() as mocker:
mocker.get(url, status_code=200, json=data)
slc = ScanListCommand(SUBPARSER)
args = Namespace(type='inspect')
with redirect_stdout(scan_out):
slc.main(args)
expected = '[{"id":1,"scan_type":"inspect"' \
',"source":{"id":1,"name":"scan1"},'\
'"status":"completed"}]'
self.assertEqual(scan_out.getvalue().replace('\n', '')
.replace(' ', '').strip(), expected)

def test_list_filter_status(self):
"""Testing the list scan with filter by state."""
scan_out = StringIO()
url = BASE_URL + SCAN_URI
scan_entry = {'id': 1,
'scan_type': 'inspect',
'source': {
'id': 1,
'name': 'scan1'},
'status': 'completed'}
data = [scan_entry]
with requests_mock.Mocker() as mocker:
mocker.get(url, status_code=200, json=data)
slc = ScanListCommand(SUBPARSER)
args = Namespace(status='completed')
with redirect_stdout(scan_out):
slc.main(args)
expected = '[{"id":1,"scan_type":"inspect"' \
',"source":{"id":1,"name":"scan1"},'\
'"status":"completed"}]'
self.assertEqual(scan_out.getvalue().replace('\n', '')
Expand Down

0 comments on commit 418f7c0

Please sign in to comment.