mirror of
https://github.com/jlengrand/engine.git
synced 2026-03-10 08:11:21 +00:00
fix: selector to be injected to helm chart (#537)
This commit is contained in:
@@ -97,6 +97,10 @@ impl crate::cloud_provider::service::Application for Application {
|
||||
}
|
||||
|
||||
impl Helm for Application {
|
||||
fn helm_selector(&self) -> Option<String> {
|
||||
self.selector()
|
||||
}
|
||||
|
||||
fn helm_release_name(&self) -> String {
|
||||
crate::string::cut(format!("application-{}-{}", self.name(), self.id()), 50)
|
||||
}
|
||||
@@ -275,8 +279,8 @@ impl Service for Application {
|
||||
Ok(context)
|
||||
}
|
||||
|
||||
fn selector(&self) -> String {
|
||||
format!("appId={}", self.id)
|
||||
fn selector(&self) -> Option<String> {
|
||||
Some(format!("appId={}", self.id))
|
||||
}
|
||||
|
||||
fn engine_error_scope(&self) -> EngineErrorScope {
|
||||
|
||||
@@ -213,8 +213,8 @@ impl Service for MongoDB {
|
||||
Ok(context)
|
||||
}
|
||||
|
||||
fn selector(&self) -> String {
|
||||
format!("app={}", self.sanitized_name())
|
||||
fn selector(&self) -> Option<String> {
|
||||
Some(format!("app={}", self.sanitized_name()))
|
||||
}
|
||||
|
||||
fn engine_error_scope(&self) -> EngineErrorScope {
|
||||
@@ -229,6 +229,10 @@ impl Service for MongoDB {
|
||||
impl Database for MongoDB {}
|
||||
|
||||
impl Helm for MongoDB {
|
||||
fn helm_selector(&self) -> Option<String> {
|
||||
self.selector()
|
||||
}
|
||||
|
||||
fn helm_release_name(&self) -> String {
|
||||
crate::string::cut(format!("mongodb-{}", self.id()), 50)
|
||||
}
|
||||
|
||||
@@ -224,8 +224,8 @@ impl Service for MySQL {
|
||||
Ok(context)
|
||||
}
|
||||
|
||||
fn selector(&self) -> String {
|
||||
format!("app={}", self.sanitized_name())
|
||||
fn selector(&self) -> Option<String> {
|
||||
Some(format!("app={}", self.sanitized_name()))
|
||||
}
|
||||
|
||||
fn engine_error_scope(&self) -> EngineErrorScope {
|
||||
@@ -240,6 +240,10 @@ impl Service for MySQL {
|
||||
impl Database for MySQL {}
|
||||
|
||||
impl Helm for MySQL {
|
||||
fn helm_selector(&self) -> Option<String> {
|
||||
self.selector()
|
||||
}
|
||||
|
||||
fn helm_release_name(&self) -> String {
|
||||
crate::string::cut(format!("mysql-{}", self.id()), 50)
|
||||
}
|
||||
|
||||
@@ -211,8 +211,8 @@ impl Service for PostgreSQL {
|
||||
Ok(context)
|
||||
}
|
||||
|
||||
fn selector(&self) -> String {
|
||||
format!("app={}", self.sanitized_name())
|
||||
fn selector(&self) -> Option<String> {
|
||||
Some(format!("app={}", self.sanitized_name()))
|
||||
}
|
||||
|
||||
fn engine_error_scope(&self) -> EngineErrorScope {
|
||||
@@ -227,6 +227,10 @@ impl Service for PostgreSQL {
|
||||
impl Database for PostgreSQL {}
|
||||
|
||||
impl Helm for PostgreSQL {
|
||||
fn helm_selector(&self) -> Option<String> {
|
||||
self.selector()
|
||||
}
|
||||
|
||||
fn helm_release_name(&self) -> String {
|
||||
crate::string::cut(format!("postgresql-{}", self.id()), 50)
|
||||
}
|
||||
|
||||
@@ -224,8 +224,8 @@ impl Service for Redis {
|
||||
Ok(context)
|
||||
}
|
||||
|
||||
fn selector(&self) -> String {
|
||||
format!("app={}", self.sanitized_name())
|
||||
fn selector(&self) -> Option<String> {
|
||||
Some(format!("app={}", self.sanitized_name()))
|
||||
}
|
||||
|
||||
fn engine_error_scope(&self) -> EngineErrorScope {
|
||||
@@ -240,6 +240,10 @@ impl Service for Redis {
|
||||
impl Database for Redis {}
|
||||
|
||||
impl Helm for Redis {
|
||||
fn helm_selector(&self) -> Option<String> {
|
||||
self.selector()
|
||||
}
|
||||
|
||||
fn helm_release_name(&self) -> String {
|
||||
crate::string::cut(format!("redis-{}", self.id()), 50)
|
||||
}
|
||||
|
||||
@@ -1242,12 +1242,14 @@ impl HelmChart for AwsVpcCniChart {
|
||||
let chart_infos = self.get_chart_info();
|
||||
|
||||
// Cleaning any existing crash looping pod for this helm chart
|
||||
kubectl_delete_crash_looping_pods(
|
||||
&kubernetes_config,
|
||||
Some(chart_infos.get_namespace_string().as_str()),
|
||||
Some(chart_infos.get_selector_string().as_str()),
|
||||
environment_variables.clone(),
|
||||
)?;
|
||||
if let Some(selector) = self.get_selector() {
|
||||
kubectl_delete_crash_looping_pods(
|
||||
&kubernetes_config,
|
||||
Some(chart_infos.get_namespace_string().as_str()),
|
||||
Some(selector.as_str()),
|
||||
environment_variables.clone(),
|
||||
)?;
|
||||
}
|
||||
|
||||
match self.enable_cni_managed_by_helm(kubernetes_config, envs) {
|
||||
true => {
|
||||
|
||||
@@ -217,8 +217,8 @@ impl Service for Router {
|
||||
Ok(context)
|
||||
}
|
||||
|
||||
fn selector(&self) -> String {
|
||||
format!("routerId={}", self.id)
|
||||
fn selector(&self) -> Option<String> {
|
||||
Some(format!("routerId={}", self.id))
|
||||
}
|
||||
|
||||
fn engine_error_scope(&self) -> EngineErrorScope {
|
||||
@@ -243,6 +243,10 @@ impl crate::cloud_provider::service::Router for Router {
|
||||
}
|
||||
|
||||
impl Helm for Router {
|
||||
fn helm_selector(&self) -> Option<String> {
|
||||
self.selector()
|
||||
}
|
||||
|
||||
fn helm_release_name(&self) -> String {
|
||||
crate::string::cut(format!("router-{}", self.id()), 50)
|
||||
}
|
||||
@@ -307,6 +311,7 @@ impl Create for Router {
|
||||
kubernetes_config_file_path.as_str(),
|
||||
environment.namespace(),
|
||||
helm_release_name.as_str(),
|
||||
self.selector(),
|
||||
workspace_dir.as_str(),
|
||||
self.start_timeout(),
|
||||
kubernetes.cloud_provider().credentials_environment_variables(),
|
||||
|
||||
@@ -99,6 +99,10 @@ impl crate::cloud_provider::service::Application for Application {
|
||||
}
|
||||
|
||||
impl Helm for Application {
|
||||
fn helm_selector(&self) -> Option<String> {
|
||||
self.selector()
|
||||
}
|
||||
|
||||
fn helm_release_name(&self) -> String {
|
||||
crate::string::cut(format!("application-{}-{}", self.name, self.id), 50)
|
||||
}
|
||||
@@ -276,8 +280,8 @@ impl Service for Application {
|
||||
Ok(context)
|
||||
}
|
||||
|
||||
fn selector(&self) -> String {
|
||||
format!("appId={}", self.id)
|
||||
fn selector(&self) -> Option<String> {
|
||||
Some(format!("appId={}", self.id))
|
||||
}
|
||||
|
||||
fn engine_error_scope(&self) -> EngineErrorScope {
|
||||
|
||||
@@ -197,8 +197,8 @@ impl Service for MongoDB {
|
||||
Ok(context)
|
||||
}
|
||||
|
||||
fn selector(&self) -> String {
|
||||
format!("app={}", self.sanitized_name())
|
||||
fn selector(&self) -> Option<String> {
|
||||
Some(format!("app={}", self.sanitized_name()))
|
||||
}
|
||||
|
||||
fn engine_error_scope(&self) -> EngineErrorScope {
|
||||
@@ -213,6 +213,10 @@ impl Service for MongoDB {
|
||||
impl Database for MongoDB {}
|
||||
|
||||
impl Helm for MongoDB {
|
||||
fn helm_selector(&self) -> Option<String> {
|
||||
self.selector()
|
||||
}
|
||||
|
||||
fn helm_release_name(&self) -> String {
|
||||
crate::string::cut(format!("mongodb-{}", self.id()), 50)
|
||||
}
|
||||
|
||||
@@ -197,8 +197,8 @@ impl Service for MySQL {
|
||||
Ok(context)
|
||||
}
|
||||
|
||||
fn selector(&self) -> String {
|
||||
format!("app={}", self.sanitized_name())
|
||||
fn selector(&self) -> Option<String> {
|
||||
Some(format!("app={}", self.sanitized_name()))
|
||||
}
|
||||
|
||||
fn engine_error_scope(&self) -> EngineErrorScope {
|
||||
@@ -213,6 +213,10 @@ impl Service for MySQL {
|
||||
impl Database for MySQL {}
|
||||
|
||||
impl Helm for MySQL {
|
||||
fn helm_selector(&self) -> Option<String> {
|
||||
self.selector()
|
||||
}
|
||||
|
||||
fn helm_release_name(&self) -> String {
|
||||
crate::string::cut(format!("mysql-{}", self.id()), 50)
|
||||
}
|
||||
|
||||
@@ -199,8 +199,8 @@ impl Service for PostgreSQL {
|
||||
Ok(context)
|
||||
}
|
||||
|
||||
fn selector(&self) -> String {
|
||||
format!("app={}", self.sanitized_name())
|
||||
fn selector(&self) -> Option<String> {
|
||||
Some(format!("app={}", self.sanitized_name()))
|
||||
}
|
||||
|
||||
fn engine_error_scope(&self) -> EngineErrorScope {
|
||||
@@ -215,6 +215,10 @@ impl Service for PostgreSQL {
|
||||
impl Database for PostgreSQL {}
|
||||
|
||||
impl Helm for PostgreSQL {
|
||||
fn helm_selector(&self) -> Option<String> {
|
||||
self.selector()
|
||||
}
|
||||
|
||||
fn helm_release_name(&self) -> String {
|
||||
crate::string::cut(format!("postgresql-{}", self.id()), 50)
|
||||
}
|
||||
|
||||
@@ -196,8 +196,8 @@ impl Service for Redis {
|
||||
Ok(context)
|
||||
}
|
||||
|
||||
fn selector(&self) -> String {
|
||||
format!("app={}", self.sanitized_name())
|
||||
fn selector(&self) -> Option<String> {
|
||||
Some(format!("app={}", self.sanitized_name()))
|
||||
}
|
||||
|
||||
fn engine_error_scope(&self) -> EngineErrorScope {
|
||||
@@ -212,6 +212,10 @@ impl Service for Redis {
|
||||
impl Database for Redis {}
|
||||
|
||||
impl Helm for Redis {
|
||||
fn helm_selector(&self) -> Option<String> {
|
||||
self.selector()
|
||||
}
|
||||
|
||||
fn helm_release_name(&self) -> String {
|
||||
crate::string::cut(format!("redis-{}", self.id()), 50)
|
||||
}
|
||||
|
||||
@@ -232,8 +232,8 @@ impl Service for Router {
|
||||
Ok(context)
|
||||
}
|
||||
|
||||
fn selector(&self) -> String {
|
||||
format!("routerId={}", self.id)
|
||||
fn selector(&self) -> Option<String> {
|
||||
Some(format!("routerId={}", self.id))
|
||||
}
|
||||
|
||||
fn engine_error_scope(&self) -> EngineErrorScope {
|
||||
@@ -258,6 +258,10 @@ impl crate::cloud_provider::service::Router for Router {
|
||||
}
|
||||
|
||||
impl Helm for Router {
|
||||
fn helm_selector(&self) -> Option<String> {
|
||||
self.selector()
|
||||
}
|
||||
|
||||
fn helm_release_name(&self) -> String {
|
||||
crate::string::cut(format!("router-{}", self.id()), 50)
|
||||
}
|
||||
@@ -326,6 +330,7 @@ impl Create for Router {
|
||||
kubernetes_config_file_path.as_str(),
|
||||
environment.namespace(),
|
||||
helm_release_name.as_str(),
|
||||
self.selector(),
|
||||
workspace_dir.as_str(),
|
||||
self.start_timeout(),
|
||||
kubernetes.cloud_provider().credentials_environment_variables(),
|
||||
|
||||
@@ -82,6 +82,7 @@ pub struct ChartInfo {
|
||||
pub values_files: Vec<String>,
|
||||
pub yaml_files_content: Vec<ChartValuesGenerated>,
|
||||
pub parse_stderr_for_error: bool,
|
||||
pub k8s_selector: Option<String>,
|
||||
}
|
||||
|
||||
impl ChartInfo {
|
||||
@@ -92,6 +93,7 @@ impl ChartInfo {
|
||||
timeout_in_seconds: i64,
|
||||
values_files: Vec<String>,
|
||||
parse_stderr_for_error: bool,
|
||||
k8s_selector: Option<String>,
|
||||
) -> Self {
|
||||
ChartInfo {
|
||||
name,
|
||||
@@ -101,6 +103,7 @@ impl ChartInfo {
|
||||
timeout_in_seconds,
|
||||
values_files,
|
||||
parse_stderr_for_error,
|
||||
k8s_selector,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
@@ -114,10 +117,6 @@ impl ChartInfo {
|
||||
_ => self.namespace.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_selector_string(&self) -> String {
|
||||
format!("app={}", self.name.to_lowercase())
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ChartInfo {
|
||||
@@ -138,6 +137,7 @@ impl Default for ChartInfo {
|
||||
values_files: Vec::new(),
|
||||
yaml_files_content: vec![],
|
||||
parse_stderr_for_error: true,
|
||||
k8s_selector: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -162,6 +162,11 @@ pub trait HelmChart: Send {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn get_selector(&self) -> Option<String> {
|
||||
let infos = self.get_chart_info();
|
||||
infos.k8s_selector.clone()
|
||||
}
|
||||
|
||||
fn get_chart_info(&self) -> &ChartInfo;
|
||||
|
||||
fn namespace(&self) -> String {
|
||||
@@ -177,12 +182,14 @@ pub trait HelmChart: Send {
|
||||
let chart_infos = self.get_chart_info();
|
||||
|
||||
// Cleaning any existing crash looping pod for this helm chart
|
||||
kubectl_delete_crash_looping_pods(
|
||||
&kubernetes_config,
|
||||
Some(chart_infos.get_namespace_string().as_str()),
|
||||
Some(chart_infos.get_selector_string().as_str()),
|
||||
envs.iter().map(|(k, v)| (k.as_str(), v.as_str())).collect(),
|
||||
)?;
|
||||
if let Some(selector) = self.get_selector() {
|
||||
kubectl_delete_crash_looping_pods(
|
||||
&kubernetes_config,
|
||||
Some(chart_infos.get_namespace_string().as_str()),
|
||||
Some(selector.as_str()),
|
||||
envs.iter().map(|(k, v)| (k.as_str(), v.as_str())).collect(),
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(payload)
|
||||
}
|
||||
@@ -402,12 +409,14 @@ impl HelmChart for CoreDNSConfigChart {
|
||||
let chart_infos = self.get_chart_info();
|
||||
|
||||
// Cleaning any existing crash looping pod for this helm chart
|
||||
kubectl_delete_crash_looping_pods(
|
||||
&kubernetes_config,
|
||||
Some(chart_infos.get_namespace_string().as_str()),
|
||||
Some(chart_infos.get_selector_string().as_str()),
|
||||
environment_variables.clone(),
|
||||
)?;
|
||||
if let Some(selector) = self.get_selector() {
|
||||
kubectl_delete_crash_looping_pods(
|
||||
&kubernetes_config,
|
||||
Some(chart_infos.get_namespace_string().as_str()),
|
||||
Some(selector.as_str()),
|
||||
environment_variables.clone(),
|
||||
)?;
|
||||
}
|
||||
|
||||
// calculate current configmap checksum
|
||||
let current_configmap_hash = match kubectl_exec_get_configmap(
|
||||
@@ -815,11 +824,11 @@ pub fn get_chart_for_shell_agent(
|
||||
},
|
||||
ChartSetValue {
|
||||
key: "environmentVariables.RUST_BACKTRACE".to_string(),
|
||||
value: "full".to_string()
|
||||
value: "full".to_string(),
|
||||
},
|
||||
ChartSetValue {
|
||||
key: "environmentVariables.RUST_LOG".to_string(),
|
||||
value: "DEBUG".to_string()
|
||||
value: "DEBUG".to_string(),
|
||||
},
|
||||
ChartSetValue {
|
||||
key: "environmentVariables.GRPC_SERVER".to_string(),
|
||||
|
||||
@@ -219,8 +219,8 @@ pub trait Kubernetes: Listen {
|
||||
e.message,
|
||||
))
|
||||
}
|
||||
Ok(config_path) => match kubectl_get_crash_looping_pods::<dyn AsRef<Path>>(
|
||||
Box::new(&config_path.0),
|
||||
Ok(config_path) => match kubectl_get_crash_looping_pods(
|
||||
&config_path.0,
|
||||
namespace,
|
||||
selector,
|
||||
restarted_min_count,
|
||||
@@ -228,21 +228,18 @@ pub trait Kubernetes: Listen {
|
||||
) {
|
||||
Ok(pods) => {
|
||||
for pod in pods {
|
||||
match kubectl_exec_delete_pod::<dyn AsRef<Path>>(
|
||||
Box::new(&config_path.0),
|
||||
if let Err(e) = kubectl_exec_delete_pod(
|
||||
&config_path.0,
|
||||
pod.metadata.namespace.as_str(),
|
||||
pod.metadata.name.as_str(),
|
||||
envs.clone(),
|
||||
) {
|
||||
Ok(..) => {}
|
||||
Err(e) => {
|
||||
return Err(EngineError::new(
|
||||
EngineErrorCause::Internal,
|
||||
self.engine_error_scope(),
|
||||
self.context().execution_id(),
|
||||
e.message,
|
||||
))
|
||||
}
|
||||
return Err(EngineError::new(
|
||||
EngineErrorCause::Internal,
|
||||
self.engine_error_scope(),
|
||||
self.context().execution_id(),
|
||||
e.message,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,6 +100,10 @@ impl crate::cloud_provider::service::Application for Application {
|
||||
}
|
||||
|
||||
impl Helm for Application {
|
||||
fn helm_selector(&self) -> Option<String> {
|
||||
self.selector()
|
||||
}
|
||||
|
||||
fn helm_release_name(&self) -> String {
|
||||
crate::string::cut(format!("application-{}-{}", self.name(), self.id()), 50)
|
||||
}
|
||||
@@ -294,8 +298,8 @@ impl Service for Application {
|
||||
Ok(context)
|
||||
}
|
||||
|
||||
fn selector(&self) -> String {
|
||||
format!("appId={}", self.id)
|
||||
fn selector(&self) -> Option<String> {
|
||||
Some(format!("appId={}", self.id))
|
||||
}
|
||||
|
||||
fn engine_error_scope(&self) -> EngineErrorScope {
|
||||
|
||||
@@ -198,8 +198,8 @@ impl Service for MongoDB {
|
||||
Ok(context)
|
||||
}
|
||||
|
||||
fn selector(&self) -> String {
|
||||
format!("app={}", self.sanitized_name())
|
||||
fn selector(&self) -> Option<String> {
|
||||
Some(format!("app={}", self.sanitized_name()))
|
||||
}
|
||||
|
||||
fn engine_error_scope(&self) -> EngineErrorScope {
|
||||
@@ -214,6 +214,10 @@ impl Service for MongoDB {
|
||||
impl Database for MongoDB {}
|
||||
|
||||
impl Helm for MongoDB {
|
||||
fn helm_selector(&self) -> Option<String> {
|
||||
self.selector()
|
||||
}
|
||||
|
||||
fn helm_release_name(&self) -> String {
|
||||
crate::string::cut(format!("mongodb-{}", self.id()), 50)
|
||||
}
|
||||
|
||||
@@ -235,8 +235,8 @@ impl Service for MySQL {
|
||||
Ok(context)
|
||||
}
|
||||
|
||||
fn selector(&self) -> String {
|
||||
format!("app={}", self.sanitized_name())
|
||||
fn selector(&self) -> Option<String> {
|
||||
Some(format!("app={}", self.sanitized_name()))
|
||||
}
|
||||
|
||||
fn engine_error_scope(&self) -> EngineErrorScope {
|
||||
@@ -251,6 +251,10 @@ impl Service for MySQL {
|
||||
impl Database for MySQL {}
|
||||
|
||||
impl Helm for MySQL {
|
||||
fn helm_selector(&self) -> Option<String> {
|
||||
self.selector()
|
||||
}
|
||||
|
||||
fn helm_release_name(&self) -> String {
|
||||
crate::string::cut(format!("mysql-{}", self.id()), 50)
|
||||
}
|
||||
|
||||
@@ -244,8 +244,8 @@ impl Service for PostgreSQL {
|
||||
Ok(context)
|
||||
}
|
||||
|
||||
fn selector(&self) -> String {
|
||||
format!("app={}", self.sanitized_name())
|
||||
fn selector(&self) -> Option<String> {
|
||||
Some(format!("app={}", self.sanitized_name()))
|
||||
}
|
||||
|
||||
fn engine_error_scope(&self) -> EngineErrorScope {
|
||||
@@ -260,6 +260,10 @@ impl Service for PostgreSQL {
|
||||
impl Database for PostgreSQL {}
|
||||
|
||||
impl Helm for PostgreSQL {
|
||||
fn helm_selector(&self) -> Option<String> {
|
||||
self.selector()
|
||||
}
|
||||
|
||||
fn helm_release_name(&self) -> String {
|
||||
crate::string::cut(format!("postgresql-{}", self.id()), 50)
|
||||
}
|
||||
|
||||
@@ -197,8 +197,8 @@ impl Service for Redis {
|
||||
Ok(context)
|
||||
}
|
||||
|
||||
fn selector(&self) -> String {
|
||||
format!("app={}", self.sanitized_name())
|
||||
fn selector(&self) -> Option<String> {
|
||||
Some(format!("app={}", self.sanitized_name()))
|
||||
}
|
||||
|
||||
fn engine_error_scope(&self) -> EngineErrorScope {
|
||||
@@ -213,6 +213,10 @@ impl Service for Redis {
|
||||
impl Database for Redis {}
|
||||
|
||||
impl Helm for Redis {
|
||||
fn helm_selector(&self) -> Option<String> {
|
||||
self.selector()
|
||||
}
|
||||
|
||||
fn helm_release_name(&self) -> String {
|
||||
crate::string::cut(format!("redis-{}", self.id()), 50)
|
||||
}
|
||||
|
||||
@@ -181,8 +181,8 @@ impl Service for Router {
|
||||
Ok(context)
|
||||
}
|
||||
|
||||
fn selector(&self) -> String {
|
||||
format!("routerId={}", self.id)
|
||||
fn selector(&self) -> Option<String> {
|
||||
Some(format!("routerId={}", self.id))
|
||||
}
|
||||
|
||||
fn engine_error_scope(&self) -> EngineErrorScope {
|
||||
@@ -207,6 +207,10 @@ impl crate::cloud_provider::service::Router for Router {
|
||||
}
|
||||
|
||||
impl Helm for Router {
|
||||
fn helm_selector(&self) -> Option<String> {
|
||||
self.selector()
|
||||
}
|
||||
|
||||
fn helm_release_name(&self) -> String {
|
||||
crate::string::cut(format!("router-{}", self.id()), 50)
|
||||
}
|
||||
@@ -272,6 +276,7 @@ impl Create for Router {
|
||||
kubernetes_config_file_path.as_str(),
|
||||
environment.namespace(),
|
||||
helm_release_name.as_str(),
|
||||
self.selector(),
|
||||
workspace_dir.as_str(),
|
||||
self.start_timeout(),
|
||||
kubernetes.cloud_provider().credentials_environment_variables(),
|
||||
|
||||
@@ -70,7 +70,7 @@ pub trait Service {
|
||||
}
|
||||
fn tera_context(&self, target: &DeploymentTarget) -> Result<TeraContext, EngineError>;
|
||||
// used to retrieve logs by using Kubernetes labels (selector)
|
||||
fn selector(&self) -> String;
|
||||
fn selector(&self) -> Option<String>;
|
||||
fn debug_logs(&self, deployment_target: &DeploymentTarget) -> Vec<String> {
|
||||
debug_logs(self, deployment_target)
|
||||
}
|
||||
@@ -204,6 +204,7 @@ pub trait Terraform {
|
||||
}
|
||||
|
||||
pub trait Helm {
|
||||
fn helm_selector(&self) -> Option<String>;
|
||||
fn helm_release_name(&self) -> String;
|
||||
fn helm_chart_dir(&self) -> String;
|
||||
fn helm_chart_values_dir(&self) -> String;
|
||||
@@ -396,6 +397,7 @@ where
|
||||
kubernetes_config_file_path.as_str(),
|
||||
environment.namespace(),
|
||||
helm_release_name.as_str(),
|
||||
service.selector(),
|
||||
workspace_dir.as_str(),
|
||||
service.start_timeout(),
|
||||
kubernetes.cloud_provider().credentials_environment_variables(),
|
||||
@@ -414,7 +416,7 @@ where
|
||||
crate::cmd::kubectl::kubectl_exec_is_pod_ready_with_retry(
|
||||
kubernetes_config_file_path.as_str(),
|
||||
environment.namespace(),
|
||||
service.selector().as_str(),
|
||||
service.selector().unwrap_or("".to_string()).as_str(),
|
||||
kubernetes.cloud_provider().credentials_environment_variables(),
|
||||
),
|
||||
)?;
|
||||
@@ -500,7 +502,7 @@ pub fn scale_down_application(
|
||||
kubernetes.cloud_provider().credentials_environment_variables(),
|
||||
environment.namespace(),
|
||||
scaling_kind,
|
||||
service.selector().as_str(),
|
||||
service.selector().unwrap_or("".to_string()).as_str(),
|
||||
replicas_count as u32,
|
||||
);
|
||||
|
||||
@@ -529,7 +531,11 @@ where
|
||||
let helm_release_name = service.helm_release_name();
|
||||
|
||||
if is_error {
|
||||
let _ = get_stateless_resource_information(kubernetes, environment, service.selector().as_str())?;
|
||||
let _ = get_stateless_resource_information(
|
||||
kubernetes,
|
||||
environment,
|
||||
service.selector().unwrap_or("".to_string()).as_str(),
|
||||
)?;
|
||||
}
|
||||
|
||||
// clean the resource
|
||||
@@ -658,6 +664,7 @@ where
|
||||
kubernetes_config_file_path.as_str(),
|
||||
environment.namespace(),
|
||||
service.helm_release_name().as_str(),
|
||||
service.selector(),
|
||||
workspace_dir.as_str(),
|
||||
service.start_timeout(),
|
||||
kubernetes.cloud_provider().credentials_environment_variables(),
|
||||
@@ -680,7 +687,7 @@ where
|
||||
match crate::cmd::kubectl::kubectl_exec_is_pod_ready_with_retry(
|
||||
kubernetes_config_file_path.as_str(),
|
||||
environment.namespace(),
|
||||
service.selector().as_str(),
|
||||
service.selector().unwrap_or("".to_string()).as_str(),
|
||||
kubernetes.cloud_provider().credentials_environment_variables(),
|
||||
) {
|
||||
Ok(Some(true)) => {}
|
||||
@@ -979,7 +986,7 @@ pub fn get_stateless_resource_information_for_user<T>(
|
||||
where
|
||||
T: Service + ?Sized,
|
||||
{
|
||||
let selector = service.selector();
|
||||
let selector = service.selector().unwrap_or("".to_string());
|
||||
let kubernetes_config_file_path = kubernetes.config_file_path()?;
|
||||
let mut result = Vec::with_capacity(50);
|
||||
|
||||
@@ -994,7 +1001,7 @@ where
|
||||
kubernetes.cloud_provider().credentials_environment_variables(),
|
||||
),
|
||||
)
|
||||
.unwrap_or_else(|_| vec![format!("Unable to retrieve logs for pod: {}", selector)]);
|
||||
.unwrap_or_else(|_| vec![format!("Unable to retrieve logs for pod with selector: {:?}", selector,)]);
|
||||
|
||||
let _ = result.extend(logs);
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ pub fn helm_exec_with_upgrade_history<P>(
|
||||
kubernetes_config: P,
|
||||
namespace: &str,
|
||||
release_name: &str,
|
||||
selector: Option<String>,
|
||||
chart_root_dir: P,
|
||||
timeout: Timeout<u32>,
|
||||
envs: Vec<(&str, &str)>,
|
||||
@@ -72,6 +73,7 @@ where
|
||||
_ => vec![],
|
||||
},
|
||||
false,
|
||||
selector,
|
||||
),
|
||||
};
|
||||
|
||||
|
||||
@@ -743,6 +743,38 @@ where
|
||||
kubectl_exec::<P, KubernetesList<KubernetesPod>>(cmd_args, kubernetes_config, envs)
|
||||
}
|
||||
|
||||
/// kubectl_exec_get_pod_by_name: allows to retrieve a pod by its name
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `kubernetes_config` - kubernetes config path
|
||||
/// * `namespace` - kubernetes namespace
|
||||
/// * `pod_name` - pod's name
|
||||
/// * `envs` - environment variables required for kubernetes connection
|
||||
pub fn kubectl_exec_get_pod_by_name<P>(
|
||||
kubernetes_config: P,
|
||||
namespace: Option<&str>,
|
||||
pod_name: &str,
|
||||
envs: Vec<(&str, &str)>,
|
||||
) -> Result<KubernetesPod, SimpleError>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
let mut cmd_args = vec!["get", "pod", "-o", "json"];
|
||||
|
||||
match namespace {
|
||||
Some(n) => {
|
||||
cmd_args.push("-n");
|
||||
cmd_args.push(n);
|
||||
}
|
||||
None => cmd_args.push("--all-namespaces"),
|
||||
}
|
||||
|
||||
cmd_args.push(pod_name);
|
||||
|
||||
kubectl_exec::<P, KubernetesPod>(cmd_args, kubernetes_config, envs)
|
||||
}
|
||||
|
||||
pub fn kubectl_exec_get_configmap<P>(
|
||||
kubernetes_config: P,
|
||||
namespace: &str,
|
||||
@@ -1044,14 +1076,14 @@ where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
let crash_looping_pods =
|
||||
match kubectl_get_crash_looping_pods(Box::new(&kubernetes_config), namespace, selector, None, envs.clone()) {
|
||||
match kubectl_get_crash_looping_pods(&kubernetes_config, namespace, selector, None, envs.clone()) {
|
||||
Ok(pods) => pods,
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
|
||||
for crash_looping_pod in crash_looping_pods.iter() {
|
||||
if let Err(e) = kubectl_exec_delete_pod(
|
||||
Box::new(&kubernetes_config),
|
||||
&kubernetes_config,
|
||||
crash_looping_pod.metadata.namespace.as_str(),
|
||||
crash_looping_pod.metadata.name.as_str(),
|
||||
envs.clone(),
|
||||
@@ -1072,8 +1104,8 @@ where
|
||||
/// * `selector`: selector to look for, if None, will look for anything.
|
||||
/// * `restarted_min_count`: minimum restart counts to be considered as crash looping. If None, default is 5.
|
||||
/// * `envs`: environment variables to be passed to kubectl.
|
||||
pub fn kubectl_get_crash_looping_pods<P: ?Sized>(
|
||||
kubernetes_config: Box<P>,
|
||||
pub fn kubectl_get_crash_looping_pods<P>(
|
||||
kubernetes_config: P,
|
||||
namespace: Option<&str>,
|
||||
selector: Option<&str>,
|
||||
restarted_min_count: Option<usize>,
|
||||
@@ -1083,29 +1115,30 @@ where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
let restarted_min = restarted_min_count.unwrap_or(5usize);
|
||||
let pods = kubectl_exec_get_pods(kubernetes_config.as_ref(), namespace, selector, envs)?;
|
||||
let pods = kubectl_exec_get_pods(kubernetes_config, namespace, selector, envs)?;
|
||||
|
||||
// Pod needs to have at least one container having backoff status (check 1)
|
||||
// AND at least a container with minimum restarts (asked in inputs) (check 2)
|
||||
Ok(pods
|
||||
let crash_looping_pods = pods
|
||||
.items
|
||||
.into_iter()
|
||||
.filter(|pod| {
|
||||
pod.status.container_statuses.as_ref().is_some()
|
||||
&& pod
|
||||
.status
|
||||
.conditions
|
||||
.iter()
|
||||
.any(|c| c.reason == KubernetesPodStatusReason::BackOff) // check 1
|
||||
&& pod
|
||||
.status
|
||||
.container_statuses
|
||||
.as_ref()
|
||||
.expect("Cannot get container statuses")
|
||||
.iter()
|
||||
.any(|e| e.restart_count >= restarted_min) // check 2
|
||||
.into_iter()
|
||||
.any(|e| {
|
||||
e.state.waiting.as_ref().is_some()
|
||||
&& e.state.waiting.as_ref().expect("cannot get container state").reason == KubernetesPodStatusReason::CrashLoopBackOff // check 1
|
||||
&& e.restart_count >= restarted_min // check 2
|
||||
})
|
||||
})
|
||||
.collect::<Vec<KubernetesPod>>())
|
||||
.collect::<Vec<KubernetesPod>>();
|
||||
|
||||
Ok(crash_looping_pods)
|
||||
}
|
||||
|
||||
/// kubectl_exec_delete_pod: allow to delete a k8s pod if exists.
|
||||
@@ -1116,8 +1149,8 @@ where
|
||||
/// * `pod_namespace`: pod's namespace.
|
||||
/// * `pod_name`: pod's name.
|
||||
/// * `envs`: environment variables to be passed to kubectl.
|
||||
pub fn kubectl_exec_delete_pod<P: ?Sized>(
|
||||
kubernetes_config: Box<P>,
|
||||
pub fn kubectl_exec_delete_pod<P>(
|
||||
kubernetes_config: P,
|
||||
pod_namespace: &str,
|
||||
pod_name: &str,
|
||||
envs: Vec<(&str, &str)>,
|
||||
@@ -1125,29 +1158,17 @@ pub fn kubectl_exec_delete_pod<P: ?Sized>(
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
let pod_to_be_deleted = match kubectl_exec_get_pods(
|
||||
kubernetes_config.as_ref(),
|
||||
Some(pod_namespace),
|
||||
Some(pod_name),
|
||||
envs.clone(),
|
||||
) {
|
||||
Ok(pods) => {
|
||||
if pods.items.is_empty() {
|
||||
return Err(SimpleError::new(
|
||||
SimpleErrorKind::Other,
|
||||
Some(format!(
|
||||
"Cannot delete pod `{}` in namespace `{}`, pod is not found.",
|
||||
pod_name, pod_namespace
|
||||
)),
|
||||
));
|
||||
}
|
||||
let pod_to_be_deleted =
|
||||
match kubectl_exec_get_pod_by_name(&kubernetes_config, Some(pod_namespace), pod_name, envs.clone()) {
|
||||
Ok(pod) => pod,
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
|
||||
pods.items[0].clone()
|
||||
}
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
let mut complete_envs = Vec::with_capacity(envs.len() + 1);
|
||||
complete_envs.push((KUBECONFIG, kubernetes_config.as_ref().to_str().unwrap()));
|
||||
complete_envs.extend(envs);
|
||||
|
||||
kubectl_exec(
|
||||
match kubectl_exec_with_output(
|
||||
vec![
|
||||
"delete",
|
||||
"pod",
|
||||
@@ -1155,11 +1176,13 @@ where
|
||||
"-n",
|
||||
pod_to_be_deleted.metadata.namespace.as_str(),
|
||||
],
|
||||
kubernetes_config.as_ref(),
|
||||
envs,
|
||||
)?;
|
||||
|
||||
Ok(pod_to_be_deleted)
|
||||
complete_envs,
|
||||
|_| {},
|
||||
|_| {},
|
||||
) {
|
||||
Ok(_) => Ok(pod_to_be_deleted),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
fn kubectl_exec<P, T>(args: Vec<&str>, kubernetes_config: P, envs: Vec<(&str, &str)>) -> Result<T, SimpleError>
|
||||
|
||||
@@ -131,7 +131,7 @@ pub enum KubernetesPodStatusReason {
|
||||
Failed,
|
||||
Killing,
|
||||
Preempting,
|
||||
BackOff,
|
||||
CrashLoopBackOff,
|
||||
ExceededGracePeriod,
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ impl From<String> for KubernetesPodStatusReason {
|
||||
"failed" => KubernetesPodStatusReason::Failed,
|
||||
"killing" => KubernetesPodStatusReason::Killing,
|
||||
"preempting" => KubernetesPodStatusReason::Preempting,
|
||||
"backoff" => KubernetesPodStatusReason::BackOff,
|
||||
"crashloopbackoff" => KubernetesPodStatusReason::CrashLoopBackOff,
|
||||
"exceededgraceperiod" => KubernetesPodStatusReason::ExceededGracePeriod,
|
||||
_ => Unknown(match s.as_str() {
|
||||
"" => None,
|
||||
@@ -182,14 +182,15 @@ pub enum KubernetesPodStatusPhase {
|
||||
#[derive(Deserialize, Clone, Eq, PartialEq, Debug)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct KubernetesPodContainerStatus {
|
||||
pub last_state: Option<KubernetesPodContainerStatusLastState>,
|
||||
pub last_state: Option<KubernetesPodContainerStatusState>,
|
||||
pub state: KubernetesPodContainerStatusState,
|
||||
pub ready: bool,
|
||||
pub restart_count: usize,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone, Eq, PartialEq, Debug)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct KubernetesPodContainerStatusLastState {
|
||||
pub struct KubernetesPodContainerStatusState {
|
||||
pub terminated: Option<ContainerStatusTerminated>,
|
||||
pub waiting: Option<ContainerStatusWaiting>,
|
||||
}
|
||||
@@ -198,7 +199,8 @@ pub struct KubernetesPodContainerStatusLastState {
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ContainerStatusWaiting {
|
||||
pub message: Option<String>,
|
||||
pub reason: String,
|
||||
#[serde(default)]
|
||||
pub reason: KubernetesPodStatusReason,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone, Eq, PartialEq, Debug)]
|
||||
@@ -206,7 +208,8 @@ pub struct ContainerStatusWaiting {
|
||||
pub struct ContainerStatusTerminated {
|
||||
pub exit_code: i16,
|
||||
pub message: Option<String>,
|
||||
pub reason: String,
|
||||
#[serde(default)]
|
||||
pub reason: KubernetesPodStatusReason,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone, Eq, PartialEq)]
|
||||
@@ -1199,7 +1202,7 @@ mod tests {
|
||||
"lastProbeTime": null,
|
||||
"lastTransitionTime": "2021-03-15T15:41:56Z",
|
||||
"message": "0/5 nodes are available: 5 Insufficient memory.",
|
||||
"reason": "BackOff",
|
||||
"reason": "CrashLoopBackOff",
|
||||
"status": "False",
|
||||
"type": "PodScheduled"
|
||||
}
|
||||
@@ -1222,7 +1225,7 @@ mod tests {
|
||||
assert_eq!(pod_status.items[0].status.conditions[0].status, "False");
|
||||
assert_eq!(
|
||||
pod_status.items[0].status.conditions[0].reason,
|
||||
KubernetesPodStatusReason::BackOff
|
||||
KubernetesPodStatusReason::CrashLoopBackOff
|
||||
);
|
||||
|
||||
let payload = r#"{
|
||||
|
||||
Reference in New Issue
Block a user