feat: define Interface trait and InterfaceConfig types (core/interface-trait-definition)
Add Layer 2 interface abstraction per ADR-026: - Interface trait with accept() and associated Session type - InterfaceConfig enum with Ssh and RawFraming variants - SshInterfaceConfig with auth, forwarding, host_key fields - RawFramingConfig (minimal, no SSH-specific config) - InterfaceSession trait with recv()/send() producing InterfaceEvent frames - InterfaceEvent wraps EventEnvelope with optional Identity - Resolves OQ-IF-01: every session produces EventEnvelope frames via InterfaceSession, making Layer 3 interface-agnostic - Valid (Transport, Interface) pair enumeration with TransportKindBase and is_valid_pair validation function - Module re-exported from lib.rs
This commit is contained in:
89
crates/alknet-core/src/interface/config.rs
Normal file
89
crates/alknet-core/src/interface/config.rs
Normal file
@@ -0,0 +1,89 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use arc_swap::ArcSwap;
|
||||
use russh::keys::PrivateKey;
|
||||
|
||||
use crate::auth::IdentityProvider;
|
||||
use crate::config::DynamicConfig;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum InterfaceKind {
|
||||
Ssh,
|
||||
RawFraming,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for InterfaceKind {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
InterfaceKind::Ssh => write!(f, "ssh"),
|
||||
InterfaceKind::RawFraming => write!(f, "raw-framing"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum InterfaceConfig {
|
||||
Ssh(SshInterfaceConfig),
|
||||
RawFraming(RawFramingConfig),
|
||||
}
|
||||
|
||||
impl InterfaceConfig {
|
||||
pub fn kind(&self) -> InterfaceKind {
|
||||
match self {
|
||||
InterfaceConfig::Ssh(_) => InterfaceKind::Ssh,
|
||||
InterfaceConfig::RawFraming(_) => InterfaceKind::RawFraming,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SshInterfaceConfig {
|
||||
pub auth: Arc<dyn IdentityProvider>,
|
||||
pub forwarding: Arc<ArcSwap<DynamicConfig>>,
|
||||
pub host_key: Arc<PrivateKey>,
|
||||
}
|
||||
|
||||
pub struct RawFramingConfig {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn interface_kind_display() {
|
||||
assert_eq!(InterfaceKind::Ssh.to_string(), "ssh");
|
||||
assert_eq!(InterfaceKind::RawFraming.to_string(), "raw-framing");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interface_kind_from_config() {
|
||||
let auth = Arc::new(crate::auth::ConfigIdentityProvider::new(Arc::new(
|
||||
ArcSwap::new(Arc::new(DynamicConfig::default())),
|
||||
)));
|
||||
let ssh_config = InterfaceConfig::Ssh(SshInterfaceConfig {
|
||||
auth,
|
||||
forwarding: Arc::new(ArcSwap::new(Arc::new(DynamicConfig::default()))),
|
||||
host_key: Arc::new(
|
||||
russh::keys::PrivateKey::random(
|
||||
&mut rand_core::OsRng,
|
||||
russh::keys::Algorithm::Ed25519,
|
||||
)
|
||||
.unwrap(),
|
||||
),
|
||||
});
|
||||
assert_eq!(ssh_config.kind(), InterfaceKind::Ssh);
|
||||
|
||||
let raw_config = InterfaceConfig::RawFraming(RawFramingConfig {});
|
||||
assert_eq!(raw_config.kind(), InterfaceKind::RawFraming);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interface_kind_equality() {
|
||||
assert_eq!(InterfaceKind::Ssh, InterfaceKind::Ssh);
|
||||
assert_eq!(InterfaceKind::RawFraming, InterfaceKind::RawFraming);
|
||||
assert_ne!(InterfaceKind::Ssh, InterfaceKind::RawFraming);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn raw_framing_config_minimal() {
|
||||
let _config = RawFramingConfig {};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user