From ae45ce141d03aa3bb7d77e15612f7105803b482f Mon Sep 17 00:00:00 2001 From: Steve McGrath Date: Tue, 20 Aug 2024 11:07:32 -0500 Subject: [PATCH] Pushed all times to UTC. added debug flag. #292 --- tenb2jira/cli.py | 10 +++++++++- tenb2jira/processor.py | 25 ++++++++++++------------- tenb2jira/tenable/tenable.py | 19 +++++++++---------- tests/tenable/test_tenable.py | 6 +++--- 4 files changed, 33 insertions(+), 27 deletions(-) diff --git a/tenb2jira/cli.py b/tenb2jira/cli.py index 9ee6737..c016965 100644 --- a/tenb2jira/cli.py +++ b/tenb2jira/cli.py @@ -129,13 +129,21 @@ def sync(configfile: Path, verbose: bool = False, cleanup: bool = True, ignore_last_run: bool = False, + debug: bool = False, ): """ Perform the sync between Tenable & Jira """ - setup_logging(verbose) with configfile.open('r', encoding='utf-8') as fobj: config = tomlkit.load(fobj) + + if debug: + verbose = True + cleanup = False + config['jira']['max_workers'] = 1 + + setup_logging(verbose) + processor = Processor(config, ignore_last_run=ignore_last_run) console.print(Columns([tenable_table(config), jira_table(config) diff --git a/tenb2jira/processor.py b/tenb2jira/processor.py index ab200d4..c37eddd 100644 --- a/tenb2jira/processor.py +++ b/tenb2jira/processor.py @@ -124,7 +124,7 @@ def build_mapping_db_model(self, value = value[0] item[fields[key]] = value # item = {fields[k]: v for k, v in issue.fields.items()} - item['updated'] = self.start_time + item['updated'] = self.start_time.datetime item['jira_id'] = issue.key if not missing: log.debug(f'Adding {issue.key} to cache.') @@ -185,11 +185,11 @@ def upsert_task(self, s: Session, finding: dict) -> (int | None): # and return the jira issue id back to the caller. if sql: if finding.get('integration_pid_updated') > self.last_run: - if sql.updated <= self.start_time: + if sql.updated <= self.start_time.datetime: self.jira.api.issues.update(sql.jira_id, fields=task.fields, ) - sql.updated = datetime.now() + sql.updated = datetime.utcnow() s.commit() log.info(f'Matched Task "{sql.jira_id}" to ' 'SQL Cache and updated.') @@ -213,7 +213,7 @@ def upsert_task(self, s: Session, finding: dict) -> (int | None): if len(page.issues) == 1: sql = TaskMap(plugin_id=task.fields[self.plugin_id], jira_id=page.issues[0].key, - updated=datetime.now(), + updated=datetime.utcnow(), ) s.add(sql) s.commit() @@ -232,7 +232,7 @@ def upsert_task(self, s: Session, finding: dict) -> (int | None): resp = self.jira.api.issues.create(fields=task.fields) sql = TaskMap(plugin_id=task.fields[self.plugin_id], jira_id=resp.key, - updated=datetime.now() + updated=datetime.utcnow() ) s.add(sql) s.commit() @@ -271,7 +271,7 @@ def upsert_subtask(self, if sql: if not task.is_open: sql.is_open = task.is_open - sql.updated = datetime.now() + sql.updated = datetime.utcnow() s.commit() self.close_task(sql.jira_id) action = 'closed subtask' @@ -313,7 +313,7 @@ def upsert_subtask(self, finding_id=task.fields[self.finding_id], jira_id=page.issues[0].key, is_open=task.is_open, - updated=datetime.now(), + updated=datetime.utcnow(), ) s.add(sql) s.commit() @@ -341,7 +341,7 @@ def upsert_subtask(self, finding_id=task.fields[self.finding_id], jira_id=resp.key, is_open=task.is_open, - updated=datetime.now(), + updated=datetime.utcnow(), ) s.add(sql) s.commit() @@ -419,11 +419,10 @@ def sync(self, cleanup: bool = True): """ Tenable to Jira Synchronization method. """ - self.start_time = datetime.now() - ts = int(arrow.get(self.start_time).timestamp()) + self.start_time = arrow.utcnow() # Get the findings and the asset cleanup generators. - findings = self.tenable.get_generator() + findings = self.tenable.get_generator(self.start_time) asset_cleanup = self.tenable.get_asset_cleanup() # build the db cache @@ -469,8 +468,8 @@ def sync(self, cleanup: bool = True): self.close_empty_tasks() # update the last_run timestamp with the time that we started the sync. - self.config['tenable']['last_run'] = ts - self.finished_time = datetime.now() + self.config['tenable']['last_run'] = int(self.start_time.timestamp()) + self.finished_time = arrow.utcnow() self.engine.dispose() # Delete the mapping database. diff --git a/tenb2jira/tenable/tenable.py b/tenb2jira/tenable/tenable.py index 6b24524..e1ba877 100644 --- a/tenb2jira/tenable/tenable.py +++ b/tenb2jira/tenable/tenable.py @@ -9,8 +9,8 @@ class Tenable: - tvm: (TenableIO | None) = None - tsc: (TenableSC | None) = None + tvm: TenableIO + tsc: TenableSC config: dict platform: str timestamp: int @@ -82,11 +82,10 @@ def get_tvm_generator(self) -> Generator[Any, Any, Any]: close_accepted=self.close_accepted, ) - def get_tsc_generator(self) -> Generator[Any, Any, Any]: + def get_tsc_generator(self, start_time: int) -> Generator[Any, Any, Any]: """ Queries the Analysis API and returns the TSC Generator. """ - self.last_run = int(arrow.now().timestamp()) # The severity map to link the string severities to the integer values # that TSC expects. @@ -99,7 +98,7 @@ def get_tsc_generator(self) -> Generator[Any, Any, Any]: } # Construct the TSC timestamp offsets. - tsc_ts = f'{self.timestamp}-{self.last_run}' + tsc_ts = f'{self.timestamp}-{start_time}' # The base parameters to pass to the API. params = { @@ -136,14 +135,15 @@ def get_tsc_generator(self) -> Generator[Any, Any, Any]: close_accepted=self.close_accepted, ) - def get_generator(self) -> (Generator[Any, Any, Any] | None): + def get_generator(self, + start_time: arrow.Arrow + ) -> Generator[Any, Any, Any]: """ Retreives the appropriate generator based on the configured platform. """ if self.platform == 'tvm': return self.get_tvm_generator() - if self.platform == 'tsc': - return self.get_tsc_generator() + return self.get_tsc_generator(int(start_time.timestamp())) def get_asset_cleanup(self) -> (Generator[Any, Any, Any] | list): if self.platform == 'tvm': @@ -154,5 +154,4 @@ def get_asset_cleanup(self) -> (Generator[Any, Any, Any] | list): chunk_size=self.chunk_size ) return tvm_asset_cleanup(dassets, tassets) - else: - return [] + return [] diff --git a/tests/tenable/test_tenable.py b/tests/tenable/test_tenable.py index b2b061a..81530dd 100644 --- a/tests/tenable/test_tenable.py +++ b/tests/tenable/test_tenable.py @@ -90,7 +90,7 @@ def test_get_asset_cleanup(tsc, tvm): def test_get_generator(tvm, tsc): responses.post('https://nourl/assets/export', json={'export_uuid': 0}) responses.post('https://nourl/vulns/export', json={'export_uuid': 0}) - assert isinstance(tvm.get_generator(), Generator) + assert isinstance(tvm.get_generator(arrow.now()), Generator) responses.get('https://nourl/rest/query/1?fields=filters', json={ 'response': {'query': {'filters': []}}, @@ -100,7 +100,7 @@ def test_get_generator(tvm, tsc): 'response': {}, 'error_code': None }) - assert isinstance(tsc.get_generator(), Generator) + assert isinstance(tsc.get_generator(arrow.now()), Generator) @responses.activate @@ -150,6 +150,6 @@ def test_get_tsc_generator(tsc, tsc_finding): })] ) tsc.vpr_score = 6.1 - generator = tsc.get_tsc_generator() + generator = tsc.get_tsc_generator(now) assert isinstance(generator, Generator) next(generator)