From 8f84ca3317df75b335d32a1e3c9f62f10e3041c6 Mon Sep 17 00:00:00 2001
From: penenadpi <penenadpi@gmail.com>
Date: Tue, 20 Sep 2022 14:55:09 +0200
Subject: [PATCH] Improved connection error handling for MongoDB interface

Added API call to enable/disable persistence

Dumping order fix

Typos fixed
---
 install-checks.sh                          |  7 -------
 src/iac_scan_runner/api.py                 | 20 +++++++++++++++++++-
 src/iac_scan_runner/results_persistence.py | 18 ++++++++++++++----
 src/iac_scan_runner/scan_runner.py         | 21 +++++++++++++--------
 4 files changed, 46 insertions(+), 20 deletions(-)

diff --git a/install-checks.sh b/install-checks.sh
index d459ae5..9806812 100755
--- a/install-checks.sh
+++ b/install-checks.sh
@@ -151,12 +151,6 @@ installSonarScannerIfNot() {
   fi
 }
 
-# TODO: Add docker-compose.yml configuration
-runMongoDocker(){
-    docker rm --force scannerdb
-    docker run --name scannerdb -d -p 27017:27017 mongo
-}
-
 # call the functions above to install all the necessary tools
 createAndActivateVenvDirIfNot
 createDirIfNot "${TOOLS_DIR}"
@@ -180,4 +174,3 @@ installTfsecIfNot
 installTerrascanIfNot
 installSonarScannerIfNot
 removeDir "${TMP_DIR}"
-runMongoDocker
diff --git a/src/iac_scan_runner/api.py b/src/iac_scan_runner/api.py
index 9d0e5a5..352ec07 100644
--- a/src/iac_scan_runner/api.py
+++ b/src/iac_scan_runner/api.py
@@ -202,4 +202,22 @@ async def delete_scan_result(uuid: str) -> JSONResponse:
             return JSONResponse(status_code=status.HTTP_200_OK, content=f"No such scan result {uuid}")     
     except Exception as e:
         return JSONResponse(status_code=status.HTTP_400_BAD_REQUEST, content=str(e))         
-        
+
+
+@app.put("/persistence_enabler/{enable}", summary="Delete particular scan result by given uuid", responses={200: {}, 400: {"model": str}})
+async def persistence_enable(enable: str) -> JSONResponse:
+    """
+    Delete a particular scan result (GET method)
+    :param uuid: Identifier of a scan record in database
+    :return: JSONResponse object (with status code 200 or 400)
+    """
+    try:
+        if(enable == "disable"):
+            scan_runner.persistence_enabled = False              
+        else:
+            scan_runner.persistence_enabled = True
+                         
+        return JSONResponse(status_code=status.HTTP_200_OK, content=f"Persistence enable: {enable}")
+
+    except Exception as e:
+        return JSONResponse(status_code=status.HTTP_400_BAD_REQUEST, content=str(e))              
diff --git a/src/iac_scan_runner/results_persistence.py b/src/iac_scan_runner/results_persistence.py
index 0c3f5d2..d70c22e 100644
--- a/src/iac_scan_runner/results_persistence.py
+++ b/src/iac_scan_runner/results_persistence.py
@@ -3,16 +3,26 @@ import bson.json_util as json_util
 from bson.json_util import dumps
 import json
 from datetime import datetime
-
+import os
 class ResultsPersistence:
     def __init__(self):
     
         """
         Initialize new scan result database, collection and client
         """        
-        self.myclient = pymongo.MongoClient("mongodb://localhost:27017/") 
-        self.mydb = self.myclient["scandb"]
-        self.mycol = self.mydb["results"]
+        
+        try:
+            connection_string = os.environ['MONGO_STRING']  
+            print(connection_string)  
+            self.myclient = pymongo.MongoClient(connection_string)
+            self.mydb = self.myclient["scandb"]
+            self.mycol = self.mydb["results"]
+            self.connection_problem = False
+            
+        except Exception as e:
+            print("Scan result persistence not available")
+            self.connection_problem = True
+
 
     def parse_json(self, data):
         return json.loads(json_util.dumps(data))
diff --git a/src/iac_scan_runner/scan_runner.py b/src/iac_scan_runner/scan_runner.py
index 65e34c5..3f61f65 100644
--- a/src/iac_scan_runner/scan_runner.py
+++ b/src/iac_scan_runner/scan_runner.py
@@ -52,9 +52,10 @@ class ScanRunner:
         self.iac_checks = {}
         self.iac_dir = None
         self.compatibility_matrix = Compatibility()
-        self.results_summary = ResultsSummary()        
+        self.results_summary = ResultsSummary()
+        self.archive_name = ""   
+        self.persistence_enabled = True          
         self.results_persistence = ResultsPersistence()
-        self.archive_name = ""        
         
     def init_checks(self):
         """Initiate predefined check objects"""
@@ -166,14 +167,16 @@ class ScanRunner:
                         non_compatible_checks.append(check.name)
                         write_string_to_file(check.name, dir_name, "No files to scan")
                         self.results_summary.summarize_no_files(check.name)
-            self.results_summary.dump_outcomes(random_uuid)
+
             self.results_summary.generate_html_prioritized(random_uuid)
 
             self.results_summary.outcomes["uuid"] = random_uuid
             self.results_summary.outcomes["archive"] = self.archive_name                     
             self.results_summary.outcomes["time"] = datetime.now().strftime("%m/%d/%Y, %H:%M:%S")
-
-            self.results_persistence.insert_result(self.results_summary.outcomes) 
+            self.results_summary.dump_outcomes(random_uuid)
+                        
+            if(self.results_persistence.connection_problem == False and self.persistence_enabled == True):
+                self.results_persistence.insert_result(self.results_summary.outcomes) 
 
         else:
             for iac_check in self.iac_checks.values():
@@ -187,14 +190,16 @@ class ScanRunner:
                         non_compatible_checks.append(iac_check.name)
                         write_string_to_file(iac_check.name, dir_name, "No files to scan")
                         self.results_summary.summarize_no_files(iac_check.name)
-            self.results_summary.dump_outcomes(random_uuid)
+
             self.results_summary.generate_html_prioritized(random_uuid)                
             
             self.results_summary.outcomes["uuid"] = random_uuid
             self.results_summary.outcomes["archive"] = self.archive_name         
             self.results_summary.outcomes["time"] = datetime.now().strftime("%m/%d/%Y, %H:%M:%S")
-
-            self.results_persistence.insert_result(self.results_summary.outcomes)         
+            self.results_summary.dump_outcomes(random_uuid)
+            
+            if(self.results_persistence.connection_problem == False and self.persistence_enabled == True):
+                self.results_persistence.insert_result(self.results_summary.outcomes) 
         
         # TODO: Discuss the format of this output
         if scan_response_type == ScanResponseType.json:
-- 
GitLab