From 99e6300247cc309dc75fd5b7fec7b1ea93b1f818 Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Wed, 16 Sep 2020 11:45:33 +0200 Subject: [PATCH 1/5] Add method to add a key with a list of elements An existing key is replaced, and duplicated values under the are allowed. --- ospd_openvas/db.py | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/ospd_openvas/db.py b/ospd_openvas/db.py index 3aea6bff..646e8d9d 100644 --- a/ospd_openvas/db.py +++ b/ospd_openvas/db.py @@ -261,8 +261,33 @@ def get_single_item( return ctx.lindex(name, index) @staticmethod - def add_single_item(ctx: RedisCtx, name: str, values: Iterable): + def add_single_list(ctx: RedisCtx, name: str, values: Iterable): """Add a single KB element with one or more values. + The values can be repeated. If the key already exists will + be removed an completely replaced. + + Arguments: + ctx: Redis context to use. + name: key name of a list. + value: Elements to add to the key. + """ + if not ctx: + raise RequiredArgument('add_single_list', 'ctx') + if not name: + raise RequiredArgument('add_single_list', 'name') + if not values: + raise RequiredArgument('add_single_list', 'value') + + pipe = ctx.pipeline() + pipe.delete(name) + pipe.rpush(name, *values) + pipe.execute() + + @staticmethod + def add_single_item(ctx: RedisCtx, name: str, values: Iterable): + """Add a single KB element with one or more values. Don't add + duplicated values during this operation, but if the the same + values already exists under the key, this will not be overwritten. Arguments: ctx: Redis context to use. From c6d91b2d4d37e71c383146ea7e3c248e88e9c01e Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Wed, 16 Sep 2020 11:46:56 +0200 Subject: [PATCH 2/5] Fix method name in message and improve docstring --- ospd_openvas/db.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ospd_openvas/db.py b/ospd_openvas/db.py index 646e8d9d..bdf7cfec 100644 --- a/ospd_openvas/db.py +++ b/ospd_openvas/db.py @@ -295,17 +295,18 @@ def add_single_item(ctx: RedisCtx, name: str, values: Iterable): value: Elements to add to the key. """ if not ctx: - raise RequiredArgument('add_list_item', 'ctx') + raise RequiredArgument('add_single_item', 'ctx') if not name: - raise RequiredArgument('add_list_item', 'name') + raise RequiredArgument('add_single_item', 'name') if not values: - raise RequiredArgument('add_list_item', 'value') + raise RequiredArgument('add_single_item', 'value') ctx.rpush(name, *set(values)) @staticmethod def set_single_item(ctx: RedisCtx, name: str, value: Iterable): - """Set (replace) a single KB element. + """Set (replace) a single KB element. If the same key exists + in the kb, it is completed removed. Values added are unique. Arguments: ctx: Redis context to use. From 73b6861c27182b52a5386cd38a5debbd912eed61 Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Wed, 16 Sep 2020 11:47:37 +0200 Subject: [PATCH 3/5] Add method to add a vt in cache --- ospd_openvas/nvticache.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/ospd_openvas/nvticache.py b/ospd_openvas/nvticache.py index 29234a71..0c2e4d35 100644 --- a/ospd_openvas/nvticache.py +++ b/ospd_openvas/nvticache.py @@ -23,6 +23,8 @@ from typing import List, Dict, Optional, Iterator, Tuple +from ospd.errors import RequiredArgument +from ospd_openvas.errors import OspdOpenvasError from ospd_openvas.db import NVT_META_FIELDS, OpenvasDB, MainDB, BaseDB, RedisCtx NVTI_CACHE_NAME = "nvticache" @@ -306,3 +308,15 @@ def get_nvt_count(self) -> int: def force_reload(self): self._main_db.release_database(self) + + def add_vt_to_cache(self, vt_id: str, vt: List[str]): + if not vt_id: + raise RequiredArgument('add_vt_to_cache', 'vt_id') + if not vt: + raise RequiredArgument('add_vt_to_cache', 'vt') + if not isinstance(vt, list) or len(vt) != 15: + raise OspdOpenvasError( + 'Error trying to load the VT' ' {} in cache'.format(vt) + ) + + OpenvasDB.add_single_list(self.ctx, vt_id, vt) From 52bc4fe1b4d93fed98579575c23f93776af5c0eb Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Wed, 16 Sep 2020 11:50:54 +0200 Subject: [PATCH 4/5] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 105cf0a0..8766da6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Added - Add dedicated port list for alive detection (Boreas only) as scanner preference if supplied via OSP. [#327](https://github.com/greenbone/ospd-openvas/pull/327) +- Add methods for adding VTs to the redis cache.[#337](https://github.com/greenbone/ospd-openvas/pull/337) ### Changed - Get all results from main kb. [#285](https://github.com/greenbone/ospd-openvas/pull/285) From 3c2253e5c3451272f65e18bf5749c8a6c2d34bf1 Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Wed, 16 Sep 2020 12:50:13 +0200 Subject: [PATCH 5/5] Add test --- tests/test_db.py | 28 ++++++++++++++++-- tests/test_nvti_cache.py | 63 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 82 insertions(+), 9 deletions(-) diff --git a/tests/test_db.py b/tests/test_db.py index 2ca1988e..87c41232 100644 --- a/tests/test_db.py +++ b/tests/test_db.py @@ -164,11 +164,23 @@ def test_get_single_item(self, mock_redis): self.assertEqual(value, 'a') ctx.lindex.assert_called_once_with('a', 0) + def test_add_single_list(self, mock_redis): + ctx = mock_redis.return_value + pipeline = ctx.pipeline.return_value + pipeline.delete.return_value = None + pipeline.execute.return_value = (None, 0) + + OpenvasDB.add_single_list(ctx, 'a', ['12', '11', '12']) + + pipeline.delete.assert_called_once_with('a') + pipeline.rpush.assert_called_once_with('a', '12', '11', '12') + assert_called(pipeline.execute) + def test_add_single_item(self, mock_redis): ctx = mock_redis.return_value ctx.rpush.return_value = 1 - OpenvasDB.add_single_item(ctx, 'a', ['12']) + OpenvasDB.add_single_item(ctx, 'a', ['12', '12']) ctx.rpush.assert_called_once_with('a', '12') @@ -350,7 +362,12 @@ def test_get_result(self, mock_openvas_db): ret = self.db.get_result() - self.assertEqual(ret, ['some result',]) + self.assertEqual( + ret, + [ + 'some result', + ], + ) mock_openvas_db.pop_list_items.assert_called_with( self.ctx, 'internal/results' ) @@ -393,7 +410,12 @@ def test_get_result(self, mock_openvas_db): ret = self.db.get_result() - self.assertEqual(ret, ['some results',]) + self.assertEqual( + ret, + [ + 'some results', + ], + ) mock_openvas_db.pop_list_items.assert_called_with( self.ctx, 'internal/results' ) diff --git a/tests/test_nvti_cache.py b/tests/test_nvti_cache.py index b535070c..b6189e41 100644 --- a/tests/test_nvti_cache.py +++ b/tests/test_nvti_cache.py @@ -84,8 +84,10 @@ def test_parse_metadata_tag_missing_value(self, MockOpenvasDB): logging.Logger.error = Mock() tags = 'tag1' - ret = NVTICache._parse_metadata_tags( # pylint: disable=protected-access - tags, '1.2.3' + ret = ( + NVTICache._parse_metadata_tags( # pylint: disable=protected-access + tags, '1.2.3' + ) ) self.assertEqual(ret, {}) @@ -93,16 +95,20 @@ def test_parse_metadata_tag_missing_value(self, MockOpenvasDB): def test_parse_metadata_tag(self, MockOpenvasDB): tags = 'tag1=value1' - ret = NVTICache._parse_metadata_tags( # pylint: disable=protected-access - tags, '1.2.3' + ret = ( + NVTICache._parse_metadata_tags( # pylint: disable=protected-access + tags, '1.2.3' + ) ) self.assertEqual(ret, {'tag1': 'value1'}) def test_parse_metadata_tags(self, MockOpenvasDB): tags = 'tag1=value1|foo=bar' - ret = NVTICache._parse_metadata_tags( # pylint: disable=protected-access - tags, '1.2.3' + ret = ( + NVTICache._parse_metadata_tags( # pylint: disable=protected-access + tags, '1.2.3' + ) ) self.assertEqual(ret, {'tag1': 'value1', 'foo': 'bar'}) @@ -310,3 +316,48 @@ def test_flush(self, _MockOpenvasDB): self.nvti.flush() self.nvti._ctx.flushdb.assert_called_with() + + def test_add_vt(self, MockOpenvasDB): + MockOpenvasDB.add_single_list = Mock() + + self.nvti.add_vt_to_cache( + '1234', + [ + 'a', + 'b', + 'c', + 'd', + 'e', + 'f', + 'g', + 'h', + 'i', + 'j', + 'k', + 'l', + 'm', + 'n', + 'o', + ], + ) + MockOpenvasDB.add_single_list.assert_called_with( + 'foo', + '1234', + [ + 'a', + 'b', + 'c', + 'd', + 'e', + 'f', + 'g', + 'h', + 'i', + 'j', + 'k', + 'l', + 'm', + 'n', + 'o', + ], + )