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 async_trait::async_trait;
|
||||||
use log::info;
|
use log::{info, warn};
|
||||||
use tokio::sync::OnceCell;
|
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};
|
use super::{Topology, k8s::K8sClient};
|
||||||
|
|
||||||
@ -13,8 +17,8 @@ struct K8sState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum K8sSource {
|
enum K8sSource {
|
||||||
Existing,
|
RemoteCluster,
|
||||||
K3d,
|
LocalK3d,
|
||||||
// TODO: Add variants for cloud providers like AwsEks, Gke, Aks
|
// TODO: Add variants for cloud providers like AwsEks, Gke, Aks
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,7 +27,7 @@ pub struct K8sAnywhereTopology {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl 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");
|
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> {
|
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!(
|
todo!(
|
||||||
"Create Maestro with LocalDockerTopology or something along these lines and run a K3dInstallationScore on it"
|
"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> {
|
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 {
|
if k8s_anywhere_config.use_system_kubeconfig {
|
||||||
match self.try_load_default_kubeconfig().await {
|
match self.try_load_system_kubeconfig().await {
|
||||||
Some(client) => todo!(),
|
Some(client) => todo!(),
|
||||||
None => todo!(),
|
None => todo!(),
|
||||||
}
|
}
|
||||||
@ -61,17 +68,36 @@ impl K8sAnywhereTopology {
|
|||||||
None => todo!(),
|
None => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
info!("No kubernetes configuration found");
|
info!("No kubernetes configuration found");
|
||||||
|
|
||||||
if !k8s_anywhere_config.autoinstall {
|
if !k8s_anywhere_config.autoinstall {
|
||||||
info!(
|
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 {
|
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!(),
|
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 host_binding;
|
||||||
mod http;
|
mod http;
|
||||||
mod k8s_anywhere;
|
mod k8s_anywhere;
|
||||||
|
mod localhost;
|
||||||
|
pub use localhost::*;
|
||||||
pub use k8s_anywhere::*;
|
pub use k8s_anywhere::*;
|
||||||
mod load_balancer;
|
mod load_balancer;
|
||||||
pub mod k8s;
|
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 okd;
|
||||||
pub mod opnsense;
|
pub mod opnsense;
|
||||||
pub mod tftp;
|
pub mod tftp;
|
||||||
|
mod k3d;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user