diff --git a/Cargo.lock b/Cargo.lock index 7e9abc4..f07fa69 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -165,11 +165,12 @@ dependencies = [ [[package]] name = "docker-autoheal" -version = "0.2.2" +version = "0.2.3" dependencies = [ "bollard", "chrono", "futures", + "rustls", "tokio", ] @@ -283,6 +284,17 @@ dependencies = [ "slab", ] +[[package]] +name = "getrandom" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "gimli" version = "0.28.1" @@ -649,12 +661,57 @@ dependencies = [ "bitflags", ] +[[package]] +name = "ring" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +dependencies = [ + "cc", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys", +] + [[package]] name = "rustc-demangle" version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +[[package]] +name = "rustls" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e87c9956bd9807afa1f77e0f7594af32566e830e088a5576d27c5b6f30f49d41" +dependencies = [ + "log", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e9d979b3ce68192e42760c7810125eb6cf2ea10efae545a156063e61f314e2a" + +[[package]] +name = "rustls-webpki" +version = "0.102.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef4ca26037c909dedb327b48c3327d0ba91d3dd3c4e05dad328f210ffb68e95b" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "ryu" version = "1.0.16" @@ -771,6 +828,18 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + [[package]] name = "syn" version = "2.0.46" @@ -942,6 +1011,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.5.0" @@ -1175,3 +1250,9 @@ name = "windows_x86_64_msvc" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/Cargo.toml b/Cargo.toml index bb84a29..5460299 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "docker-autoheal" -version = "0.2.2" +version = "0.2.3" authors = ["Travis M Knight "] license = "MIT" description = "Monitor and restart unhealthy docker containers" @@ -13,6 +13,7 @@ rust-version = "1.74.1" bollard = "*" chrono = "0.4.*" futures = "0.3.*" +rustls = "0.22.*" tokio = { version = "1.*", features = ["full"] } [[bin]] diff --git a/src/main.rs b/src/main.rs index de8ff6d..d24db3f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ use bollard::container::{ListContainersOptions, RestartContainerOptions}; -use bollard::Docker; +use bollard::{Docker, API_DEFAULT_VERSION}; use chrono::prelude::*; use std::collections::HashMap; use std::io::{stdout, Write}; @@ -16,20 +16,28 @@ async fn log_message(msg: &str) { fn get_env(key: &str, default: &str) -> String { match std::env::var(key) { Ok(val) => return val.to_lowercase(), - Err(e) => return default.to_string().to_lowercase(), + Err(_e) => return default.to_string().to_lowercase(), } } #[tokio::main] async fn main() -> Result<(), Box> { - // Autoheal variables - let autoheal_connection_type = get_env("AUTOHEAL_CONNECTION_TYPE", "local"); - let autoheal_container_label = get_env("AUTOHEAL_CONTAINER_LABEL", "autoheal"); - let autoheal_default_stop_timeout = get_env("AUTOHEAL_DEFAULT_STOP_TIMEOUT", "10") - .parse() - .unwrap(); - let autoheal_interval = get_env("AUTOHEAL_INTERVAL", "5").parse().unwrap(); - let autoheal_start_period = get_env("AUTOHEAL_START_PERIOD", "0").parse().unwrap(); + // Autoheal core variables + let autoheal_connection_type: String = get_env("AUTOHEAL_CONNECTION_TYPE", "local"); + let autoheal_container_label: String = get_env("AUTOHEAL_CONTAINER_LABEL", "autoheal"); + let autoheal_stop_timeout: isize = get_env("AUTOHEAL_STOP_TIMEOUT", "10").parse().unwrap(); + let autoheal_interval: u64 = get_env("AUTOHEAL_INTERVAL", "5").parse().unwrap(); + let autoheal_start_delay: u64 = get_env("AUTOHEAL_START_DELAY", "0").parse().unwrap(); + // Autoheal tcp variables + let autoheal_tcp_host: String = get_env("AUTOHEAL_TCP_HOST", "localhost"); + let autoheal_tcp_port: u64 = get_env("AUTOHEAL_TCP_PORT", "2375").parse().unwrap(); + let autoheal_tcp_address: String = autoheal_tcp_host + ":" + &autoheal_tcp_port.to_string(); + let autoheal_tcp_timeout: u64 = get_env("AUTOHEAL_TCP_TIMEOUT", "10").parse().unwrap(); + let autoheal_key_path: String = + get_env("AUTOHEAL_KEY_PATH", "/opt/docker-autoheal/tls/key.pem"); + let autoheal_cert_path: String = + get_env("AUTOHEAL_CERT_PATH", "/opt/docker-autoheal/tls/cert.pem"); + let autoheal_ca_path: String = get_env("AUTOHEAL_CA_PATH", "/opt/docker-autoheal/tls/ca.pem"); // todo // Webhook variables @@ -42,18 +50,29 @@ async fn main() -> Result<(), Box> { match autoheal_connection_type.as_str() { "socket" => { docker_tmp = Some( - #[cfg(unix)] + // #[cfg(unix)] Docker::connect_with_socket_defaults()?, ); } "http" => { - docker_tmp = Some(Docker::connect_with_http_defaults()?); + docker_tmp = Some(Docker::connect_with_http( + &autoheal_tcp_address, + autoheal_tcp_timeout, + API_DEFAULT_VERSION, + )?); } // todo // "ssl" => { // docker_tmp = Some( - // // #[cfg(feature = "ssl")] - // Docker::connect_with_ssl_defaults()?, + // #[cfg(feature = "ssl")] + // Docker::connect_with_ssl( + // autoheal_tcp_address, + // autoheal_tcp_timeout, + // Path::new(autoheal_key_path), + // Path::new(autoheal_cert_path), + // Path::new(autoheal_ca_path), + // API_DEFAULT_VERSION + // )?, // ); // } &_ => { @@ -66,10 +85,10 @@ async fn main() -> Result<(), Box> { let docker = docker_tmp.unwrap(); // Delay start of loop if specified - if autoheal_start_period > 0 { - let msg0 = format!("Delaying evaluation {}s on request", autoheal_start_period); + if autoheal_start_delay > 0 { + let msg0 = format!("Delaying evaluation {}s on request", autoheal_start_delay); log_message(&msg0).await; - std::thread::sleep(Duration::from_secs(autoheal_start_period)); + std::thread::sleep(Duration::from_secs(autoheal_start_delay)); } // Establish loop interval @@ -106,7 +125,7 @@ async fn main() -> Result<(), Box> { if !matches!(state.as_str(), "paused" | "restarting") { // Build restart options let restart_options = Some(RestartContainerOptions { - t: autoheal_default_stop_timeout, + t: autoheal_stop_timeout, ..Default::default() }); @@ -114,7 +133,7 @@ async fn main() -> Result<(), Box> { let msg0 = format!("Container '{}' ({}) unhealthy", name, id); let msg1 = format!( "Restarting '{}' with {}s timeout", - name, autoheal_default_stop_timeout + name, autoheal_stop_timeout ); log_message(&msg0).await; log_message(&msg1).await;