Skip to content

opencti: track partial state on failure and reduce redundant API calls#3337

Open
gks281263 wants to merge 4 commits intointelowlproject:developfrom
gks281263:fix/opencti-partial-state-tracking
Open

opencti: track partial state on failure and reduce redundant API calls#3337
gks281263 wants to merge 4 commits intointelowlproject:developfrom
gks281263:fix/opencti-partial-state-tracking

Conversation

@gks281263
Copy link
Contributor

@gks281263 gks281263 commented Feb 19, 2026

This change improves failure visibility in the OpenCTI connector.

  • Track created entity IDs during execution
  • Append partial-state information to report.errors on failure
  • Cache organization_id and marking_definition_id to avoid redundant API calls

Success path and return structure remain unchanged.

…I calls

Wrap OpenCTI connector run() flow in try/except to improve failure visibility.
Track created entity IDs (observable, report, external reference, labels)
and append them to report.errors when an exception occurs, while preserving
existing failure semantics.

Also cache organization_id and marking_definition_id to avoid redundant
API calls within a single execution.

Success path and return structure remain unchanged.
Copy link
Member

@mlodic mlodic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the main problem about this refactors is that there are 0 unittests and that there is no live test with a real OpenCTI instance. Without doing so, how can we reliable say that this works?

@gks281263 gks281263 requested a review from mlodic February 21, 2026 13:19
@gks281263
Copy link
Contributor Author

Thank you for pointing this out — you’re absolutely right.

Since this change affects failure semantics at the integration boundary, it should not rely only on manual verification. I will add dedicated unit tests that mock the OpenCTI/pycti client and simulate failures at different stages (e.g. after observable creation, after report creation). These tests will assert that:

report.errors contains the expected partial-state information with the correct created IDs

the success path remains unchanged

organization and marking resolution are not invoked redundantly within a single execution

Regarding live validation, my plan is to complement the mocked tests with a lightweight integration test using a real OpenCTI instance (via docker), so we validate actual API interaction as well.

If this direction aligns with your expectations, I’ll proceed with implementing the tests accordingly.

@gks281263 gks281263 force-pushed the fix/opencti-partial-state-tracking branch 3 times, most recently from 09a30e9 to 63083a9 Compare February 24, 2026 03:33
…reliability

add deterministic unit tests covering failure at each critical stage (observable, report, external reference) to validate partial-state contract

enforce strict assertion on Created IDs message to guarantee no silent partial object leak

validate success path integrity and ensure no regression in return structure

verify organization and marking creation is executed only once per run (caching correctness)

add env-guarded live OpenCTI integration test for real API validation without breaking CI

This makes OpenCTI connector behavior testable, predictable and safe against API schema drift.
@gks281263 gks281263 force-pushed the fix/opencti-partial-state-tracking branch from 63083a9 to f43264f Compare February 24, 2026 03:35
…I responses

Tests (test_opencti.py):
- Patch pycti classes (Identity, MarkingDefinition, StixCyberObservable, Label,
  Report, ExternalReference, StixDomainObject) instead of .create/.read so
  pycti.Class(inst).create() is intercepted in CI.
- Configure instance mocks via .return_value.create.return_value (and .read,
  .add_external_reference, .add_stix_object_or_stix_relationship) per test.
- Wrap connector.start() in try/except in failure and live tests so when
  after_run_failed re-raises under STAGE_CI the test still asserts on report.
- Assert identity_mock.return_value.create.assert_called_once() (and marking)
  for the "called only once" test.
- Remove OPENCTI_MODULE and _opencti_patch helper.

Connector (opencti.py):
- Validate Identity.create and MarkingDefinition.create responses (dict with
  "id"); raise ValueError with a clear message otherwise, consistent with
  Label.create.
- In _monkeypatch, patch the same pycti classes and add _configure_pycti_mocks
  to set .return_value.create/.read/etc. so instance method calls are mocked
  when MOCK_CONNECTIONS is used.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants