Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ dpdk-sysroot-helper = { path = "./dpdk-sysroot-helper", package = "dataplane-dpd
dplane-rpc = { git = "https://github.com/githedgehog/dplane-rpc.git", rev = "e8fc33db10e1d00785f2a2b90cbadcad7900f200", features = [] }
errno = { path = "./errno", package = "dataplane-errno", features = [] }
flow-info = { path = "./flow-info", package = "dataplane-flow-info", features = [] }
gateway_config = { git = "https://github.com/githedgehog/gateway-proto", tag = "v0.17.0", features = [] }
gateway_config = { git = "https://github.com/githedgehog/gateway-proto", tag = "v0.19.0", features = [] }
gwname = { path = "./gwname", package = "dataplane-gwname", features = [] }
hardware = { path = "./hardware", package = "dataplane-hardware", features = [] }
id = { path = "./id", package = "dataplane-id", features = [] }
Expand Down
1 change: 1 addition & 0 deletions config/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ version.workspace = true
[dependencies]
# internal
gateway_config = { workspace = true }
gwname = { workspace = true }
hardware = { workspace = true }
net = { workspace = true }
lpm = { workspace = true }
Expand Down
46 changes: 46 additions & 0 deletions config/src/converters/grpc/gateway_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
use tracing::warn;

use crate::external::ExternalConfigBuilder;
use crate::external::communities::PriorityCommunityTable;
use crate::external::gwgroup::{GwGroup, GwGroupTable};
use crate::external::overlay::Overlay;
use crate::external::underlay::Underlay;
use crate::internal::device::{DeviceConfig, settings::DeviceSettings};
use crate::{ExternalConfig, GwConfig};
use gateway_config::config::GatewayGroup;

// Helper Functions
//--------------------------------------------------------------------------------
Expand Down Expand Up @@ -45,12 +48,29 @@ pub fn convert_gateway_config_from_grpc_with_defaults(
Overlay::default()
};

// convert gateway groups
let mut gw_groups = GwGroupTable::new();
for g in &grpc_config.gw_groups {
let group = GwGroup::try_from(g)?;
gw_groups.add_group(group).map_err(|e| e.to_string())?;
}

// convert community table
let mut comtable = PriorityCommunityTable::new();
for (prio, community) in &grpc_config.communities {
comtable
.insert(*prio, community)
.map_err(|e| e.to_string())?;
}

// Create the ExternalConfig using the builder pattern
let external_config = ExternalConfigBuilder::default()
.genid(grpc_config.generation)
.device(device_config)
.underlay(underlay_config)
.overlay(overlay_config)
.gwgroups(gw_groups)
.communities(comtable)
.build()
.map_err(|e| format!("Failed to build ExternalConfig: {e}"))?;

Expand Down Expand Up @@ -82,12 +102,29 @@ impl TryFrom<&gateway_config::GatewayConfig> for ExternalConfig {
Err("Missing overlay configuration!".to_string())
}?;

// convert gateway groups
let mut gw_groups = GwGroupTable::new();
for g in &grpc_config.gw_groups {
let group = GwGroup::try_from(g)?;
gw_groups.add_group(group).map_err(|e| e.to_string())?;
}

// convert community table
let mut comtable = PriorityCommunityTable::new();
for (prio, community) in &grpc_config.communities {
comtable
.insert(*prio, community)
.map_err(|e| e.to_string())?;
}

// Create the ExternalConfig using the builder pattern
let external_config = ExternalConfigBuilder::default()
.genid(grpc_config.generation)
.device(device_config)
.underlay(underlay_config)
.overlay(overlay_config)
.gwgroups(gw_groups)
.communities(comtable)
.build()
.map_err(|e| format!("Failed to build ExternalConfig: {e}"))?;

Expand All @@ -108,12 +145,21 @@ impl TryFrom<&ExternalConfig> for gateway_config::GatewayConfig {
// Convert overlay config
let overlay = gateway_config::Overlay::try_from(&external_config.overlay)?;

// Convert gateway groups
let gw_groups: Vec<_> = external_config
.gwgroups
.iter()
.map(|g| GatewayGroup::try_from(g).unwrap_or_else(|_| unreachable!()))
.collect();

// Create the complete gRPC config
Ok(gateway_config::GatewayConfig {
generation: external_config.genid,
device: Some(device),
underlay: Some(underlay),
overlay: Some(overlay),
gw_groups,
communities: external_config.communities.inner().clone(),
})
}
}
57 changes: 57 additions & 0 deletions config/src/converters/grpc/gwgroups.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Open Network Fabric Authors

use crate::converters::strings::parse_address;
use crate::external::gwgroup::{GwGroup, GwGroupMember};
use gateway_config::config as gateway_config;

impl TryFrom<&gateway_config::GatewayGroupMember> for GwGroupMember {
type Error = String;

fn try_from(value: &gateway_config::GatewayGroupMember) -> Result<Self, Self::Error> {
let address = parse_address(&value.ipaddress)
.map_err(|e| format!("Bad ip address '{}': {e}", value.ipaddress))?;
Ok(GwGroupMember::new(&value.name, value.priority, address))
}
}
impl TryFrom<&GwGroupMember> for gateway_config::GatewayGroupMember {
type Error = String;

fn try_from(value: &GwGroupMember) -> Result<Self, Self::Error> {
Ok(gateway_config::GatewayGroupMember {
name: value.name.clone(),
priority: value.priority,
ipaddress: value.ipaddress.to_string(),
})
}
}

impl TryFrom<&gateway_config::GatewayGroup> for GwGroup {
type Error = String;

fn try_from(value: &gateway_config::GatewayGroup) -> Result<Self, Self::Error> {
let mut rgroup = GwGroup::new(&value.name);
for m in &value.members {
let member = GwGroupMember::try_from(m)?;
rgroup.add_member(member).map_err(|e| e.to_string())?;
}
Ok(rgroup)
}
}

impl TryFrom<&GwGroup> for gateway_config::GatewayGroup {
type Error = String;

fn try_from(value: &GwGroup) -> Result<Self, Self::Error> {
let members: Vec<_> = value
.iter()
.map(|m| {
gateway_config::GatewayGroupMember::try_from(m).unwrap_or_else(|_| unreachable!())
})
.collect();
Ok(Self {
name: value.name().to_owned(),
members,
})
}
}
34 changes: 34 additions & 0 deletions config/src/converters/grpc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ mod bgp;
mod device;
mod expose;
mod gateway_config;
mod gwgroups;
mod interface;
mod overlay;
mod peering;
Expand All @@ -25,6 +26,8 @@ pub use device::*;
pub use expose::*;
pub use gateway_config::*;
#[allow(unused)] // Remove if we do anything but implement traits
pub use gwgroups::*;
#[allow(unused)] // Remove if we do anything but implement traits
pub use interface::*;
#[allow(unused)] // Remove if we do anything but implement traits
pub use overlay::*;
Expand All @@ -44,13 +47,16 @@ pub use vrf::*;
#[cfg(test)]
mod test {
use gateway_config::GatewayConfig;
use gateway_config::GatewayGroupMember;
use gateway_config::config::GatewayGroup;
use gateway_config::config::TracingConfig as ApiTracingConfig;
use pretty_assertions::assert_eq;

use crate::converters::grpc::convert_gateway_config_from_grpc_with_defaults;
use crate::converters::grpc::{
convert_dataplane_status_from_grpc, convert_dataplane_status_to_grpc,
};
use crate::external::communities::PriorityCommunityTable;
use crate::internal::device::DeviceConfig;
use crate::internal::interfaces::interface::InterfaceConfig;

Expand Down Expand Up @@ -304,6 +310,7 @@ mod test {
let peering = gateway_config::VpcPeering {
name: "vpc1-vpc2-peering".to_string(),
r#for: vec![vpc1_entry, vpc2_entry],
gateway_group: "gw-group-1".to_string(),
};

// Create Overlay
Expand All @@ -312,12 +319,39 @@ mod test {
peerings: vec![peering],
};

// Create gateway group
let gw_group = GatewayGroup {
name: "gw-group-1".to_string(),
members: vec![
GatewayGroupMember {
name: "gw1".to_owned(),
priority: 1,
ipaddress: "172.128.0.1".to_string(),
},
GatewayGroupMember {
name: "gw2".to_owned(),
priority: 2,
ipaddress: "172.128.0.2".to_string(),
},
],
};

// Create priority-to-community table
let mut commtable = PriorityCommunityTable::new();
commtable.insert(0, "65000:800").unwrap();
commtable.insert(1, "65000:801").unwrap();
commtable.insert(2, "65000:802").unwrap();
commtable.insert(3, "65000:803").unwrap();
commtable.insert(4, "65000:804").unwrap();

// Create the full GatewayConfig
GatewayConfig {
generation: 42,
device: Some(device),
underlay: Some(underlay),
overlay: Some(overlay),
gw_groups: vec![gw_group],
communities: commtable.inner().clone(),
}
}

Expand Down
14 changes: 13 additions & 1 deletion config/src/converters/grpc/peering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,19 @@ impl TryFrom<&gateway_config::VpcPeering> for VpcPeering {
)),
}?;

let gwgroup = if peering.gateway_group.is_empty() {
None
} else {
Some(peering.gateway_group.clone())
};

// Create the peering using the constructor
Ok(VpcPeering::new(&peering.name, vpc1_manifest, vpc2_manifest))
Ok(VpcPeering::new(
&peering.name,
vpc1_manifest,
vpc2_manifest,
gwgroup,
))
}
}

Expand All @@ -40,6 +51,7 @@ impl TryFrom<&VpcPeering> for gateway_config::VpcPeering {
Ok(gateway_config::VpcPeering {
name: peering.name.clone(),
r#for: vec![left_for, right_for],
gateway_group: peering.gw_group.clone().unwrap_or_default(),
})
}
}
Expand Down
27 changes: 27 additions & 0 deletions config/src/converters/k8s/config/communities.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Open Network Fabric Authors

use crate::converters::k8s::FromK8sConversionError;
use k8s_intf::gateway_agent_crd::GatewayAgentSpec;

use crate::external::communities::PriorityCommunityTable;

impl TryFrom<&GatewayAgentSpec> for PriorityCommunityTable {
type Error = FromK8sConversionError;

fn try_from(spec: &GatewayAgentSpec) -> Result<Self, Self::Error> {
let mut comtable = PriorityCommunityTable::new();
match &spec.communities {
None => Ok(comtable),
Some(map) => {
for (prio, community) in map {
let priority: u32 = prio.parse().map_err(|e| {
Self::Error::ParseError(format!("Community priority '{prio}': {e}"))
})?;
comtable.insert(priority, community)?;
}
Ok(comtable)
}
}
}
}
Loading
Loading