All checks were successful
Run Check Script / check (pull_request) Successful in 59s
Co-authored-by: Jean-Gabriel Gill-Couture <jeangabriel.gc@gmail.com> Co-authored-by: Ian Letourneau <ian@noma.to> Reviewed-on: #130 Reviewed-by: Ian Letourneau <ian@noma.to> Co-authored-by: Jean-Gabriel Gill-Couture <jg@nationtech.io> Co-committed-by: Jean-Gabriel Gill-Couture <jg@nationtech.io>
89 lines
3.0 KiB
Rust
89 lines
3.0 KiB
Rust
use std::net::Ipv4Addr;
|
|
|
|
use harmony_types::net::IpAddress;
|
|
use serde::Serialize;
|
|
|
|
use crate::{
|
|
interpret::Interpret,
|
|
inventory::Inventory,
|
|
modules::dhcp::DhcpScore,
|
|
score::Score,
|
|
topology::{DhcpServer, HAClusterTopology, HostBinding, Topology},
|
|
};
|
|
|
|
#[derive(Debug, Clone, Serialize)]
|
|
pub struct OKDDhcpScore {
|
|
dhcp_score: DhcpScore,
|
|
}
|
|
|
|
impl OKDDhcpScore {
|
|
pub fn new(topology: &HAClusterTopology, inventory: &Inventory) -> Self {
|
|
let mut host_binding: Vec<HostBinding> = topology
|
|
.control_plane
|
|
.iter()
|
|
.enumerate()
|
|
.map(|(index, topology_entry)| HostBinding {
|
|
logical_host: topology_entry.clone(),
|
|
physical_host: inventory
|
|
.control_plane_host
|
|
.get(index)
|
|
.expect("Iventory should contain at least as many physical hosts as topology")
|
|
.clone(),
|
|
})
|
|
.collect();
|
|
|
|
topology
|
|
.workers
|
|
.iter()
|
|
.enumerate()
|
|
.for_each(|(index, topology_entry)| {
|
|
host_binding.push(HostBinding {
|
|
logical_host: topology_entry.clone(),
|
|
physical_host: inventory
|
|
.worker_host
|
|
.get(index)
|
|
.expect("There should be enough worker hosts to fill topology")
|
|
.clone(),
|
|
})
|
|
});
|
|
|
|
let dhcp_server_ip = match topology.dhcp_server.get_ip() {
|
|
std::net::IpAddr::V4(ipv4_addr) => ipv4_addr,
|
|
std::net::IpAddr::V6(_ipv6_addr) => todo!("Support ipv6 someday"),
|
|
};
|
|
|
|
// TODO this could overflow, we should use proper subnet maths here instead of an ip
|
|
// address and guessing the subnet size from there
|
|
let start = Ipv4Addr::from(u32::from(dhcp_server_ip) + 100);
|
|
let end = Ipv4Addr::from(u32::from(dhcp_server_ip) + 150);
|
|
|
|
Self {
|
|
// TODO : we should add a tftp server to the topology instead of relying on the
|
|
// router address, this is leaking implementation details
|
|
dhcp_score: DhcpScore {
|
|
host_binding,
|
|
next_server: Some(topology.router.get_gateway()),
|
|
boot_filename: None,
|
|
filename: Some("undionly.kpxe".to_string()),
|
|
filename64: Some("ipxe.efi".to_string()),
|
|
filenameipxe: Some(format!(
|
|
"http://{}:8080/boot.ipxe",
|
|
topology.router.get_gateway()
|
|
)),
|
|
dhcp_range: (IpAddress::from(start), IpAddress::from(end)),
|
|
domain: Some(topology.domain_name.clone()),
|
|
},
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<T: Topology + DhcpServer> Score<T> for OKDDhcpScore {
|
|
fn create_interpret(&self) -> Box<dyn Interpret<T>> {
|
|
self.dhcp_score.create_interpret()
|
|
}
|
|
|
|
fn name(&self) -> String {
|
|
"OKDDhcpScore".to_string()
|
|
}
|
|
}
|