diff --git a/.sqlx/query-934035c7ca6e064815393e4e049a7934b0a7fac04a4fe4b2a354f0443d630990.json b/.sqlx/query-934035c7ca6e064815393e4e049a7934b0a7fac04a4fe4b2a354f0443d630990.json new file mode 100644 index 0000000..2d1f1ba --- /dev/null +++ b/.sqlx/query-934035c7ca6e064815393e4e049a7934b0a7fac04a4fe4b2a354f0443d630990.json @@ -0,0 +1,32 @@ +{ + "db_name": "SQLite", + "query": "SELECT id, version_id, data as \"data: Json\" FROM physical_hosts WHERE id = ? ORDER BY version_id DESC LIMIT 1", + "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": 1 + }, + "nullable": [ + false, + false, + false + ] + }, + "hash": "934035c7ca6e064815393e4e049a7934b0a7fac04a4fe4b2a354f0443d630990" +} diff --git a/.sqlx/query-f10f615ee42129ffa293e46f2f893d65a237d31d24b74a29c6a8d8420d255ab8.json b/.sqlx/query-f10f615ee42129ffa293e46f2f893d65a237d31d24b74a29c6a8d8420d255ab8.json new file mode 100644 index 0000000..7df288a --- /dev/null +++ b/.sqlx/query-f10f615ee42129ffa293e46f2f893d65a237d31d24b74a29c6a8d8420d255ab8.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "INSERT INTO physical_hosts (id, version_id, data) VALUES (?, ?, ?)", + "describe": { + "columns": [], + "parameters": { + "Right": 3 + }, + "nullable": [] + }, + "hash": "f10f615ee42129ffa293e46f2f893d65a237d31d24b74a29c6a8d8420d255ab8" +} diff --git a/Cargo.lock b/Cargo.lock index ad3f964..66d3cd8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,7 +65,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" dependencies = [ "quote", - "syn", + "syn 2.0.105", ] [[package]] @@ -182,7 +182,7 @@ dependencies = [ "actix-router", "proc-macro2", "quote", - "syn", + "syn 2.0.105", ] [[package]] @@ -249,6 +249,15 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "aho-corasick" +version = "0.6.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81ce3d38065e618af2d7b77e10c5ad9a069859b4be3c2250f674af3840d9c8a5" +dependencies = [ + "memchr", +] + [[package]] name = "aho-corasick" version = "1.1.3" @@ -362,6 +371,48 @@ version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" +[[package]] +name = "askama" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f75363874b771be265f4ffe307ca705ef6f3baa19011c149da8674a87f1b75c4" +dependencies = [ + "askama_derive", + "itoa", + "percent-encoding", + "serde", + "serde_json", +] + +[[package]] +name = "askama_derive" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "129397200fe83088e8a68407a8e2b1f826cf0086b21ccdb866a722c8bcd3a94f" +dependencies = [ + "askama_parser", + "basic-toml", + "memchr", + "proc-macro2", + "quote", + "rustc-hash", + "serde", + "serde_derive", + "syn 2.0.105", +] + +[[package]] +name = "askama_parser" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6ab5630b3d5eaf232620167977f95eb51f3432fc76852328774afbd242d4358" +dependencies = [ + "memchr", + "serde", + "serde_derive", + "winnow", +] + [[package]] name = "assert_cmd" version = "2.0.17" @@ -409,7 +460,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.105", ] [[package]] @@ -420,7 +471,16 @@ checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.105", +] + +[[package]] +name = "atoi" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" +dependencies = [ + "num-traits", ] [[package]] @@ -485,6 +545,15 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" +[[package]] +name = "basic-toml" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba62675e8242a4c4e806d12f11d136e626e6c8361d6b829310732241652a178a" +dependencies = [ + "serde", +] + [[package]] name = "bcrypt-pbkdf" version = "0.10.0" @@ -581,7 +650,7 @@ dependencies = [ "tokio-util", "tower-service", "url", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -655,6 +724,12 @@ dependencies = [ "bytes", ] +[[package]] +name = "c_linked_list" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4964518bd3b4a8190e832886cdc0da9794f12e8e6c1613a9e90ff331c4c8724b" + [[package]] name = "camino" version = "1.1.10" @@ -798,9 +873,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.40" +version = "4.5.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f" +checksum = "2c5e4fcf9c21d2e544ca1ee9d8552de13019a42aa7dbf32747fa7aaf1df76e57" dependencies = [ "clap_builder", "clap_derive", @@ -808,9 +883,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.40" +version = "4.5.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e" +checksum = "fecb53a0e6fcfb055f686001bc2e2592fa527efaf38dbe81a6a9563562e57d41" dependencies = [ "anstream", "anstyle", @@ -820,14 +895,14 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.40" +version = "4.5.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce" +checksum = "14cb31bb0a7d536caef2639baa7fad459e15c3144efefa6dbd1c84562c4739f6" dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 2.0.105", ] [[package]] @@ -986,6 +1061,21 @@ dependencies = [ "libc", ] +[[package]] +name = "crc" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9710d3b3739c2e349eb44fe848ad0b7c8cb1e42bd87ee49371df2f7acaf3e675" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + [[package]] name = "crc32fast" version = "1.4.2" @@ -1023,6 +1113,15 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-queue" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.21" @@ -1042,7 +1141,7 @@ dependencies = [ "parking_lot", "signal-hook", "signal-hook-mio", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -1059,7 +1158,7 @@ dependencies = [ "rustix 0.38.44", "signal-hook", "signal-hook-mio", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -1068,7 +1167,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" dependencies = [ - "winapi", + "winapi 0.3.9", ] [[package]] @@ -1139,7 +1238,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.105", ] [[package]] @@ -1163,7 +1262,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn", + "syn 2.0.105", ] [[package]] @@ -1174,7 +1273,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core", "quote", - "syn", + "syn 2.0.105", ] [[package]] @@ -1212,7 +1311,7 @@ checksum = "2cdc8d50f426189eef89dac62fabfa0abb27d5cc008f25bf4156a0203325becc" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.105", ] [[package]] @@ -1232,7 +1331,7 @@ checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.105", "unicode-xid", ] @@ -1298,7 +1397,20 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.105", +] + +[[package]] +name = "dmidecode" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e529c1bd93d69804dc1e0a0c73aacd12bb13c7a18c659497411abdc6acf5e5f" +dependencies = [ + "aho-corasick 0.6.10", + "bitflags 1.3.2", + "failure", + "failure_derive", + "lazy_static", ] [[package]] @@ -1327,9 +1439,15 @@ dependencies = [ "anyhow", "proc-macro2", "quote", - "syn", + "syn 2.0.105", ] +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + [[package]] name = "dyn-clone" version = "1.0.19" @@ -1384,7 +1502,7 @@ dependencies = [ "enum-ordinalize", "proc-macro2", "quote", - "syn", + "syn 2.0.105", ] [[package]] @@ -1392,6 +1510,9 @@ name = "either" version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +dependencies = [ + "serde", +] [[package]] name = "elliptic-curve" @@ -1455,7 +1576,7 @@ checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.105", ] [[package]] @@ -1507,6 +1628,17 @@ dependencies = [ "windows-sys 0.60.2", ] +[[package]] +name = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys 0.48.0", +] + [[package]] name = "event-listener" version = "5.4.0" @@ -1539,6 +1671,7 @@ dependencies = [ "env_logger", "harmony", "harmony_cli", + "harmony_types", "logging", "tokio", "url", @@ -1600,6 +1733,7 @@ dependencies = [ "harmony", "harmony_cli", "harmony_macros", + "harmony_types", "tokio", "url", ] @@ -1611,6 +1745,7 @@ dependencies = [ "cidr", "harmony", "harmony_cli", + "harmony_types", "tokio", "url", ] @@ -1655,6 +1790,24 @@ dependencies = [ "url", ] +[[package]] +name = "example-pxe" +version = "0.1.0" +dependencies = [ + "cidr", + "env_logger", + "harmony", + "harmony_cli", + "harmony_macros", + "harmony_secret", + "harmony_secret_derive", + "harmony_types", + "log", + "serde", + "tokio", + "url", +] + [[package]] name = "example-rust" version = "0.1.0" @@ -1729,6 +1882,28 @@ dependencies = [ "once_cell", ] +[[package]] +name = "failure" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" +dependencies = [ + "backtrace", + "failure_derive", +] + +[[package]] +name = "failure_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "synstructure 0.12.6", +] + [[package]] name = "fastrand" version = "2.3.0" @@ -1773,6 +1948,17 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "flume" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" +dependencies = [ + "futures-core", + "futures-sink", + "spin", +] + [[package]] name = "flurry" version = "0.5.2" @@ -1797,21 +1983,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "form_urlencoded" version = "1.2.1" @@ -1879,6 +2050,17 @@ dependencies = [ "futures-util", ] +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot", +] + [[package]] name = "futures-io" version = "0.3.31" @@ -1893,7 +2075,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.105", ] [[package]] @@ -1944,6 +2126,12 @@ dependencies = [ "byteorder", ] +[[package]] +name = "gcc" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" + [[package]] name = "generic-array" version = "0.14.7" @@ -1955,6 +2143,28 @@ dependencies = [ "zeroize", ] +[[package]] +name = "get_if_addrs" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abddb55a898d32925f3148bd281174a68eeb68bbfd9a5938a57b18f506ee4ef7" +dependencies = [ + "c_linked_list", + "get_if_addrs-sys", + "libc", + "winapi 0.2.8", +] + +[[package]] +name = "get_if_addrs-sys" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d04f9fb746cf36b191c00f3ede8bde9c8e64f9f4b05ae2694a9ccf5e3f5ab48" +dependencies = [ + "gcc", + "libc", +] + [[package]] name = "getrandom" version = "0.2.16" @@ -2063,6 +2273,7 @@ dependencies = [ name = "harmony" version = "0.1.0" dependencies = [ + "askama", "async-trait", "base64 0.22.1", "bollard", @@ -2077,8 +2288,9 @@ dependencies = [ "env_logger", "fqdn", "futures-util", - "harmony-secret-derive", + "harmony_inventory_agent", "harmony_macros", + "harmony_secret_derive", "harmony_types", "helm-wrapper-rs", "hex", @@ -2088,14 +2300,12 @@ dependencies = [ "kube", "kube-derive", "lazy_static", - "libredfish", "log", "non-blank-string-rs", "once_cell", "opnsense-config", "opnsense-config-xml", "pretty_assertions", - "rand 0.9.1", "reqwest 0.11.27", "russh", "rust-ipmi", @@ -2107,11 +2317,13 @@ dependencies = [ "serde_with", "serde_yaml", "similar", + "sqlx", "strum 0.27.1", "tar", "temp-dir", "temp-file", "tempfile", + "thiserror 2.0.14", "tokio", "tokio-util", "url", @@ -2119,35 +2331,6 @@ dependencies = [ "walkdir", ] -[[package]] -name = "harmony-secret" -version = "0.1.0" -dependencies = [ - "async-trait", - "directories", - "harmony-secret-derive", - "http 1.3.1", - "infisical", - "lazy_static", - "log", - "pretty_assertions", - "serde", - "serde_json", - "tempfile", - "thiserror 2.0.14", - "tokio", -] - -[[package]] -name = "harmony-secret-derive" -version = "0.1.0" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "harmony_cli" version = "0.1.0" @@ -2194,10 +2377,17 @@ version = "0.1.0" dependencies = [ "actix-web", "env_logger", + "harmony_macros", + "harmony_types", + "local-ip-address", "log", + "mdns-sd 0.14.1 (git+https://github.com/jggc/mdns-sd.git?branch=patch-1)", + "reqwest 0.12.20", "serde", "serde_json", "sysinfo", + "thiserror 2.0.14", + "tokio", ] [[package]] @@ -2209,7 +2399,36 @@ dependencies = [ "quote", "serde", "serde_yaml", - "syn", + "syn 2.0.105", +] + +[[package]] +name = "harmony_secret" +version = "0.1.0" +dependencies = [ + "async-trait", + "directories", + "harmony_secret_derive", + "http 1.3.1", + "infisical", + "lazy_static", + "log", + "pretty_assertions", + "serde", + "serde_json", + "tempfile", + "thiserror 2.0.14", + "tokio", +] + +[[package]] +name = "harmony_secret_derive" +version = "0.1.0" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.105", ] [[package]] @@ -2234,7 +2453,9 @@ dependencies = [ name = "harmony_types" version = "0.1.0" dependencies = [ + "rand 0.9.1", "serde", + "url", ] [[package]] @@ -2254,6 +2475,15 @@ dependencies = [ "foldhash", ] +[[package]] +name = "hashlink" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" +dependencies = [ + "hashbrown 0.15.4", +] + [[package]] name = "headers" version = "0.4.1" @@ -2501,12 +2731,12 @@ dependencies = [ "headers", "http 1.3.1", "hyper 1.6.0", - "hyper-rustls", + "hyper-rustls 0.27.7", "hyper-util", "pin-project-lite", "rustls-native-certs 0.7.3", "tokio", - "tokio-rustls", + "tokio-rustls 0.26.2", "tower-service", ] @@ -2522,7 +2752,21 @@ dependencies = [ "pin-project-lite", "tokio", "tower-service", - "winapi", + "winapi 0.3.9", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http 0.2.12", + "hyper 0.14.32", + "rustls 0.21.12", + "tokio", + "tokio-rustls 0.24.1", ] [[package]] @@ -2535,13 +2779,13 @@ dependencies = [ "hyper 1.6.0", "hyper-util", "log", - "rustls", + "rustls 0.23.28", "rustls-native-certs 0.8.1", "rustls-pki-types", "tokio", - "tokio-rustls", + "tokio-rustls 0.26.2", "tower-service", - "webpki-roots", + "webpki-roots 1.0.2", ] [[package]] @@ -2557,35 +2801,6 @@ dependencies = [ "tower-service", ] -[[package]] -name = "hyper-tls" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" -dependencies = [ - "bytes", - "hyper 0.14.32", - "native-tls", - "tokio", - "tokio-native-tls", -] - -[[package]] -name = "hyper-tls" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" -dependencies = [ - "bytes", - "http-body-util", - "hyper 1.6.0", - "hyper-util", - "native-tls", - "tokio", - "tokio-native-tls", - "tower-service", -] - [[package]] name = "hyper-util" version = "0.1.14" @@ -2605,11 +2820,9 @@ dependencies = [ "percent-encoding", "pin-project-lite", "socket2 0.5.10", - "system-configuration 0.6.1", "tokio", "tower-service", "tracing", - "windows-registry", ] [[package]] @@ -2764,6 +2977,16 @@ dependencies = [ "icu_properties", ] +[[package]] +name = "if-addrs" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf39cc0423ee66021dc5eccface85580e4a001e0c5288bae8bea7ecb69225e90" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + [[package]] name = "impl-more" version = "0.1.9" @@ -2830,8 +3053,7 @@ checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd" [[package]] name = "infisical" version = "0.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d97c33b08e22b2f7b9f87a8fc06a7d247442db7bf216ffc6661a74ed8aea658" +source = "git+https://github.com/jggc/rust-sdk.git?branch=patch-1#30d820194d29491411bd14f6c2e18ec500bb0b14" dependencies = [ "base64 0.22.1", "reqwest 0.12.20", @@ -2879,7 +3101,7 @@ dependencies = [ "indoc", "proc-macro2", "quote", - "syn", + "syn 2.0.105", ] [[package]] @@ -2951,7 +3173,7 @@ checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.105", ] [[package]] @@ -3085,14 +3307,14 @@ dependencies = [ "http-body-util", "hyper 1.6.0", "hyper-http-proxy", - "hyper-rustls", + "hyper-rustls 0.27.7", "hyper-timeout", "hyper-util", "jsonpath-rust", "k8s-openapi", "kube-core", "pem", - "rustls", + "rustls 0.23.28", "secrecy", "serde", "serde_json", @@ -3136,7 +3358,7 @@ dependencies = [ "quote", "serde", "serde_json", - "syn", + "syn 2.0.105", ] [[package]] @@ -3193,19 +3415,6 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" -[[package]] -name = "libredfish" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7f0a8985e53d18c60dc82e7b5fa512fd194ea4c0d8bf1409b65cf44f8b0a8d9" -dependencies = [ - "log", - "reqwest 0.11.27", - "serde", - "serde_derive", - "serde_json", -] - [[package]] name = "libredox" version = "0.1.4" @@ -3217,6 +3426,17 @@ dependencies = [ "redox_syscall", ] +[[package]] +name = "libsqlite3-sys" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + [[package]] name = "linux-raw-sys" version = "0.4.15" @@ -3246,6 +3466,18 @@ dependencies = [ "local-waker", ] +[[package]] +name = "local-ip-address" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "656b3b27f8893f7bbf9485148ff9a65f019e3f33bd5cdc87c83cab16b3fd9ec8" +dependencies = [ + "libc", + "neli", + "thiserror 2.0.14", + "windows-sys 0.59.0", +] + [[package]] name = "local-waker" version = "0.1.4" @@ -3301,12 +3533,66 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest", +] + [[package]] name = "md5" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" +[[package]] +name = "mdns" +version = "0.1.0" +dependencies = [ + "clap", + "dmidecode", + "env_logger", + "futures", + "get_if_addrs", + "local-ip-address", + "log", + "mdns-sd 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio", +] + +[[package]] +name = "mdns-sd" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e0a59b04e17a195b0674198b3182931801c4759d00f36acad51b5a97210a692" +dependencies = [ + "fastrand", + "flume", + "if-addrs", + "log", + "mio 1.0.4", + "socket-pktinfo", + "socket2 0.6.0", +] + +[[package]] +name = "mdns-sd" +version = "0.14.1" +source = "git+https://github.com/jggc/mdns-sd.git?branch=patch-1#371b65c0d6207e702dda8a2eb442cff21f0bab90" +dependencies = [ + "fastrand", + "flume", + "if-addrs", + "log", + "mio 1.0.4", + "socket-pktinfo", + "socket2 0.6.0", +] + [[package]] name = "memchr" version = "2.7.5" @@ -3353,20 +3639,28 @@ dependencies = [ ] [[package]] -name = "native-tls" -version = "0.2.14" +name = "neli" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +checksum = "93062a0dce6da2517ea35f301dfc88184ce18d3601ec786a727a87bf535deca9" dependencies = [ + "byteorder", "libc", "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework 2.11.1", - "security-framework-sys", - "tempfile", + "neli-proc-macros", +] + +[[package]] +name = "neli-proc-macros" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c8034b7fbb6f9455b2a96c19e6edf8dc9fc34c70449938d8ee3b4df363f61fe" +dependencies = [ + "either", + "proc-macro2", + "quote", + "serde", + "syn 1.0.109", ] [[package]] @@ -3393,7 +3687,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" dependencies = [ - "winapi", + "winapi 0.3.9", ] [[package]] @@ -3498,7 +3792,7 @@ dependencies = [ "http-body 1.0.1", "http-body-util", "hyper 1.6.0", - "hyper-rustls", + "hyper-rustls 0.27.7", "hyper-timeout", "hyper-util", "jsonwebtoken", @@ -3537,50 +3831,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" -[[package]] -name = "openssl" -version = "0.10.73" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" -dependencies = [ - "bitflags 2.9.1", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "openssl-probe" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" -[[package]] -name = "openssl-sys" -version = "0.9.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - [[package]] name = "opnsense-config" version = "0.1.0" @@ -3600,6 +3856,7 @@ dependencies = [ "tokio", "tokio-stream", "tokio-util", + "uuid", ] [[package]] @@ -3610,7 +3867,7 @@ dependencies = [ "env_logger", "log", "pretty_assertions", - "rand 0.8.5", + "rand 0.9.1", "serde", "thiserror 2.0.14", "tokio", @@ -3803,7 +4060,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn", + "syn 2.0.105", ] [[package]] @@ -3833,7 +4090,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.105", ] [[package]] @@ -4036,7 +4293,7 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash", - "rustls", + "rustls 0.23.28", "socket2 0.5.10", "thiserror 2.0.14", "tokio", @@ -4056,7 +4313,7 @@ dependencies = [ "rand 0.9.1", "ring", "rustc-hash", - "rustls", + "rustls 0.23.28", "rustls-pki-types", "slab", "thiserror 2.0.14", @@ -4237,7 +4494,7 @@ checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.105", ] [[package]] @@ -4246,7 +4503,7 @@ version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ - "aho-corasick", + "aho-corasick 1.1.3", "memchr", "regex-automata", "regex-syntax", @@ -4258,7 +4515,7 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ - "aho-corasick", + "aho-corasick 1.1.3", "memchr", "regex-syntax", ] @@ -4290,28 +4547,29 @@ dependencies = [ "http 0.2.12", "http-body 0.4.6", "hyper 0.14.32", - "hyper-tls 0.5.0", + "hyper-rustls 0.24.2", "ipnet", "js-sys", "log", "mime", - "native-tls", "once_cell", "percent-encoding", "pin-project-lite", + "rustls 0.21.12", "rustls-pemfile 1.0.4", "serde", "serde_json", "serde_urlencoded", "sync_wrapper 0.1.2", - "system-configuration 0.5.1", + "system-configuration", "tokio", - "tokio-native-tls", + "tokio-rustls 0.24.1", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", + "webpki-roots 0.25.4", "winreg", ] @@ -4323,7 +4581,6 @@ checksum = "eabf4c97d9130e2bf606614eb937e86edac8292eaa6f422f995d7e8de1eb1813" dependencies = [ "base64 0.22.1", "bytes", - "encoding_rs", "futures-channel", "futures-core", "futures-util", @@ -4332,25 +4589,21 @@ dependencies = [ "http-body 1.0.1", "http-body-util", "hyper 1.6.0", - "hyper-rustls", - "hyper-tls 0.6.0", + "hyper-rustls 0.27.7", "hyper-util", "js-sys", "log", - "mime", - "native-tls", "percent-encoding", "pin-project-lite", "quinn", - "rustls", + "rustls 0.23.28", "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", "sync_wrapper 1.0.2", "tokio", - "tokio-native-tls", - "tokio-rustls", + "tokio-rustls 0.26.2", "tokio-util", "tower", "tower-http", @@ -4360,7 +4613,7 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots", + "webpki-roots 1.0.2", ] [[package]] @@ -4458,7 +4711,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fadd2c0ab350e21c66556f94ee06f766d8bdae3213857ba7610bfd8e10e51880" dependencies = [ "libc", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -4591,6 +4844,18 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "rustls" +version = "0.21.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +dependencies = [ + "log", + "ring", + "rustls-webpki 0.101.7", + "sct", +] + [[package]] name = "rustls" version = "0.23.28" @@ -4601,7 +4866,7 @@ dependencies = [ "once_cell", "ring", "rustls-pki-types", - "rustls-webpki", + "rustls-webpki 0.103.3", "subtle", "zeroize", ] @@ -4659,6 +4924,16 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "rustls-webpki" version = "0.103.3" @@ -4754,7 +5029,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn", + "syn 2.0.105", ] [[package]] @@ -4774,6 +5049,16 @@ dependencies = [ "sha2", ] +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "sec1" version = "0.7.3" @@ -4886,7 +5171,7 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.105", ] [[package]] @@ -4897,7 +5182,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.105", ] [[package]] @@ -4930,7 +5215,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.105", ] [[package]] @@ -4951,7 +5236,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn", + "syn 2.0.105", ] [[package]] @@ -4995,7 +5280,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn", + "syn 2.0.105", ] [[package]] @@ -5118,6 +5403,9 @@ name = "smallvec" version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +dependencies = [ + "serde", +] [[package]] name = "snafu" @@ -5137,7 +5425,18 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 2.0.105", +] + +[[package]] +name = "socket-pktinfo" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "927136cc2ae6a1b0e66ac6b1210902b75c3f726db004a73bc18686dcd0dcd22f" +dependencies = [ + "libc", + "socket2 0.6.0", + "windows-sys 0.60.2", ] [[package]] @@ -5165,6 +5464,9 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] [[package]] name = "spki" @@ -5176,6 +5478,194 @@ dependencies = [ "der", ] +[[package]] +name = "sqlx" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fefb893899429669dcdd979aff487bd78f4064e5e7907e4269081e0ef7d97dc" +dependencies = [ + "sqlx-core", + "sqlx-macros", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", +] + +[[package]] +name = "sqlx-core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6" +dependencies = [ + "base64 0.22.1", + "bytes", + "crc", + "crossbeam-queue", + "either", + "event-listener", + "futures-core", + "futures-intrusive", + "futures-io", + "futures-util", + "hashbrown 0.15.4", + "hashlink", + "indexmap 2.10.0", + "log", + "memchr", + "once_cell", + "percent-encoding", + "serde", + "serde_json", + "sha2", + "smallvec", + "thiserror 2.0.14", + "tokio", + "tokio-stream", + "tracing", + "url", +] + +[[package]] +name = "sqlx-macros" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2d452988ccaacfbf5e0bdbc348fb91d7c8af5bee192173ac3636b5fb6e6715d" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn 2.0.105", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b" +dependencies = [ + "dotenvy", + "either", + "heck", + "hex", + "once_cell", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2", + "sqlx-core", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", + "syn 2.0.105", + "tokio", + "url", +] + +[[package]] +name = "sqlx-mysql" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526" +dependencies = [ + "atoi", + "base64 0.22.1", + "bitflags 2.9.1", + "byteorder", + "bytes", + "crc", + "digest", + "dotenvy", + "either", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "generic-array", + "hex", + "hkdf", + "hmac", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "percent-encoding", + "rand 0.8.5", + "rsa", + "serde", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror 2.0.14", + "tracing", + "whoami", +] + +[[package]] +name = "sqlx-postgres" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46" +dependencies = [ + "atoi", + "base64 0.22.1", + "bitflags 2.9.1", + "byteorder", + "crc", + "dotenvy", + "etcetera", + "futures-channel", + "futures-core", + "futures-util", + "hex", + "hkdf", + "hmac", + "home", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "rand 0.8.5", + "serde", + "serde_json", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror 2.0.14", + "tracing", + "whoami", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2d12fe70b2c1b4401038055f90f151b78208de1f9f89a7dbfd41587a10c3eea" +dependencies = [ + "atoi", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log", + "percent-encoding", + "serde", + "serde_urlencoded", + "sqlx-core", + "thiserror 2.0.14", + "tracing", + "url", +] + [[package]] name = "ssh-cipher" version = "0.2.0" @@ -5239,6 +5729,17 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "stringprep" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" +dependencies = [ + "unicode-bidi", + "unicode-normalization", + "unicode-properties", +] + [[package]] name = "strsim" version = "0.11.1" @@ -5273,7 +5774,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn", + "syn 2.0.105", ] [[package]] @@ -5286,7 +5787,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn", + "syn 2.0.105", ] [[package]] @@ -5295,6 +5796,17 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.105" @@ -5321,6 +5833,18 @@ dependencies = [ "futures-core", ] +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "unicode-xid", +] + [[package]] name = "synstructure" version = "0.13.2" @@ -5329,7 +5853,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.105", ] [[package]] @@ -5355,18 +5879,7 @@ checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ "bitflags 1.3.2", "core-foundation 0.9.4", - "system-configuration-sys 0.5.0", -] - -[[package]] -name = "system-configuration" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" -dependencies = [ - "bitflags 2.9.1", - "core-foundation 0.9.4", - "system-configuration-sys 0.6.0", + "system-configuration-sys", ] [[package]] @@ -5379,16 +5892,6 @@ dependencies = [ "libc", ] -[[package]] -name = "system-configuration-sys" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "tap" version = "1.0.1" @@ -5463,7 +5966,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.105", ] [[package]] @@ -5474,7 +5977,7 @@ checksum = "cc5b44b4ab9c2fdd0e0512e6bece8388e214c0749f5862b114cc5b7a25daf227" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.105", ] [[package]] @@ -5579,16 +6082,16 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.105", ] [[package]] -name = "tokio-native-tls" -version = "0.3.1" +name = "tokio-rustls" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "native-tls", + "rustls 0.21.12", "tokio", ] @@ -5598,7 +6101,7 @@ version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" dependencies = [ - "rustls", + "rustls 0.23.28", "tokio", ] @@ -5750,7 +6253,7 @@ checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.105", ] [[package]] @@ -5840,12 +6343,33 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" +[[package]] +name = "unicode-bidi" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" + [[package]] name = "unicode-ident" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +[[package]] +name = "unicode-normalization" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-properties" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" + [[package]] name = "unicode-segmentation" version = "1.12.0" @@ -5960,7 +6484,7 @@ checksum = "26b682e8c381995ea03130e381928e0e005b7c9eb483c6c8682f50e07b33c2b7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.105", ] [[package]] @@ -6024,6 +6548,12 @@ dependencies = [ "wit-bindgen-rt", ] +[[package]] +name = "wasite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + [[package]] name = "wasm-bindgen" version = "0.2.100" @@ -6046,7 +6576,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn", + "syn 2.0.105", "wasm-bindgen-shared", ] @@ -6081,7 +6611,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.105", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6129,6 +6659,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + [[package]] name = "webpki-roots" version = "1.0.2" @@ -6138,6 +6674,22 @@ dependencies = [ "rustls-pki-types", ] +[[package]] +name = "whoami" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4a4db5077702ca3015d3d02d74974948aba2ad9e12ab7df718ee64ccd7e97d" +dependencies = [ + "libredox", + "wasite", +] + +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" + [[package]] name = "winapi" version = "0.3.9" @@ -6209,7 +6761,7 @@ checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.105", ] [[package]] @@ -6220,7 +6772,7 @@ checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.105", ] [[package]] @@ -6229,17 +6781,6 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" -[[package]] -name = "windows-registry" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" -dependencies = [ - "windows-link", - "windows-result", - "windows-strings", -] - [[package]] name = "windows-result" version = "0.3.4" @@ -6564,7 +7105,7 @@ dependencies = [ "quote", "serde", "serde_tokenstream", - "syn", + "syn 2.0.105", "xml-rs", ] @@ -6588,8 +7129,8 @@ checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" dependencies = [ "proc-macro2", "quote", - "syn", - "synstructure", + "syn 2.0.105", + "synstructure 0.13.2", ] [[package]] @@ -6609,7 +7150,7 @@ checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.105", ] [[package]] @@ -6629,8 +7170,8 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn", - "synstructure", + "syn 2.0.105", + "synstructure 0.13.2", ] [[package]] @@ -6669,7 +7210,7 @@ checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.105", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index fcc315f..d92c0e7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ members = [ "harmony_composer", "harmony_inventory_agent", "harmony_secret_derive", - "harmony_secret", + "harmony_secret", "adr/agent_discovery/mdns", ] [workspace.package] @@ -36,7 +36,7 @@ tokio = { version = "1.40", features = [ cidr = { features = ["serde"], version = "0.2" } russh = "0.45" russh-keys = "0.45" -rand = "0.8" +rand = "0.9" url = "2.5" kube = { version = "1.1.0", features = [ "config", @@ -65,3 +65,6 @@ directories = "6.0.0" thiserror = "2.0.14" serde = { version = "1.0.209", features = ["derive", "rc"] } serde_json = "1.0.127" +askama = "0.14" +sqlx = { version = "0.8", features = ["runtime-tokio", "sqlite" ] } +reqwest = { version = "0.12", features = ["blocking", "stream", "rustls-tls", "http2", "json"], default-features = false } diff --git a/adr/agent_discovery/mdns/Cargo.toml b/adr/agent_discovery/mdns/Cargo.toml new file mode 100644 index 0000000..b5fc525 --- /dev/null +++ b/adr/agent_discovery/mdns/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "mdns" +edition = "2024" +version.workspace = true +readme.workspace = true +license.workspace = true + +[dependencies] +mdns-sd = "0.14" +tokio = { version = "1", features = ["full"] } +futures = "0.3" +dmidecode = "0.2" # For getting the motherboard ID on the agent +log.workspace=true +env_logger.workspace=true +clap = { version = "4.5.46", features = ["derive"] } +get_if_addrs = "0.5.3" +local-ip-address = "0.6.5" diff --git a/adr/agent_discovery/mdns/src/advertise.rs b/adr/agent_discovery/mdns/src/advertise.rs new file mode 100644 index 0000000..a98f237 --- /dev/null +++ b/adr/agent_discovery/mdns/src/advertise.rs @@ -0,0 +1,60 @@ +// harmony-agent/src/main.rs + +use log::info; +use mdns_sd::{ServiceDaemon, ServiceInfo}; +use std::collections::HashMap; + +use crate::SERVICE_TYPE; + +// The service we are advertising. +const SERVICE_PORT: u16 = 43210; // A port for the service. It needs one, even if unused. + +pub async fn advertise() { + info!("Starting Harmony Agent..."); + + // Get a unique ID for this machine. + let motherboard_id = "some motherboard id"; + let instance_name = format!("harmony-agent-{}", motherboard_id); + info!("This agent's instance name: {}", instance_name); + info!("Advertising with ID: {}", motherboard_id); + + // Create a new mDNS daemon. + let mdns = ServiceDaemon::new().expect("Failed to create mDNS daemon"); + + // Create a TXT record HashMap to hold our metadata. + let mut properties = HashMap::new(); + properties.insert("id".to_string(), motherboard_id.to_string()); + properties.insert("version".to_string(), "1.0".to_string()); + + // Create the service information. + // The instance name should be unique on the network. + let local_ip = local_ip_address::local_ip().unwrap(); + let service_info = ServiceInfo::new( + SERVICE_TYPE, + &instance_name, + "harmony-host.local.", // A hostname for the service + local_ip, + // "0.0.0.0", + SERVICE_PORT, + Some(properties), + ) + .expect("Failed to create service info"); + + // Register our service with the daemon. + mdns.register(service_info) + .expect("Failed to register service"); + + info!( + "Service '{}' registered and now being advertised.", + instance_name + ); + info!("Agent is running. Press Ctrl+C to exit."); + + for iface in get_if_addrs::get_if_addrs().unwrap() { + println!("{:#?}", iface); + } + + // Keep the agent running indefinitely. + tokio::signal::ctrl_c().await.unwrap(); + info!("Shutting down agent."); +} diff --git a/adr/agent_discovery/mdns/src/discover.rs b/adr/agent_discovery/mdns/src/discover.rs new file mode 100644 index 0000000..bf339de --- /dev/null +++ b/adr/agent_discovery/mdns/src/discover.rs @@ -0,0 +1,110 @@ +use log::debug; +use mdns_sd::{ServiceDaemon, ServiceEvent}; + +use crate::SERVICE_TYPE; + +pub async fn discover() { + println!("Starting Harmony Master and browsing for agents..."); + + // Create a new mDNS daemon. + let mdns = ServiceDaemon::new().expect("Failed to create mDNS daemon"); + + // Start browsing for the service type. + // The receiver will be a stream of events. + let receiver = mdns.browse(SERVICE_TYPE).expect("Failed to browse"); + + println!( + "Listening for mDNS events for '{}'. Press Ctrl+C to exit.", + SERVICE_TYPE + ); + + std::thread::spawn(move || { + while let Ok(event) = receiver.recv() { + match event { + ServiceEvent::ServiceData(resolved) => { + println!("Resolved a new service: {}", resolved.fullname); + } + other_event => { + println!("Received other event: {:?}", &other_event); + } + } + } + }); + + // Gracefully shutdown the daemon. + std::thread::sleep(std::time::Duration::from_secs(1000000)); + mdns.shutdown().unwrap(); + + // Process events as they come in. + // while let Ok(event) = receiver.recv_async().await { + // debug!("Received event {event:?}"); + // // match event { + // // ServiceEvent::ServiceFound(svc_type, fullname) => { + // // println!("\n--- Agent Discovered ---"); + // // println!(" Service Name: {}", fullname()); + // // // You can now resolve this service to get its IP, port, and TXT records + // // // The resolve operation is a separate network call. + // // let receiver = mdns.browse(info.get_fullname()).unwrap(); + // // if let Ok(resolve_event) = receiver.recv_timeout(Duration::from_secs(2)) { + // // if let ServiceEvent::ServiceResolved(info) = resolve_event { + // // let ip = info.get_addresses().iter().next().unwrap(); + // // let port = info.get_port(); + // // let motherboard_id = info.get_property("id").map_or("N/A", |v| v.val_str()); + // // + // // println!(" IP: {}:{}", ip, port); + // // println!(" Motherboard ID: {}", motherboard_id); + // // println!("------------------------"); + // // + // // // TODO: Add this agent to your central list of discovered hosts. + // // } + // // } else { + // // println!("Could not resolve service '{}' in time.", info.get_fullname()); + // // } + // // } + // // ServiceEvent::ServiceRemoved(info) => { + // // println!("\n--- Agent Removed ---"); + // // println!(" Service Name: {}", info.get_fullname()); + // // println!("---------------------"); + // // // TODO: Remove this agent from your list. + // // } + // // _ => { + // // // We don't care about other event types for this example + // // } + // // } + // } +} + +async fn discover_example() { + use mdns_sd::{ServiceDaemon, ServiceEvent}; + + // Create a daemon + let mdns = ServiceDaemon::new().expect("Failed to create daemon"); + + // Use recently added `ServiceEvent::ServiceData`. + mdns.use_service_data(true) + .expect("Failed to use ServiceData"); + + // Browse for a service type. + let service_type = "_mdns-sd-my-test._udp.local."; + let receiver = mdns.browse(service_type).expect("Failed to browse"); + + // Receive the browse events in sync or async. Here is + // an example of using a thread. Users can call `receiver.recv_async().await` + // if running in async environment. + std::thread::spawn(move || { + while let Ok(event) = receiver.recv() { + match event { + ServiceEvent::ServiceData(resolved) => { + println!("Resolved a new service: {}", resolved.fullname); + } + other_event => { + println!("Received other event: {:?}", &other_event); + } + } + } + }); + + // Gracefully shutdown the daemon. + std::thread::sleep(std::time::Duration::from_secs(1)); + mdns.shutdown().unwrap(); +} diff --git a/adr/agent_discovery/mdns/src/main.rs b/adr/agent_discovery/mdns/src/main.rs new file mode 100644 index 0000000..9e22da5 --- /dev/null +++ b/adr/agent_discovery/mdns/src/main.rs @@ -0,0 +1,31 @@ +use clap::{Parser, ValueEnum}; + +mod advertise; +mod discover; + +#[derive(Parser, Debug)] +#[command(version, about, long_about = None)] +struct Args { + #[arg(value_enum)] + profile: Profiles, +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, ValueEnum)] +enum Profiles { + Advertise, + Discover, +} + +// The service type we are looking for. +const SERVICE_TYPE: &str = "_harmony._tcp.local."; + +#[tokio::main] +async fn main() { + env_logger::init(); + let args = Args::parse(); + + match args.profile { + Profiles::Advertise => advertise::advertise().await, + Profiles::Discover => discover::discover().await, + } +} diff --git a/check.sh b/check.sh index 3bcbc6a..616bccb 100755 --- a/check.sh +++ b/check.sh @@ -1,6 +1,7 @@ #!/bin/sh set -e +rustc --version cargo check --all-targets --all-features --keep-going cargo fmt --check cargo clippy diff --git a/data/pxe/okd/README.md b/data/pxe/okd/README.md new file mode 100644 index 0000000..7c53daf --- /dev/null +++ b/data/pxe/okd/README.md @@ -0,0 +1,8 @@ +Here lies all the data files required for an OKD cluster PXE boot setup. + +This inclues ISO files, binary boot files, ipxe, etc. + +TODO as of august 2025 : + +- `harmony_inventory_agent` should be downloaded from official releases, this embedded version is practical for now though +- The cluster ssh key should be generated and handled by harmony with the private key saved in a secret store diff --git a/data/pxe/okd/http_files/.gitattributes b/data/pxe/okd/http_files/.gitattributes new file mode 100644 index 0000000..f6bc73d --- /dev/null +++ b/data/pxe/okd/http_files/.gitattributes @@ -0,0 +1,9 @@ +harmony_inventory_agent filter=lfs diff=lfs merge=lfs -text +os filter=lfs diff=lfs merge=lfs -text +os/centos-stream-9 filter=lfs diff=lfs merge=lfs -text +os/centos-stream-9/images filter=lfs diff=lfs merge=lfs -text +os/centos-stream-9/initrd.img filter=lfs diff=lfs merge=lfs -text +os/centos-stream-9/vmlinuz filter=lfs diff=lfs merge=lfs -text +os/centos-stream-9/images/efiboot.img filter=lfs diff=lfs merge=lfs -text +os/centos-stream-9/images/install.img filter=lfs diff=lfs merge=lfs -text +os/centos-stream-9/images/pxeboot filter=lfs diff=lfs merge=lfs -text diff --git a/data/pxe/okd/http_files/cluster_ssh_key.pub b/data/pxe/okd/http_files/cluster_ssh_key.pub new file mode 100644 index 0000000..8a68662 --- /dev/null +++ b/data/pxe/okd/http_files/cluster_ssh_key.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBx6bDylvC68cVpjKfEFtLQJ/dOFi6PVS2vsIOqPDJIc jeangab@liliane2 diff --git a/data/pxe/okd/http_files/harmony_inventory_agent b/data/pxe/okd/http_files/harmony_inventory_agent new file mode 100755 index 0000000..1d802f7 --- /dev/null +++ b/data/pxe/okd/http_files/harmony_inventory_agent @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5244fa8968fe15c2415de6cc487e6112f8aedd9989951e018f9bdb536b1016d2 +size 8139216 diff --git a/data/pxe/okd/http_files/os/centos-stream-9/images/efiboot.img b/data/pxe/okd/http_files/os/centos-stream-9/images/efiboot.img new file mode 100644 index 0000000..0c96e5d --- /dev/null +++ b/data/pxe/okd/http_files/os/centos-stream-9/images/efiboot.img @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dcf735affacdc66c3255ef74434bb5bc6c55387adbfc880e598b5ab68f2371d0 +size 7899136 diff --git a/data/pxe/okd/http_files/os/centos-stream-9/images/install.img b/data/pxe/okd/http_files/os/centos-stream-9/images/install.img new file mode 100644 index 0000000..89a855e --- /dev/null +++ b/data/pxe/okd/http_files/os/centos-stream-9/images/install.img @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d9bf91e65af208695993a5e2b8b263d60e934dec83f139cc9ebe10a6bf91a24a +size 1197342720 diff --git a/data/pxe/okd/http_files/os/centos-stream-9/images/pxeboot/initrd.img b/data/pxe/okd/http_files/os/centos-stream-9/images/pxeboot/initrd.img new file mode 100644 index 0000000..8103aff Binary files /dev/null and b/data/pxe/okd/http_files/os/centos-stream-9/images/pxeboot/initrd.img differ diff --git a/data/pxe/okd/http_files/os/centos-stream-9/images/pxeboot/vmlinuz b/data/pxe/okd/http_files/os/centos-stream-9/images/pxeboot/vmlinuz new file mode 100755 index 0000000..50e9afa Binary files /dev/null and b/data/pxe/okd/http_files/os/centos-stream-9/images/pxeboot/vmlinuz differ diff --git a/data/pxe/okd/http_files/os/centos-stream-9/initrd.img b/data/pxe/okd/http_files/os/centos-stream-9/initrd.img new file mode 100644 index 0000000..f6811c3 --- /dev/null +++ b/data/pxe/okd/http_files/os/centos-stream-9/initrd.img @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f9499b71d6d1d1c8e62ee6b8247d32a5d729ab7c55b310a5dcf9507fecc85142 +size 158657144 diff --git a/data/pxe/okd/http_files/os/centos-stream-9/vmlinuz b/data/pxe/okd/http_files/os/centos-stream-9/vmlinuz new file mode 100755 index 0000000..050a67c --- /dev/null +++ b/data/pxe/okd/http_files/os/centos-stream-9/vmlinuz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d8dd3361f0b6db53f8d98e8bdaf32cf9ca4ae788847576fd2e9c5d6c890e53a1 +size 15083560 diff --git a/data/pxe/okd/tftpboot/ipxe.efi b/data/pxe/okd/tftpboot/ipxe.efi new file mode 100644 index 0000000..24a9510 Binary files /dev/null and b/data/pxe/okd/tftpboot/ipxe.efi differ diff --git a/data/pxe/okd/tftpboot/undionly.kpxe b/data/pxe/okd/tftpboot/undionly.kpxe new file mode 100644 index 0000000..a265f30 Binary files /dev/null and b/data/pxe/okd/tftpboot/undionly.kpxe differ diff --git a/docs/pxe_test/README.md b/docs/pxe_test/README.md new file mode 100644 index 0000000..c515aab --- /dev/null +++ b/docs/pxe_test/README.md @@ -0,0 +1,108 @@ +# OPNsense PXE Lab Environment + +This project contains a script to automatically set up a virtual lab environment for testing PXE boot services managed by an OPNsense firewall. + +## Overview + +The `pxe_vm_lab_setup.sh` script will create the following resources using libvirt/KVM: + +1. **A Virtual Network**: An isolated network named `harmonylan` (`virbr1`) for the lab. +2. **Two Virtual Machines**: + * `opnsense-pxe`: A firewall VM that will act as the gateway and PXE server. + * `pxe-node-1`: A client VM configured to boot from the network. + +## Prerequisites + +Ensure you have the following software installed on your Arch Linux host: + +* `libvirt` +* `qemu` +* `virt-install` (from the `virt-install` package) +* `curl` +* `bzip2` + +## Usage + +### 1. Create the Environment + +Run the `up` command to download the necessary images and create the network and VMs. + +```bash +sudo ./pxe_vm_lab_setup.sh up +``` + +### 2. Install and Configure OPNsense + +The OPNsense VM is created but the OS needs to be installed manually via the console. + +1. **Connect to the VM console**: + ```bash + sudo virsh console opnsense-pxe + ``` + +2. **Log in as the installer**: + * Username: `installer` + * Password: `opnsense` + +3. **Follow the on-screen installation wizard**. When prompted to assign network interfaces (`WAN` and `LAN`): + * Find the MAC address for the `harmonylan` interface by running this command in another terminal: + ```bash + virsh domiflist opnsense-pxe + # Example output: + # Interface Type Source Model MAC + # --------------------------------------------------------- + # vnet18 network default virtio 52:54:00:b5:c4:6d + # vnet19 network harmonylan virtio 52:54:00:21:f9:ba + ``` + * Assign the interface connected to `harmonylan` (e.g., `vtnet1` with MAC `52:54:00:21:f9:ba`) as your **LAN**. + * Assign the other interface as your **WAN**. + +4. After the installation is complete, **shut down** the VM from the console menu. + +5. **Detach the installation media** by editing the VM's configuration: + ```bash + sudo virsh edit opnsense-pxe + ``` + Find and **delete** the entire `` block corresponding to the `.img` file (the one with ``). + +6. **Start the VM** to boot into the newly installed system: + ```bash + sudo virsh start opnsense-pxe + ``` + +### 3. Connect to OPNsense from Your Host + +To configure OPNsense, you need to connect your host to the `harmonylan` network. + +1. By default, OPNsense configures its LAN interface with the IP `192.168.1.1`. +2. Assign a compatible IP address to your host's `virbr1` bridge interface: + ```bash + sudo ip addr add 192.168.1.5/24 dev virbr1 + ``` +3. You can now access the OPNsense VM from your host: + * **SSH**: `ssh root@192.168.1.1` (password: `opnsense`) + * **Web UI**: `https://192.168.1.1` + +### 4. Configure PXE Services with Harmony + +With connectivity established, you can now use Harmony to configure the OPNsense firewall for PXE booting. Point your Harmony OPNsense scores to the firewall using these details: + +* **Hostname/IP**: `192.168.1.1` +* **Credentials**: `root` / `opnsense` + +### 5. Boot the PXE Client + +Once your Harmony configuration has been applied and OPNsense is serving DHCP/TFTP, start the client VM. It will automatically attempt to boot from the network. + +```bash +sudo virsh start pxe-node-1 +sudo virsh console pxe-node-1 +``` + +## Cleanup + +To destroy all VMs and networks created by the script, run the `clean` command: + +```bash +sudo ./pxe_vm_lab_setup.sh clean +``` diff --git a/docs/pxe_test/pxe_vm_lab_setup.sh b/docs/pxe_test/pxe_vm_lab_setup.sh new file mode 100755 index 0000000..f53cea3 --- /dev/null +++ b/docs/pxe_test/pxe_vm_lab_setup.sh @@ -0,0 +1,191 @@ +#!/usr/bin/env bash +set -euo pipefail + +# --- Configuration --- +LAB_DIR="/var/lib/harmony_pxe_test" +IMG_DIR="${LAB_DIR}/images" +STATE_DIR="${LAB_DIR}/state" +VM_OPN="opnsense-pxe" +VM_PXE="pxe-node-1" +NET_HARMONYLAN="harmonylan" + +# Network settings for the isolated LAN +VLAN_CIDR="192.168.150.0/24" +VLAN_GW="192.168.150.1" +VLAN_MASK="255.255.255.0" + +# VM Specifications +RAM_OPN="2048" +VCPUS_OPN="2" +DISK_OPN_GB="10" +OS_VARIANT_OPN="freebsd14.0" # Updated to a more recent FreeBSD variant + +RAM_PXE="4096" +VCPUS_PXE="2" +DISK_PXE_GB="40" +OS_VARIANT_LINUX="centos-stream9" + +OPN_IMG_URL="https://mirror.ams1.nl.leaseweb.net/opnsense/releases/25.7/OPNsense-25.7-serial-amd64.img.bz2" +OPN_IMG_PATH="${IMG_DIR}/OPNsense-25.7-serial-amd64.img" +CENTOS_ISO_URL="https://mirror.stream.centos.org/9-stream/BaseOS/x86_64/os/images/boot.iso" +CENTOS_ISO_PATH="${IMG_DIR}/CentOS-Stream-9-latest-boot.iso" + +CONNECT_URI="qemu:///system" + +download_if_missing() { + local url="$1" + local dest="$2" + if [[ ! -f "$dest" ]]; then + echo "Downloading $url to $dest" + mkdir -p "$(dirname "$dest")" + local tmp + tmp="$(mktemp)" + curl -L --progress-bar "$url" -o "$tmp" + case "$url" in + *.bz2) bunzip2 -c "$tmp" > "$dest" && rm -f "$tmp" ;; + *) mv "$tmp" "$dest" ;; + esac + else + echo "Already present: $dest" + fi +} + +# Ensures a libvirt network is defined and active +ensure_network() { + local net_name="$1" + local net_xml_path="$2" + if virsh --connect "${CONNECT_URI}" net-info "${net_name}" >/dev/null 2>&1; then + echo "Network ${net_name} already exists." + else + echo "Defining network ${net_name} from ${net_xml_path}" + virsh --connect "${CONNECT_URI}" net-define "${net_xml_path}" + fi + + if ! virsh --connect "${CONNECT_URI}" net-info "${net_name}" | grep "Active: *yes"; then + echo "Starting network ${net_name}..." + virsh --connect "${CONNECT_URI}" net-start "${net_name}" + virsh --connect "${CONNECT_URI}" net-autostart "${net_name}" + fi +} + +# Destroys a VM completely +destroy_vm() { + local vm_name="$1" + if virsh --connect "${CONNECT_URI}" dominfo "$vm_name" >/dev/null 2>&1; then + echo "Destroying and undefining VM: ${vm_name}" + virsh --connect "${CONNECT_URI}" destroy "$vm_name" || true + virsh --connect "${CONNECT_URI}" undefine "$vm_name" --nvram + fi +} + +# Destroys a libvirt network +destroy_network() { + local net_name="$1" + if virsh --connect "${CONNECT_URI}" net-info "$net_name" >/dev/null 2>&1; then + echo "Destroying and undefining network: ${net_name}" + virsh --connect "${CONNECT_URI}" net-destroy "$net_name" || true + virsh --connect "${CONNECT_URI}" net-undefine "$net_name" + fi +} + +# --- Main Logic --- +create_lab_environment() { + # Create network definition files + cat > "${STATE_DIR}/default.xml" < + default + + + + + + + + +EOF + + cat > "${STATE_DIR}/${NET_HARMONYLAN}.xml" < + ${NET_HARMONYLAN} + + +EOF + + # Ensure both networks exist and are active + ensure_network "default" "${STATE_DIR}/default.xml" + ensure_network "${NET_HARMONYLAN}" "${STATE_DIR}/${NET_HARMONYLAN}.xml" + + # --- Create OPNsense VM (MODIFIED SECTION) --- + local disk_opn="${IMG_DIR}/${VM_OPN}.qcow2" + if [[ ! -f "$disk_opn" ]]; then + qemu-img create -f qcow2 "$disk_opn" "${DISK_OPN_GB}G" + fi + + echo "Creating OPNsense VM using serial image..." + virt-install \ + --connect "${CONNECT_URI}" \ + --name "${VM_OPN}" \ + --ram "${RAM_OPN}" \ + --vcpus "${VCPUS_OPN}" \ + --cpu host-passthrough \ + --os-variant "${OS_VARIANT_OPN}" \ + --graphics none \ + --noautoconsole \ + --disk path="${disk_opn}",device=disk,bus=virtio,boot.order=1 \ + --disk path="${OPN_IMG_PATH}",device=disk,bus=usb,readonly=on,boot.order=2 \ + --network network=default,model=virtio \ + --network network="${NET_HARMONYLAN}",model=virtio \ + --boot uefi,menu=on + + echo "OPNsense VM created. Connect with: sudo virsh console ${VM_OPN}" + echo "The VM will boot from the serial installation image." + echo "Login with user 'installer' and password 'opnsense' to start the installation." + echo "Install onto the VirtIO disk (vtbd0)." + echo "After installation, shutdown the VM, then run 'sudo virsh edit ${VM_OPN}' and remove the USB disk block to boot from the installed system." + + # --- Create PXE Client VM --- + local disk_pxe="${IMG_DIR}/${VM_PXE}.qcow2" + if [[ ! -f "$disk_pxe" ]]; then + qemu-img create -f qcow2 "$disk_pxe" "${DISK_PXE_GB}G" + fi + + echo "Creating PXE client VM..." + virt-install \ + --connect "${CONNECT_URI}" \ + --name "${VM_PXE}" \ + --ram "${RAM_PXE}" \ + --vcpus "${VCPUS_PXE}" \ + --cpu host-passthrough \ + --os-variant "${OS_VARIANT_LINUX}" \ + --graphics none \ + --noautoconsole \ + --disk path="${disk_pxe}",format=qcow2,bus=virtio \ + --network network="${NET_HARMONYLAN}",model=virtio \ + --pxe \ + --boot uefi,menu=on + + echo "PXE VM created. It will attempt to netboot on ${NET_HARMONYLAN}." +} + +# --- Script Entrypoint --- +case "${1:-}" in + up) + mkdir -p "${IMG_DIR}" "${STATE_DIR}" + download_if_missing "$OPN_IMG_URL" "$OPN_IMG_PATH" + download_if_missing "$CENTOS_ISO_URL" "$CENTOS_ISO_PATH" + create_lab_environment + echo "Lab setup complete. Use 'sudo virsh list --all' to see VMs." + ;; + clean) + destroy_vm "${VM_PXE}" + destroy_vm "${VM_OPN}" + destroy_network "${NET_HARMONYLAN}" + # Optionally destroy the default network if you want a full reset + # destroy_network "default" + echo "Cleanup complete." + ;; + *) + echo "Usage: sudo $0 {up|clean}" + exit 1 + ;; +esac diff --git a/examples/application_monitoring_with_tenant/Cargo.toml b/examples/application_monitoring_with_tenant/Cargo.toml index b9b63de..3f162d3 100644 --- a/examples/application_monitoring_with_tenant/Cargo.toml +++ b/examples/application_monitoring_with_tenant/Cargo.toml @@ -7,8 +7,9 @@ license.workspace = true [dependencies] env_logger.workspace = true -harmony = { version = "0.1.0", path = "../../harmony" } -harmony_cli = { version = "0.1.0", path = "../../harmony_cli" } +harmony = { path = "../../harmony" } +harmony_cli = { path = "../../harmony_cli" } +harmony_types = { path = "../../harmony_types" } logging = "0.1.0" tokio.workspace = true url.workspace = true diff --git a/examples/application_monitoring_with_tenant/src/main.rs b/examples/application_monitoring_with_tenant/src/main.rs index 4691bf9..f46a993 100644 --- a/examples/application_monitoring_with_tenant/src/main.rs +++ b/examples/application_monitoring_with_tenant/src/main.rs @@ -1,15 +1,16 @@ use std::{path::PathBuf, str::FromStr, sync::Arc}; use harmony::{ - data::Id, inventory::Inventory, modules::{ application::{ApplicationScore, RustWebFramework, RustWebapp, features::Monitoring}, monitoring::alert_channel::webhook_receiver::WebhookReceiver, tenant::TenantScore, }, - topology::{K8sAnywhereTopology, Url, tenant::TenantConfig}, + topology::{K8sAnywhereTopology, tenant::TenantConfig}, }; +use harmony_types::id::Id; +use harmony_types::net::Url; #[tokio::main] async fn main() { diff --git a/examples/cli/src/main.rs b/examples/cli/src/main.rs index 34a032b..524d69c 100644 --- a/examples/cli/src/main.rs +++ b/examples/cli/src/main.rs @@ -1,6 +1,9 @@ use harmony::{ inventory::Inventory, - modules::dummy::{ErrorScore, PanicScore, SuccessScore}, + modules::{ + dummy::{ErrorScore, PanicScore, SuccessScore}, + inventory::DiscoverInventoryAgentScore, + }, topology::LocalhostTopology, }; @@ -13,6 +16,9 @@ async fn main() { Box::new(SuccessScore {}), Box::new(ErrorScore {}), Box::new(PanicScore {}), + Box::new(DiscoverInventoryAgentScore { + discovery_timeout: Some(10), + }), ], None, ) diff --git a/examples/lamp/src/main.rs b/examples/lamp/src/main.rs index b621156..3dc5a25 100644 --- a/examples/lamp/src/main.rs +++ b/examples/lamp/src/main.rs @@ -2,8 +2,9 @@ use harmony::{ data::Version, inventory::Inventory, modules::lamp::{LAMPConfig, LAMPScore}, - topology::{K8sAnywhereTopology, Url}, + topology::K8sAnywhereTopology, }; +use harmony_types::net::Url; #[tokio::main] async fn main() { diff --git a/examples/monitoring/Cargo.toml b/examples/monitoring/Cargo.toml index 1c35330..c9f7d80 100644 --- a/examples/monitoring/Cargo.toml +++ b/examples/monitoring/Cargo.toml @@ -6,8 +6,9 @@ readme.workspace = true license.workspace = true [dependencies] -harmony = { version = "0.1.0", path = "../../harmony" } -harmony_cli = { version = "0.1.0", path = "../../harmony_cli" } -harmony_macros = { version = "0.1.0", path = "../../harmony_macros" } +harmony = { path = "../../harmony" } +harmony_cli = { path = "../../harmony_cli" } +harmony_macros = { path = "../../harmony_macros" } +harmony_types = { path = "../../harmony_types" } tokio.workspace = true url.workspace = true diff --git a/examples/monitoring/src/main.rs b/examples/monitoring/src/main.rs index b0a3939..d06a93e 100644 --- a/examples/monitoring/src/main.rs +++ b/examples/monitoring/src/main.rs @@ -22,8 +22,9 @@ use harmony::{ k8s::pvc::high_pvc_fill_rate_over_two_days, }, }, - topology::{K8sAnywhereTopology, Url}, + topology::K8sAnywhereTopology, }; +use harmony_types::net::Url; #[tokio::main] async fn main() { diff --git a/examples/monitoring_with_tenant/Cargo.toml b/examples/monitoring_with_tenant/Cargo.toml index 27fd4dd..10049c6 100644 --- a/examples/monitoring_with_tenant/Cargo.toml +++ b/examples/monitoring_with_tenant/Cargo.toml @@ -7,7 +7,8 @@ license.workspace = true [dependencies] cidr.workspace = true -harmony = { version = "0.1.0", path = "../../harmony" } -harmony_cli = { version = "0.1.0", path = "../../harmony_cli" } +harmony = { path = "../../harmony" } +harmony_cli = { path = "../../harmony_cli" } +harmony_types = { path = "../../harmony_types" } tokio.workspace = true url.workspace = true diff --git a/examples/monitoring_with_tenant/src/main.rs b/examples/monitoring_with_tenant/src/main.rs index 2960944..5b85f78 100644 --- a/examples/monitoring_with_tenant/src/main.rs +++ b/examples/monitoring_with_tenant/src/main.rs @@ -1,7 +1,6 @@ use std::{collections::HashMap, str::FromStr}; use harmony::{ - data::Id, inventory::Inventory, modules::{ monitoring::{ @@ -19,10 +18,12 @@ use harmony::{ tenant::TenantScore, }, topology::{ - K8sAnywhereTopology, Url, + K8sAnywhereTopology, tenant::{ResourceLimits, TenantConfig, TenantNetworkPolicy}, }, }; +use harmony_types::id::Id; +use harmony_types::net::Url; #[tokio::main] async fn main() { diff --git a/examples/nanodc/src/main.rs b/examples/nanodc/src/main.rs index 10754b4..a6bb8e4 100644 --- a/examples/nanodc/src/main.rs +++ b/examples/nanodc/src/main.rs @@ -18,9 +18,10 @@ use harmony::{ }, tftp::TftpScore, }, - topology::{LogicalHost, UnmanagedRouter, Url}, + topology::{LogicalHost, UnmanagedRouter}, }; use harmony_macros::{ip, mac_address}; +use harmony_types::net::Url; #[tokio::main] async fn main() { @@ -86,8 +87,7 @@ async fn main() { let inventory = Inventory { location: Location::new("I am mobile".to_string(), "earth".to_string()), switch: SwitchGroup::from([]), - firewall: FirewallGroup::from([PhysicalHost::empty(HostCategory::Firewall) - .management(Arc::new(OPNSenseManagementInterface::new()))]), + firewall_mgmt: Box::new(OPNSenseManagementInterface::new()), storage_host: vec![], worker_host: vec![ PhysicalHost::empty(HostCategory::Server) @@ -125,9 +125,12 @@ async fn main() { harmony::modules::okd::load_balancer::OKDLoadBalancerScore::new(&topology); let tftp_score = TftpScore::new(Url::LocalFolder("./data/watchguard/tftpboot".to_string())); - let http_score = StaticFilesHttpScore::new(Url::LocalFolder( - "./data/watchguard/pxe-http-files".to_string(), - )); + let http_score = StaticFilesHttpScore { + folder_to_serve: Some(Url::LocalFolder( + "./data/watchguard/pxe-http-files".to_string(), + )), + files: vec![], + }; let ipxe_score = IpxeScore::new(); harmony_tui::run( diff --git a/examples/okd_pxe/Cargo.toml b/examples/okd_pxe/Cargo.toml new file mode 100644 index 0000000..f75f42b --- /dev/null +++ b/examples/okd_pxe/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "example-pxe" +edition = "2024" +version.workspace = true +readme.workspace = true +license.workspace = true +publish = false + +[dependencies] +harmony = { path = "../../harmony" } +harmony_cli = { path = "../../harmony_cli" } +harmony_types = { path = "../../harmony_types" } +harmony_secret = { path = "../../harmony_secret" } +harmony_secret_derive = { path = "../../harmony_secret_derive" } +cidr = { workspace = true } +tokio = { workspace = true } +harmony_macros = { path = "../../harmony_macros" } +log = { workspace = true } +env_logger = { workspace = true } +url = { workspace = true } +serde.workspace = true diff --git a/examples/okd_pxe/src/main.rs b/examples/okd_pxe/src/main.rs new file mode 100644 index 0000000..42e4729 --- /dev/null +++ b/examples/okd_pxe/src/main.rs @@ -0,0 +1,24 @@ +mod topology; + +use crate::topology::{get_inventory, get_topology}; +use harmony::modules::okd::ipxe::OkdIpxeScore; + +#[tokio::main] +async fn main() { + let inventory = get_inventory(); + let topology = get_topology().await; + + let kickstart_filename = "inventory.kickstart".to_string(); + let cluster_pubkey_filename = "cluster_ssh_key.pub".to_string(); + let harmony_inventory_agent = "harmony_inventory_agent".to_string(); + + let ipxe_score = OkdIpxeScore { + kickstart_filename, + harmony_inventory_agent, + cluster_pubkey_filename, + }; + + harmony_cli::run(inventory, topology, vec![Box::new(ipxe_score)], None) + .await + .unwrap(); +} diff --git a/examples/okd_pxe/src/topology.rs b/examples/okd_pxe/src/topology.rs new file mode 100644 index 0000000..27eb8c0 --- /dev/null +++ b/examples/okd_pxe/src/topology.rs @@ -0,0 +1,77 @@ +use cidr::Ipv4Cidr; +use harmony::{ + hardware::{FirewallGroup, HostCategory, Location, PhysicalHost, SwitchGroup}, + infra::opnsense::OPNSenseManagementInterface, + inventory::Inventory, + topology::{HAClusterTopology, LogicalHost, UnmanagedRouter}, +}; +use harmony_macros::{ip, ipv4}; +use harmony_secret::{Secret, SecretManager}; +use serde::{Deserialize, Serialize}; +use std::{net::IpAddr, sync::Arc}; + +#[derive(Secret, Serialize, Deserialize, Debug, PartialEq)] +struct OPNSenseFirewallConfig { + username: String, + password: String, +} + +pub async fn get_topology() -> HAClusterTopology { + let firewall = harmony::topology::LogicalHost { + ip: ip!("192.168.1.1"), + name: String::from("opnsense-1"), + }; + + let config = SecretManager::get::().await; + let config = config.unwrap(); + + let opnsense = Arc::new( + harmony::infra::opnsense::OPNSenseFirewall::new( + firewall, + None, + &config.username, + &config.password, + ) + .await, + ); + let lan_subnet = ipv4!("192.168.1.0"); + let gateway_ipv4 = ipv4!("192.168.1.1"); + let gateway_ip = IpAddr::V4(gateway_ipv4); + harmony::topology::HAClusterTopology { + domain_name: "demo.harmony.mcd".to_string(), + router: Arc::new(UnmanagedRouter::new( + gateway_ip, + Ipv4Cidr::new(lan_subnet, 24).unwrap(), + )), + load_balancer: opnsense.clone(), + firewall: opnsense.clone(), + tftp_server: opnsense.clone(), + http_server: opnsense.clone(), + dhcp_server: opnsense.clone(), + dns_server: opnsense.clone(), + control_plane: vec![LogicalHost { + ip: ip!("10.100.8.20"), + name: "cp0".to_string(), + }], + bootstrap_host: LogicalHost { + ip: ip!("10.100.8.20"), + name: "cp0".to_string(), + }, + workers: vec![], + switch: vec![], + } +} + +pub fn get_inventory() -> Inventory { + Inventory { + location: Location::new( + "Some virtual machine or maybe a physical machine if you're cool".to_string(), + "testopnsense".to_string(), + ), + switch: SwitchGroup::from([]), + firewall_mgmt: Box::new(OPNSenseManagementInterface::new()), + storage_host: vec![], + worker_host: vec![], + control_plane_host: vec![], + } +} diff --git a/examples/okd_pxe/ssh_example_key b/examples/okd_pxe/ssh_example_key new file mode 100644 index 0000000..272bfb3 --- /dev/null +++ b/examples/okd_pxe/ssh_example_key @@ -0,0 +1,7 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW +QyNTUxOQAAACAcemw8pbwuvHFaYynxBbS0Cf3ThYuj1Utr7CDqjwySHAAAAJikacCNpGnA +jQAAAAtzc2gtZWQyNTUxOQAAACAcemw8pbwuvHFaYynxBbS0Cf3ThYuj1Utr7CDqjwySHA +AAAECiiKk4V6Q5cVs6axDM4sjAzZn/QCZLQekmYQXS9XbEYxx6bDylvC68cVpjKfEFtLQJ +/dOFi6PVS2vsIOqPDJIcAAAAEGplYW5nYWJAbGlsaWFuZTIBAgMEBQ== +-----END OPENSSH PRIVATE KEY----- diff --git a/examples/okd_pxe/ssh_example_key.pub b/examples/okd_pxe/ssh_example_key.pub new file mode 100644 index 0000000..8a68662 --- /dev/null +++ b/examples/okd_pxe/ssh_example_key.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBx6bDylvC68cVpjKfEFtLQJ/dOFi6PVS2vsIOqPDJIc jeangab@liliane2 diff --git a/examples/opnsense/src/main.rs b/examples/opnsense/src/main.rs index 61f8f18..465b0fa 100644 --- a/examples/opnsense/src/main.rs +++ b/examples/opnsense/src/main.rs @@ -15,9 +15,10 @@ use harmony::{ opnsense::OPNsenseShellCommandScore, tftp::TftpScore, }, - topology::{LogicalHost, UnmanagedRouter, Url}, + topology::{LogicalHost, UnmanagedRouter}, }; use harmony_macros::{ip, mac_address}; +use harmony_types::net::Url; #[tokio::main] async fn main() { @@ -62,8 +63,7 @@ async fn main() { "wk".to_string(), ), switch: SwitchGroup::from([]), - firewall: FirewallGroup::from([PhysicalHost::empty(HostCategory::Firewall) - .management(Arc::new(OPNSenseManagementInterface::new()))]), + firewall_mgmt: Box::new(OPNSenseManagementInterface::new()), storage_host: vec![], worker_host: vec![], control_plane_host: vec![ @@ -80,9 +80,12 @@ async fn main() { let load_balancer_score = OKDLoadBalancerScore::new(&topology); let tftp_score = TftpScore::new(Url::LocalFolder("./data/watchguard/tftpboot".to_string())); - let http_score = StaticFilesHttpScore::new(Url::LocalFolder( - "./data/watchguard/pxe-http-files".to_string(), - )); + let http_score = StaticFilesHttpScore { + folder_to_serve: Some(Url::LocalFolder( + "./data/watchguard/pxe-http-files".to_string(), + )), + files: vec![], + }; harmony_tui::run( inventory, diff --git a/examples/rust/src/main.rs b/examples/rust/src/main.rs index d3d52ec..031887b 100644 --- a/examples/rust/src/main.rs +++ b/examples/rust/src/main.rs @@ -11,8 +11,9 @@ use harmony::{ discord_alert_channel::DiscordWebhook, webhook_receiver::WebhookReceiver, }, }, - topology::{K8sAnywhereTopology, Url}, + topology::K8sAnywhereTopology, }; +use harmony_types::net::Url; #[tokio::main] async fn main() { diff --git a/examples/tenant/src/main.rs b/examples/tenant/src/main.rs index 356ad1b..1b0a3e4 100644 --- a/examples/tenant/src/main.rs +++ b/examples/tenant/src/main.rs @@ -1,11 +1,11 @@ use std::str::FromStr; use harmony::{ - data::Id, inventory::Inventory, modules::tenant::TenantScore, topology::{K8sAnywhereTopology, tenant::TenantConfig}, }; +use harmony_types::id::Id; #[tokio::main] async fn main() { diff --git a/harmony/Cargo.toml b/harmony/Cargo.toml index 47e6c5c..0fe3fa8 100644 --- a/harmony/Cargo.toml +++ b/harmony/Cargo.toml @@ -9,10 +9,8 @@ license.workspace = true testing = [] [dependencies] -rand = "0.9" hex = "0.4" -libredfish = "0.1.1" -reqwest = { version = "0.11", features = ["blocking", "json"] } +reqwest = { version = "0.11", features = ["blocking", "json", "rustls-tls"], default-features = false } russh = "0.45.0" rust-ipmi = "0.1.1" semver = "1.0.23" @@ -66,9 +64,14 @@ kube-derive = "1.1.0" bollard.workspace = true tar.workspace = true base64.workspace = true +thiserror.workspace = true once_cell = "1.21.3" harmony-secret-derive = { version = "0.1.0", path = "../harmony_secret_derive" } walkdir = "2.5.0" +harmony_inventory_agent = { path = "../harmony_inventory_agent" } +harmony_secret_derive = { version = "0.1.0", path = "../harmony_secret_derive" } +askama.workspace = true +sqlx.workspace = true [dev-dependencies] pretty_assertions.workspace = true diff --git a/harmony/src/domain/config.rs b/harmony/src/domain/config.rs index 62f612f..1a91684 100644 --- a/harmony/src/domain/config.rs +++ b/harmony/src/domain/config.rs @@ -12,4 +12,12 @@ lazy_static! { std::env::var("HARMONY_REGISTRY_PROJECT").unwrap_or_else(|_| "harmony".to_string()); pub static ref DRY_RUN: bool = std::env::var("HARMONY_DRY_RUN").is_ok_and(|value| value.parse().unwrap_or(false)); + pub static ref DEFAULT_DATABASE_URL: String = "sqlite://harmony.sqlite".to_string(); + pub static ref DATABASE_URL: String = std::env::var("HARMONY_DATABASE_URL") + .map(|value| if value.is_empty() { + (*DEFAULT_DATABASE_URL).clone() + } else { + value + }) + .unwrap_or((*DEFAULT_DATABASE_URL).clone()); } diff --git a/harmony/src/domain/data/file.rs b/harmony/src/domain/data/file.rs new file mode 100644 index 0000000..3ae7f3a --- /dev/null +++ b/harmony/src/domain/data/file.rs @@ -0,0 +1,22 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct FileContent { + pub path: FilePath, + pub content: String, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum FilePath { + Relative(String), + Absolute(String), +} + +impl std::fmt::Display for FilePath { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FilePath::Relative(path) => f.write_fmt(format_args!("./{path}")), + FilePath::Absolute(path) => f.write_fmt(format_args!("/{path}")), + } + } +} diff --git a/harmony/src/domain/data/id.rs b/harmony/src/domain/data/id.rs index 5a17ae0..98cf1b9 100644 --- a/harmony/src/domain/data/id.rs +++ b/harmony/src/domain/data/id.rs @@ -24,6 +24,14 @@ pub struct Id { value: String, } +impl Id { + pub fn empty() -> Self { + Id { + value: String::new(), + } + } +} + impl FromStr for Id { type Err = (); @@ -34,6 +42,12 @@ impl FromStr for Id { } } +impl From for Id { + fn from(value: String) -> Self { + Self { value } + } +} + 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/harmony/src/domain/data/mod.rs b/harmony/src/domain/data/mod.rs index e122b20..10d6dc5 100644 --- a/harmony/src/domain/data/mod.rs +++ b/harmony/src/domain/data/mod.rs @@ -1,4 +1,4 @@ -mod id; +mod file; mod version; -pub use id::*; +pub use file::*; pub use version::*; diff --git a/harmony/src/domain/executors/mod.rs b/harmony/src/domain/executors/mod.rs index fb95701..19d0cad 100644 --- a/harmony/src/domain/executors/mod.rs +++ b/harmony/src/domain/executors/mod.rs @@ -1,8 +1,7 @@ use std::fmt; use async_trait::async_trait; - -use super::topology::IpAddress; +use harmony_types::net::IpAddress; #[derive(Debug)] pub enum ExecutorError { diff --git a/harmony/src/domain/hardware/mod.rs b/harmony/src/domain/hardware/mod.rs index 399f313..3a14e1a 100644 --- a/harmony/src/domain/hardware/mod.rs +++ b/harmony/src/domain/hardware/mod.rs @@ -1,38 +1,156 @@ use std::sync::Arc; use derive_new::new; +use harmony_inventory_agent::hwinfo::{CPU, MemoryModule, NetworkInterface, StorageDrive}; use harmony_types::net::MacAddress; -use serde::{Serialize, Serializer, ser::SerializeStruct}; +use serde::{Deserialize, Serialize}; use serde_value::Value; pub type HostGroup = Vec; pub type SwitchGroup = Vec; pub type FirewallGroup = Vec; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Serialize)] pub struct PhysicalHost { + pub id: Id, pub category: HostCategory, pub network: Vec, - pub management: Arc, - pub storage: Vec, + pub storage: Vec, pub labels: Vec