Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Towards better inference: bits → nibbles #3808

Open
wants to merge 189 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 50 commits
Commits
Show all changes
189 commits
Select commit Hold shift + click to select a range
ae00a8e
Introducing nibbles
originalsouth Aug 27, 2024
c90fcb0
Prototyping
originalsouth Aug 28, 2024
d57cf19
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Sep 18, 2024
64ece62
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Sep 18, 2024
bba22a3
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Sep 18, 2024
0896eba
set default in model
noamblitz Sep 19, 2024
964b89b
remove default bit
noamblitz Sep 19, 2024
5915f03
fix test
noamblitz Sep 19, 2024
ed7be58
Fix Octopoes tests for patch related changes
originalsouth Sep 19, 2024
efa3c97
Merge branch 'set-default-risk-in-model' of github.com:minvws/nl-kat-…
originalsouth Sep 19, 2024
663a9bb
Fix Octopoes tests for patch related changes II
originalsouth Sep 19, 2024
bd78ed9
Merge branch 'main' into set-default-risk-in-model
originalsouth Sep 19, 2024
b5ba90a
Fix Octopoes tests for patch related changes III
originalsouth Sep 19, 2024
f885652
Merge branch 'set-default-risk-in-model' of github.com:minvws/nl-kat-…
originalsouth Sep 19, 2024
b05283e
Prevent race conditions between Octopoes' event manager and the sched…
originalsouth Sep 19, 2024
06d1080
Merge branch 'main' into set-default-risk-in-model
underdarknl Sep 20, 2024
5bf8b35
Merge branch 'main' into set-default-risk-in-model
originalsouth Sep 23, 2024
967d41b
Merge branch 'main' into set-default-risk-in-model
underdarknl Sep 23, 2024
d30b33f
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Sep 23, 2024
86fe7d5
Merge branch 'fix/prevent_race_conditions_between_event_manager_and_s…
originalsouth Sep 23, 2024
dca2b20
Merge branch 'set-default-risk-in-model' into feature/nibbles
originalsouth Sep 23, 2024
7699d93
Fixes for idle run
originalsouth Sep 23, 2024
0eb106f
Merge branch 'main' into feature/nibbles
originalsouth Sep 24, 2024
2ed89fb
Manual merge
originalsouth Oct 14, 2024
d9c9fa2
Revert "Set default findingtype risk in model instead of in bit (#3562)"
originalsouth Oct 14, 2024
20c5abf
Pre-commit after revert
originalsouth Oct 14, 2024
2d09141
Remove bogus rlu_cache
originalsouth Oct 15, 2024
6adeffe
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Oct 16, 2024
f3f4277
Register origins and add parameters begins
originalsouth Oct 16, 2024
ef9ad80
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Oct 16, 2024
5546cd8
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Oct 16, 2024
cf2f04c
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Oct 16, 2024
6fd5f74
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Oct 29, 2024
1b49c3b
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Oct 30, 2024
b28ae84
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Oct 30, 2024
8b0f50d
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Oct 31, 2024
f140e87
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Nov 4, 2024
be03bf8
Add blocklist and ooi reuse to inference
originalsouth Nov 4, 2024
852ec3e
Fix runner
originalsouth Nov 4, 2024
ed4c40a
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Nov 4, 2024
df9a329
Basic nibbler
originalsouth Nov 6, 2024
5908b42
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Nov 6, 2024
2de975d
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Nov 7, 2024
a67b297
Add more boilerplating
originalsouth Nov 7, 2024
f20cb4b
Check clearance for seed OOI in nibbles
originalsouth Nov 7, 2024
d706b35
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Nov 7, 2024
49e1116
Add unit test
originalsouth Nov 7, 2024
8ff6fac
Add unit test
originalsouth Nov 7, 2024
a9da549
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Nov 7, 2024
6fbcf12
Make SonarClaus Happier
originalsouth Nov 7, 2024
bd7b82d
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Nov 12, 2024
13400b3
More testing and fixing
originalsouth Nov 12, 2024
137b687
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Nov 12, 2024
aa66104
Moves towards a new niddles
originalsouth Nov 13, 2024
4d9baa2
Purge NMAX
originalsouth Nov 13, 2024
63cdaec
Another day another design
originalsouth Nov 14, 2024
f337ee3
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Nov 14, 2024
a18929b
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Nov 17, 2024
e35b101
Add multivariable support
originalsouth Nov 18, 2024
0c8a6bb
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Nov 18, 2024
d320be2
Refactor
originalsouth Nov 19, 2024
87909ae
Fix typing
originalsouth Nov 19, 2024
4b853d9
Refactor
originalsouth Nov 19, 2024
d084a38
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Nov 19, 2024
5266ccd
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Nov 20, 2024
e7b3a5a
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Nov 20, 2024
bd59705
Mostly fix nibble-origins -> nibblettes
originalsouth Nov 21, 2024
e9a4576
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Nov 21, 2024
8c6d6e5
Add comment
originalsouth Nov 21, 2024
9890402
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Nov 26, 2024
ac80ae0
Give me the $$$ AWK input
originalsouth Nov 26, 2024
d978519
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Nov 26, 2024
6272afc
Faster serialization
originalsouth Nov 27, 2024
82b6ad4
Skip encoding
originalsouth Nov 27, 2024
dee4a4a
Revert "Faster serialization"
originalsouth Nov 27, 2024
c40537d
nibblette -> nibblet
originalsouth Nov 27, 2024
9e0a0ca
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Nov 27, 2024
d19812d
Test re-evaluation
originalsouth Nov 27, 2024
5e5ff0b
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Nov 27, 2024
cc73cf0
Fix double dict entry "bug"
originalsouth Nov 28, 2024
986b32d
Run all nibbles not touched by nibblets
originalsouth Nov 28, 2024
40f9093
Cleanup code
originalsouth Dec 2, 2024
555dcd5
Manual merge poetry.lock
originalsouth Dec 2, 2024
4bd5198
Rais non-nibblet origins
originalsouth Dec 2, 2024
b0352d6
Better specializations
originalsouth Dec 2, 2024
16e5259
Fix requirements
originalsouth Dec 2, 2024
603c943
Don't change the integration test
originalsouth Dec 2, 2024
c5da166
Add FIXME comment
originalsouth Dec 2, 2024
6751284
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Dec 2, 2024
6dd8b9b
Type fix
originalsouth Dec 2, 2024
0ebdc9d
Add OOI caching
originalsouth Dec 2, 2024
09fd601
Remove useless tests
originalsouth Dec 2, 2024
8cf3533
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Dec 3, 2024
edb8822
Serialization fixes
originalsouth Dec 4, 2024
4d5ef74
Remove parameter hash
originalsouth Dec 4, 2024
193342e
Add first (test) nibblet
originalsouth Dec 4, 2024
665439c
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Dec 4, 2024
715036f
Minor updates
originalsouth Dec 4, 2024
2b246c6
Minimum scanlevel per variable
originalsouth Dec 4, 2024
7ad6614
Remove min scan level requirements (for now)
originalsouth Dec 4, 2024
de0c783
Fixed some patched bit tests
originalsouth Dec 4, 2024
7b2417b
Remove legacy min_scan_level
originalsouth Dec 4, 2024
03eea29
Nibble functionality in router
originalsouth Dec 4, 2024
14c9f0e
Add first real nibble
originalsouth Dec 4, 2024
8185ed1
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Dec 4, 2024
f73ccb1
Fix Octopoes' integration tests
originalsouth Dec 4, 2024
23af315
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Dec 4, 2024
0f0204a
Fix Octopoes' tests
originalsouth Dec 4, 2024
58e4e5f
Redo pad_level
originalsouth Dec 4, 2024
f5b1a78
Migrate 1 to N bits to nibbles
originalsouth Dec 5, 2024
ae1d35c
Fix dov nibble
originalsouth Dec 5, 2024
128be59
Fix SPF header
originalsouth Dec 5, 2024
ea90a6d
website discovery bit to nibble
noamblitz Dec 5, 2024
a857ee3
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Dec 9, 2024
c7e6a34
Implement recalculate for nibbler
originalsouth Dec 9, 2024
d03014a
Implement recalculate for nibbler
originalsouth Dec 9, 2024
1813b23
Fix octopoes tests (non-integration)
originalsouth Dec 9, 2024
d9dac77
Add reset routine
originalsouth Dec 9, 2024
4315910
Allow queries to be callable
originalsouth Dec 10, 2024
cfb5266
Update callable queries
originalsouth Dec 10, 2024
73dddf1
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Dec 10, 2024
c044dd0
Test for callability
originalsouth Dec 10, 2024
f731775
Retire the dollars
originalsouth Dec 10, 2024
04c8cda
add failing parent ooi type test
noamblitz Dec 10, 2024
df49296
check types with isinstance
noamblitz Dec 10, 2024
1495aef
Retire port_common
originalsouth Dec 10, 2024
d3686de
Manual merge of main
originalsouth Dec 10, 2024
887abee
Fix event manager test
originalsouth Dec 10, 2024
8e0c9ee
Remove printer
originalsouth Dec 10, 2024
b224e4c
Remove port_common tests from test
originalsouth Dec 10, 2024
dc81654
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Dec 10, 2024
e703325
Delete Nibblets properly
originalsouth Dec 11, 2024
9d426d6
Better deletion II
originalsouth Dec 11, 2024
653b004
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Dec 11, 2024
9e3ba58
Remove dangling affirmation a bit later
originalsouth Dec 12, 2024
eb5f6ec
Remove redundant nibble definitions in test_nibbles
originalsouth Dec 12, 2024
191c9ae
More utility functions and maintenance
originalsouth Dec 12, 2024
884a3d7
POJO --> BaseModel
originalsouth Dec 12, 2024
fda34e8
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Dec 12, 2024
0daf3a7
Convert check_hsts_header
originalsouth Dec 12, 2024
5701a6c
Convert check_hsts_header II
originalsouth Dec 12, 2024
2109257
Port disallowed_csp_hostnames
originalsouth Dec 12, 2024
2eef723
allow optional nibble params
noamblitz Dec 12, 2024
c88d03b
Port ooi_in_headers
originalsouth Dec 12, 2024
67fe804
Port ooi_in_headers tests
originalsouth Dec 12, 2024
fe40e42
Add referencefield?
originalsouth Dec 12, 2024
a579212
Add referencefield
originalsouth Dec 12, 2024
d0bdaf9
Add referencefield
originalsouth Dec 12, 2024
b49e831
port missing_spf bit with tests
noamblitz Dec 13, 2024
c3d2763
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Dec 13, 2024
03baf16
fix hsts header nibble with tests
noamblitz Dec 13, 2024
3521a97
check for bit id in query
noamblitz Dec 13, 2024
366e830
Fix itests
originalsouth Dec 16, 2024
9ebe56e
Update config ooi nibbles
originalsouth Dec 16, 2024
a1d02f7
Support nibbles with duplicate parameters in signature
originalsouth Dec 16, 2024
66df903
Fix bit_id for disallowed_csp_hostnames nibble
originalsouth Dec 16, 2024
ac699ef
Unit tests for objectify
originalsouth Dec 16, 2024
c51dca9
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Dec 16, 2024
0ecceec
Introduce tests for config nibbles
originalsouth Dec 17, 2024
66a287a
Fix tests for config nibbles
originalsouth Dec 17, 2024
38dc032
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Dec 17, 2024
1e81c09
Bypass SonarCloudSecurity check?
originalsouth Dec 17, 2024
e9b29b4
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Dec 17, 2024
b74d36a
Fix config queries
originalsouth Dec 18, 2024
779afb7
Patch the ROBOT tetst (there should be more objects with the nibble a…
originalsouth Dec 18, 2024
ec0f8bd
Remove nibbles reset routine (unwanted and premature for now)
originalsouth Dec 18, 2024
15304bc
Update disallow_csp_hostnames from upstream
originalsouth Dec 18, 2024
2076e50
Allow none configs in new nibble
originalsouth Dec 18, 2024
d7403c5
Retire perform_writes option
originalsouth Dec 18, 2024
719da7c
Make sonarcloud happier
originalsouth Dec 18, 2024
7524a11
Make sonarcloud happier
originalsouth Dec 18, 2024
a2d383c
Make sonarcloud happier
originalsouth Dec 18, 2024
e680adc
Cleanup unused code
originalsouth Dec 18, 2024
b4181f1
Allow reruns when nibbles are updated (part I)
originalsouth Dec 18, 2024
e27fbbe
Add retrieve functionality
originalsouth Dec 19, 2024
777b1b8
Implement yields
originalsouth Dec 19, 2024
7cd694f
Add update nibble routines
originalsouth Dec 19, 2024
acc8bbc
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Dec 23, 2024
8106a26
Document objectify a bit
originalsouth Dec 23, 2024
e4dbe69
Rename objectify --> parse_as
originalsouth Dec 23, 2024
cb7ebfb
Beginnings of NibbleRepository etc
originalsouth Dec 24, 2024
22b025f
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Dec 24, 2024
0cd92b2
Actually add the NibbleRepository
originalsouth Dec 24, 2024
ee92430
Fix integration tests
originalsouth Dec 24, 2024
358ec81
Fix tests...
originalsouth Dec 24, 2024
f1d8d15
Merge remote-tracking branch 'origin/main' into feature/nibbles
originalsouth Dec 26, 2024
2b92683
Implement centralized Nibble toggle mechanism
originalsouth Dec 26, 2024
8b1f232
Federilized Nibblers
originalsouth Dec 26, 2024
7149279
Federilized Nibblers II
originalsouth Dec 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added octopoes/nibbles/__init__.py
Empty file.
95 changes: 95 additions & 0 deletions octopoes/nibbles/definitions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import importlib
import pkgutil
from logging import getLogger
from pathlib import Path
from types import MethodType, ModuleType

from pydantic import BaseModel

from octopoes.models import OOI

NIBBLES_DIR = Path(__file__).parent
NIBBLE_ATTR_NAME = "NIBBLE"
NIBBLE_FUNC_NAME = "nibble"
logger = getLogger(__name__)
originalsouth marked this conversation as resolved.
Show resolved Hide resolved


class NibbleParameterDefinition(BaseModel):
ooi_type: type[OOI]
relation_path: str | None = None

def __eq__(self, other):
if isinstance(other, NibbleParameterDefinition):
return vars(self) == vars(other)
elif isinstance(other, type):
return self.ooi_type == other
else:
return False

def __hash__(self):
return hash(str(self.ooi_type) + self.relation_path if self.relation_path else "\0")
originalsouth marked this conversation as resolved.
Show resolved Hide resolved


class NibbleDefinition:
originalsouth marked this conversation as resolved.
Show resolved Hide resolved
id: str
signature: list[NibbleParameterDefinition]
min_scan_level: int = 1
default_enabled: bool = True
config_ooi_relation_path: str | None = None
payload: MethodType | None = None

def __init__(
self,
name: str,
signature: list,
min_scan_level: int = 1,
default_enabled: bool = True,
config_ooi_relation_path: str | None = None,
):
self.id = name
self.signature = signature
self.min_scan_level = min_scan_level
self.default_enabled = default_enabled
self.config_ooi_relation_path = config_ooi_relation_path

def __call__(self, args):
if self.payload is None:
raise NotImplementedError
else:
return self.payload(*args)


def get_nibble_definitions() -> list[NibbleDefinition]:
nibble_definitions = []

for package in pkgutil.walk_packages([str(NIBBLES_DIR)]):
if package.name in ["definitions", "runner"]:
continue

try:
module: ModuleType = importlib.import_module(".nibble", f"{NIBBLES_DIR.name}.{package.name}")

if hasattr(module, NIBBLE_ATTR_NAME):
nibble_definition: NibbleDefinition = getattr(module, NIBBLE_ATTR_NAME)

try:
payload: ModuleType = importlib.import_module(
f".{package.name}", f"{NIBBLES_DIR.name}.{package.name}"
)
if hasattr(payload, NIBBLE_FUNC_NAME):
nibble_definition.payload = getattr(payload, NIBBLE_FUNC_NAME)
else:
logger.warning('module "%s" has no function %s', package.name, NIBBLE_FUNC_NAME)

except ModuleNotFoundError:
logger.warning('package "%s" has no function nibble', package.name)

nibble_definitions.append(nibble_definition)

else:
logger.warning('module "%s" has no attribute %s', package.name, NIBBLE_ATTR_NAME)

except ModuleNotFoundError:
logger.warning('package "%s" has no module nibble', package.name)

return nibble_definitions
83 changes: 83 additions & 0 deletions octopoes/nibbles/runner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
from collections.abc import Callable
from datetime import datetime
from itertools import chain, product
from typing import TypeVar

from nibbles.definitions import NibbleDefinition, get_nibble_definitions
from octopoes.models import OOI
from octopoes.models.types import type_by_name
from octopoes.repositories.ooi_repository import OOIRepository
from octopoes.repositories.origin_parameter_repository import OriginParameterRepository
from octopoes.repositories.scan_profile_repository import ScanProfileRepository

T = TypeVar("T")
U = TypeVar("U")


def otype(ooi: OOI) -> type[OOI]:
originalsouth marked this conversation as resolved.
Show resolved Hide resolved
return type_by_name(ooi.get_ooi_type())


def mergewith(func: Callable[[set[T], set[T]], set[T]], d1: dict[U, set[T]], d2: dict[U, set[T]]) -> dict[U, set[T]]:
originalsouth marked this conversation as resolved.
Show resolved Hide resolved
return {k: func(d1.get(k, set()), d2.get(k, set())) for k in set(d1) | set(d2)}


class NibblesRunner:
def __init__(
self,
ooi_repository: OOIRepository,
scan_profile_repository: ScanProfileRepository,
origin_parameter_repository: OriginParameterRepository,
):
self.ooi_repository = ooi_repository
self.scan_profile_repository = scan_profile_repository
self.origin_parameter_repository = origin_parameter_repository
self.objects_by_type_cache: dict[type[OOI], set[OOI]]
self.update_nibbles()

def _retrieve(self, types: set[type[OOI]], valid_time: datetime) -> None:
cached_types = set(self.objects_by_type_cache)
target_types = set(filter(lambda x: x not in cached_types, types))
objects = self.ooi_repository.list_oois_by_object_types(target_types, valid_time)
objects_by_type = {t: {x for x in objects if isinstance(otype(x), t)} for t in set(map(otype, objects))}
self.objects_by_type_cache = mergewith(set.union, self.objects_by_type_cache, objects_by_type)

def _run(self, ooi: OOI, valid_time: datetime) -> dict[str, set[OOI]]:
retval: dict[str, set[OOI]] = {}
target_nibbles = list(filter(lambda x: type(ooi) in x.signature, self.nibbles))
self._retrieve(
set(map(lambda x: x.ooi_type, chain.from_iterable(map(lambda x: x.signature, target_nibbles)))), valid_time
)
for nibble in target_nibbles:
# TODO: filter OOI not abiding the parameters from radix
radix = [self.objects_by_type_cache[sgn.ooi_type] for sgn in nibble.signature]
results = set(
filter(lambda ooi: ooi is not None, chain(map(nibble, filter(lambda x: ooi in x, product(*radix)))))
)
if results:
retval |= {nibble.id: results}
return retval

def update_nibbles(self):
self.nibbles: list[NibbleDefinition] = get_nibble_definitions()

def _cleared(self, ooi: OOI, valid_time: datetime) -> bool:
ooi_level = self.scan_profile_repository.get(ooi.reference, valid_time).level.value
target_nibbles = list(filter(lambda x: type(ooi) in x.signature, self.nibbles))
originalsouth marked this conversation as resolved.
Show resolved Hide resolved
return any(nibble.min_scan_level < ooi_level for nibble in target_nibbles)

def infer(self, stack: list[OOI], valid_time: datetime) -> dict[OOI, dict[str, set[OOI]]]:
retval: dict[OOI, dict[str, set[OOI]]] = {}
originalsouth marked this conversation as resolved.
Show resolved Hide resolved
blockset = set(stack)
self.objects_by_type_cache = {}
if self._cleared(stack[-1], valid_time):
originalsouth marked this conversation as resolved.
Show resolved Hide resolved
while stack:
ooi = stack.pop()
self.objects_by_type_cache = mergewith(set.union, self.objects_by_type_cache, {otype(ooi): {ooi}})
results = self._run(ooi, valid_time)
if results:
blocks = set(chain.from_iterable(results.values()))
stack += [ooi for ooi in blocks if ooi not in blockset]
blockset |= blocks
retval |= {ooi: results}
return retval
24 changes: 21 additions & 3 deletions octopoes/octopoes/core/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import structlog
from bits.definitions import get_bit_definitions
from bits.runner import BitRunner
from nibbles.runner import NibblesRunner
from pydantic import TypeAdapter

from octopoes.config.settings import (
Expand Down Expand Up @@ -77,6 +78,7 @@ def __init__(
self.origin_parameter_repository = origin_parameter_repository
self.scan_profile_repository = scan_profile_repository
self.session = session
self.nibbles = NibblesRunner(ooi_repository, scan_profile_repository, origin_parameter_repository)

@overload
def _populate_scan_profiles(self, oois: ValuesView[OOI], valid_time: datetime) -> ValuesView[OOI]: ...
Expand Down Expand Up @@ -170,10 +172,10 @@ def save_origin(
self.ooi_repository.get(origin.source, valid_time)
except ObjectNotFoundException:
if (
origin.origin_type not in [OriginType.DECLARATION, OriginType.AFFIRMATION]
origin.origin_type not in [OriginType.DECLARATION, OriginType.AFFIRMATION, OriginType.NIBBLE]
and origin.source not in origin.result
):
raise ValueError("Origin source of observation does not exist")
raise ValueError(f"Origin source [{origin.source}] does not exist")
elif origin.origin_type == OriginType.AFFIRMATION:
logger.debug("Affirmation source %s already deleted", origin.source)
return
Expand All @@ -200,6 +202,7 @@ def save_origin(
self.origin_repository.delete(origin, valid_time=valid_time)

def _run_inference(self, origin: Origin, valid_time: datetime) -> None:
# The bit part of inferring
bit_definition = get_bit_definitions().get(origin.method, None)

if bit_definition is None:
Expand Down Expand Up @@ -234,6 +237,7 @@ def _run_inference(self, origin: Origin, valid_time: datetime) -> None:
if len(configs) != 0:
config = configs[-1].config

resulting_oois: list[OOI] = []
try:
if isinstance(self.session, XTDBSession):
start = perf_counter()
Expand All @@ -252,10 +256,24 @@ def _run_inference(self, origin: Origin, valid_time: datetime) -> None:
self.session.client.submit_transaction(ops)
else:
resulting_oois = BitRunner(bit_definition).run(source, parameters, config=config)
self.save_origin(origin, resulting_oois, valid_time)
except Exception as e:
logger.exception("Error running inference", exc_info=e)

self.save_origin(origin, resulting_oois, valid_time)

# The nibble part of inferring
resulting_nibble_oois = self.nibbles.infer([source], valid_time)
for source_ooi, results in resulting_nibble_oois.items():
self.ooi_repository.save(source_ooi, valid_time)
for nibble_id, result_oois in results.items():
inference_origin = Origin(
method=nibble_id,
origin_type=OriginType.NIBBLE,
result=[ooi.reference for ooi in result_oois],
source=source_ooi.reference,
)
self.save_origin(inference_origin, list(result_oois), valid_time)

@staticmethod
def check_path_level(path_level: int | None, current_level: int):
return path_level is not None and path_level >= current_level
Expand Down
1 change: 1 addition & 0 deletions octopoes/octopoes/models/origin.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class OriginType(Enum):
OBSERVATION = "observation"
INFERENCE = "inference"
AFFIRMATION = "affirmation"
NIBBLE = "nibble"


class Origin(BaseModel):
Expand Down
47 changes: 47 additions & 0 deletions octopoes/tests/integration/test_nibbles.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import os
import sys
from datetime import datetime
from unittest.mock import Mock

import pytest
from nibbles.definitions import NibbleDefinition, NibbleParameterDefinition

from octopoes.core.service import OctopoesService
from octopoes.models import OOI, ScanLevel
from octopoes.models.ooi.network import Network

if os.environ.get("CI") != "1":
pytest.skip("Needs XTDB multinode container.", allow_module_level=True)

NMAX = 13
originalsouth marked this conversation as resolved.
Show resolved Hide resolved
dummy_nibble = NibbleDefinition(name="dummy", signature=[NibbleParameterDefinition(ooi_type=Network)])


def dummy(network: Network):
global NMAX
originalsouth marked this conversation as resolved.
Show resolved Hide resolved
if len(network.name) < NMAX:
new_name = network.name + "I"
return Network(name=new_name)


dummy_nibble.payload = getattr(sys.modules[__name__], "dummy")


def test_dummy_nibble(xtdb_octopoes_service: OctopoesService, event_manager: Mock, valid_time: datetime):
xtdb_octopoes_service.nibbles.nibbles = [dummy_nibble]
network = Network(name="internet")
xtdb_octopoes_service.ooi_repository.save(network, valid_time)
event_manager.complete_process_events(xtdb_octopoes_service)

assert xtdb_octopoes_service.ooi_repository.list_oois({Network}, valid_time).count == 1
assert xtdb_octopoes_service.ooi_repository.list_oois({OOI}, valid_time).count == 3

sp = xtdb_octopoes_service.scan_profile_repository.get(network.reference, valid_time)
new_sp = sp.model_copy()
new_sp.level = ScanLevel.L2
xtdb_octopoes_service.scan_profile_repository.save(sp, new_sp, valid_time)
event_manager.complete_process_events(xtdb_octopoes_service)

ctx = 1 + NMAX - len(network.name)
assert xtdb_octopoes_service.ooi_repository.list_oois({Network}, valid_time).count == ctx
assert xtdb_octopoes_service.ooi_repository.list_oois({OOI}, valid_time).count == 3 * ctx