Skip to content

Commit 8978fb7

Browse files
committed
feat(status): add TryFrom for BGP Dataplane status section
Signed-off-by: Sergey Matov <[email protected]>
1 parent 0d97dd4 commit 8978fb7

File tree

7 files changed

+249
-12
lines changed

7 files changed

+249
-12
lines changed
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
// Copyright Open Network Fabric Authors
3+
4+
use std::collections::BTreeMap;
5+
6+
use k8s_intf::gateway_agent_crd::{
7+
GatewayAgentStatusStateBgp, GatewayAgentStatusStateBgpVrfs,
8+
GatewayAgentStatusStateBgpVrfsNeighbors,
9+
GatewayAgentStatusStateBgpVrfsNeighborsIpv4UnicastPrefixes,
10+
GatewayAgentStatusStateBgpVrfsNeighborsIpv6UnicastPrefixes,
11+
GatewayAgentStatusStateBgpVrfsNeighborsL2VpnevpnPrefixes,
12+
GatewayAgentStatusStateBgpVrfsNeighborsMessages,
13+
GatewayAgentStatusStateBgpVrfsNeighborsMessagesReceived,
14+
GatewayAgentStatusStateBgpVrfsNeighborsMessagesSent,
15+
GatewayAgentStatusStateBgpVrfsNeighborsSessionState,
16+
};
17+
18+
use crate::converters::k8s::ToK8sConversionError;
19+
use crate::internal::status::{
20+
BgpMessageCounters, BgpMessages, BgpNeighborPrefixes, BgpNeighborSessionState,
21+
BgpNeighborStatus, BgpStatus, BgpVrfStatus,
22+
};
23+
24+
fn u64_to_i64_sat(v: u64) -> i64 {
25+
i64::try_from(v).unwrap_or(i64::MAX)
26+
}
27+
28+
fn u32_to_i32_sat(v: u32) -> i32 {
29+
i32::try_from(v).unwrap_or(i32::MAX)
30+
}
31+
32+
impl TryFrom<&BgpStatus> for GatewayAgentStatusStateBgp {
33+
type Error = ToK8sConversionError;
34+
35+
fn try_from(status: &BgpStatus) -> Result<Self, Self::Error> {
36+
let vrfs = status
37+
.vrfs
38+
.iter()
39+
.map(|(k, v)| Ok((k.clone(), GatewayAgentStatusStateBgpVrfs::try_from(v)?)))
40+
.collect::<Result<BTreeMap<_, _>, _>>()?;
41+
42+
Ok(GatewayAgentStatusStateBgp {
43+
vrfs: Some(vrfs).filter(|m| !m.is_empty()),
44+
})
45+
}
46+
}
47+
48+
impl TryFrom<&BgpVrfStatus> for GatewayAgentStatusStateBgpVrfs {
49+
type Error = ToK8sConversionError;
50+
51+
fn try_from(status: &BgpVrfStatus) -> Result<Self, Self::Error> {
52+
let neighbors = status
53+
.neighbors
54+
.iter()
55+
.map(|(k, v)| {
56+
Ok((
57+
k.clone(),
58+
GatewayAgentStatusStateBgpVrfsNeighbors::try_from(v)?,
59+
))
60+
})
61+
.collect::<Result<BTreeMap<_, _>, _>>()?;
62+
63+
Ok(GatewayAgentStatusStateBgpVrfs {
64+
neighbors: Some(neighbors).filter(|m| !m.is_empty()),
65+
})
66+
}
67+
}
68+
69+
impl TryFrom<&BgpNeighborStatus> for GatewayAgentStatusStateBgpVrfsNeighbors {
70+
type Error = ToK8sConversionError;
71+
72+
fn try_from(status: &BgpNeighborStatus) -> Result<Self, Self::Error> {
73+
let session_state = match status.session_state {
74+
BgpNeighborSessionState::Unset => {
75+
GatewayAgentStatusStateBgpVrfsNeighborsSessionState::Unset
76+
}
77+
BgpNeighborSessionState::Idle => {
78+
GatewayAgentStatusStateBgpVrfsNeighborsSessionState::Idle
79+
}
80+
BgpNeighborSessionState::Connect => {
81+
GatewayAgentStatusStateBgpVrfsNeighborsSessionState::Connect
82+
}
83+
BgpNeighborSessionState::Active => {
84+
GatewayAgentStatusStateBgpVrfsNeighborsSessionState::Active
85+
}
86+
BgpNeighborSessionState::Open => {
87+
GatewayAgentStatusStateBgpVrfsNeighborsSessionState::Open
88+
}
89+
BgpNeighborSessionState::Established => {
90+
GatewayAgentStatusStateBgpVrfsNeighborsSessionState::Established
91+
}
92+
};
93+
94+
Ok(GatewayAgentStatusStateBgpVrfsNeighbors {
95+
enabled: Some(status.enabled),
96+
local_as: Some(u32_to_i32_sat(status.local_as)),
97+
peer_as: Some(u32_to_i32_sat(status.peer_as)),
98+
remote_router_id: Some(status.remote_router_id.clone()),
99+
session_state: Some(session_state),
100+
101+
connections_dropped: Some(status.connections_dropped),
102+
// NOTE: generated CRD uses i64 here
103+
established_transitions: Some(u64_to_i64_sat(status.established_transitions)),
104+
last_reset_reason: Some(status.last_reset_reason.clone()),
105+
106+
messages: status
107+
.messages
108+
.as_ref()
109+
.map(GatewayAgentStatusStateBgpVrfsNeighborsMessages::try_from)
110+
.transpose()?,
111+
112+
ipv4_unicast_prefixes: status
113+
.ipv4_unicast_prefixes
114+
.as_ref()
115+
.map(GatewayAgentStatusStateBgpVrfsNeighborsIpv4UnicastPrefixes::try_from)
116+
.transpose()?,
117+
118+
ipv6_unicast_prefixes: status
119+
.ipv6_unicast_prefixes
120+
.as_ref()
121+
.map(GatewayAgentStatusStateBgpVrfsNeighborsIpv6UnicastPrefixes::try_from)
122+
.transpose()?,
123+
124+
l2_vpnevpn_prefixes: status
125+
.l2vpn_evpn_prefixes
126+
.as_ref()
127+
.map(GatewayAgentStatusStateBgpVrfsNeighborsL2VpnevpnPrefixes::try_from)
128+
.transpose()?,
129+
})
130+
}
131+
}
132+
133+
impl TryFrom<&BgpNeighborPrefixes> for GatewayAgentStatusStateBgpVrfsNeighborsIpv4UnicastPrefixes {
134+
type Error = ToK8sConversionError;
135+
136+
fn try_from(p: &BgpNeighborPrefixes) -> Result<Self, Self::Error> {
137+
Ok(GatewayAgentStatusStateBgpVrfsNeighborsIpv4UnicastPrefixes {
138+
received: Some(u32_to_i32_sat(p.received)),
139+
received_pre_policy: Some(u32_to_i32_sat(p.received_pre_policy)),
140+
sent: Some(u32_to_i32_sat(p.sent)),
141+
})
142+
}
143+
}
144+
145+
impl TryFrom<&BgpNeighborPrefixes> for GatewayAgentStatusStateBgpVrfsNeighborsIpv6UnicastPrefixes {
146+
type Error = ToK8sConversionError;
147+
148+
fn try_from(p: &BgpNeighborPrefixes) -> Result<Self, Self::Error> {
149+
Ok(GatewayAgentStatusStateBgpVrfsNeighborsIpv6UnicastPrefixes {
150+
received: Some(u32_to_i32_sat(p.received)),
151+
received_pre_policy: Some(u32_to_i32_sat(p.received_pre_policy)),
152+
sent: Some(u32_to_i32_sat(p.sent)),
153+
})
154+
}
155+
}
156+
157+
impl TryFrom<&BgpNeighborPrefixes> for GatewayAgentStatusStateBgpVrfsNeighborsL2VpnevpnPrefixes {
158+
type Error = ToK8sConversionError;
159+
160+
fn try_from(p: &BgpNeighborPrefixes) -> Result<Self, Self::Error> {
161+
Ok(GatewayAgentStatusStateBgpVrfsNeighborsL2VpnevpnPrefixes {
162+
received: Some(u32_to_i32_sat(p.received)),
163+
received_pre_policy: Some(u32_to_i32_sat(p.received_pre_policy)),
164+
sent: Some(u32_to_i32_sat(p.sent)),
165+
})
166+
}
167+
}
168+
169+
impl TryFrom<&BgpMessages> for GatewayAgentStatusStateBgpVrfsNeighborsMessages {
170+
type Error = ToK8sConversionError;
171+
172+
fn try_from(m: &BgpMessages) -> Result<Self, Self::Error> {
173+
Ok(GatewayAgentStatusStateBgpVrfsNeighborsMessages {
174+
received: m
175+
.received
176+
.as_ref()
177+
.map(GatewayAgentStatusStateBgpVrfsNeighborsMessagesReceived::try_from)
178+
.transpose()?,
179+
sent: m
180+
.sent
181+
.as_ref()
182+
.map(GatewayAgentStatusStateBgpVrfsNeighborsMessagesSent::try_from)
183+
.transpose()?,
184+
})
185+
}
186+
}
187+
188+
impl TryFrom<&BgpMessageCounters> for GatewayAgentStatusStateBgpVrfsNeighborsMessagesReceived {
189+
type Error = ToK8sConversionError;
190+
191+
fn try_from(c: &BgpMessageCounters) -> Result<Self, Self::Error> {
192+
Ok(GatewayAgentStatusStateBgpVrfsNeighborsMessagesReceived {
193+
capability: Some(u64_to_i64_sat(c.capability)),
194+
keepalive: Some(u64_to_i64_sat(c.keepalive)),
195+
notification: Some(u64_to_i64_sat(c.notification)),
196+
open: Some(u64_to_i64_sat(c.open)),
197+
route_refresh: Some(u64_to_i64_sat(c.route_refresh)),
198+
update: Some(u64_to_i64_sat(c.update)),
199+
})
200+
}
201+
}
202+
203+
impl TryFrom<&BgpMessageCounters> for GatewayAgentStatusStateBgpVrfsNeighborsMessagesSent {
204+
type Error = ToK8sConversionError;
205+
206+
fn try_from(c: &BgpMessageCounters) -> Result<Self, Self::Error> {
207+
Ok(GatewayAgentStatusStateBgpVrfsNeighborsMessagesSent {
208+
capability: Some(u64_to_i64_sat(c.capability)),
209+
keepalive: Some(u64_to_i64_sat(c.keepalive)),
210+
notification: Some(u64_to_i64_sat(c.notification)),
211+
open: Some(u64_to_i64_sat(c.open)),
212+
route_refresh: Some(u64_to_i64_sat(c.route_refresh)),
213+
update: Some(u64_to_i64_sat(c.update)),
214+
})
215+
}
216+
}

config/src/converters/k8s/status/dataplane_status.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ use std::collections::BTreeMap;
66
use chrono::{DateTime, Utc};
77

88
use k8s_intf::gateway_agent_crd::{
9-
GatewayAgentStatus, GatewayAgentStatusState, GatewayAgentStatusStateDataplane,
10-
GatewayAgentStatusStateFrr, GatewayAgentStatusStatePeerings, GatewayAgentStatusStateVpcs,
9+
GatewayAgentStatus, GatewayAgentStatusState, GatewayAgentStatusStateBgp,
10+
GatewayAgentStatusStateDataplane, GatewayAgentStatusStateFrr, GatewayAgentStatusStatePeerings,
11+
GatewayAgentStatusStateVpcs,
1112
};
1213

1314
use crate::converters::k8s::ToK8sConversionError;
@@ -69,6 +70,16 @@ impl TryFrom<&DataplaneStatusForK8sConversion<'_>> for GatewayAgentStatus {
6970
})
7071
.transpose()?;
7172

73+
let bgp = status
74+
.status
75+
.and_then(|status| {
76+
status
77+
.bgp
78+
.as_ref()
79+
.map(GatewayAgentStatusStateBgp::try_from)
80+
})
81+
.transpose()?;
82+
7283
Ok(GatewayAgentStatus {
7384
agent_version: None,
7485
last_applied_gen: status.last_applied_gen,
@@ -79,6 +90,7 @@ impl TryFrom<&DataplaneStatusForK8sConversion<'_>> for GatewayAgentStatus {
7990
.last_heartbeat
8091
.map(|lhb| lhb.to_rfc3339_opts(chrono::SecondsFormat::Nanos, true)),
8192
state: status.status.map(|_| GatewayAgentStatusState {
93+
bgp,
8294
dataplane: Some(GatewayAgentStatusStateDataplane {
8395
version: Some(option_env!("VERSION").unwrap_or("dev").to_string()),
8496
}),

config/src/converters/k8s/status/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
//! Converter for gateway-schema k8s objects from internal status
55
6+
pub mod bgp;
67
pub mod dataplane_status;
78
pub mod frr;
89
pub mod peerings;

mgmt/src/processor/k8s_client.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use config::converters::k8s::ToK8sConversionError;
1212
use config::converters::k8s::status::dataplane_status::DataplaneStatusForK8sConversion;
1313
use config::{ExternalConfig, GwConfig};
1414
use k8s_intf::client::{
15-
ReplaceStatusError, WatchError, replace_gateway_status, watch_gateway_agent_crd,
15+
replace_gateway_status, watch_gateway_agent_crd, ReplaceStatusError, WatchError,
1616
};
1717
use k8s_intf::gateway_agent_crd::{
1818
GatewayAgentStatus, GatewayAgentStatusState, GatewayAgentStatusStateDataplane,
@@ -41,9 +41,7 @@ fn to_datetime(opt_time: Option<&SystemTime>) -> chrono::DateTime<Utc> {
4141
}
4242

4343
/// Main function to create a `GatewayAgentStatus` object
44-
pub(crate) async fn build_gateway_status(
45-
config_client: &ConfigClient,
46-
) -> Option<GatewayAgentStatus> {
44+
pub(crate) async fn build_gateway_status(config_client: &ConfigClient) -> Option<GatewayAgentStatus> {
4745
let status = config_client.get_status().await;
4846
let status = match status {
4947
Ok(status) => status,
@@ -109,6 +107,7 @@ impl K8sClient {
109107
chrono::Utc::now().to_rfc3339_opts(chrono::SecondsFormat::Nanos, true),
110108
),
111109
state: Some(GatewayAgentStatusState {
110+
bgp: None,
112111
dataplane: Some(GatewayAgentStatusStateDataplane {
113112
version: Some(option_env!("VERSION").unwrap_or("dev").to_string()),
114113
}),
@@ -162,7 +161,7 @@ impl K8sClient {
162161
Ok(()) => {
163162
info!("Config for generation {genid} was successfully applied. Updating status...");
164163
k8s_client.update_gateway_status().await;
165-
},
164+
}
166165
Err(e) => error!("Failed to apply the config for generation {genid}: {e}"),
167166
}
168167
}

routing/src/bmp/bmp_render.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,10 @@ fn on_peer_up(status: &mut DataplaneStatus, pu: &PeerUpNotificationMessage) {
106106

107107
let peer_as = peer.peer_as();
108108
let bgp_id = peer.bgp_id().to_string();
109-
let peer_addr = peer.address().map(|a| a.to_string()).unwrap_or_else(|| "none".to_string());
109+
let peer_addr = peer
110+
.address()
111+
.map(|a| a.to_string())
112+
.unwrap_or_else(|| "none".to_string());
110113
let peer_port = pu.remote_port().unwrap_or_default() as u32;
111114

112115
let bgp = ensure_bgp(status);
@@ -181,13 +184,19 @@ fn on_peer_down(status: &mut DataplaneStatus, pd: &PeerDownNotificationMessage)
181184
neigh.connections_dropped
182185
);
183186
} else {
184-
debug!("BMP: peer-down for unknown neighbor: vrf={} key={}", vrf, key);
187+
debug!(
188+
"BMP: peer-down for unknown neighbor: vrf={} key={}",
189+
vrf, key
190+
);
185191
}
186192
} else {
187193
debug!("BMP: peer-down for unknown vrf: vrf={} key={}", vrf, key);
188194
}
189195
} else {
190-
debug!("BMP: peer-down but DataplaneStatus.bgp is None (vrf={} key={})", vrf, key);
196+
debug!(
197+
"BMP: peer-down but DataplaneStatus.bgp is None (vrf={} key={})",
198+
vrf, key
199+
);
191200
}
192201
}
193202

routing/src/bmp/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use concurrency::sync::{Arc, RwLock};
1212
use config::internal::status::DataplaneStatus;
1313
use netgauze_bmp_pkt::BmpMessage;
1414
use tokio::task::JoinHandle;
15-
use tracing::{error, info, debug};
15+
use tracing::{debug, error, info};
1616

1717
/// Background BMP server runner that updates shared dataplane status.
1818
pub struct StatusHandler {

routing/src/bmp/server.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ use tokio::net::{TcpListener, TcpStream};
1616
use tokio::task::JoinSet;
1717
use tokio_util::codec::FramedRead;
1818

19-
use tracing::debug;
2019
use crate::bmp::handler::BmpHandler;
20+
use tracing::debug;
2121

2222
#[derive(Clone, Debug)]
2323
pub struct BmpServerConfig {

0 commit comments

Comments
 (0)