Skip to content

Commit

Permalink
Add support for multiple docker hosts, fixed #62
Browse files Browse the repository at this point in the history
  • Loading branch information
BigBoot committed Aug 7, 2024
1 parent 42a3c64 commit ba903f6
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 36 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ services:
# {{container_name}}_http.http.url: https://{{@0}}:{{@1}}
# {{container_name}}_docker.docker.name: {{container_name}} Docker
# {{container_name}}_docker.docker.docker_container: {{container_name}}
# AUTOKUMA__DOCKER__SOCKET: /var/run/docker.sock
# AUTOKUMA__DOCKER__HOSTS: /var/run/docker.sock
# AUTOKUMA__DOCKER__LABEL_PREFIX: kuma

volumes:
Expand All @@ -91,7 +91,7 @@ AutoKuma can be configured using the following environment variables/config keys
| `AUTOKUMA__KUMA__HEADERS` | `kuma.headers` | List of HTTP headers to send when connecting to Uptime Kuma |
| `AUTOKUMA__KUMA__CONNECT_TIMEOUT` | `kuma.connect_timeout` | The timeout for the initial connection to Uptime Kuma |
| `AUTOKUMA__KUMA__CALL_TIMEOUT` | `kuma.call_timeout` | The timeout for executing calls to the Uptime Kuma server |
| `AUTOKUMA__DOCKER__SOCKET` | `docker.socket` | Path to the Docker socket |
| `AUTOKUMA__DOCKER__HOSTS` | `docker.hosts` | List of Docker hosts. Use a semicolon separated string when setting using an env variable. |
| `AUTOKUMA__DOCKER__LABEL_PREFIX` | `docker.label_prefix` | Prefix used when scanning for container labels |
| `AUTOKUMA__DOCKER__SOURCE` | `docker.source` | Wether monitors should be created from `container` or `service` labels (or `both`). |

Expand Down
12 changes: 11 additions & 1 deletion autokuma/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use kuma_client::deserialize::DeserializeVecLenient;
use serde::{Deserialize, Serialize};
use serde_alias::serde_alias;
use serde_inline_default::serde_inline_default;
use serde_with::{formats::SemicolonSeparator, serde_as, PickFirst, StringWithSeparator};
use std::collections::HashMap;

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
Expand All @@ -15,16 +17,24 @@ pub enum DockerSource {

#[serde_alias(ScreamingSnakeCase)]
#[serde_inline_default]
#[serde_as]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct DockerConfig {
/// Wether docker integration should be enabled or not.
#[serde_inline_default(true)]
pub enabled: bool,

/// Path to the Docker socket.
/// Path to the Docker socket. If not set, the DOCKER_HOST will be used.
#[serde_inline_default(None)]
pub socket_path: Option<String>,

/// List of Docker hosts. If set this will override socker_path. Use a semicolon separated string when setting using an env variable.
#[serde_as(
as = "Option<PickFirst<(DeserializeVecLenient<String>, StringWithSeparator::<SemicolonSeparator, String>)>>"
)]
#[serde(default)]
pub hosts: Option<Vec<String>>,

/// Wether monitors should be created from container or service labels (or both).
#[serde_inline_default(DockerSource::Containers)]
pub source: DockerSource,
Expand Down
55 changes: 33 additions & 22 deletions autokuma/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -482,33 +482,44 @@ impl Sync {
let mut new_monitors: HashMap<String, Monitor> = HashMap::new();

if self.config.docker.enabled {
if let Some(docker_socket) = &self.config.docker.socket_path {
env::set_var("DOCKER_HOST", format!("unix://{}", docker_socket));
}
let docker_hosts = self
.config
.docker
.hosts
.clone()
.map(|f| f.into_iter().map(Some).collect::<Vec<_>>())
.unwrap_or_else(|| vec![self.config.docker.socket_path.clone()]);

for docker_host in docker_hosts {
if let Some(docker_socket) = &docker_host {
env::set_var("DOCKER_HOST", format!("unix://{}", docker_socket));
}

let docker = Docker::connect_with_defaults().log_warn(std::module_path!(), |_| {
format!(
"Using DOCKER_HOST={}",
env::var("DOCKER_HOST").unwrap_or_else(|_| "None".to_owned())
)
})?;
let docker =
Docker::connect_with_defaults().log_warn(std::module_path!(), |_| {
format!(
"Using DOCKER_HOST={}",
env::var("DOCKER_HOST").unwrap_or_else(|_| "None".to_owned())
)
})?;

if self.config.docker.source == DockerSource::Containers
|| self.config.docker.source == DockerSource::Both
{
let containers = self.get_kuma_containers(&docker).await?;
new_monitors.extend(self.get_monitors_from_containers(&containers)?);
}

if self.config.docker.source == DockerSource::Services
|| self.config.docker.source == DockerSource::Both
{
let services = self.get_kuma_services(&docker).await?;
new_monitors.extend(self.get_monitors_from_services(&services)?);
}

if self.config.docker.source == DockerSource::Containers
|| self.config.docker.source == DockerSource::Both
{
let containers = self.get_kuma_containers(&docker).await?;
new_monitors.extend(self.get_monitors_from_containers(&containers)?);
}

if self.config.docker.source == DockerSource::Services
|| self.config.docker.source == DockerSource::Both
{
let services = self.get_kuma_services(&docker).await?;
new_monitors.extend(self.get_monitors_from_services(&services)?);
}

let containers = self.get_kuma_containers(&docker).await?;
new_monitors.extend(self.get_monitors_from_containers(&containers)?);
}

let static_monitor_path = self
Expand Down
22 changes: 11 additions & 11 deletions kuma-client/src/deserialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use serde_with::{DeserializeAs, SerializeAs};
use std::{collections::HashMap, hash::Hash, marker::PhantomData, str::FromStr};
use time::{format_description::well_known::Iso8601, PrimitiveDateTime, Time};

pub(crate) struct DeserializeNumberLenient;
pub struct DeserializeNumberLenient;

impl<'de, T> DeserializeAs<'de, T> for DeserializeNumberLenient
where
Expand Down Expand Up @@ -56,7 +56,7 @@ where
}
}

pub(crate) struct DeserializeBoolLenient;
pub struct DeserializeBoolLenient;

impl<'de> DeserializeAs<'de, bool> for DeserializeBoolLenient {
fn deserialize_as<D>(deserializer: D) -> Result<bool, D::Error>
Expand Down Expand Up @@ -100,7 +100,7 @@ where
}
}

pub(crate) struct DeserializeVecLenient<T>(PhantomData<T>);
pub struct DeserializeVecLenient<T>(PhantomData<T>);

impl<'de, T> DeserializeAs<'de, Vec<T>> for DeserializeVecLenient<T>
where
Expand Down Expand Up @@ -138,7 +138,7 @@ where
}
}

pub(crate) struct DeserializeHashMapLenient<K, V>(PhantomData<K>, PhantomData<V>);
pub struct DeserializeHashMapLenient<K, V>(PhantomData<K>, PhantomData<V>);

impl<'de, K, V> DeserializeAs<'de, HashMap<K, V>> for DeserializeHashMapLenient<K, V>
where
Expand Down Expand Up @@ -177,7 +177,7 @@ where
}
}

pub(crate) struct DeserializeValueLenient;
pub struct DeserializeValueLenient;

impl<'de> DeserializeAs<'de, Value> for DeserializeValueLenient {
fn deserialize_as<D>(deserializer: D) -> Result<Value, D::Error>
Expand Down Expand Up @@ -222,7 +222,7 @@ impl<'de> DeserializeAs<'de, PrimitiveDateTime> for DeserializeBoolLenient {
}
}

pub(crate) struct SerializeDateRange;
pub struct SerializeDateRange;

impl<'de> DeserializeAs<'de, Option<Range<PrimitiveDateTime>>> for SerializeDateRange {
fn deserialize_as<D>(deserializer: D) -> Result<Option<Range<PrimitiveDateTime>>, D::Error>
Expand Down Expand Up @@ -287,13 +287,13 @@ impl SerializeAs<Option<Range<PrimitiveDateTime>>> for SerializeDateRange {
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub(crate) struct TimePoint {
pub(crate) hours: u8,
pub(crate) minutes: u8,
pub(crate) seconds: Option<u8>,
pub struct TimePoint {
pub hours: u8,
pub minutes: u8,
pub seconds: Option<u8>,
}

pub(crate) struct SerializeTimeRange;
pub struct SerializeTimeRange;

impl<'de> DeserializeAs<'de, Range<Time>> for SerializeTimeRange {
fn deserialize_as<D>(deserializer: D) -> Result<Range<Time>, D::Error>
Expand Down
6 changes: 6 additions & 0 deletions kuma-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ build_env: {}, {}"#,
);
}

#[cfg(feature = "private-api")]
#[doc(hidden)]
pub mod deserialize;

#[cfg(not(feature = "private-api"))]
#[doc(hidden)]
pub(crate) mod deserialize;

#[doc(hidden)]
Expand Down

0 comments on commit ba903f6

Please sign in to comment.