Compare commits
No commits in common. "e5ddd296db85f6d4f567126e4be75b4240320ecb" and "78e989334195c3b9807833b94b6b9c4e5d9ab29d" have entirely different histories.
e5ddd296db
...
78e9893341
@ -1,11 +1,6 @@
|
|||||||
use derive_new::new;
|
use derive_new::new;
|
||||||
use k8s_openapi::NamespaceResourceScope;
|
use k8s_openapi::NamespaceResourceScope;
|
||||||
use kube::{
|
use kube::{Api, Client, Error, Resource, api::PostParams};
|
||||||
Api, Client, Config, Error, Resource,
|
|
||||||
api::PostParams,
|
|
||||||
config::{KubeConfigOptions, Kubeconfig},
|
|
||||||
};
|
|
||||||
use log::error;
|
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
|
|
||||||
#[derive(new)]
|
#[derive(new)]
|
||||||
@ -62,22 +57,4 @@ impl K8sClient {
|
|||||||
}
|
}
|
||||||
todo!("")
|
todo!("")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn from_kubeconfig(path: &str) -> Option<K8sClient> {
|
|
||||||
let k = match Kubeconfig::read_from(path) {
|
|
||||||
Ok(k) => k,
|
|
||||||
Err(e) => {
|
|
||||||
error!("Failed to load kubeconfig from {path} : {e}");
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Some(K8sClient::new(
|
|
||||||
Client::try_from(
|
|
||||||
Config::from_custom_kubeconfig(k, &KubeConfigOptions::default())
|
|
||||||
.await
|
|
||||||
.unwrap(),
|
|
||||||
)
|
|
||||||
.unwrap(),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,13 +17,12 @@ use super::{HelmCommand, K8sclient, Topology, k8s::K8sClient};
|
|||||||
|
|
||||||
struct K8sState {
|
struct K8sState {
|
||||||
client: Arc<K8sClient>,
|
client: Arc<K8sClient>,
|
||||||
source: K8sSource,
|
_source: K8sSource,
|
||||||
message: String,
|
message: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum K8sSource {
|
enum K8sSource {
|
||||||
LocalK3d,
|
LocalK3d,
|
||||||
Kubeconfig,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct K8sAnywhereTopology {
|
pub struct K8sAnywhereTopology {
|
||||||
@ -76,7 +75,7 @@ impl K8sAnywhereTopology {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn try_load_kubeconfig(&self, path: &str) -> Option<K8sClient> {
|
async fn try_load_kubeconfig(&self, path: &str) -> Option<K8sClient> {
|
||||||
K8sClient::from_kubeconfig(path).await
|
todo!("Use kube-rs to load kubeconfig at path {path}");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_k3d_installation_score(&self) -> K3DInstallationScore {
|
fn get_k3d_installation_score(&self) -> K3DInstallationScore {
|
||||||
@ -110,18 +109,8 @@ impl K8sAnywhereTopology {
|
|||||||
|
|
||||||
if let Some(kubeconfig) = k8s_anywhere_config.kubeconfig {
|
if let Some(kubeconfig) = k8s_anywhere_config.kubeconfig {
|
||||||
match self.try_load_kubeconfig(&kubeconfig).await {
|
match self.try_load_kubeconfig(&kubeconfig).await {
|
||||||
Some(client) => {
|
Some(_client) => todo!(),
|
||||||
return Ok(Some(K8sState {
|
None => todo!(),
|
||||||
client: Arc::new(client),
|
|
||||||
source: K8sSource::Kubeconfig,
|
|
||||||
message: format!("Loaded k8s client from kubeconfig {kubeconfig}"),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
return Err(InterpretError::new(format!(
|
|
||||||
"Failed to load kubeconfig from {kubeconfig}"
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,7 +142,7 @@ impl K8sAnywhereTopology {
|
|||||||
let state = match k3d.get_client().await {
|
let state = match k3d.get_client().await {
|
||||||
Ok(client) => K8sState {
|
Ok(client) => K8sState {
|
||||||
client: Arc::new(K8sClient::new(client)),
|
client: Arc::new(K8sClient::new(client)),
|
||||||
source: K8sSource::LocalK3d,
|
_source: K8sSource::LocalK3d,
|
||||||
message: "Successfully installed K3D cluster and acquired client".to_string(),
|
message: "Successfully installed K3D cluster and acquired client".to_string(),
|
||||||
},
|
},
|
||||||
Err(_) => todo!(),
|
Err(_) => todo!(),
|
||||||
|
|||||||
@ -1,46 +0,0 @@
|
|||||||
use std::{collections::HashMap, str::FromStr};
|
|
||||||
|
|
||||||
use non_blank_string_rs::NonBlankString;
|
|
||||||
use serde::Serialize;
|
|
||||||
use url::Url;
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
modules::helm::chart::{HelmChartScore, HelmRepository},
|
|
||||||
score::Score,
|
|
||||||
topology::{HelmCommand, Topology},
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Clone)]
|
|
||||||
pub struct CertManagerHelmScore {}
|
|
||||||
|
|
||||||
impl<T: Topology + HelmCommand> Score<T> for CertManagerHelmScore {
|
|
||||||
fn create_interpret(&self) -> Box<dyn crate::interpret::Interpret<T>> {
|
|
||||||
let mut values_overrides = HashMap::new();
|
|
||||||
values_overrides.insert(
|
|
||||||
NonBlankString::from_str("crds.enabled").unwrap(),
|
|
||||||
"true".to_string(),
|
|
||||||
);
|
|
||||||
let values_overrides = Some(values_overrides);
|
|
||||||
|
|
||||||
HelmChartScore {
|
|
||||||
namespace: Some(NonBlankString::from_str("cert-manager").unwrap()),
|
|
||||||
release_name: NonBlankString::from_str("cert-manager").unwrap(),
|
|
||||||
chart_name: NonBlankString::from_str("jetstack/cert-manager").unwrap(),
|
|
||||||
chart_version: None,
|
|
||||||
values_overrides,
|
|
||||||
values_yaml: None,
|
|
||||||
create_namespace: true,
|
|
||||||
install_only: true,
|
|
||||||
repository: Some(HelmRepository::new(
|
|
||||||
"jetstack".to_string(),
|
|
||||||
Url::parse("https://charts.jetstack.io").unwrap(),
|
|
||||||
true,
|
|
||||||
)),
|
|
||||||
}
|
|
||||||
.create_interpret()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn name(&self) -> String {
|
|
||||||
format!("CertManagerHelmScore")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
mod helm;
|
|
||||||
pub use helm::*;
|
|
||||||
@ -6,31 +6,13 @@ use crate::topology::{HelmCommand, Topology};
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use helm_wrapper_rs;
|
use helm_wrapper_rs;
|
||||||
use helm_wrapper_rs::blocking::{DefaultHelmExecutor, HelmExecutor};
|
use helm_wrapper_rs::blocking::{DefaultHelmExecutor, HelmExecutor};
|
||||||
use log::{debug, error, info, warn};
|
use log::info;
|
||||||
pub use non_blank_string_rs::NonBlankString;
|
pub use non_blank_string_rs::NonBlankString;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::process::{Command, Output, Stdio};
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use temp_file::TempFile;
|
use temp_file::TempFile;
|
||||||
use url::Url;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize)]
|
|
||||||
pub struct HelmRepository {
|
|
||||||
name: String,
|
|
||||||
url: Url,
|
|
||||||
force_update: bool,
|
|
||||||
}
|
|
||||||
impl HelmRepository {
|
|
||||||
pub(crate) fn new(name: String, url: Url, force_update: bool) -> Self {
|
|
||||||
Self {
|
|
||||||
name,
|
|
||||||
url,
|
|
||||||
force_update,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
pub struct HelmChartScore {
|
pub struct HelmChartScore {
|
||||||
@ -44,7 +26,6 @@ pub struct HelmChartScore {
|
|||||||
|
|
||||||
/// Wether to run `helm upgrade --install` under the hood or only install when not present
|
/// Wether to run `helm upgrade --install` under the hood or only install when not present
|
||||||
pub install_only: bool,
|
pub install_only: bool,
|
||||||
pub repository: Option<HelmRepository>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Topology + HelmCommand> Score<T> for HelmChartScore {
|
impl<T: Topology + HelmCommand> Score<T> for HelmChartScore {
|
||||||
@ -63,77 +44,6 @@ impl<T: Topology + HelmCommand> Score<T> for HelmChartScore {
|
|||||||
pub struct HelmChartInterpret {
|
pub struct HelmChartInterpret {
|
||||||
pub score: HelmChartScore,
|
pub score: HelmChartScore,
|
||||||
}
|
}
|
||||||
impl HelmChartInterpret {
|
|
||||||
fn add_repo(&self) -> Result<(), InterpretError> {
|
|
||||||
let repo = match &self.score.repository {
|
|
||||||
Some(repo) => repo,
|
|
||||||
None => {
|
|
||||||
info!("No Helm repository specified in the score. Skipping repository setup.");
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
info!(
|
|
||||||
"Ensuring Helm repository exists: Name='{}', URL='{}', ForceUpdate={}",
|
|
||||||
repo.name, repo.url, repo.force_update
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut add_args = vec!["repo", "add", &repo.name, repo.url.as_str()];
|
|
||||||
if repo.force_update {
|
|
||||||
add_args.push("--force-update");
|
|
||||||
}
|
|
||||||
|
|
||||||
let add_output = run_helm_command(&add_args)?;
|
|
||||||
let full_output = format!(
|
|
||||||
"{}\n{}",
|
|
||||||
String::from_utf8_lossy(&add_output.stdout),
|
|
||||||
String::from_utf8_lossy(&add_output.stderr)
|
|
||||||
);
|
|
||||||
|
|
||||||
match add_output.status.success() {
|
|
||||||
true => {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
false => {
|
|
||||||
return Err(InterpretError::new(format!(
|
|
||||||
"Failed to add helm repository!\n{full_output}"
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn run_helm_command(args: &[&str]) -> Result<Output, InterpretError> {
|
|
||||||
let command_str = format!("helm {}", args.join(" "));
|
|
||||||
debug!("Running Helm command: `{}`", command_str);
|
|
||||||
|
|
||||||
let output = Command::new("helm")
|
|
||||||
.args(args)
|
|
||||||
.stdout(Stdio::piped())
|
|
||||||
.stderr(Stdio::piped())
|
|
||||||
.output()
|
|
||||||
.map_err(|e| {
|
|
||||||
InterpretError::new(format!(
|
|
||||||
"Failed to execute helm command '{}': {}. Is helm installed and in PATH?",
|
|
||||||
command_str, e
|
|
||||||
))
|
|
||||||
})?;
|
|
||||||
|
|
||||||
if !output.status.success() {
|
|
||||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
|
||||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
|
||||||
warn!(
|
|
||||||
"Helm command `{}` failed with status: {}\nStdout:\n{}\nStderr:\n{}",
|
|
||||||
command_str, output.status, stdout, stderr
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
debug!(
|
|
||||||
"Helm command `{}` finished successfully. Status: {}",
|
|
||||||
command_str, output.status
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(output)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<T: Topology + HelmCommand> Interpret<T> for HelmChartInterpret {
|
impl<T: Topology + HelmCommand> Interpret<T> for HelmChartInterpret {
|
||||||
@ -157,8 +67,6 @@ impl<T: Topology + HelmCommand> Interpret<T> for HelmChartInterpret {
|
|||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.add_repo()?;
|
|
||||||
|
|
||||||
let helm_executor = DefaultHelmExecutor::new();
|
let helm_executor = DefaultHelmExecutor::new();
|
||||||
|
|
||||||
let mut helm_options = Vec::new();
|
let mut helm_options = Vec::new();
|
||||||
|
|||||||
@ -179,7 +179,6 @@ impl LAMPInterpret {
|
|||||||
create_namespace: true,
|
create_namespace: true,
|
||||||
install_only: true,
|
install_only: true,
|
||||||
values_yaml: None,
|
values_yaml: None,
|
||||||
repository: None,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
score.create_interpret().execute(inventory, topology).await
|
score.create_interpret().execute(inventory, topology).await
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
pub mod cert_manager;
|
|
||||||
pub mod dhcp;
|
pub mod dhcp;
|
||||||
pub mod dns;
|
pub mod dns;
|
||||||
pub mod dummy;
|
pub mod dummy;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user