Conversation
Phase 0: capture baseline (cargo nextest 241 passing, clippy clean, openapi check fresh) before structural migration to RFD 619 layout. Phase 1: scaffold three new versions crates and v6/v7/v8 module directories in mg-types-versions: - mg-common-types + mg-common-types-versions (new) - bgp-types + bgp-types-versions (new) - rdb-types/versions (new sibling under existing rdb-types) - mg-types/versions: add v6 (rib_exported_string_key), v7 (operation_id_cleanup), v8 (bgp_src_addr) module dirs No types are migrated yet; module directories are empty placeholders. The new facade crates re-export from latest. mg-common-types-versions already includes v1::net (TunnelOrigin, Ipv6Prefix, Ipv4Prefix, IpPrefix) but consumers have not yet been re-pointed; that lands in Phase 2a. Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…lFilter to rdb-types-versions Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
Move Path and BgpPathProperties out of rdb/src/types.rs into
rdb-types-versions: v1::path holds the pre-UNNUMBERED shape (peer is
IpAddr), v5::path holds the UNNUMBERED shape (peer is PeerId,
nexthop_interface added). Conversions live in v5 (newer module);
the BgpPathProperties -> v1 fallback for PeerId::Interface is silent
(Ipv6Addr::UNSPECIFIED). impl Ord for Path and as_stale move to
rdb-types-versions/impls/path.rs. From<StaticRouteKey> for Path stays
in rdb/src/types.rs until StaticRouteKey migrates.
Split mg-types-versions::rib::GetRibResult per version: v1 references
v1::path::Path, v5 references v5::path::Path; latest re-exports v5.
Free fn v5::rib::get_rib_result_into_v1 downgrades for shims.
Version-gate static_list_v{4,6}_routes in mg-api so prior-version docs
keep their v1-shaped Path. Latest endpoints scoped to VERSION_UNNUMBERED..;
shims static_list_v4_routes_v1 (..VERSION_UNNUMBERED) and
static_list_v6_routes_v2 (VERSION_IPV6_BASIC..VERSION_UNNUMBERED) call
the latest impl and downgrade. Both pairs pin operation_id explicitly so
generated clients see one method per endpoint across versions.
OpenAPI: all 11 blessed docs (mg-admin v1..v8, ddm-admin v1, both
*-latest) byte-identical to baseline.
Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…ions
Move ImportExportPolicyV1 → v1::policy::ImportExportPolicy (suffix dropped;
schemars(rename) annotation no longer needed since the Rust name now matches
the schema name naturally). Move ImportExportPolicy{,4,6} → v4::policy::*.
Conversions From<v1::policy::ImportExportPolicy> for ImportExportPolicy{4,6}
live in the v4 module. The as_ipv4_policy/as_ipv6_policy/from_per_af_policies
inherent methods on the v1 type move into impls/policy.rs.
The combined v4::policy::ImportExportPolicy enum is internal-only (no
JsonSchema), so there is no schema-name collision with v1::policy::Import
ExportPolicy in any blessed OpenAPI doc. Verified all 9 docs byte-identical.
Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…ypes
Move BgpRouterInfo into v1::router; BfdPeerConfig + SessionMode into
v1::bfd. BfdPeerConfig and SessionMode schemas verified byte-identical
across all 8 blessed mg-admin docs.
The remaining trio (BgpNeighborInfo, BgpUnnumberedNeighborInfo,
BgpNeighborParameters) is not present in any blessed OpenAPI document --
they are internal db-persistence types with vestigial JsonSchema
derives. BgpNeighborParameters references ImportExportPolicy{4,6}, which
live in v4 per the prior Phase 2b sub-step, so the only-prior-versions
rule forces all three into v4::neighbor.
OpenAPI: all 9 blessed docs (mg-admin v1..v8, ddm-admin v1) plus both
*-latest symlinks byte-identical to baseline.
Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
mg-types-versions/src/initial/bfd.rs was importing rdb::BfdPeerConfig (a floating identifier from the rdb facade), violating RFD 619 §determinations-only-prior-versions. Switch to rdb_types_versions::v1::bfd::BfdPeerConfig. Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…rsions Move the 12 leaf wire-message enumerations (MessageType, OptionalParameterCode, CapabilityCode, Safi, PathAttributeTypeCode, AsPathType, ErrorCode, HeaderErrorSubcode, OpenErrorSubcode, UpdateErrorSubcode, CeaseErrorSubcode, PathOrigin) into bgp-types-versions::v1::messages, plus Afi into bgp-types-versions::v4::messages. Their Display/slog::Value impls and the Afi <-> rdb-types-versions::v1::AddressFamily conversions go to bgp-types-versions::impls::messages (orphan-rule case 1). The three From impls that take protocol types as input (From<&Message> for MessageType, From<PathAttributeValue> for PathAttributeTypeCode, From<Capability> for CapabilityCode) become free functions in bgp/src/messages.rs (message_type_of, path_attribute_type_code_of, capability_code_of) since their input types live in bgp/ and pulling them into bgp-types-versions would break the leaf-crate property (orphan-rule case 2). The handful of call sites are updated. bgp-types-versions::error::WireError is scaffolded with the parse-only + leaf wire-error variants (TooSmall, TooLarge, NoMarker, BadLength, BadVersion, Eom, Parse, Io, Unassigned, Experimental, InvalidCode, ReservedCapability/Code, ReservedOptionalParameter, InvalidMessageType, BadBgpIdentifier, MalformedAttributeList, InvalidNlriPrefix, InvalidPrefixLength, plus the 11 TryFromPrimitiveError variants for the moved enums). bgp::error::Error gains a #[from] WireError variant for future ?-upcasting; existing variants stay put because the parse code that produces them still lives in bgp/. bgp-types-versions gains nom/num_enum/thiserror/slog/rdb-types-versions deps plus an optional clap feature (Afi has #[cfg_attr(feature=clap, derive(ValueEnum))]); the bgp crate's clap feature now passes through. The migrated types' Rust paths (bgp::messages::TYPE) still resolve via pub use re-exports, so no downstream code changes beyond the call-site updates above. Verified all 11 blessed OpenAPI docs sha256-identical to baseline; cargo fmt --check, cargo clippy --workspace -- -D warnings, and cargo nextest (241 passed) all clean. Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…rsions Move seven leaf wire-message types into bgp-types-versions::messages: Tlv, Header, Community, AddPathElement (v1) and BgpNexthop, Ipv6DoubleNexthop, ExtendedNexthopElement (v4). Header gains the MAX_MESSAGE_SIZE constant alongside its existing WIRE_SIZE associated const, both also re-exported from bgp::messages so existing call sites in bgp::connection_tcp continue to compile unchanged. Inherent methods on the moved types (Header::new/to_wire/from_wire, BgpNexthop::from_bytes/to_bytes/byte_len, ExtendedNexthopElement:: is_v4_over_v6/is_v6_over_v4) and their Display/From impls move to bgp-types-versions::impls::messages (orphan-rule case 1: every input type is std or already migrated). Header and BgpNexthop parse paths now produce WireError instead of bgp::Error; bgp::Error already grew a #[from] WireError variant in chunk 1, so ? propagation through the session-time call sites is unchanged. WireError gains an InvalidAddress(String) variant to cover BgpNexthop::from_bytes. bgp::messages keeps backward-compatible pub use re-exports so the crate-public Rust paths (bgp::messages::Header etc.) still resolve. The is_v4_over_v6/is_v6_over_v4 helpers become pub (they were private methods before, but only consumed from inside bgp/, so widening them is a no-op for downstream consumers). Verified all 11 OpenAPI documents fresh with no schema drift; cargo fmt --check, cargo clippy --workspace -- -D warnings, and cargo nextest (241 passed) all clean. Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…s-versions Move the MP-BGP PathAttribute family into bgp-types-versions. The 12-variant PathAttributeTypeCode (incorrectly placed at v1::messages in chunk 1) moves to v4::messages where it belongs; a 10-variant V1 form is introduced at v1::messages with #[schemars(rename = "PathAttributeTypeCode")] to keep the v1 admin schema byte-identical. v4::messages additions: PathAttribute, PathAttributeType, PathAttributeValue, PathAttributeTypeCode (12-variant), Aggregator, As4Aggregator, As4PathSegment, MpReachNlri, MpReachIpv4Unicast, MpReachIpv6Unicast, MpUnreachNlri, MpUnreachIpv4Unicast, MpUnreachIpv6Unicast, and the path_attribute_flags constants module. v1::messages additions (the v1 wire-shape compat types, formerly named *V1 in bgp::messages): Prefix, PathAttribute, PathAttributeType, PathAttributeTypeCode, PathAttributeValue. These are re-exported from bgp::messages under their historical *V1 aliases to minimize call-site churn. impls/messages.rs gains Display impls for the new types, the self-contained inherent methods (Aggregator/As4Aggregator to_wire/from_wire/to_bytes; MpReach/MpUnreach afi/safi/nexthop/ ipv4_unicast/ipv6_unicast/is_empty/len), the v4 → v1 cross-version From conversions, and reabsorbed-into-From impls for path_attribute_type_code_of and From<PathAttributeValue> for PathAttribute. In bgp/src/messages.rs the type definitions become re-exports from bgp_types::messages. Wire methods that produce bgp::error::Error or UpdateParseErrorReason (PathAttribute::to_wire / from_bytes, PathAttributeType::to_wire / error_action, PathAttributeValue::to_wire / from_wire, As4PathSegment::to_wire / from_wire, MpReachNlri::to_wire / from_wire, MpUnreachNlri::to_wire / from_wire) become free fns (path_attribute_to_wire, path_attribute_from_bytes, path_attribute_type_to_wire, path_attribute_type_error_action, path_attribute_value_to_wire, path_attribute_value_from_wire, as4_path_segment_to_wire, as4_path_segment_from_wire, mp_reach_nlri_to_wire, mp_reach_nlri_from_wire, mp_unreach_nlri_to_wire, mp_unreach_nlri_from_wire). Internal call sites in bgp/src/messages.rs are updated. WireError::PathAttributeCode in bgp-types-versions::error switches from v1::messages::PathAttributeTypeCode (10-variant) to v4::messages::PathAttributeTypeCode (12-variant) since wire parsing operates on the MP-BGP form. Verification: cargo fmt --check; cargo clippy --workspace -- -D warnings; cargo nextest run --workspace (241 passed); cargo run -p xtask -- openapi check (11 fresh, 0 stale, 0 failed). All blessed mg-admin/ddm-admin schemas remain sha256-identical to baseline. Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…nd to bgp-types-versions Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…rorSubcode to bgp-types-versions Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
… RouteRefreshMessage to bgp-types-versions Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…types-versions, drop UpdateMessage::errors field Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…versions Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…erParameters families to mg-types-versions Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…fo/FsmStateKindV1 to mg-types-versions Migrates the v1 and v2 forms of the PeerInfo family to mg-types-versions: - v1::bgp::FsmStateKind (was params::FsmStateKindV1, 7-variant pre-IPV6_BASIC). - v1::bgp::DynamicTimerInfo (was params::DynamicTimerInfoV1, 2-field). - v1::bgp::PeerTimers (was params::PeerTimersV1). - v1::bgp::PeerInfo (was params::PeerInfoV1). - v2::bgp::PeerInfo (was params::PeerInfoV2). - v4::bgp::DynamicTimerInfo (the latest 3-field form, re-exported as latest). Cross-version conversions in mg-types-versions/src/impls/bgp.rs: - From<bgp_types_versions::v2::session::FsmStateKind> for v1::bgp::FsmStateKind - From<v2::bgp::PeerInfo> for v1::bgp::PeerInfo The latest PeerInfo (v5 shape) and latest PeerTimers (v5 shape) remain in bgp/src/params.rs because their public fields embed BgpCapability, PeerCounters, and StaticTimerInfo, all of which are scheduled for sub-chunk 6c. mg-types-versions cannot depend on bgp, so those types must migrate together. Sub-chunk 6c will pull the remaining PeerInfo/PeerTimers latest forms across once the unversioned-but-published group lands. bgp/src/params.rs preserves the existing public surface via re-export aliases so call sites in mgd/mg-api are unchanged. Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…d rdb tail to versions crates Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…ffixed convention Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…rse module Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…dules
Three orphan-rule-adjacent violations found in `mg-types-versions/src/impls/`:
- `From<latest::static_routes::StaticRoute{4,6}> for rdb::StaticRouteKey`
forced `mg-types-versions` to depend on `rdb` (a business-logic crate).
Replaced with free fns at the only call site (`mgd/src/static_admin.rs`).
- `From<rdb::db::Rib> for {latest, v1}::rib::Rib` had the same problem.
Replaced with `rib_latest_from_rdb` / `rib_v1_from_rdb` free fns in
`mg-types/src/rib.rs` (the facade crate, which already depends on both
`rdb` and `rdb-types-versions`).
`mg-types-versions` no longer depends on `rdb`. The Phase 3 audit
(`rg "use {bgp,rdb,mg_common,ddm}::"` and the corresponding `_types::`
sweep across all `*-types-versions/src/`) is now clean.
Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…or migrated paths Adds `docs/types-organization.md` as a tangible reference for where schema-published types now live: facade vs versions crate pairs, the crate map, a type -> crate quick reference, and recipes for adding new types and new API versions. Calls out the leaf-crate rule, the internal-vs-published distinction, and the boundary helpers (free functions in the facade crate or at call sites) used when both source and target of a conversion are foreign. `docs/bgp-architecture.md` and `docs/bgp-unnumbered.md` were scanned for stale type-path references and are unchanged: they reference types only by short name (`MessageHistory`, `FsmStateKind`, `Path`, `PeerId`), which remain valid via the facade re-exports. `README.md` was scanned for moved type paths and is unchanged. Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…ports Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
Adds a dedicated facade+versions crate pair for BFD types and migrates `BfdPeerState`, `BfdPeerConfig`, `BfdPeerInfo`, and `SessionMode` into `bfd-types-versions::v1`. This was the last leaf-crate-rule violation in `mg-types-versions` — its `bfd.workspace = true` dependency (and the transitive edge into `rdb`/`mg-common`) is now gone. Type relocations: - `BfdPeerState` (was `bfd::BfdPeerState`) -> `bfd_types_versions::v1`, with the `wire_format()` helper carried along as an inherent method. - `BfdPeerConfig` and `SessionMode` (was `rdb_types_versions::v1::bfd::*`) -> `bfd_types_versions::v1`. - `BfdPeerInfo` (was `mg_types_versions::v1::bfd`) -> `bfd_types_versions::v1`. `mg_types_versions::v1::bfd` keeps only `DeleteBfdPeerPathParams` (an admin-API path-params shape, not a BFD type proper). Call-site updates: `bfd`, `rdb`, `mg-api`, and `mgd` now import BFD types from the `bfd-types` facade. `bfd::BfdPeerState` continues to work via a `pub use` re-export. OpenAPI verification: `cargo run -p xtask -- openapi check` reports zero stale documents — all schemas (`BfdPeerState`, `BfdPeerConfig`, `BfdPeerInfo`, `SessionMode`) emit byte-identical JsonSchema output, so no client regeneration is required. Drive-by: also fixes a stale doc comment in `bgp/src/session.rs` that referred to the (since-renamed) `UpdateMessage::from_wire()` method; the actual function is the free fn `update_message_from_wire`. Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
Extends the per-domain test-* jobs to cover their corresponding type crates so any future tests added there get picked up automatically: - test-bfd: adds `bfd-types` and `bfd-types-versions`. - test-bgp: adds `bgp-types` and `bgp-types-versions` (alongside bgp); adds `mg-types` and `mg-types-versions` (alongside mgd). - test-rdb: adds `rdb-types` and `rdb-types-versions` (alongside rdb). Bare `-p rdb-types` is ambiguous because omicron transitively pins an upstream copy of rdb-types via mg-admin-client, leaving two rdb-types nodes in Cargo.lock. The Package ID Spec form `path+file://$PWD/../rdb-types` selects the local crate unambiguously. Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
Squashes adjacent same-prefix `pub use`/`use` lines into single
braced statements and lifts scattered branch-added re-exports to the
top of each file. Touches only items the branch already added or
moved; pre-existing imports and test-module imports are left alone.
- bgp/src/messages.rs: 20 scattered `pub use bgp_types::messages::*`
and `pub use bgp_types_versions::*` lines -> four consolidated
blocks at the top.
- bgp/src/session.rs: three scattered uses -> top of file; trims a
stale doc-comment block whose content is now redundant.
- bgp/src/params.rs: drops single-use `v{1,2,4,5,8}_bgp` aliases in
favor of fully-qualified `pub use mg_types_versions::vN::bgp::{...}`.
- mg-types/versions/src/latest.rs, mg-common-types/versions/src/latest.rs,
mg-types/src/rib.rs, bfd/src/lib.rs: minor adjacent-run merges.
OpenAPI verified byte-identical (`cargo xtask openapi check`: all 10
documents fresh). 152 of 152 bgp+bfd tests still pass.
Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
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.
Many types were not fully migrated to the RFD 619 conventions in #611 and #665. This PR seeks to remedy that.
As a whole, this PR is simply a re-organization of existing code rather than a functional change.
It does so by splitting some crates apart (introducing
$CRATE-typesand$CRATE-types-versionsfor it) and attempting to bring some order to this chaos. In some cases, types were moved into a more fitting home (e.g. BFD types moving out of rdb/mgd crates and into bfd-types).The exception to no functional changes is that the operation_id in the OpenAPI spec does change for a handful of methods.
These are all broken out into a new dropshot API version for mg-api:
ENDPOINT_RENAME.This results in clients seeing a different method name when importing the latest API version via mg-admin-client.
Aside from the method/operation_id name change, the API remains byte-compatible.
I had claude help with the grunt work on this one, and the commit messages describe the implementation plan it followed (including some course corrections).