Skip to content

Commit

Permalink
Merge pull request #142 from milliams/macaddr_port
Browse files Browse the repository at this point in the history
Port from eui48 to macaddr
  • Loading branch information
dtantsur authored Oct 30, 2023
2 parents 02b8a01 + 511ae0d commit a3b6412
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 8 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ rustls = ["reqwest/rustls-tls", "osauth/rustls"]
async-stream = "^0.3"
async-trait = "^0.1"
chrono = { version = "^0.4", features = ["serde"] }
eui48 = { version = "^1.0", features = ["disp_hexstring", "serde"] }
macaddr = { version = "^1.0", features = ["serde_std"]}
futures = "^0.3"
ipnet = { version = "^2.0", features = ["serde"] }
log = "^0.4"
Expand Down
6 changes: 3 additions & 3 deletions src/network/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ pub use self::networks::{Network, NetworkQuery, NewNetwork};
pub use self::ports::{NewPort, Port, PortIpAddress, PortIpRequest, PortQuery};
pub use self::protocol::{
AllocationPool, AllowedAddressPair, ConntrackHelper, ExternalGateway, FloatingIpSortKey,
FloatingIpStatus, Helper, HostRoute, IpVersion, Ipv6Mode, NetworkProtocol, NetworkSortKey,
NetworkStatus, PortExtraDhcpOption, PortForwarding, PortSortKey, RouterSortKey, RouterStatus,
SubnetSortKey,
FloatingIpStatus, Helper, HostRoute, IpVersion, Ipv6Mode, MacAddress, NetworkProtocol,
NetworkSortKey, NetworkStatus, PortExtraDhcpOption, PortForwarding, PortSortKey, RouterSortKey,
RouterStatus, SubnetSortKey,
};
pub use self::routers::{NewRouter, Router, RouterQuery};
pub use self::subnets::{NewSubnet, Subnet, SubnetQuery};
3 changes: 1 addition & 2 deletions src/network/ports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ use std::time::Duration;

use async_trait::async_trait;
use chrono::{DateTime, FixedOffset};
use eui48::MacAddress;
use futures::stream::{Stream, TryStreamExt};

use super::super::common::{
Expand All @@ -31,7 +30,7 @@ use super::super::session::Session;
use super::super::utils::Query;
use super::super::waiter::DeletionWaiter;
use super::super::{Result, Sort};
use super::{api, protocol, Network, Subnet};
use super::{api, protocol, MacAddress, Network, Subnet};

/// A query to port list.
#[derive(Clone, Debug)]
Expand Down
88 changes: 86 additions & 2 deletions src/network/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,8 @@ use std::net;
use std::ops::Not;

use chrono::{DateTime, FixedOffset};
use eui48::MacAddress;
use osauth::common::empty_as_default;
use serde::{Deserialize, Serialize};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde_json::Value;

use super::super::common::{NetworkRef, SecurityGroupRef};
Expand Down Expand Up @@ -330,6 +329,56 @@ pub struct FixedIp {
pub subnet_id: String,
}

#[derive(Copy, Clone, Debug, Eq, PartialEq, Default, Ord, PartialOrd, Hash)]
pub struct MacAddress(macaddr::MacAddr6);

impl MacAddress {
pub fn is_nil(&self) -> bool {
self.0.is_nil()
}
}

impl std::fmt::Display for MacAddress {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}

impl std::ops::Deref for MacAddress {
type Target = macaddr::MacAddr6;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl std::str::FromStr for MacAddress {
type Err = macaddr::ParseError;

fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
Ok(Self(s.parse::<macaddr::MacAddr6>()?))
}
}

impl Serialize for MacAddress {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&self.to_string())
}
}

impl<'de> Deserialize<'de> for MacAddress {
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s: String = Deserialize::deserialize(deserializer)?;
s.parse().map_err(serde::de::Error::custom)
}
}

/// A port's IP address.
#[derive(Debug, Clone, Deserialize, Serialize, Copy)]
pub struct AllowedAddressPair {
Expand Down Expand Up @@ -855,3 +904,38 @@ pub struct FloatingIpUpdateRoot {
pub struct FloatingIpsRoot {
pub floatingips: Vec<FloatingIp>,
}

#[cfg(test)]
mod test {
use super::*;

#[test]
fn test_parse_macaddr() {
// Test that a JSON deserialisation of MAC addresses work
let a: AllowedAddressPair = serde_json::from_value(
serde_json::json!({"ip_address":"0.0.0.0", "mac_address":"ab:aa:aa:aa:aa:aa"}),
)
.expect("Could not parse this JSON");
assert_eq!(
a.mac_address.expect("MAC address is missing").to_string(),
"AB:AA:AA:AA:AA:AA"
);

// Test that a JSON serialisation of MAC addresses work
assert_eq!(
serde_json::to_value(&a)
.expect("Could not serialize")
.get("mac_address")
.expect("No mac_address")
.as_str()
.expect("No string found"),
"AB:AA:AA:AA:AA:AA"
);

// Test that missing MAC addresses are parsed as None
let a: AllowedAddressPair =
serde_json::from_value(serde_json::json!({"ip_address":"0.0.0.0"}))
.expect("Cannot parse this JSON");
assert_eq!(a.mac_address, None);
}
}

0 comments on commit a3b6412

Please sign in to comment.