diff --git a/CHANGELOG.md b/CHANGELOG.md index b051da2..a81c0f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 To prevent data loss, AutoKuma will refuse to run if it detects any old monitors with an AutoKuma label. After adding a persistent storage location, AutoKuma will need to be started once with the environment variable `AUTOKUMA__MIGRATE=true` set to take over any existing monitors. This environment variable can be removed afterward. - Access to environment variables in templates restricted to variables starting with `AUTOKUMA__ENV__`, see [#97](https://github.com/BigBoot/AutoKuma/issues/97) - Changed Monitor::proxy_id to Option, parsing now supports both numbers and strings, see [#95](https://github.com/BigBoot/AutoKuma/issues/95) +- File source now skips hidden files ### Added - All CLI commands now support reading multiple files/ids/slugs at once, as well as parsing arrays of objects where applicable, [#74](https://github.com/BigBoot/AutoKuma/issues/74) @@ -24,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for creating Tags from Labels, see [#40](https://github.com/BigBoot/AutoKuma/issues/40) - File source now supports multiple entities per file, the ids will be named `[]` accordingly, see [#86](https://github.com/BigBoot/AutoKuma/issues/86) - Kubernetes integration, see [#58](https://github.com/BigBoot/AutoKuma/issues/58) +- File source can now follow symlinks (configurable, disabled by default) ### Fixed - File source now skips unsupported files rather then interrupting the whole sync, see [#89](https://github.com/BigBoot/AutoKuma/issues/89) diff --git a/README.md b/README.md index 3d26754..5f6e9b0 100644 --- a/README.md +++ b/README.md @@ -103,28 +103,29 @@ volumes: AutoKuma can be configured using the following environment variables/config keys: -| Env Variable | Config Key | Description | -|-----------------------------------|------------------------|--------------------------------------------------------------------------------------------------------------------------| -| `AUTOKUMA__STATIC_MONITORS` | `static_monitors` | The path to the folder in which AutoKuma will search for static Monitor definitions | -| `AUTOKUMA__TAG_NAME` | `tag_name` | The name of the AutoKuma tag, used to track managed containers | -| `AUTOKUMA__TAG_COLOR` | `tag_color` | The color of the AutoKuma tag | -| `AUTOKUMA__DEFAULT_SETTINGS` | `default_settings` | Default settings applied to all generated Monitors, see the example above for the syntax | -| `AUTOKUMA__LOG_DIR` | `log_dir` | Path to a directory where log files will be stored | -| `AUTOKUMA__ON_DELETE` | `on_delete` | Specify what should happen to a monitor if the autokuma id is not found anymore, either `delete` or `keep` | -| `AUTOKUMA__INSECURE_ENV_ACCESS` | `insecure_env_access` | Allow access to all env variables in templates, by default only variables starting with AUTOKUMA__ENV__ can be accessed. | -| `AUTOKUMA__SNIPPETS__` | `snippets.` | Define a snippet named ``, see [Snippets](#snippets) for details | -| `AUTOKUMA__KUMA__URL` | `kuma.url` | The URL AutoKuma should use to connect to Uptime Kuma | -| `AUTOKUMA__KUMA__USERNAME` | `kuma.username` | The username for logging into Uptime Kuma (required unless auth is disabled) | -| `AUTOKUMA__KUMA__PASSWORD` | `kuma.password` | The password for logging into Uptime Kuma (required unless auth is disabled) | -| `AUTOKUMA__KUMA__MFA_TOKEN` | `kuma.mfa_token` | The MFA token for logging into Uptime Kuma (required if MFA is enabled) | -| `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__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` | Whether monitors should be created from `Containers` or `Services` labels (or `Both`). | -| `AUTOKUMA__DOCKER__TLS__VERIFY` | `docker.tls.verify` | Whether to verify the TLS certificate or not. | -| `AUTOKUMA__DOCKER__TLS__CERT` | `docker.tls.cert` | The path to a custom tls certificate in PEM format. | +| Env Variable | Config Key | Description | +|------------------------------------|-------------------------|--------------------------------------------------------------------------------------------------------------------------| +| `AUTOKUMA__STATIC_MONITORS` | `static_monitors` | The path to the folder in which AutoKuma will search for static Monitor definitions | +| `AUTOKUMA__TAG_NAME` | `tag_name` | The name of the AutoKuma tag, used to track managed containers | +| `AUTOKUMA__TAG_COLOR` | `tag_color` | The color of the AutoKuma tag | +| `AUTOKUMA__DEFAULT_SETTINGS` | `default_settings` | Default settings applied to all generated Monitors, see the example above for the syntax | +| `AUTOKUMA__LOG_DIR` | `log_dir` | Path to a directory where log files will be stored | +| `AUTOKUMA__ON_DELETE` | `on_delete` | Specify what should happen to a monitor if the autokuma id is not found anymore, either `delete` or `keep` | +| `AUTOKUMA__INSECURE_ENV_ACCESS` | `insecure_env_access` | Allow access to all env variables in templates, by default only variables starting with AUTOKUMA__ENV__ can be accessed. | +| `AUTOKUMA__SNIPPETS__` | `snippets.` | Define a snippet named ``, see [Snippets](#snippets) for details | +| `AUTOKUMA__KUMA__URL` | `kuma.url` | The URL AutoKuma should use to connect to Uptime Kuma | +| `AUTOKUMA__KUMA__USERNAME` | `kuma.username` | The username for logging into Uptime Kuma (required unless auth is disabled) | +| `AUTOKUMA__KUMA__PASSWORD` | `kuma.password` | The password for logging into Uptime Kuma (required unless auth is disabled) | +| `AUTOKUMA__KUMA__MFA_TOKEN` | `kuma.mfa_token` | The MFA token for logging into Uptime Kuma (required if MFA is enabled) | +| `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__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` | Whether monitors should be created from `Containers` or `Services` labels (or `Both`). | +| `AUTOKUMA__DOCKER__TLS__VERIFY` | `docker.tls.verify` | Whether to verify the TLS certificate or not. | +| `AUTOKUMA__DOCKER__TLS__CERT` | `docker.tls.cert` | The path to a custom tls certificate in PEM format. | +| `AUTOKUMA__FILES__FOLLOW_SYMLINKS` | `files.follow_symlinks` | Wether AutoKuma should follow symlinks when looking for "static monitors" (Defaults to false) | AutoKuma will read configuration from a file named `autokuma.{toml,yaml,json}` in the current directory and in the following locations: diff --git a/autokuma/src/config.rs b/autokuma/src/config.rs index 75b974a..dfd6f09 100644 --- a/autokuma/src/config.rs +++ b/autokuma/src/config.rs @@ -54,6 +54,20 @@ pub struct KubernetesConfig { pub enabled: bool, } +#[serde_alias(ScreamingSnakeCase)] +#[serde_inline_default] +#[serde_as] +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +pub struct FilesConfig { + /// Whether files source should be enabled or not. + #[serde_inline_default(true)] + pub enabled: bool, + + /// Whether the files source should follow symlinks or not. + #[serde_inline_default(false)] + pub follow_symlinks: bool, +} + #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] pub enum DeleteBehavior { #[serde(alias = "delete")] @@ -72,6 +86,8 @@ pub struct Config { pub kubernetes: KubernetesConfig, + pub files: FilesConfig, + /// The interval in between syncs. #[serde_inline_default(5.0)] pub sync_interval: f64, diff --git a/autokuma/src/kuma.rs b/autokuma/src/kuma.rs index ab905eb..5e1024b 100644 --- a/autokuma/src/kuma.rs +++ b/autokuma/src/kuma.rs @@ -27,6 +27,12 @@ pub fn get_kuma_labels( ) .map(|key| (key, value.to_owned())) }) + .chain( + labels + .iter() + .filter(|(key, _)| state.config.snippets.contains_key(&format!("!{}", key))) + .map(|(key, value)| Ok((format!("__!{}", key), value.to_owned()))), + ) .collect::>>() }, ) diff --git a/autokuma/src/sources/file_source.rs b/autokuma/src/sources/file_source.rs index f1199e3..efe312a 100644 --- a/autokuma/src/sources/file_source.rs +++ b/autokuma/src/sources/file_source.rs @@ -136,9 +136,19 @@ impl Source for FileSource { .is_ok_and(|md| md.is_dir()) { let files = WalkDir::new(&static_monitor_path) + .follow_links(self.state.config.files.follow_symlinks) .into_iter() + .filter_entry(|e| { + e.file_name() + .to_str() + .map(|s| !s.starts_with('.')) + .unwrap_or(false) + }) .filter_map(|e| e.log_warn(std::module_path!(), |e| e.to_string()).ok()) - .filter(|e| e.file_type().is_file()); + .filter(|e| { + e.file_type().is_file() + || (self.state.config.files.follow_symlinks && e.file_type().is_symlink()) + }); for file in files { let file_path = file.path().strip_prefix(&static_monitor_path).unwrap(); diff --git a/autokuma/src/sources/mod.rs b/autokuma/src/sources/mod.rs index 6d12171..970eb2f 100644 --- a/autokuma/src/sources/mod.rs +++ b/autokuma/src/sources/mod.rs @@ -10,8 +10,11 @@ pub mod source; pub mod kubernetes_source; pub fn get_sources(state: Arc) -> Vec> { - let mut sources: Vec> = - vec![Box::new(file_source::FileSource::new(state.clone()))]; + let mut sources: Vec> = vec![]; + + if state.config.files.enabled { + sources.push(Box::new(file_source::FileSource::new(state.clone()))); + } if state.config.docker.enabled { sources.push(Box::new(docker_source::DockerSource::new(state.clone())));