diff --git a/.sqlx/query-8d247918eca10a88b784ee353db090c94a222115c543231f2140cba27bd0f067.json b/.sqlx/query-8d247918eca10a88b784ee353db090c94a222115c543231f2140cba27bd0f067.json new file mode 100644 index 0000000..ba998bc --- /dev/null +++ b/.sqlx/query-8d247918eca10a88b784ee353db090c94a222115c543231f2140cba27bd0f067.json @@ -0,0 +1,32 @@ +{ + "db_name": "SQLite", + "query": "\n SELECT\n p1.id,\n p1.version_id,\n p1.data as \"data: Json\"\n FROM\n physical_hosts p1\n INNER JOIN (\n SELECT\n id,\n MAX(version_id) AS max_version\n FROM\n physical_hosts\n GROUP BY\n id\n ) p2 ON p1.id = p2.id AND p1.version_id = p2.max_version\n ", + "describe": { + "columns": [ + { + "name": "id", + "ordinal": 0, + "type_info": "Text" + }, + { + "name": "version_id", + "ordinal": 1, + "type_info": "Text" + }, + { + "name": "data: Json", + "ordinal": 2, + "type_info": "Null" + } + ], + "parameters": { + "Right": 0 + }, + "nullable": [ + false, + false, + false + ] + }, + "hash": "8d247918eca10a88b784ee353db090c94a222115c543231f2140cba27bd0f067" +} diff --git a/.sqlx/query-df7a7c9cfdd0972e2e0ce7ea444ba8bc9d708a4fb89d5593a0be2bbebde62aff.json b/.sqlx/query-df7a7c9cfdd0972e2e0ce7ea444ba8bc9d708a4fb89d5593a0be2bbebde62aff.json new file mode 100644 index 0000000..eb799e9 --- /dev/null +++ b/.sqlx/query-df7a7c9cfdd0972e2e0ce7ea444ba8bc9d708a4fb89d5593a0be2bbebde62aff.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "\n INSERT INTO host_role_mapping (host_id, role)\n VALUES (?, ?)\n ", + "describe": { + "columns": [], + "parameters": { + "Right": 2 + }, + "nullable": [] + }, + "hash": "df7a7c9cfdd0972e2e0ce7ea444ba8bc9d708a4fb89d5593a0be2bbebde62aff" +} diff --git a/harmony/src/domain/hardware/mod.rs b/harmony/src/domain/hardware/mod.rs index 4ad7836..e605380 100644 --- a/harmony/src/domain/hardware/mod.rs +++ b/harmony/src/domain/hardware/mod.rs @@ -10,7 +10,7 @@ pub type HostGroup = Vec; pub type SwitchGroup = Vec; pub type FirewallGroup = Vec; -#[derive(Debug, Clone, Serialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct PhysicalHost { pub id: Id, pub category: HostCategory, @@ -225,14 +225,6 @@ impl PhysicalHost { // } // } -impl<'de> Deserialize<'de> for PhysicalHost { - fn deserialize(_deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - todo!() - } -} #[derive(new, Serialize)] pub struct ManualManagementInterface; @@ -277,7 +269,7 @@ where } } -#[derive(Debug, Clone, Serialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub enum HostCategory { Server, Firewall, @@ -295,7 +287,7 @@ pub struct Switch { _management_interface: NetworkInterface, } -#[derive(Debug, new, Clone, Serialize)] +#[derive(Debug, new, Clone, Serialize, Deserialize)] pub struct Label { pub name: String, pub value: String, diff --git a/harmony/src/domain/inventory/mod.rs b/harmony/src/domain/inventory/mod.rs index 894d0f2..b0250e1 100644 --- a/harmony/src/domain/inventory/mod.rs +++ b/harmony/src/domain/inventory/mod.rs @@ -17,6 +17,7 @@ impl InventoryFilter { use derive_new::new; use log::info; +use serde::{Deserialize, Serialize}; use crate::hardware::{ManagementInterface, ManualManagementInterface}; @@ -62,6 +63,7 @@ impl Inventory { } } +#[derive(Debug, Serialize, Deserialize, sqlx::Type)] pub enum HostRole { Bootstrap, ControlPlane, diff --git a/harmony/src/infra/inventory/sqlite.rs b/harmony/src/infra/inventory/sqlite.rs index 63c662c..b678b0e 100644 --- a/harmony/src/infra/inventory/sqlite.rs +++ b/harmony/src/infra/inventory/sqlite.rs @@ -57,7 +57,32 @@ impl InventoryRepository for SqliteInventoryRepository { } async fn get_all_hosts(&self) -> Result, RepoError> { - todo!() + let db_hosts = sqlx::query_as!( + DbHost, + r#" + SELECT + p1.id, + p1.version_id, + p1.data as "data: Json" + FROM + physical_hosts p1 + INNER JOIN ( + SELECT + id, + MAX(version_id) AS max_version + FROM + physical_hosts + GROUP BY + id + ) p2 ON p1.id = p2.id AND p1.version_id = p2.max_version + "# + ) + .fetch_all(&self.pool) + .await?; + + let hosts = db_hosts.into_iter().map(|row| row.data.0).collect(); + + Ok(hosts) } async fn save_role_mapping( @@ -65,13 +90,29 @@ impl InventoryRepository for SqliteInventoryRepository { role: &HostRole, host: &PhysicalHost, ) -> Result<(), RepoError> { - todo!("save role, host.id in the table host_role_mapping") + let host_id = host.id.to_string(); + + sqlx::query!( + r#" + INSERT INTO host_role_mapping (host_id, role) + VALUES (?, ?) + "#, + host_id, + role + ) + .execute(&self.pool) + .await?; + + info!("Saved role mapping for host '{}' as '{:?}'", host.id, role); + + Ok(()) } } use sqlx::types::Json; struct DbHost { data: Json, - id: Id, - version_id: Id, + id: String, + version_id: String, } + diff --git a/harmony/src/modules/okd/installation.rs b/harmony/src/modules/okd/installation.rs index ca0d704..e61de25 100644 --- a/harmony/src/modules/okd/installation.rs +++ b/harmony/src/modules/okd/installation.rs @@ -284,7 +284,7 @@ impl Interpret for OKDSetup01InventoryInterpret { "Launching discovery agent, make sure that your nodes are successfully PXE booted and running inventory agent. They should answer on `http://:8080/inventory`" ); LaunchDiscoverInventoryAgentScore { - discovery_timeout: Some(60), + discovery_timeout: None, } .interpret(inventory, topology) .await?; diff --git a/harmony_types/src/id.rs b/harmony_types/src/id.rs index 98cf1b9..2cb2674 100644 --- a/harmony_types/src/id.rs +++ b/harmony_types/src/id.rs @@ -48,6 +48,12 @@ impl From for Id { } } +impl From for String { + fn from(value: Id) -> Self { + value.to_string() + } +} + impl std::fmt::Display for Id { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str(&self.value) diff --git a/migrations/20250902035357_Host_role_mapping.sql b/migrations/20250902035357_Host_role_mapping.sql new file mode 100644 index 0000000..dce122d --- /dev/null +++ b/migrations/20250902035357_Host_role_mapping.sql @@ -0,0 +1,5 @@ +CREATE TABLE IF NOT EXISTS host_role_mapping ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + host_id TEXT NOT NULL, + role TEXT NOT NULL +);