Skip to content

Commit 88313e4

Browse files
committed
integrated scanning abstraction
1 parent 61d4f24 commit 88313e4

File tree

2 files changed

+47
-38
lines changed

2 files changed

+47
-38
lines changed

cxone_api/scanning.py

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,13 @@
22
from . import CxOneClient
33
from .util import json_on_ok
44
from .exceptions import ScanException
5+
from requests import Response
56

67

78
class ScanInvoker:
8-
99
@staticmethod
10-
async def scan(cxone_client : CxOneClient, project_repo : ProjectRepoConfig, branch : str, engines : list = None , tags : dict = None, src_zip_path : str = None,
11-
clone_user : str = None, clone_cred_type : str = None, clone_cred_value : str = None) -> str:
12-
10+
async def scan_get_response(cxone_client : CxOneClient, project_repo : ProjectRepoConfig, branch : str, engines : list = None , tags : dict = None, src_zip_path : str = None,
11+
clone_user : str = None, clone_cred_type : str = None, clone_cred_value : str = None) -> Response:
1312
submit_payload = {}
1413

1514
target_repo = await project_repo.repo_url
@@ -42,13 +41,7 @@ async def scan(cxone_client : CxOneClient, project_repo : ProjectRepoConfig, bra
4241
if target_repo is not None:
4342
submit_payload["handler"]["repoUrl"] = target_repo
4443

45-
scan_submit_response = await cxone_client.execute_scan(submit_payload)
46-
47-
if not scan_submit_response.ok:
48-
raise ScanException(f"Scan error for project {project_repo.project_id}: Status: {scan_submit_response.status_code} : {scan_submit_response.json()}")
49-
50-
return json_on_ok(scan_submit_response)['id']
51-
44+
return await cxone_client.execute_scan(submit_payload)
5245
else:
5346
submit_payload["repoOrigin"] = await project_repo.scm_type
5447
submit_payload["project"] = {
@@ -62,13 +55,21 @@ async def scan(cxone_client : CxOneClient, project_repo : ProjectRepoConfig, bra
6255

6356
scm_org = await project_repo.scm_org
6457

65-
scan_submit_response = await cxone_client.execute_repo_scan(await project_repo.scm_id, project_repo.project_id,
58+
return await cxone_client.execute_repo_scan(await project_repo.scm_id, project_repo.project_id,
6659
scm_org if scm_org is not None else "anyorg", submit_payload)
67-
if not scan_submit_response.ok:
68-
raise ScanException(f"Scan error for project {project_repo.project_id}: Status: {scan_submit_response.status_code} : {scan_submit_response.json()}")
69-
70-
return None
71-
60+
61+
@staticmethod
62+
async def scan_get_scanid(cxone_client : CxOneClient, project_repo : ProjectRepoConfig, branch : str, engines : list = None , tags : dict = None, src_zip_path : str = None,
63+
clone_user : str = None, clone_cred_type : str = None, clone_cred_value : str = None) -> str:
64+
65+
response = await ScanInvoker.scan_get_response(cxone_client, project_repo, branch, engines, tags, src_zip_path, clone_user, clone_cred_type, clone_cred_value)
66+
response_json = response.json()
67+
68+
if not response.ok:
69+
raise ScanException(f"Scan error for project {project_repo.project_id}: Status: {response.status_code} : {response.json()}")
70+
71+
return json_on_ok(response_json)['id'] if "id" in response_json.keys() else None
72+
7273

7374
@staticmethod
7475
async def __upload_zip(cxone_client : CxOneClient, zip_path : str) -> str:

scanner.py

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#!/usr/bin/python3
22
import logging, argparse, utils, asyncio
33
from cxone_api import CxOneClient
4+
from cxone_api.scanning import ScanInvoker
5+
from cxone_api.projects import ProjectRepoConfig
6+
from cxone_api.util import json_on_ok
47
from posix_ipc import Semaphore, BusyError, O_CREAT
58

69
utils.configure_normal_logging()
@@ -15,6 +18,24 @@
1518
parser.add_argument('--branch', '-b', action='store', type=str, required=True, dest="branch", help="The code repository URL.")
1619
parser.add_argument('--schedule', '-s', action='store', type=str, required=False, default='unknown', dest="schedule", help="The schedule string assigned to the 'scheduled' scan tag.")
1720

21+
22+
async def should_scan(client : CxOneClient, project_repo : ProjectRepoConfig, branch : str) -> bool:
23+
if not await project_repo.is_scm_imported:
24+
running_scans = json_on_ok(await client.get_scans(tags_keys="scheduled", branch=branch, project_id=project_repo.project_id, statuses=['Queued', 'Running']))
25+
if int(running_scans['filteredTotalCount']) == 0:
26+
return True
27+
else:
28+
# It currently isn't possible to tag a scan created in a project that was import from SCM, so just look
29+
# at the last scan in status Queued or Running.
30+
potential_running_scan = json_on_ok(await client.get_projects_last_scan(branch=branch, limit=1, project_ids=[project_repo.project_id], scan_status="Running"))
31+
potential_queued_scan = json_on_ok(await client.get_projects_last_scan(branch=branch, limit=1, project_ids=[project_repo.project_id], scan_status="Queued"))
32+
33+
if project_repo.project_id in potential_running_scan.keys() or project_repo.project_id in potential_queued_scan.keys():
34+
return True
35+
36+
return False
37+
38+
1839
async def main():
1940
try:
2041
args = parser.parse_args()
@@ -51,31 +72,18 @@ async def main():
5172

5273
try:
5374
__log.debug(f"Semaphore acquired for {utils.make_safe_name(args.projectid, args.branch)}")
75+
76+
project_repo = await ProjectRepoConfig.from_project_id(client, args.projectid)
5477

5578
# Do not submit a scheduled scan if a scheduled scan is already running.
56-
scans = (await client.get_scans(tags_keys="scheduled", branch=args.branch, project_id=args.projectid, statuses=['Queued', 'Running'])).json()
57-
58-
if scans['filteredTotalCount'] == 0:
59-
scan_spec = {
60-
"type" : "git",
61-
"handler" : {
62-
"branch" : args.branch,
63-
"repoUrl" : args.repo
64-
},
65-
"project" : {
66-
"id" : args.projectid,
67-
},
68-
"config" : [{ "type" : x, "value" : {} } for x in args.engines],
69-
"tags" : tag
70-
}
71-
72-
73-
response = await client.execute_scan(scan_spec)
74-
if response.ok:
79+
if await should_scan(client, project_repo, args.branch):
80+
81+
scan_response = await ScanInvoker.scan_get_response(client, project_repo, args.branch, args.engines, tag)
82+
83+
if scan_response.ok:
7584
__log.info(f"Scanning project {args.projectid} branch {args.branch}")
7685
else:
77-
__log.error(f"Failed to start scan for project {args.projectid} branch {args.branch}: {response.status_code}:{response.reason}")
78-
86+
__log.error(f"Failed to start scan for project {args.projectid} branch {args.branch}: {scan_response.status_code}:{scan_response.json()}")
7987

8088
else:
8189
__log.warning(f"Scheduled scan for project {args.projectid} branch {args.branch} is already running, skipping.")

0 commit comments

Comments
 (0)