Compare commits
1 Commits
a353249eec
...
0070373714
Author | SHA1 | Date | |
---|---|---|---|
0070373714 |
@ -0,0 +1,20 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT host_id FROM host_role_mapping WHERE role = ?",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "host_id",
|
||||
"ordinal": 0,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "2ea29df2326f7c84bd4100ad510a3fd4878dc2e217dc83f9bf45a402dfd62a91"
|
||||
}
|
@ -16,7 +16,7 @@
|
||||
{
|
||||
"name": "data: Json<PhysicalHost>",
|
||||
"ordinal": 2,
|
||||
"type_info": "Null"
|
||||
"type_info": "Blob"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
|
@ -50,12 +50,12 @@ pub async fn get_topology() -> HAClusterTopology {
|
||||
dhcp_server: opnsense.clone(),
|
||||
dns_server: opnsense.clone(),
|
||||
control_plane: vec![LogicalHost {
|
||||
ip: ip!("10.100.8.20"),
|
||||
ip: ip!("192.168.1.20"),
|
||||
name: "cp0".to_string(),
|
||||
}],
|
||||
bootstrap_host: LogicalHost {
|
||||
ip: ip!("10.100.8.20"),
|
||||
name: "cp0".to_string(),
|
||||
ip: ip!("192.168.1.20"),
|
||||
name: "bootstrap".to_string(),
|
||||
},
|
||||
workers: vec![],
|
||||
switch: vec![],
|
||||
|
@ -225,7 +225,6 @@ impl PhysicalHost {
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
#[derive(new, Serialize)]
|
||||
pub struct ManualManagementInterface;
|
||||
|
||||
|
@ -29,6 +29,7 @@ pub trait InventoryRepository: Send + Sync + 'static {
|
||||
async fn save(&self, host: &PhysicalHost) -> Result<(), RepoError>;
|
||||
async fn get_latest_by_id(&self, host_id: &str) -> Result<Option<PhysicalHost>, RepoError>;
|
||||
async fn get_all_hosts(&self) -> Result<Vec<PhysicalHost>, RepoError>;
|
||||
async fn get_host_for_role(&self, role: HostRole) -> Result<Vec<PhysicalHost>, RepoError>;
|
||||
async fn save_role_mapping(
|
||||
&self,
|
||||
role: &HostRole,
|
||||
|
@ -46,14 +46,15 @@ impl InventoryRepository for SqliteInventoryRepository {
|
||||
}
|
||||
|
||||
async fn get_latest_by_id(&self, host_id: &str) -> Result<Option<PhysicalHost>, RepoError> {
|
||||
let _row = sqlx::query_as!(
|
||||
let row = sqlx::query_as!(
|
||||
DbHost,
|
||||
r#"SELECT id, version_id, data as "data: Json<PhysicalHost>" FROM physical_hosts WHERE id = ? ORDER BY version_id DESC LIMIT 1"#,
|
||||
host_id
|
||||
)
|
||||
.fetch_optional(&self.pool)
|
||||
.await?;
|
||||
todo!()
|
||||
|
||||
Ok(row.map(|r| r.data.0))
|
||||
}
|
||||
|
||||
async fn get_all_hosts(&self) -> Result<Vec<PhysicalHost>, RepoError> {
|
||||
@ -107,6 +108,36 @@ impl InventoryRepository for SqliteInventoryRepository {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
async fn get_host_for_role(&self, role: HostRole) -> Result<Vec<PhysicalHost>, RepoError> {
|
||||
struct HostIdRow {
|
||||
host_id: String,
|
||||
}
|
||||
|
||||
let role_str = format!("{:?}", role);
|
||||
|
||||
let host_id_rows = sqlx::query_as!(
|
||||
HostIdRow,
|
||||
"SELECT host_id FROM host_role_mapping WHERE role = ?",
|
||||
role_str
|
||||
)
|
||||
.fetch_all(&self.pool)
|
||||
.await?;
|
||||
|
||||
let mut hosts = Vec::with_capacity(host_id_rows.len());
|
||||
for row in host_id_rows {
|
||||
match self.get_latest_by_id(&row.host_id).await? {
|
||||
Some(host) => hosts.push(host),
|
||||
None => {
|
||||
log::warn!(
|
||||
"Found a role mapping for host_id '{}', but the host does not exist in the physical_hosts table. This may indicate a data integrity issue.",
|
||||
row.host_id
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(hosts)
|
||||
}
|
||||
}
|
||||
|
||||
use sqlx::types::Json;
|
||||
@ -115,4 +146,3 @@ struct DbHost {
|
||||
id: String,
|
||||
version_id: String,
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use async_trait::async_trait;
|
||||
use derive_new::new;
|
||||
use harmony_types::id::Id;
|
||||
use log::info;
|
||||
use log::{info, trace};
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::{
|
||||
@ -177,7 +177,7 @@ impl DhcpHostBindingInterpret {
|
||||
.collect();
|
||||
info!("DHCPStaticEntry : {:?}", dhcp_entries);
|
||||
|
||||
info!("DHCP server : {:?}", dhcp_server);
|
||||
trace!("DHCP server : {:?}", dhcp_server);
|
||||
|
||||
let number_new_entries = dhcp_entries.len();
|
||||
|
||||
|
@ -411,11 +411,22 @@ impl OKDSetup02BootstrapInterpret {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_bootstrap_node<'a>(&self, inventory: &'a Inventory) -> &'a PhysicalHost {
|
||||
inventory
|
||||
.worker_host
|
||||
.first()
|
||||
.expect("At least one worker host is required to be used as bootstrap node")
|
||||
async fn get_bootstrap_node(
|
||||
&self,
|
||||
_inventory: &Inventory,
|
||||
) -> Result<PhysicalHost, InterpretError> {
|
||||
let repo = InventoryRepositoryFactory::build().await?;
|
||||
match repo
|
||||
.get_host_for_role(HostRole::Bootstrap)
|
||||
.await?
|
||||
.into_iter()
|
||||
.next()
|
||||
{
|
||||
Some(host) => Ok(host),
|
||||
None => Err(InterpretError::new(
|
||||
"No bootstrap node available".to_string(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
async fn configure_host_binding(
|
||||
@ -425,7 +436,7 @@ impl OKDSetup02BootstrapInterpret {
|
||||
) -> Result<(), InterpretError> {
|
||||
let binding = HostBinding {
|
||||
logical_host: topology.bootstrap_host.clone(),
|
||||
physical_host: self.get_bootstrap_node(inventory).clone(),
|
||||
physical_host: self.get_bootstrap_node(inventory).await?,
|
||||
};
|
||||
info!("Configuring host binding for bootstrap node {binding:?}");
|
||||
|
||||
@ -444,7 +455,7 @@ impl OKDSetup02BootstrapInterpret {
|
||||
) -> Result<(), InterpretError> {
|
||||
// Placeholder: use Harmony templates to emit {MAC}.ipxe selecting SCOS live + bootstrap ignition.
|
||||
info!("[Bootstrap] Rendering per-MAC PXE for bootstrap node");
|
||||
let bootstrap_node = self.get_bootstrap_node(inventory);
|
||||
let bootstrap_node = self.get_bootstrap_node(inventory).await?;
|
||||
IPxeMacBootFileScore {
|
||||
mac_address: bootstrap_node.get_mac_address(),
|
||||
content: todo!("templace for bootstrap node"),
|
||||
|
Loading…
Reference in New Issue
Block a user