Skip to content

Commit 7baf4fc

Browse files
committed
feat(grpc): add DataplaneStatus backend
Signed-off-by: Sergey Matov <[email protected]>
1 parent 49fc16a commit 7baf4fc

File tree

8 files changed

+1476
-26
lines changed

8 files changed

+1476
-26
lines changed

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ dpdk-sysroot-helper = { path = "./dpdk-sysroot-helper", package = "dataplane-dpd
4343
dplane-rpc = { git = "https://github.com/githedgehog/dplane-rpc.git", rev = "e8fc33db10e1d00785f2a2b90cbadcad7900f200" }
4444
errno = { path = "./errno", package = "dataplane-errno" }
4545
flow-info = { path = "./flow-info", package = "dataplane-flow-info" }
46-
gateway_config = { git = "https://github.com/githedgehog/gateway-proto", tag = "v0.15.0" }
46+
gateway_config = { git = "https://github.com/githedgehog/gateway-proto", tag = "v0.15.1" }
4747
hardware = { path = "./hardware", package = "dataplane-hardware" }
4848
id = { path = "./id", package = "dataplane-id" }
4949
init = { path = "./init", package = "dataplane-init" }

config/src/converters/grpc/mod.rs

Lines changed: 178 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ mod gateway_config;
1212
mod interface;
1313
mod overlay;
1414
mod peering;
15+
mod status;
1516
mod tracecfg;
1617
mod underlay;
1718
mod vpc;
@@ -30,6 +31,8 @@ pub use overlay::*;
3031
#[allow(unused)] // Remove if we do anything but implement traits
3132
pub use peering::*;
3233
#[allow(unused)] // Remove if we do anything but implement traits
34+
pub use status::*;
35+
#[allow(unused)] // Remove if we do anything but implement traits
3336
pub use tracecfg::*;
3437
#[allow(unused)] // Remove if we do anything but implement traits
3538
pub use underlay::*;
@@ -45,6 +48,9 @@ mod test {
4548
use pretty_assertions::assert_eq;
4649

4750
use crate::converters::grpc::convert_gateway_config_from_grpc_with_defaults;
51+
use crate::converters::grpc::{
52+
convert_dataplane_status_from_grpc, convert_dataplane_status_to_grpc,
53+
};
4854
use crate::internal::device::DeviceConfig;
4955
use crate::internal::interfaces::interface::InterfaceConfig;
5056

@@ -316,7 +322,6 @@ mod test {
316322
// Create test data
317323
let grpc_config = create_test_gateway_config();
318324
// Call the conversion function (gRPC -> ExternalConfig)
319-
// Using standalone function instead of manager method
320325
let result = convert_gateway_config_from_grpc_with_defaults(&grpc_config);
321326

322327
// Verify result
@@ -327,11 +332,8 @@ mod test {
327332
);
328333
let external_config = result.unwrap();
329334

330-
// Call the conversion function (ExternalConfig -> gRPC)
331-
// Using standalone function instead of manager method
335+
// ExternalConfig -> gRPC
332336
let result = gateway_config::GatewayConfig::try_from(&external_config);
333-
334-
// Verify result
335337
assert!(
336338
result.is_ok(),
337339
"Conversion to gRPC failed: {:?}",
@@ -367,50 +369,209 @@ mod test {
367369
mtu: Some(9000),
368370
};
369371

370-
// Test DeviceConfig TryFrom
372+
// DeviceConfig TryFrom
371373
let device_config_result = DeviceConfig::try_from(&device);
372374
assert!(
373375
device_config_result.is_ok(),
374376
"TryFrom for DeviceConfig failed"
375377
);
376378
let device_config = device_config_result.unwrap();
377-
378-
// Verify conversion result
379379
assert_eq!(device_config.settings.hostname, "test-device");
380380

381-
// Convert back using TryFrom
381+
// Back to gRPC
382382
let device_back_result = gateway_config::Device::try_from(&device_config);
383383
assert!(device_back_result.is_ok(), "TryFrom back to Device failed");
384384
let device_back = device_back_result.unwrap();
385-
386-
// Verify round trip conversion
387385
assert_eq!(device_back.hostname, device.hostname);
388386
assert_eq!(device_back.driver, device.driver);
389387
assert_eq!(device_back.tracing.as_ref().unwrap(), &tracing);
390388

391-
// Test InterfaceConfig TryFrom
389+
// InterfaceConfig TryFrom
392390
let interface_config_result = InterfaceConfig::try_from(&interface);
393391
assert!(
394392
interface_config_result.is_ok(),
395393
"TryFrom for InterfaceConfig failed"
396394
);
397395
let interface_config = interface_config_result.unwrap();
398-
399-
// Verify conversion result
400396
assert_eq!(interface_config.name, "eth0");
401397
assert!(!interface_config.addresses.is_empty());
402398

403-
// Convert back using TryFrom
399+
// Back to gRPC
404400
let interface_back_result = gateway_config::Interface::try_from(&interface_config);
405401
assert!(
406402
interface_back_result.is_ok(),
407403
"TryFrom back to Interface failed"
408404
);
409405
let interface_back = interface_back_result.unwrap();
410-
411-
// Verify round trip conversion
412406
assert_eq!(interface_back.name, interface.name);
413407
assert_eq!(interface_back.r#type, interface.r#type);
414408
assert!(!interface_back.ipaddrs.is_empty());
415409
}
410+
411+
#[allow(clippy::too_many_lines)]
412+
fn create_test_status() -> gateway_config::GetDataplaneStatusResponse {
413+
// interface_statuses
414+
let interface_statuses = vec![
415+
gateway_config::InterfaceStatus {
416+
ifname: "eth0".into(),
417+
oper_status: gateway_config::InterfaceOperStatusType::InterfaceStatusOperUp as i32,
418+
admin_status: gateway_config::InterfaceAdminStatusType::InterfaceAdminStatusUp
419+
as i32,
420+
},
421+
gateway_config::InterfaceStatus {
422+
ifname: "eth1".into(),
423+
oper_status: gateway_config::InterfaceOperStatusType::InterfaceStatusOperDown
424+
as i32,
425+
admin_status: gateway_config::InterfaceAdminStatusType::InterfaceAdminStatusDown
426+
as i32,
427+
},
428+
];
429+
430+
// FRR
431+
let frr_status = Some(gateway_config::FrrStatus {
432+
zebra_status: gateway_config::ZebraStatusType::ZebraStatusConnected as i32,
433+
frr_agent_status: gateway_config::FrrAgentStatusType::FrrAgentStatusConnected as i32,
434+
applied_config_gen: 42,
435+
restarts: 1,
436+
applied_configs: 10,
437+
failed_configs: 0,
438+
});
439+
440+
// Dataplane overall
441+
let dataplane_status = Some(gateway_config::DataplaneStatusInfo {
442+
status: gateway_config::DataplaneStatusType::DataplaneStatusHealthy as i32,
443+
});
444+
445+
// interface_runtime
446+
let mut interface_runtime = std::collections::HashMap::new();
447+
interface_runtime.insert(
448+
"eth0".to_string(),
449+
gateway_config::InterfaceRuntimeStatus {
450+
admin_status: gateway_config::InterfaceAdminStatusType::InterfaceAdminStatusUp
451+
as i32,
452+
oper_status: gateway_config::InterfaceOperStatusType::InterfaceStatusOperUp as i32,
453+
mac: "00:11:22:33:44:55".into(),
454+
mtu: 1500,
455+
counters: Some(gateway_config::InterfaceCounters {
456+
tx_bits: 1_000_000,
457+
tx_bps: 1000.0,
458+
tx_errors: 1,
459+
rx_bits: 2_000_000,
460+
rx_bps: 2000.0,
461+
rx_errors: 2,
462+
}),
463+
},
464+
);
465+
466+
// BGP runtime
467+
let bgp_msgs = Some(gateway_config::BgpMessages {
468+
received: Some(gateway_config::BgpMessageCounters {
469+
capability: 1,
470+
keepalive: 10,
471+
notification: 0,
472+
open: 1,
473+
route_refresh: 0,
474+
update: 42,
475+
}),
476+
sent: Some(gateway_config::BgpMessageCounters {
477+
capability: 1,
478+
keepalive: 11,
479+
notification: 0,
480+
open: 1,
481+
route_refresh: 0,
482+
update: 40,
483+
}),
484+
});
485+
let v4pfx = Some(gateway_config::BgpNeighborPrefixes {
486+
received: 100,
487+
received_pre_policy: 120,
488+
sent: 90,
489+
});
490+
491+
let mut neighbors = std::collections::HashMap::new();
492+
neighbors.insert(
493+
"192.0.2.1".to_string(),
494+
gateway_config::BgpNeighborStatus {
495+
enabled: true,
496+
local_as: 65001,
497+
peer_as: 65002,
498+
peer_port: 179,
499+
peer_group: "spines".into(),
500+
remote_router_id: "10.0.0.2".into(),
501+
session_state: gateway_config::BgpNeighborSessionState::BgpStateEstablished as i32,
502+
connections_dropped: 0,
503+
established_transitions: 3,
504+
last_reset_reason: String::new(),
505+
messages: bgp_msgs,
506+
ipv4_unicast_prefixes: v4pfx,
507+
ipv6_unicast_prefixes: None,
508+
l2vpn_evpn_prefixes: None,
509+
},
510+
);
511+
let mut vrfs = std::collections::HashMap::new();
512+
vrfs.insert("default".into(), gateway_config::BgpVrfStatus { neighbors });
513+
let bgp = Some(gateway_config::BgpStatus { vrfs });
514+
515+
// VPCs + VPC peering counters
516+
let mut vpc_ifaces = std::collections::HashMap::new();
517+
vpc_ifaces.insert(
518+
"veth0".into(),
519+
gateway_config::VpcInterfaceStatus {
520+
ifname: "veth0".into(),
521+
admin_status: gateway_config::InterfaceAdminStatusType::InterfaceAdminStatusUp
522+
as i32,
523+
oper_status: gateway_config::InterfaceOperStatusType::InterfaceStatusOperUp as i32,
524+
},
525+
);
526+
let mut vpcs = std::collections::HashMap::new();
527+
vpcs.insert(
528+
"vpc-1".into(),
529+
gateway_config::VpcStatus {
530+
id: "0x202".into(),
531+
name: "vpc-1".into(),
532+
vni: 1001,
533+
route_count: 17,
534+
interfaces: vpc_ifaces,
535+
},
536+
);
537+
538+
let mut vpc_peering_counters = std::collections::HashMap::new();
539+
vpc_peering_counters.insert(
540+
"peering-1".into(),
541+
gateway_config::VpcPeeringCounters {
542+
name: "peering-1".into(),
543+
src_vpc: "vpc-1".into(),
544+
dst_vpc: "vpc-2".into(),
545+
packets: 12345,
546+
bytes: 987_654,
547+
drops: 12,
548+
pps: 321.0,
549+
},
550+
);
551+
552+
gateway_config::GetDataplaneStatusResponse {
553+
interface_statuses,
554+
frr_status,
555+
dataplane_status,
556+
interface_runtime,
557+
bgp,
558+
vpcs,
559+
vpc_peering_counters,
560+
}
561+
}
562+
563+
#[test]
564+
fn test_convert_to_from_grpc_status() {
565+
let grpc_status = create_test_status();
566+
567+
// gRPC -> internal
568+
let internal = convert_dataplane_status_from_grpc(&grpc_status)
569+
.expect("conversion from gRPC status failed");
570+
571+
// internal -> gRPC
572+
let back =
573+
convert_dataplane_status_to_grpc(&internal).expect("conversion to gRPC status failed");
574+
575+
assert_eq!(grpc_status, back);
576+
}
416577
}

0 commit comments

Comments
 (0)