Compare commits
3 Commits
master
...
opnsense_u
Author | SHA1 | Date | |
---|---|---|---|
|
670b701f6a | ||
|
1eaae2016a | ||
|
c4f4a58dcf |
81
Cargo.lock
generated
81
Cargo.lock
generated
@ -219,6 +219,15 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atomic"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a89cbf775b137e9b968e67227ef7f775587cde3fd31b0d8599dbd0f598a48340"
|
||||||
|
dependencies = [
|
||||||
|
"bytemuck",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atomic-waker"
|
name = "atomic-waker"
|
||||||
version = "1.1.2"
|
version = "1.1.2"
|
||||||
@ -409,6 +418,12 @@ version = "3.19.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
|
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bytemuck"
|
||||||
|
version = "1.23.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder"
|
name = "byteorder"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
@ -1343,6 +1358,7 @@ dependencies = [
|
|||||||
"cidr",
|
"cidr",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"harmony",
|
"harmony",
|
||||||
|
"harmony_cli",
|
||||||
"harmony_macros",
|
"harmony_macros",
|
||||||
"harmony_tui",
|
"harmony_tui",
|
||||||
"harmony_types",
|
"harmony_types",
|
||||||
@ -1428,6 +1444,19 @@ version = "0.2.9"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d"
|
checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "figment"
|
||||||
|
version = "0.10.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8cb01cd46b0cf372153850f4c6c272d9cbea2da513e07538405148f95bd789f3"
|
||||||
|
dependencies = [
|
||||||
|
"atomic",
|
||||||
|
"pear",
|
||||||
|
"serde",
|
||||||
|
"uncased",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "filetime"
|
name = "filetime"
|
||||||
version = "0.2.25"
|
version = "0.2.25"
|
||||||
@ -1750,6 +1779,7 @@ dependencies = [
|
|||||||
"dyn-clone",
|
"dyn-clone",
|
||||||
"email_address",
|
"email_address",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
|
"figment",
|
||||||
"fqdn",
|
"fqdn",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"harmony_macros",
|
"harmony_macros",
|
||||||
@ -2415,6 +2445,12 @@ version = "2.0.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd"
|
checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "inlinable_string"
|
||||||
|
version = "0.1.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "inout"
|
name = "inout"
|
||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
@ -3236,6 +3272,29 @@ dependencies = [
|
|||||||
"hmac",
|
"hmac",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pear"
|
||||||
|
version = "0.2.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bdeeaa00ce488657faba8ebf44ab9361f9365a97bd39ffb8a60663f57ff4b467"
|
||||||
|
dependencies = [
|
||||||
|
"inlinable_string",
|
||||||
|
"pear_codegen",
|
||||||
|
"yansi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pear_codegen"
|
||||||
|
version = "0.2.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4bab5b985dc082b345f812b7df84e1bef27e7207b39e448439ba8bd69c93f147"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"proc-macro2-diagnostics",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pem"
|
name = "pem"
|
||||||
version = "3.0.5"
|
version = "3.0.5"
|
||||||
@ -3498,6 +3557,19 @@ dependencies = [
|
|||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2-diagnostics"
|
||||||
|
version = "0.10.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"version_check",
|
||||||
|
"yansi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "punycode"
|
name = "punycode"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
@ -5140,6 +5212,15 @@ version = "0.1.7"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
|
checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uncased"
|
||||||
|
version = "0.9.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e1b88fcfe09e89d3866a5c11019378088af2d24c3fbd4f0543f96b479ec90697"
|
||||||
|
dependencies = [
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.18"
|
version = "1.0.18"
|
||||||
|
@ -56,3 +56,4 @@ pretty_assertions = "1.4.1"
|
|||||||
bollard = "0.19.1"
|
bollard = "0.19.1"
|
||||||
base64 = "0.22.1"
|
base64 = "0.22.1"
|
||||||
tar = "0.4.44"
|
tar = "0.4.44"
|
||||||
|
figment = { version = "0.10.19", features = ["env"] }
|
||||||
|
@ -16,3 +16,4 @@ harmony_macros = { path = "../../harmony_macros" }
|
|||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
env_logger = { workspace = true }
|
env_logger = { workspace = true }
|
||||||
url = { workspace = true }
|
url = { workspace = true }
|
||||||
|
harmony_cli = { version = "0.1.0", path = "../../harmony_cli" }
|
||||||
|
@ -13,7 +13,7 @@ use harmony::{
|
|||||||
dummy::{ErrorScore, PanicScore, SuccessScore},
|
dummy::{ErrorScore, PanicScore, SuccessScore},
|
||||||
http::StaticFilesHttpScore,
|
http::StaticFilesHttpScore,
|
||||||
okd::{dhcp::OKDDhcpScore, dns::OKDDnsScore, load_balancer::OKDLoadBalancerScore},
|
okd::{dhcp::OKDDhcpScore, dns::OKDDnsScore, load_balancer::OKDLoadBalancerScore},
|
||||||
opnsense::OPNsenseShellCommandScore,
|
opnsense::{OPNSenseLaunchUpgrade, OPNsenseShellCommandScore},
|
||||||
tftp::TftpScore,
|
tftp::TftpScore,
|
||||||
},
|
},
|
||||||
topology::{LogicalHost, UnmanagedRouter, Url},
|
topology::{LogicalHost, UnmanagedRouter, Url},
|
||||||
@ -22,8 +22,10 @@ use harmony_macros::{ip, mac_address};
|
|||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
|
env_logger::init();
|
||||||
|
|
||||||
let firewall = harmony::topology::LogicalHost {
|
let firewall = harmony::topology::LogicalHost {
|
||||||
ip: ip!("192.168.5.229"),
|
ip: ip!("192.168.122.106"),
|
||||||
name: String::from("opnsense-1"),
|
name: String::from("opnsense-1"),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -95,9 +97,12 @@ async fn main() {
|
|||||||
opnsense: opnsense.get_opnsense_config(),
|
opnsense: opnsense.get_opnsense_config(),
|
||||||
command: "touch /tmp/helloharmonytouching".to_string(),
|
command: "touch /tmp/helloharmonytouching".to_string(),
|
||||||
}),
|
}),
|
||||||
|
// Box::new(OPNSenseLaunchUpgrade {
|
||||||
|
// opnsense: opnsense.get_opnsense_config(),
|
||||||
|
// }),
|
||||||
Box::new(SuccessScore {}),
|
Box::new(SuccessScore {}),
|
||||||
Box::new(ErrorScore {}),
|
Box::new(ErrorScore {}),
|
||||||
Box::new(PanicScore {}),
|
Box::new(PanicScore {}),
|
||||||
]);
|
]);
|
||||||
harmony_tui::init(maestro).await.unwrap();
|
harmony_cli::init(maestro, None).await.unwrap();
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,7 @@ serde_with = "3.14.0"
|
|||||||
bollard.workspace = true
|
bollard.workspace = true
|
||||||
tar.workspace = true
|
tar.workspace = true
|
||||||
base64.workspace = true
|
base64.workspace = true
|
||||||
|
figment.workspace = true
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
pretty_assertions.workspace = true
|
pretty_assertions.workspace = true
|
||||||
|
@ -1,15 +1,66 @@
|
|||||||
|
use figment::{
|
||||||
|
Error, Figment, Metadata, Profile, Provider,
|
||||||
|
providers::{Env, Format},
|
||||||
|
value::{Dict, Map},
|
||||||
|
};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
lazy_static! {
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
pub static ref HARMONY_DATA_DIR: PathBuf = directories::BaseDirs::new()
|
pub struct Config {
|
||||||
.unwrap()
|
pub data_dir: PathBuf,
|
||||||
.data_dir()
|
pub registry_url: String,
|
||||||
.join("harmony");
|
pub registry_project: String,
|
||||||
pub static ref REGISTRY_URL: String =
|
pub dry_run: bool,
|
||||||
std::env::var("HARMONY_REGISTRY_URL").unwrap_or_else(|_| "hub.nationtech.io".to_string());
|
pub run_upgrades: bool,
|
||||||
pub static ref REGISTRY_PROJECT: String =
|
}
|
||||||
std::env::var("HARMONY_REGISTRY_PROJECT").unwrap_or_else(|_| "harmony".to_string());
|
|
||||||
pub static ref DRY_RUN: bool =
|
impl Default for Config {
|
||||||
std::env::var("HARMONY_DRY_RUN").map_or(true, |value| value.parse().unwrap_or(true));
|
fn default() -> Self {
|
||||||
|
Config {
|
||||||
|
data_dir: directories::BaseDirs::new()
|
||||||
|
.unwrap()
|
||||||
|
.data_dir()
|
||||||
|
.join("harmony"),
|
||||||
|
registry_url: "hub.nationtech.io".to_string(),
|
||||||
|
registry_project: "harmony".to_string(),
|
||||||
|
dry_run: true,
|
||||||
|
run_upgrades: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Config {
|
||||||
|
pub fn load() -> Result<Self, figment::Error> {
|
||||||
|
Figment::from(Config::default())
|
||||||
|
.merge(Env::prefixed("HARMONY_"))
|
||||||
|
.extract()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from<T: Provider>(provider: T) -> Result<Config, Error> {
|
||||||
|
Figment::from(provider).extract()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn figment() -> Figment {
|
||||||
|
use figment::providers::Env;
|
||||||
|
|
||||||
|
// In reality, whatever the library desires.
|
||||||
|
Figment::from(Config::default()).merge(Env::prefixed("HARMONY_"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Provider for Config {
|
||||||
|
fn metadata(&self) -> Metadata {
|
||||||
|
Metadata::named("Harmony Config")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn data(&self) -> Result<Map<Profile, Dict>, Error> {
|
||||||
|
figment::providers::Serialized::defaults(Config::default()).data()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn profile(&self) -> Option<Profile> {
|
||||||
|
// Optionally, a profile that's selected by default.
|
||||||
|
Some(Profile::Default)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use harmony_macros::ip;
|
use harmony_macros::ip;
|
||||||
use harmony_types::net::MacAddress;
|
use harmony_types::net::MacAddress;
|
||||||
|
use log::error;
|
||||||
use log::info;
|
use log::info;
|
||||||
|
|
||||||
|
use crate::config::Config;
|
||||||
use crate::executors::ExecutorError;
|
use crate::executors::ExecutorError;
|
||||||
use crate::interpret::InterpretError;
|
use crate::interpret::InterpretError;
|
||||||
use crate::interpret::Outcome;
|
use crate::interpret::Outcome;
|
||||||
|
use crate::inventory::Inventory;
|
||||||
|
use crate::topology::upgradeable::Upgradeable;
|
||||||
|
|
||||||
use super::DHCPStaticEntry;
|
use super::DHCPStaticEntry;
|
||||||
use super::DhcpServer;
|
use super::DhcpServer;
|
||||||
@ -25,9 +29,12 @@ use super::TftpServer;
|
|||||||
use super::Topology;
|
use super::Topology;
|
||||||
use super::Url;
|
use super::Url;
|
||||||
use super::k8s::K8sClient;
|
use super::k8s::K8sClient;
|
||||||
|
use std::fmt::Debug;
|
||||||
|
use std::net::IpAddr;
|
||||||
|
use std::str::FromStr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct HAClusterTopology {
|
pub struct HAClusterTopology {
|
||||||
pub domain_name: String,
|
pub domain_name: String,
|
||||||
pub router: Arc<dyn Router>,
|
pub router: Arc<dyn Router>,
|
||||||
@ -49,9 +56,15 @@ impl Topology for HAClusterTopology {
|
|||||||
"HAClusterTopology"
|
"HAClusterTopology"
|
||||||
}
|
}
|
||||||
async fn ensure_ready(&self) -> Result<Outcome, InterpretError> {
|
async fn ensure_ready(&self) -> Result<Outcome, InterpretError> {
|
||||||
todo!(
|
error!(
|
||||||
"ensure_ready, not entirely sure what it should do here, probably something like verify that the hosts are reachable and all services are up and ready."
|
"ensure_ready, not entirely sure what it should do here, probably something like verify that the hosts are reachable and all services are up and ready."
|
||||||
)
|
);
|
||||||
|
let config = Config::load().expect("couldn't load config");
|
||||||
|
|
||||||
|
if config.run_upgrades {
|
||||||
|
self.upgrade(&Inventory::empty(), self).await?;
|
||||||
|
}
|
||||||
|
Ok(Outcome::success("for now do nothing".to_string()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,6 +264,13 @@ impl Topology for DummyInfra {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl<T: Topology> Upgradeable<T> for DummyInfra {
|
||||||
|
async fn upgrade(&self, _inventory: &Inventory, _topology: &T) -> Result<(), InterpretError> {
|
||||||
|
unimplemented!("{}", UNIMPLEMENTED_DUMMY_INFRA)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const UNIMPLEMENTED_DUMMY_INFRA: &str = "This is a dummy infrastructure, no operation is supported";
|
const UNIMPLEMENTED_DUMMY_INFRA: &str = "This is a dummy infrastructure, no operation is supported";
|
||||||
|
|
||||||
impl Router for DummyInfra {
|
impl Router for DummyInfra {
|
||||||
@ -417,3 +437,12 @@ impl DnsServer for DummyInfra {
|
|||||||
unimplemented!("{}", UNIMPLEMENTED_DUMMY_INFRA)
|
unimplemented!("{}", UNIMPLEMENTED_DUMMY_INFRA)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl<T: Topology> Upgradeable<T> for HAClusterTopology {
|
||||||
|
async fn upgrade(&self, inventory: &Inventory, topology: &T) -> Result<(), InterpretError> {
|
||||||
|
error!("TODO implement upgrades for all parts of the cluster");
|
||||||
|
self.firewall.upgrade(inventory, topology).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -20,6 +20,8 @@ use log::{debug, error, trace};
|
|||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
use similar::{DiffableStr, TextDiff};
|
use similar::{DiffableStr, TextDiff};
|
||||||
|
|
||||||
|
use crate::config::Config as HarmonyConfig;
|
||||||
|
|
||||||
#[derive(new, Clone)]
|
#[derive(new, Clone)]
|
||||||
pub struct K8sClient {
|
pub struct K8sClient {
|
||||||
client: Client,
|
client: Client,
|
||||||
@ -154,7 +156,9 @@ impl K8sClient {
|
|||||||
.as_ref()
|
.as_ref()
|
||||||
.expect("K8s Resource should have a name");
|
.expect("K8s Resource should have a name");
|
||||||
|
|
||||||
if *crate::config::DRY_RUN {
|
let config = HarmonyConfig::load().expect("couldn't load config");
|
||||||
|
|
||||||
|
if config.dry_run {
|
||||||
match api.get(name).await {
|
match api.get(name).await {
|
||||||
Ok(current) => {
|
Ok(current) => {
|
||||||
trace!("Received current value {current:#?}");
|
trace!("Received current value {current:#?}");
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
use std::{process::Command, sync::Arc};
|
use std::{process::Command, sync::Arc};
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use figment::{Figment, providers::Env};
|
||||||
use inquire::Confirm;
|
use inquire::Confirm;
|
||||||
use log::{debug, info, warn};
|
use log::{debug, info, warn};
|
||||||
use serde::Serialize;
|
use serde::{Deserialize, Serialize};
|
||||||
use tokio::sync::OnceCell;
|
use tokio::sync::OnceCell;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -219,7 +220,7 @@ impl K8sAnywhereTopology {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug, Deserialize)]
|
||||||
pub struct K8sAnywhereConfig {
|
pub struct K8sAnywhereConfig {
|
||||||
/// The path of the KUBECONFIG file that Harmony should use to interact with the Kubernetes
|
/// The path of the KUBECONFIG file that Harmony should use to interact with the Kubernetes
|
||||||
/// cluster
|
/// cluster
|
||||||
@ -246,25 +247,29 @@ pub struct K8sAnywhereConfig {
|
|||||||
///
|
///
|
||||||
/// default: true
|
/// default: true
|
||||||
pub use_local_k3d: bool,
|
pub use_local_k3d: bool,
|
||||||
pub harmony_profile: String,
|
pub profile: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for K8sAnywhereConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
kubeconfig: None,
|
||||||
|
use_system_kubeconfig: false,
|
||||||
|
autoinstall: false,
|
||||||
|
// TODO harmony_profile should be managed at a more core level than this
|
||||||
|
profile: "dev".to_string(),
|
||||||
|
use_local_k3d: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl K8sAnywhereConfig {
|
impl K8sAnywhereConfig {
|
||||||
fn from_env() -> Self {
|
fn from_env() -> Self {
|
||||||
Self {
|
Figment::new()
|
||||||
kubeconfig: std::env::var("KUBECONFIG").ok().map(|v| v.to_string()),
|
.merge(Env::prefixed("HARMONY_"))
|
||||||
use_system_kubeconfig: std::env::var("HARMONY_USE_SYSTEM_KUBECONFIG")
|
.merge(Env::raw().only(&["KUBECONFIG"]))
|
||||||
.map_or_else(|_| false, |v| v.parse().ok().unwrap_or(false)),
|
.extract()
|
||||||
autoinstall: std::env::var("HARMONY_AUTOINSTALL")
|
.expect("couldn't load config from env")
|
||||||
.map_or_else(|_| false, |v| v.parse().ok().unwrap_or(false)),
|
|
||||||
// TODO harmony_profile should be managed at a more core level than this
|
|
||||||
harmony_profile: std::env::var("HARMONY_PROFILE").map_or_else(
|
|
||||||
|_| "dev".to_string(),
|
|
||||||
|v| v.parse().ok().unwrap_or("dev".to_string()),
|
|
||||||
),
|
|
||||||
use_local_k3d: std::env::var("HARMONY_USE_LOCAL_K3D")
|
|
||||||
.map_or_else(|_| true, |v| v.parse().ok().unwrap_or(true)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,7 +309,7 @@ impl MultiTargetTopology for K8sAnywhereTopology {
|
|||||||
return DeploymentTarget::LocalDev;
|
return DeploymentTarget::LocalDev;
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.config.harmony_profile.to_lowercase().as_str() {
|
match self.config.profile.to_lowercase().as_str() {
|
||||||
"staging" => DeploymentTarget::Staging,
|
"staging" => DeploymentTarget::Staging,
|
||||||
"production" => DeploymentTarget::Production,
|
"production" => DeploymentTarget::Production,
|
||||||
_ => todo!("HARMONY_PROFILE must be set when use_local_k3d is not set"),
|
_ => todo!("HARMONY_PROFILE must be set when use_local_k3d is not set"),
|
||||||
|
@ -6,6 +6,7 @@ mod k8s_anywhere;
|
|||||||
mod localhost;
|
mod localhost;
|
||||||
pub mod oberservability;
|
pub mod oberservability;
|
||||||
pub mod tenant;
|
pub mod tenant;
|
||||||
|
pub mod upgradeable;
|
||||||
pub use k8s_anywhere::*;
|
pub use k8s_anywhere::*;
|
||||||
pub use localhost::*;
|
pub use localhost::*;
|
||||||
pub mod k8s;
|
pub mod k8s;
|
||||||
|
@ -2,9 +2,15 @@ use std::{net::Ipv4Addr, str::FromStr, sync::Arc};
|
|||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use harmony_types::net::MacAddress;
|
use harmony_types::net::MacAddress;
|
||||||
|
use log::debug;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
use crate::executors::ExecutorError;
|
use crate::{
|
||||||
|
executors::ExecutorError,
|
||||||
|
interpret::InterpretError,
|
||||||
|
inventory::Inventory,
|
||||||
|
topology::{Topology, upgradeable::Upgradeable},
|
||||||
|
};
|
||||||
|
|
||||||
use super::{IpAddress, LogicalHost, k8s::K8sClient};
|
use super::{IpAddress, LogicalHost, k8s::K8sClient};
|
||||||
|
|
||||||
@ -38,6 +44,15 @@ impl std::fmt::Debug for dyn Firewall {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #[async_trait]
|
||||||
|
// impl<T: Topology> Upgradeable<T> for dyn Firewall {
|
||||||
|
// async fn upgrade(&self, inventory: &Inventory, topology: &T) -> Result<(), InterpretError> {
|
||||||
|
// debug!("upgrading");
|
||||||
|
// self.upgrade(inventory, topology).await?;
|
||||||
|
// Ok(())
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
pub struct NetworkDomain {
|
pub struct NetworkDomain {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
}
|
}
|
||||||
|
8
harmony/src/domain/topology/upgradeable.rs
Normal file
8
harmony/src/domain/topology/upgradeable.rs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
use async_trait::async_trait;
|
||||||
|
|
||||||
|
use crate::{interpret::InterpretError, inventory::Inventory};
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
pub trait Upgradeable<T>: Send + Sync {
|
||||||
|
async fn upgrade(&self, inventory: &Inventory, topology: &T) -> Result<(), InterpretError>;
|
||||||
|
}
|
@ -7,13 +7,18 @@ mod management;
|
|||||||
mod tftp;
|
mod tftp;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use async_trait::async_trait;
|
||||||
pub use management::*;
|
pub use management::*;
|
||||||
use opnsense_config_xml::Host;
|
use opnsense_config_xml::Host;
|
||||||
use tokio::sync::RwLock;
|
use tokio::sync::RwLock;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
executors::ExecutorError,
|
executors::ExecutorError,
|
||||||
topology::{IpAddress, LogicalHost},
|
interpret::InterpretError,
|
||||||
|
inventory::Inventory,
|
||||||
|
modules::opnsense::OPNSenseLaunchUpgrade,
|
||||||
|
score::Score,
|
||||||
|
topology::{IpAddress, LogicalHost, Topology, upgradeable::Upgradeable},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -49,3 +54,17 @@ impl OPNSenseFirewall {
|
|||||||
.map_err(|e| ExecutorError::UnexpectedError(e.to_string()))
|
.map_err(|e| ExecutorError::UnexpectedError(e.to_string()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl<T: Topology> Upgradeable<T> for OPNSenseFirewall {
|
||||||
|
async fn upgrade(&self, inventory: &Inventory, topology: &T) -> Result<(), InterpretError> {
|
||||||
|
OPNSenseLaunchUpgrade {
|
||||||
|
opnsense: self.get_opnsense_config(),
|
||||||
|
}
|
||||||
|
.create_interpret()
|
||||||
|
.execute(inventory, topology)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -6,7 +6,7 @@ use serde_yaml::Value;
|
|||||||
use tempfile::NamedTempFile;
|
use tempfile::NamedTempFile;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::HARMONY_DATA_DIR,
|
config::Config,
|
||||||
data::Version,
|
data::Version,
|
||||||
inventory::Inventory,
|
inventory::Inventory,
|
||||||
modules::application::{
|
modules::application::{
|
||||||
@ -56,12 +56,14 @@ impl<A: OCICompliant + HelmPackage> ContinuousDelivery<A> {
|
|||||||
chart_url: String,
|
chart_url: String,
|
||||||
image_name: String,
|
image_name: String,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
|
let config = Config::load().expect("couldn't load config");
|
||||||
|
|
||||||
error!(
|
error!(
|
||||||
"FIXME This works only with local k3d installations, which is fine only for current demo purposes. We assume usage of K8sAnywhereTopology"
|
"FIXME This works only with local k3d installations, which is fine only for current demo purposes. We assume usage of K8sAnywhereTopology"
|
||||||
);
|
);
|
||||||
|
|
||||||
error!("TODO hardcoded k3d bin path is wrong");
|
error!("TODO hardcoded k3d bin path is wrong");
|
||||||
let k3d_bin_path = (*HARMONY_DATA_DIR).join("k3d").join("k3d");
|
let k3d_bin_path = config.data_dir.join("k3d").join("k3d");
|
||||||
// --- 1. Import the container image into the k3d cluster ---
|
// --- 1. Import the container image into the k3d cluster ---
|
||||||
info!(
|
info!(
|
||||||
"Importing image '{}' into k3d cluster 'harmony'",
|
"Importing image '{}' into k3d cluster 'harmony'",
|
||||||
|
@ -14,7 +14,7 @@ use log::{debug, error, info};
|
|||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use tar::Archive;
|
use tar::Archive;
|
||||||
|
|
||||||
use crate::config::{REGISTRY_PROJECT, REGISTRY_URL};
|
use crate::config::Config;
|
||||||
use crate::{
|
use crate::{
|
||||||
score::Score,
|
score::Score,
|
||||||
topology::{Topology, Url},
|
topology::{Topology, Url},
|
||||||
@ -134,10 +134,12 @@ impl OCICompliant for RustWebapp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn image_name(&self) -> String {
|
fn image_name(&self) -> String {
|
||||||
|
let config = Config::load().expect("couldn't load config");
|
||||||
|
|
||||||
format!(
|
format!(
|
||||||
"{}/{}/{}",
|
"{}/{}/{}",
|
||||||
*REGISTRY_URL,
|
config.registry_url,
|
||||||
*REGISTRY_PROJECT,
|
config.registry_project,
|
||||||
&self.local_image_name()
|
&self.local_image_name()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -575,9 +577,11 @@ spec:
|
|||||||
&self,
|
&self,
|
||||||
packaged_chart_path: &PathBuf,
|
packaged_chart_path: &PathBuf,
|
||||||
) -> Result<String, Box<dyn std::error::Error>> {
|
) -> Result<String, Box<dyn std::error::Error>> {
|
||||||
|
let config = Config::load().expect("couldn't load config");
|
||||||
|
|
||||||
// The chart name is the file stem of the .tgz file
|
// The chart name is the file stem of the .tgz file
|
||||||
let chart_file_name = packaged_chart_path.file_stem().unwrap().to_str().unwrap();
|
let chart_file_name = packaged_chart_path.file_stem().unwrap().to_str().unwrap();
|
||||||
let oci_push_url = format!("oci://{}/{}", *REGISTRY_URL, *REGISTRY_PROJECT);
|
let oci_push_url = format!("oci://{}/{}", config.registry_url, config.registry_project);
|
||||||
let oci_pull_url = format!("{oci_push_url}/{}-chart", self.name);
|
let oci_pull_url = format!("{oci_push_url}/{}-chart", self.name);
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
|
@ -5,7 +5,7 @@ use log::info;
|
|||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::HARMONY_DATA_DIR,
|
config::Config,
|
||||||
data::{Id, Version},
|
data::{Id, Version},
|
||||||
interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome},
|
interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome},
|
||||||
inventory::Inventory,
|
inventory::Inventory,
|
||||||
@ -21,8 +21,10 @@ pub struct K3DInstallationScore {
|
|||||||
|
|
||||||
impl Default for K3DInstallationScore {
|
impl Default for K3DInstallationScore {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
let config = Config::load().expect("couldn't load config");
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
installation_path: HARMONY_DATA_DIR.join("k3d"),
|
installation_path: config.data_dir.join("k3d"),
|
||||||
cluster_name: "harmony".to_string(),
|
cluster_name: "harmony".to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ use async_trait::async_trait;
|
|||||||
use log::{debug, info};
|
use log::{debug, info};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
use crate::config::{REGISTRY_PROJECT, REGISTRY_URL};
|
use crate::config::Config as HarmonyConfig;
|
||||||
use crate::modules::k8s::ingress::K8sIngressScore;
|
use crate::modules::k8s::ingress::K8sIngressScore;
|
||||||
use crate::topology::HelmCommand;
|
use crate::topology::HelmCommand;
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -355,7 +355,12 @@ opcache.fast_shutdown=1
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn push_docker_image(&self, image_name: &str) -> Result<String, Box<dyn std::error::Error>> {
|
fn push_docker_image(&self, image_name: &str) -> Result<String, Box<dyn std::error::Error>> {
|
||||||
let full_tag = format!("{}/{}/{}", *REGISTRY_URL, *REGISTRY_PROJECT, &image_name);
|
let config = HarmonyConfig::load().expect("couldn't load config");
|
||||||
|
|
||||||
|
let full_tag = format!(
|
||||||
|
"{}/{}/{}",
|
||||||
|
config.registry_url, config.registry_project, &image_name
|
||||||
|
);
|
||||||
let output = std::process::Command::new("docker")
|
let output = std::process::Command::new("docker")
|
||||||
.args(["tag", image_name, &full_tag])
|
.args(["tag", image_name, &full_tag])
|
||||||
.output()?;
|
.output()?;
|
||||||
|
@ -83,6 +83,7 @@ pub struct Interface {
|
|||||||
pub adv_dhcp_config_advanced: Option<MaybeString>,
|
pub adv_dhcp_config_advanced: Option<MaybeString>,
|
||||||
pub adv_dhcp_config_file_override: Option<MaybeString>,
|
pub adv_dhcp_config_file_override: Option<MaybeString>,
|
||||||
pub adv_dhcp_config_file_override_path: Option<MaybeString>,
|
pub adv_dhcp_config_file_override_path: Option<MaybeString>,
|
||||||
|
pub mtu: Option<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::HAProxy;
|
use crate::HAProxy;
|
||||||
use crate::{data::dhcpd::DhcpInterface, xml_utils::to_xml_str};
|
use crate::{data::dhcpd::DhcpInterface, xml_utils::to_xml_str};
|
||||||
use log::error;
|
use log::{debug, error};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use yaserde::{MaybeString, NamedList, RawXml};
|
use yaserde::{MaybeString, NamedList, RawXml};
|
||||||
use yaserde_derive::{YaDeserialize, YaSerialize};
|
use yaserde_derive::{YaDeserialize, YaSerialize};
|
||||||
@ -17,12 +17,12 @@ pub struct OPNsense {
|
|||||||
pub dhcpd: NamedList<DhcpInterface>,
|
pub dhcpd: NamedList<DhcpInterface>,
|
||||||
pub snmpd: Snmpd,
|
pub snmpd: Snmpd,
|
||||||
pub syslog: Syslog,
|
pub syslog: Syslog,
|
||||||
pub nat: Nat,
|
pub nat: Option<Nat>,
|
||||||
pub filter: Filters,
|
pub filter: Filters,
|
||||||
pub load_balancer: Option<LoadBalancer>,
|
pub load_balancer: Option<LoadBalancer>,
|
||||||
pub rrd: Option<RawXml>,
|
pub rrd: Option<RawXml>,
|
||||||
pub ntpd: Ntpd,
|
pub ntpd: Ntpd,
|
||||||
pub widgets: Widgets,
|
pub widgets: Option<Widgets>,
|
||||||
pub revision: Revision,
|
pub revision: Revision,
|
||||||
#[yaserde(rename = "OPNsense")]
|
#[yaserde(rename = "OPNsense")]
|
||||||
pub opnsense: OPNsenseXmlSection,
|
pub opnsense: OPNsenseXmlSection,
|
||||||
@ -46,10 +46,12 @@ pub struct OPNsense {
|
|||||||
pub pischem: Option<Pischem>,
|
pub pischem: Option<Pischem>,
|
||||||
pub ifgroups: Ifgroups,
|
pub ifgroups: Ifgroups,
|
||||||
pub dnsmasq: Option<RawXml>,
|
pub dnsmasq: Option<RawXml>,
|
||||||
|
pub wizardtemp: Option<RawXml>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<String> for OPNsense {
|
impl From<String> for OPNsense {
|
||||||
fn from(content: String) -> Self {
|
fn from(content: String) -> Self {
|
||||||
|
debug!("XML content: {content}");
|
||||||
yaserde::de::from_str(&content)
|
yaserde::de::from_str(&content)
|
||||||
.map_err(|e| println!("{}", e.to_string()))
|
.map_err(|e| println!("{}", e.to_string()))
|
||||||
.expect("OPNSense received invalid string, should be full XML")
|
.expect("OPNSense received invalid string, should be full XML")
|
||||||
@ -242,6 +244,7 @@ pub struct Ssh {
|
|||||||
pub passwordauth: u8,
|
pub passwordauth: u8,
|
||||||
pub keysig: MaybeString,
|
pub keysig: MaybeString,
|
||||||
pub permitrootlogin: u8,
|
pub permitrootlogin: u8,
|
||||||
|
pub rekeylimit: MaybeString,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
|
#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
|
||||||
@ -271,6 +274,7 @@ pub struct Group {
|
|||||||
pub member: Vec<u32>,
|
pub member: Vec<u32>,
|
||||||
#[yaserde(rename = "priv")]
|
#[yaserde(rename = "priv")]
|
||||||
pub priv_field: String,
|
pub priv_field: String,
|
||||||
|
pub source_networks: Vec<MaybeString>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
|
#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
|
||||||
@ -1506,7 +1510,7 @@ pub struct Vlans {
|
|||||||
|
|
||||||
#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
|
#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
|
||||||
pub struct Bridges {
|
pub struct Bridges {
|
||||||
pub bridged: MaybeString,
|
pub bridged: Option<MaybeString>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
|
#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
|
||||||
|
Loading…
Reference in New Issue
Block a user