Feature/federation v1 - #343
Open
fwromano wants to merge 14 commits into
Open
Conversation
…truststore - Vendor the federation protobuf definitions (fig.proto, binarypayload.proto) from the TAK Product Center's public TAK Server source (GPLv3), minus the gRPC service which federation v1 does not use. Field numbers unchanged, so the wire format is identical to official TAK Server federation. - Frame codec for v1's length-prefixed FederatedEvent stream, with partial-frame buffering and a max-frame-size guard. - CoT XML <-> FederatedEvent mapper mirroring TAK Server's ProtoBufHelper: track/status/precisionlocation/image extraction, opaque detail passthrough, and <marti><dest> to ptpCallsigns/ptpUids/missionNames mapping. - Federation truststore: peer CAs live in a separate folder from the EUD CA so a federate's server can connect while its client certs cannot, with helpers for CA management and peer identity (SHA-256 cert fingerprint).
- FederationConnection bridges one TLS link to RabbitMQ: outbound consumes the firehose exchange, filters by the federate's outbound groups against the sender's group memberships, and streams frames; inbound converts received events to CoT and publishes them to cot_parser tagged with the federate's inbound groups. Contact announcements track local EUD presence. - Loop prevention is structural: only EUD handlers publish to firehose and federated traffic enters via cot_parser, so federated events are never re-federated (point-to-point semantics, like TAK Server without a hub). - FederationManager runs the v1 listener (mutual TLS against the federation truststore, auto-registering inbound federates with no groups) and dials enabled outbound federates with reconnect and certificate pinning on first connect. - New federation_server console script following the eud_handler/cot_parser process model. Disabled by default (OTS_ENABLE_FEDERATION).
- Federation model + migration: peer address/port, direction, enable flag, reconnect interval, pinned certificate fingerprint, and inbound/outbound group lists (empty lists exchange nothing, matching TAK Server's default). - /api/federation CRUD and /api/federation/ca truststore management, administrator-only.
An optional 'groups' list in the message envelope routes the event to those group channels instead of the sender's memberships or __ANON__. Used by the federation server to deliver inbound federated traffic into a federate's configured inbound groups; any other non-user publisher can use it the same way.
Unit tests for the frame codec, CoT mapper, and truststore, plus an integration test federating two in-process engines over real mutually authenticated TLS: SA and contacts flow both ways, outbound group filtering blocks unshared groups, federates without groups exchange nothing, and servers with untrusted CAs are rejected during the handshake.
The previous parent 6a7929c07690 already had a descendant (00442761c803), producing two alembic heads and breaking 'flask db upgrade'. Caught by live two-server validation.
…ve validation Validated end-to-end between two live OTS stacks (real eud_handler / cot_parser / federation_server over RabbitMQ + Postgres, federated over mutual TLS). Fixes surfaced there: - Register a lightweight EUD row for each federated sender (from ContactListEntry announcements and from GeoEvents), so inbound federated CoT satisfies the cot->eud foreign key and remote units appear as federated contacts - mirrors TAK Server behavior. Chat is attributed to its sending EUD via sender_identity() rather than the GeoChat message uid. - Carry the sender callsign across the wire in GeoEvent.screenName. - Import all model modules in the federation_server process so SQLAlchemy can resolve cross-model relationships (Group <-> groups_missions). - Use the update() construct instead of Query.update() wrapped in session.execute() (which raised 'Executable SQL construct expected, got 1' and dropped every federation connection before any event flowed).
Adds the official FederatedChannel gRPC service (v2, port 9001) alongside v1. Both carry the same FederatedEvent and share the CoT mapper, group filtering, loop guard, federated-EUD registration, and truststore - only the transport differs, so the shared logic was factored into engine.build_outbound_event / apply_inbound_event / contact_announcements and is used by both. - fig.proto: restore the FederatedChannel service definition; generate grpc stubs. OTS serves the SA subset (getIdentity, HealthCheck, ClientEventStream, ServerEventStream); ROL and group-mapping RPCs are declared for wire compatibility but not served. - grpc_engine.py: FederationServicer (inbound listener) and GrpcClient (outbound dialer), mutual TLS against the federation truststore, peer identified by client certificate. - FederationManager runs both the v1 and v2 listeners; outbound dials route by the federate's protocol_version. - New config: OTS_FEDERATION_ENABLE_V2, OTS_FEDERATION_V2_PORT, OTS_FEDERATION_V2_AUTHORITY. grpcio added as a dependency.
In-process gRPC integration tests over mutual TLS (getIdentity/HealthCheck + inbound SA routing + federated-EUD registration, and untrusted-CA rejection). Skipped under gevent monkey-patching (grpc deadlocks on patched sockets; the production federation_server does not monkey-patch) - covered live by fed_live_test.py --v2. README and FEDERATION.md updated for v2.
A scriptable front end over the Federation model and the federation truststore: list/status (with --json), add/remove/enable/disable federates, and ca import/export/list. Lets an operator manage federation without hand-writing REST calls, and gives the HeartBeat 'heartbeat fed' wrapper and dashboard a stable JSON interface (status --json).
fwromano
marked this pull request as draft
July 21, 2026 17:35
fwromano
marked this pull request as ready for review
July 21, 2026 21:03
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.