feat: support new configurable field in dhcp config: filename

This commit is contained in:
Sylvain Tremblay 2025-03-01 08:56:41 -05:00
parent d5125dd811
commit 3f77bc7aef
8 changed files with 52 additions and 4 deletions

View File

@ -121,6 +121,9 @@ impl DhcpServer for DummyInfra {
async fn set_boot_filename(&self, _boot_filename: &str) -> Result<(), ExecutorError> { async fn set_boot_filename(&self, _boot_filename: &str) -> Result<(), ExecutorError> {
unimplemented!("{}", UNIMPLEMENTED_DUMMY_INFRA) unimplemented!("{}", UNIMPLEMENTED_DUMMY_INFRA)
} }
async fn set_filename(&self, _filename: &str) -> Result<(), ExecutorError> {
unimplemented!("{}", UNIMPLEMENTED_DUMMY_INFRA)
}
fn get_ip(&self) -> IpAddress { fn get_ip(&self) -> IpAddress {
unimplemented!("{}", UNIMPLEMENTED_DUMMY_INFRA) unimplemented!("{}", UNIMPLEMENTED_DUMMY_INFRA)
} }

View File

@ -48,6 +48,7 @@ pub trait DhcpServer: Send + Sync {
async fn list_static_mappings(&self) -> Vec<(MacAddress, IpAddress)>; async fn list_static_mappings(&self) -> Vec<(MacAddress, IpAddress)>;
async fn set_next_server(&self, ip: IpAddress) -> Result<(), ExecutorError>; async fn set_next_server(&self, ip: IpAddress) -> Result<(), ExecutorError>;
async fn set_boot_filename(&self, boot_filename: &str) -> Result<(), ExecutorError>; async fn set_boot_filename(&self, boot_filename: &str) -> Result<(), ExecutorError>;
async fn set_filename(&self, filename: &str) -> Result<(), ExecutorError>;
fn get_ip(&self) -> IpAddress; fn get_ip(&self) -> IpAddress;
fn get_host(&self) -> LogicalHost; fn get_host(&self) -> LogicalHost;
async fn commit_config(&self) -> Result<(), ExecutorError>; async fn commit_config(&self) -> Result<(), ExecutorError>;

View File

@ -69,4 +69,14 @@ impl DhcpServer for OPNSenseFirewall {
Ok(()) Ok(())
} }
async fn set_filename(&self, filename: &str) -> Result<(), ExecutorError> {
{
let mut writable_opnsense = self.opnsense_config.write().await;
writable_opnsense.dhcp().set_filename(filename);
debug!("OPNsense dhcp server set filename {filename}");
}
Ok(())
}
} }

View File

@ -18,6 +18,8 @@ pub struct DhcpScore {
pub host_binding: Vec<HostBinding>, pub host_binding: Vec<HostBinding>,
pub next_server: Option<IpAddress>, pub next_server: Option<IpAddress>,
pub boot_filename: Option<String>, pub boot_filename: Option<String>,
pub filename: Option<String>,
pub filename_ipxe: Option<String>,
} }
impl Score for DhcpScore { impl Score for DhcpScore {
@ -125,8 +127,21 @@ impl DhcpInterpret {
None => Outcome::noop(), None => Outcome::noop(),
}; };
let filename_outcome = match &self.score.filename {
Some(filename) => {
let dhcp_server = Arc::new(topology.dhcp_server.clone());
dhcp_server.set_filename(&filename).await?;
Outcome::new(
InterpretStatus::SUCCESS,
format!("Dhcp Interpret Set filename to {filename}"),
)
}
None => Outcome::noop(),
};
if next_server_outcome.status == InterpretStatus::NOOP if next_server_outcome.status == InterpretStatus::NOOP
&& boot_filename_outcome.status == InterpretStatus::NOOP && boot_filename_outcome.status == InterpretStatus::NOOP
&& filename_outcome.status == InterpretStatus::NOOP
{ {
return Ok(Outcome::noop()); return Ok(Outcome::noop());
} }
@ -134,8 +149,8 @@ impl DhcpInterpret {
Ok(Outcome::new( Ok(Outcome::new(
InterpretStatus::SUCCESS, InterpretStatus::SUCCESS,
format!( format!(
"Dhcp Interpret Set next boot to {:?} and boot_filename to {:?}", "Dhcp Interpret Set next boot to [{:?}], boot_filename to [{:?}], filename to [{:?}]",
self.score.boot_filename, self.score.boot_filename self.score.boot_filename, self.score.boot_filename, self.score.filename
), ),
)) ))
} }

View File

@ -41,6 +41,8 @@ impl OKDBootstrapDhcpScore {
// router address, this is leaking implementation details // router address, this is leaking implementation details
Some(topology.router.get_gateway()), Some(topology.router.get_gateway()),
Some("bootx64.efi".to_string()), Some("bootx64.efi".to_string()),
Some(format!("{}:8080/boot.ipxe", topology.router.get_gateway())),
Some("undionly.kpxe".to_string()),
), ),
} }
} }

View File

@ -32,7 +32,9 @@ impl OKDDhcpScore {
dhcp_score: DhcpScore { dhcp_score: DhcpScore {
host_binding, host_binding,
next_server: Some(topology.router.get_gateway()), next_server: Some(topology.router.get_gateway()),
boot_filename: Some("bootx64.efi".to_string()), boot_filename: None,
filename_ipxe: Some(format!("{}:8080/boot.ipxe", topology.router.get_gateway())),
filename: Some("undionly.kpxe".to_string()),
}, },
} }
} }

View File

@ -22,6 +22,7 @@ pub struct DhcpInterface {
pub nextserver: Option<String>, pub nextserver: Option<String>,
pub filename64: Option<String>, pub filename64: Option<String>,
pub filename: Option<String>, pub filename: Option<String>,
pub filenameipxe: Option<String>,
#[yaserde(rename = "ddnsdomainalgorithm")] #[yaserde(rename = "ddnsdomainalgorithm")]
pub ddns_domain_algorithm: Option<MaybeString>, pub ddns_domain_algorithm: Option<MaybeString>,
#[yaserde(rename = "numberoptions")] #[yaserde(rename = "numberoptions")]

View File

@ -179,7 +179,21 @@ impl<'a> DhcpConfig<'a> {
pub fn set_boot_filename(&mut self, boot_filename: &str) { pub fn set_boot_filename(&mut self, boot_filename: &str) {
self.enable_netboot(); self.enable_netboot();
self.get_lan_dhcpd().filename64 = Some(boot_filename.to_string());
self.get_lan_dhcpd().bootfilename = Some(boot_filename.to_string()); self.get_lan_dhcpd().bootfilename = Some(boot_filename.to_string());
} }
pub fn set_filename(&mut self, filename: &str) {
self.enable_netboot();
self.get_lan_dhcpd().filename = Some(filename.to_string());
}
pub fn set_filename64(&mut self, filename64: &str) {
self.enable_netboot();
self.get_lan_dhcpd().filename64 = Some(filename64.to_string());
}
pub fn set_filenameipxe(&mut self, filenameipxe: &str) {
self.enable_netboot();
self.get_lan_dhcpd().filenameipxe = Some(filenameipxe.to_string());
}
} }