fix: Support multiple mac address on static host binding
Some checks failed
Run Check Script / check (pull_request) Failing after 30s
Some checks failed
Run Check Script / check (pull_request) Failing after 30s
This commit is contained in:
parent
ceea03d6ce
commit
fed4a8076c
661
Cargo.lock
generated
661
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -11,15 +11,16 @@ use super::{LogicalHost, k8s::K8sClient};
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DHCPStaticEntry {
|
pub struct DHCPStaticEntry {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub mac: MacAddress,
|
pub mac: Vec<MacAddress>,
|
||||||
pub ip: Ipv4Addr,
|
pub ip: Ipv4Addr,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for DHCPStaticEntry {
|
impl std::fmt::Display for DHCPStaticEntry {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
let mac = self.mac.iter().map(|m| m.to_string()).collect::<Vec<String>>().join(",");
|
||||||
f.write_fmt(format_args!(
|
f.write_fmt(format_args!(
|
||||||
"DHCPStaticEntry : name {}, mac {}, ip {}",
|
"DHCPStaticEntry : name {}, mac {}, ip {}",
|
||||||
self.name, self.mac, self.ip
|
self.name, mac, self.ip
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -41,6 +42,7 @@ impl std::fmt::Debug for dyn Firewall {
|
|||||||
pub struct NetworkDomain {
|
pub struct NetworkDomain {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait K8sclient: Send + Sync {
|
pub trait K8sclient: Send + Sync {
|
||||||
async fn k8s_client(&self) -> Result<Arc<K8sClient>, String>;
|
async fn k8s_client(&self) -> Result<Arc<K8sClient>, String>;
|
||||||
|
@ -17,13 +17,13 @@ impl DhcpServer for OPNSenseFirewall {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn add_static_mapping(&self, entry: &DHCPStaticEntry) -> Result<(), ExecutorError> {
|
async fn add_static_mapping(&self, entry: &DHCPStaticEntry) -> Result<(), ExecutorError> {
|
||||||
let mac: String = String::from(&entry.mac);
|
let mac: Vec<String> = entry.mac.iter().map(MacAddress::to_string).collect();
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut writable_opnsense = self.opnsense_config.write().await;
|
let mut writable_opnsense = self.opnsense_config.write().await;
|
||||||
writable_opnsense
|
writable_opnsense
|
||||||
.dhcp()
|
.dhcp()
|
||||||
.add_static_mapping(&mac, entry.ip, &entry.name)
|
.add_static_mapping(&mac, &entry.ip, &entry.name)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,7 +179,7 @@ impl DhcpHostBindingInterpret {
|
|||||||
|
|
||||||
DHCPStaticEntry {
|
DHCPStaticEntry {
|
||||||
name,
|
name,
|
||||||
mac: binding.physical_host.cluster_mac(),
|
mac: binding.physical_host.get_mac_address(),
|
||||||
ip,
|
ip,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -21,7 +21,7 @@ impl From<&MacAddress> for String {
|
|||||||
|
|
||||||
impl std::fmt::Display for MacAddress {
|
impl std::fmt::Display for MacAddress {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
f.write_fmt(format_args!("MacAddress {}", String::from(self)))
|
f.write_str(&String::from(self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,16 +75,16 @@ impl<'a> DhcpConfigDnsMasq<'a> {
|
|||||||
/// ambiguous state.
|
/// ambiguous state.
|
||||||
pub fn add_static_mapping(
|
pub fn add_static_mapping(
|
||||||
&mut self,
|
&mut self,
|
||||||
mac: &str,
|
mac: &Vec<String>,
|
||||||
ipaddr: Ipv4Addr,
|
ipaddr: &Ipv4Addr,
|
||||||
hostname: &str,
|
hostname: &str,
|
||||||
) -> Result<(), DhcpError> {
|
) -> Result<(), DhcpError> {
|
||||||
let mut hostname_split = hostname.split(".");
|
let mut hostname_split = hostname.split(".");
|
||||||
let hostname = hostname_split.next().expect("hostname cannot be empty");
|
let hostname = hostname_split.next().expect("hostname cannot be empty");
|
||||||
let domain_name = hostname_split.collect::<Vec<&str>>().join(".");
|
let domain_name = hostname_split.collect::<Vec<&str>>().join(".");
|
||||||
|
|
||||||
if !Self::is_valid_mac(mac) {
|
if let Some(m) = mac.iter().find(|m| !Self::is_valid_mac(m)) {
|
||||||
return Err(DhcpError::InvalidMacAddress(mac.to_string()));
|
return Err(DhcpError::InvalidMacAddress(m.to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let ip_str = ipaddr.to_string();
|
let ip_str = ipaddr.to_string();
|
||||||
@ -120,17 +120,19 @@ impl<'a> DhcpConfigDnsMasq<'a> {
|
|||||||
let mut all_indices: Vec<&usize> = ip_set.union(&hostname_set).collect();
|
let mut all_indices: Vec<&usize> = ip_set.union(&hostname_set).collect();
|
||||||
all_indices.sort();
|
all_indices.sort();
|
||||||
|
|
||||||
|
let mac_list = mac.join(",");
|
||||||
|
|
||||||
match all_indices.len() {
|
match all_indices.len() {
|
||||||
0 => {
|
0 => {
|
||||||
info!(
|
info!(
|
||||||
"Creating new static host for {} ({}) with MAC {}",
|
"Creating new static host for {} ({}) with MAC {}",
|
||||||
hostname, ipaddr, mac
|
hostname, ipaddr, mac_list
|
||||||
);
|
);
|
||||||
let new_host = DnsmasqHost {
|
let new_host = DnsmasqHost {
|
||||||
uuid: Uuid::new_v4().to_string(),
|
uuid: Uuid::new_v4().to_string(),
|
||||||
host: hostname.to_string(),
|
host: hostname.to_string(),
|
||||||
ip: ip_str.into(),
|
ip: ip_str.into(),
|
||||||
hwaddr: mac.to_string().into(),
|
hwaddr: mac_list.into(),
|
||||||
local: MaybeString::from("1"),
|
local: MaybeString::from("1"),
|
||||||
ignore: Some(0),
|
ignore: Some(0),
|
||||||
domain: domain_name.into(),
|
domain: domain_name.into(),
|
||||||
@ -145,38 +147,40 @@ impl<'a> DhcpConfigDnsMasq<'a> {
|
|||||||
if host_to_modify_ip != ip_str {
|
if host_to_modify_ip != ip_str {
|
||||||
warn!(
|
warn!(
|
||||||
"Hostname '{}' already exists with a different IP ({}). Setting new IP {ip_str}. Appending MAC {}.",
|
"Hostname '{}' already exists with a different IP ({}). Setting new IP {ip_str}. Appending MAC {}.",
|
||||||
hostname, host_to_modify_ip, mac
|
hostname, host_to_modify_ip, mac_list
|
||||||
);
|
);
|
||||||
host_to_modify.ip.content = Some(ip_str);
|
host_to_modify.ip.content = Some(ip_str);
|
||||||
} else if host_to_modify.host != hostname {
|
} else if host_to_modify.host != hostname {
|
||||||
warn!(
|
warn!(
|
||||||
"IP {} already exists with a different hostname ('{}'). Setting hostname to {hostname}. Appending MAC {}.",
|
"IP {} already exists with a different hostname ('{}'). Setting hostname to {hostname}. Appending MAC {}.",
|
||||||
ipaddr, host_to_modify.host, mac
|
ipaddr, host_to_modify.host, mac_list
|
||||||
);
|
);
|
||||||
host_to_modify.host = hostname.to_string();
|
host_to_modify.host = hostname.to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for single_mac in mac.iter() {
|
||||||
if !host_to_modify
|
if !host_to_modify
|
||||||
.hwaddr
|
.hwaddr
|
||||||
.content_string()
|
.content_string()
|
||||||
.split(',')
|
.split(',')
|
||||||
.any(|m| m.eq_ignore_ascii_case(mac))
|
.any(|m| m.eq_ignore_ascii_case(single_mac))
|
||||||
{
|
{
|
||||||
info!(
|
info!(
|
||||||
"Appending MAC {} to existing static host for {} ({})",
|
"Appending MAC {} to existing static host for {} ({})",
|
||||||
mac, host_to_modify.host, host_to_modify_ip
|
single_mac, host_to_modify.host, host_to_modify_ip
|
||||||
);
|
);
|
||||||
let mut updated_macs = host_to_modify.hwaddr.content_string().to_string();
|
let mut updated_macs = host_to_modify.hwaddr.content_string().to_string();
|
||||||
updated_macs.push(',');
|
updated_macs.push(',');
|
||||||
updated_macs.push_str(mac);
|
updated_macs.push_str(single_mac);
|
||||||
host_to_modify.hwaddr.content = updated_macs.into();
|
host_to_modify.hwaddr.content = updated_macs.into();
|
||||||
} else {
|
} else {
|
||||||
info!(
|
debug!(
|
||||||
"MAC {} already present in static host entry for {} ({}). No changes made.",
|
"MAC {} already present in static host entry for {} ({}). No changes made.",
|
||||||
mac, host_to_modify.host, host_to_modify_ip
|
single_mac, host_to_modify.host, host_to_modify_ip
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(DhcpError::Configuration(format!(
|
return Err(DhcpError::Configuration(format!(
|
||||||
"Configuration conflict: Found multiple host entries matching IP {} and/or hostname '{}'. Cannot resolve automatically.",
|
"Configuration conflict: Found multiple host entries matching IP {} and/or hostname '{}'. Cannot resolve automatically.",
|
||||||
|
Loading…
Reference in New Issue
Block a user