feat(microsoft-defender-incidents): migrate connector to manager-supported mode (#5260)#6684
feat(microsoft-defender-incidents): migrate connector to manager-supported mode (#5260)#6684jabesq wants to merge 15 commits into
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #6684 +/- ##
===========================================
- Coverage 32.26% 0.56% -31.70%
===========================================
Files 1986 1894 -92
Lines 122165 119611 -2554
===========================================
- Hits 39413 680 -38733
- Misses 82752 118931 +36179
📢 Thoughts on this report? Let us know! 🚀 New features to boost your workflow:
|
1f618f9 to
2719d8b
Compare
There was a problem hiding this comment.
Pull request overview
This PR migrates the Microsoft Defender Incidents connector toward a manager-supported layout by introducing typed Pydantic-based settings, updating the connector bootstrap entry point, and adding generated configuration schema/docs plus a new test suite.
Changes:
- Introduces
ConnectorSettings(connectors-sdk) and refactors runtime config access to use typed settings. - Updates runtime/bootstrap and packaging (new
connector/module layout, updated Docker/compose, manifest set tomanager_supported: true). - Adds extensive unit tests plus generated config documentation (
connector_config_schema.json,CONNECTOR_CONFIG_DOC.md) and.env.sample.
Reviewed changes
Copilot reviewed 28 out of 29 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| external-import/microsoft-defender-incidents/tests/tests_connector/test_utils.py | Adds tests for small utility helpers (IP detection, date formatting, matching files, priority mapping). |
| external-import/microsoft-defender-incidents/tests/tests_connector/test_settings.py | Adds tests validating ConnectorSettings happy-path and validation errors. |
| external-import/microsoft-defender-incidents/tests/tests_connector/test_converter_to_stix.py | Adds tests for STIX conversion helpers and error handling decorator. |
| external-import/microsoft-defender-incidents/tests/tests_connector/test_connector.py | Adds tests for connector state handling, extraction flow, and run loop integration points. |
| external-import/microsoft-defender-incidents/tests/tests_connector/test_client_api.py | Adds tests for OAuth token retrieval, query building, pagination, and incident fetching behavior. |
| external-import/microsoft-defender-incidents/tests/tests_connector/conftest.py | Provides shared fixtures (stub settings, helper/config mocks, converter/client instances). |
| external-import/microsoft-defender-incidents/tests/test-requirements.txt | Defines connector test dependencies (includes connector requirements + pytest). |
| external-import/microsoft-defender-incidents/tests/test_main.py | Adds tests for main.py bootstrap path and error exit behavior. |
| external-import/microsoft-defender-incidents/tests/conftest.py | Ensures src/ is importable during tests by adjusting sys.path. |
| external-import/microsoft-defender-incidents/src/requirements.txt | Adds connectors-sdk + Pydantic dependency needed for settings/schema generation. |
| external-import/microsoft-defender-incidents/src/microsoft_defender_incidents_connector/config_variables.py | Removes legacy get_config_variable-based configuration loader. |
| external-import/microsoft-defender-incidents/src/microsoft_defender_incidents_connector/init.py | Removes legacy package export path. |
| external-import/microsoft-defender-incidents/src/main.py | Updates entry point to instantiate settings + helper + connector explicitly. |
| external-import/microsoft-defender-incidents/src/connector/utils.py | Adds new shared utility helpers used by connector and converter. |
| external-import/microsoft-defender-incidents/src/connector/settings.py | Adds typed ConnectorSettings and connector-specific config models. |
| external-import/microsoft-defender-incidents/src/connector/converter_to_stix.py | Adjusts imports and refactors some string building to f-strings. |
| external-import/microsoft-defender-incidents/src/connector/connector.py | Refactors connector initialization to accept injected settings/helper; updates scheduling and error handling. |
| external-import/microsoft-defender-incidents/src/connector/client_api.py | Updates client to use nested settings model and improves query-builder typing. |
| external-import/microsoft-defender-incidents/src/connector/init.py | Exposes connector + settings as the public module surface. |
| external-import/microsoft-defender-incidents/README.md | Simplifies configuration documentation and links to generated config docs. |
| external-import/microsoft-defender-incidents/entrypoint.sh | Removes shell entrypoint in favor of direct Python entrypoint. |
| external-import/microsoft-defender-incidents/Dockerfile | Migrates Docker build/entrypoint structure for manager-supported mode. |
| external-import/microsoft-defender-incidents/docker-compose.yml | Updates compose examples/comments for the new settings model defaults and options. |
| external-import/microsoft-defender-incidents/config.yml.sample | Updates sample config defaults and boolean formatting. |
| external-import/microsoft-defender-incidents/.env.sample | Adds a complete env var sample aligned with the settings model. |
| external-import/microsoft-defender-incidents/.dockerignore | Expands ignore rules for Python caches/build outputs and local artifacts. |
| external-import/microsoft-defender-incidents/metadata/connector_manifest.json | Sets manager_supported: true and updates verification date. |
| external-import/microsoft-defender-incidents/metadata/connector_config_schema.json | Adds generated JSON schema for connector configuration. |
| external-import/microsoft-defender-incidents/metadata/CONNECTOR_CONFIG_DOC.md | Adds generated config documentation table derived from schema. |
Comments suppressed due to low confidence (4)
external-import/microsoft-defender-incidents/src/connector/connector.py:405
- In the
(KeyboardInterrupt, SystemExit)handler,work_idmay be unbound if the connector is interrupted beforeinitiate_work()runs (e.g., during auth or incident fetch). Accessingif work_id:would then raiseUnboundLocalError, masking the original shutdown.
external-import/microsoft-defender-incidents/src/connector/connector.py:329 - When
_get_last_incident_date()returnsNone(no state + noimport_start_date),process_message()still callsget_incidents(None). That triggers an exception path inConnectorClient.get_incidents()and the connector then logs a “successfully run, no new data” message, effectively skipping the initial import silently.
external-import/microsoft-defender-incidents/src/connector/client_api.py:66 query_builder()now returns arequests.PreparedRequest(.prepare()), but the docstring still describes returning a URL string. This mismatch makes the API harder to use correctly and can confuse type-aware tooling.
external-import/microsoft-defender-incidents/src/connector/connector.py:12- PR description says the connector was refactored to the
ConnectorBasepattern to enable manager-supported orchestration, butMicrosoftDefenderIncidentsConnectoris still a standalone class (noConnectorBaseinheritance / lifecycle hooks). If manager-supported mode requires the base class, this looks incomplete or the PR description should be updated.
…upported migration
…ger-supported mode
… for manager-supported mode
…er-supported mode
…connector manifest
…d fix error handling
…atting in converter
…docker entrypoint
2719d8b to
c7a3fa0
Compare
c7a3fa0 to
5b12c2b
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 28 out of 29 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
external-import/microsoft-defender-incidents/src/connector/connector.py:71
_get_last_incident_date()has unreachable code (return None) and will also raise ifimport_start_dateis missing/None (it calls.timestamp()unconditionally). This contradicts the intent of making the start date optional and can crash the connector on first run.
external-import/microsoft-defender-incidents/src/connector/connector.py:328work_idcan be referenced in the(KeyboardInterrupt, SystemExit)handler before being assigned (e.g., if the interruption happens beforeinitiate_work()), which will raiseUnboundLocalErrorand prevent graceful shutdown handling.
Proposed changes
ConnectorSettingsPydantic class — replaces all legacyget_config_variablecalls with a typed, validated settings model; this is the prerequisite for manager-supported mode and makes misconfiguration fail fast at startup.connector.pytoConnectorBasepattern — rewrites the connector class to extendConnectorBaseand consumeConnectorSettings, decoupling lifecycle management from business logic and enabling the platform manager to orchestrate runs.main.pyentry point — provides the standard manager-supported entry point (python main.py) and removes the need for a separateentrypoint.shshell wrapper.manager_supported: trueinconnector_manifest.json— signals to the OpenCTI platform that this connector can be managed directly by the connector manager.import_start_dateoptional and fix error handling — prevents a hard crash when the field is absent and aligns error surfacing with theConnectorBasepattern.ConnectorSettingsvalidation (required fields, defaults, type coercion) and smoke-tests themain.pybootstrap path.CONNECTOR_CONFIG_DOC.mdandconnector_config_schema.json— replaces the hand-maintained README config table with schema-driven documentation..env.sample— documents every connector env var with required/optional sections.WORKDIR-based layout and a directENTRYPOINT ["python", "main.py"], removingentrypoint.sh..dockerignore— covers all Python cache artefacts and build outputs.client_api.pyandconverter_to_stix.py— consistency refactor; no behaviour change.CONNECTOR_CONFIG_DOC.mdinstead.Related issues
Checklist
Further comments
This PR applies the manager-supported migration pattern:
ConnectorSettings(PydanticBaseSettings) — all connector-specific configuration is declared as a typed Pydantic model. Environment variables are read and validated automatically, replacing the ad-hocget_config_variablehelper. Required fields raise aValidationErroron startup rather than failing silently at runtime.ConnectorBasesubclass — the connector class extendsConnectorBase(fromconnectors-sdk) and receives aConnectorSettingsinstance via dependency injection. The base class owns the OpenCTI client lifecycle, the run loop, and error recovery. Settingmanager_supported = Truein the manifest tells the platform it may call into these lifecycle hooks directly.