forked from NationTech/harmony
wip: Implement basic K8sAnywhere setup with K3d support
- Added initial K8sAnywhere topology and related modules. - Implemented a basic K3d installation score for cluster bootstrapping. - Introduced LocalhostTopology for local development and testing. - Added necessary module structure and dependencies. - Implemented user prompt for K3d installation confirmation. - Added basic error handling and logging. - Refactored existing code to improve modularity and maintainability. - Included necessary tests to ensure functionality.
This commit is contained in:
parent
6812d05849
commit
3f6f1fa0d4
@ -1,8 +1,12 @@
|
||||
use std::io;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use log::info;
|
||||
use log::{info, warn};
|
||||
use tokio::sync::OnceCell;
|
||||
|
||||
use crate::interpret::{InterpretError, Outcome};
|
||||
use crate::{
|
||||
interpret::{InterpretError, Outcome}, inventory::Inventory, maestro::Maestro, topology::LocalhostTopology
|
||||
};
|
||||
|
||||
use super::{Topology, k8s::K8sClient};
|
||||
|
||||
@ -13,8 +17,8 @@ struct K8sState {
|
||||
}
|
||||
|
||||
enum K8sSource {
|
||||
Existing,
|
||||
K3d,
|
||||
RemoteCluster,
|
||||
LocalK3d,
|
||||
// TODO: Add variants for cloud providers like AwsEks, Gke, Aks
|
||||
}
|
||||
|
||||
@ -23,7 +27,7 @@ pub struct K8sAnywhereTopology {
|
||||
}
|
||||
|
||||
impl K8sAnywhereTopology {
|
||||
async fn try_load_default_kubeconfig(&self) -> Option<K8sClient> {
|
||||
async fn try_load_system_kubeconfig(&self) -> Option<K8sClient> {
|
||||
todo!("Use kube-rs default behavior to load system kubeconfig");
|
||||
}
|
||||
|
||||
@ -32,9 +36,12 @@ impl K8sAnywhereTopology {
|
||||
}
|
||||
|
||||
async fn try_install_k3d(&self) -> Result<K8sClient, InterpretError> {
|
||||
let maestro = Maestro::new(Inventory::autoload(), LocalhostTopology::new());
|
||||
let k3d_score = K3DInstallationScore::default();
|
||||
maestro.interpret(Box::new(k3d_score)).await;
|
||||
todo!(
|
||||
"Create Maestro with LocalDockerTopology or something along these lines and run a K3dInstallationScore on it"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
async fn try_get_or_install_k8s_client(&self) -> Result<Option<K8sState>, InterpretError> {
|
||||
@ -49,7 +56,7 @@ impl K8sAnywhereTopology {
|
||||
};
|
||||
|
||||
if k8s_anywhere_config.use_system_kubeconfig {
|
||||
match self.try_load_default_kubeconfig().await {
|
||||
match self.try_load_system_kubeconfig().await {
|
||||
Some(client) => todo!(),
|
||||
None => todo!(),
|
||||
}
|
||||
@ -61,17 +68,36 @@ impl K8sAnywhereTopology {
|
||||
None => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
info!("No kubernetes configuration found");
|
||||
|
||||
if !k8s_anywhere_config.autoinstall {
|
||||
info!(
|
||||
"Harmony autoinstallation is not activated, do you wish to launch autoinstallation?"
|
||||
"Harmony autoinstallation is not activated, do you wish to launch autoinstallation? (y/N) : "
|
||||
);
|
||||
todo!("Prompt user");
|
||||
let mut input = String::new();
|
||||
|
||||
io::stdin()
|
||||
.read_line(&mut input)
|
||||
.expect("Failed to read line");
|
||||
|
||||
let input = input.trim();
|
||||
|
||||
if !input.eq_ignore_ascii_case("y") {
|
||||
warn!(
|
||||
"Installation cancelled, K8sAnywhere could not initialize a valid Kubernetes client"
|
||||
);
|
||||
return Ok(None);
|
||||
}
|
||||
}
|
||||
|
||||
info!("Starting K8sAnywhere installation");
|
||||
match self.try_install_k3d().await {
|
||||
Ok(client) => todo!(),
|
||||
Ok(client) => Ok(Some(K8sState {
|
||||
client,
|
||||
source: K8sSource::LocalK3d,
|
||||
message: "Successfully installed K3D cluster and acquired client".to_string(),
|
||||
})),
|
||||
Err(_) => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
20
harmony/src/domain/topology/localhost.rs
Normal file
20
harmony/src/domain/topology/localhost.rs
Normal file
@ -0,0 +1,20 @@
|
||||
use async_trait::async_trait;
|
||||
use derive_new::new;
|
||||
|
||||
use crate::interpret::{InterpretError, Outcome};
|
||||
|
||||
use super::Topology;
|
||||
|
||||
#[derive(new)]
|
||||
pub struct LocalhostTopology;
|
||||
|
||||
#[async_trait]
|
||||
impl Topology for LocalhostTopology {
|
||||
fn name(&self) -> &str {
|
||||
"LocalHostTopology"
|
||||
}
|
||||
|
||||
async fn ensure_ready(&self) -> Result<Outcome, InterpretError> {
|
||||
Ok(Outcome::success("Localhost is Chuck Norris, always ready.".to_string()))
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,8 @@ mod ha_cluster;
|
||||
mod host_binding;
|
||||
mod http;
|
||||
mod k8s_anywhere;
|
||||
mod localhost;
|
||||
pub use localhost::*;
|
||||
pub use k8s_anywhere::*;
|
||||
mod load_balancer;
|
||||
pub mod k8s;
|
||||
|
||||
25
harmony/src/modules/k3d/install.rs
Normal file
25
harmony/src/modules/k3d/install.rs
Normal file
@ -0,0 +1,25 @@
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::{score::Score, topology::Topology};
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct K3DInstallationScore {}
|
||||
|
||||
impl<T: Topology> Score<T> for K3DInstallationScore {
|
||||
fn create_interpret(&self) -> Box<dyn crate::interpret::Interpret<T>> {
|
||||
todo!("
|
||||
1. Decide if I create a new crate for k3d management, especially to avoid the ocrtograb dependency
|
||||
2. Implement k3d management
|
||||
3. Find latest tag
|
||||
4. Download k3d to some path managed by harmony (or not?)
|
||||
5. Bootstrap cluster
|
||||
6. Get kubeconfig
|
||||
7. Load kubeconfig in k8s anywhere
|
||||
8. Complete k8sanywhere setup
|
||||
")
|
||||
}
|
||||
|
||||
fn name(&self) -> String {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
3
harmony/src/modules/k3d/mod.rs
Normal file
3
harmony/src/modules/k3d/mod.rs
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
mod install;
|
||||
|
||||
@ -8,3 +8,4 @@ pub mod load_balancer;
|
||||
pub mod okd;
|
||||
pub mod opnsense;
|
||||
pub mod tftp;
|
||||
mod k3d;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user