Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/10980_loki_endpoint_validation.fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The `loki` sink now validates the `endpoint` option at startup and returns a clear error when it is not an absolute URL (for example, a host name with a missing or mistyped scheme). Previously such values were accepted during configuration parsing but later failed with an opaque `invalid format` error.
41 changes: 40 additions & 1 deletion src/sinks/loki/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,8 @@ impl SinkConfig for LokiConfig {
}
}

validate_endpoint(&self.endpoint)?;

let client = self.build_client(cx)?;

let config = LokiConfig {
Expand Down Expand Up @@ -277,11 +279,30 @@ pub fn valid_label_name(label: &Template) -> bool {
}
}

/// Validates that the configured `endpoint` is a usable absolute URL.
///
/// `endpoint` is deserialized as a permissive `UriSerde`, so values without a
/// scheme (for example a bare host name with a typo) are accepted at parse time
/// but later fail with an opaque "invalid format" error when the request URI is
/// built. Checking here lets us surface a clear, actionable message instead.
fn validate_endpoint(endpoint: &UriSerde) -> crate::Result<()> {
let uri = &endpoint.uri;
if uri.scheme().is_none() || uri.authority().is_none() {
return Err(format!(
"Invalid `endpoint`: {endpoint:?} is not an absolute URL. \
Expected a value with a scheme and host, such as \"http://localhost:3100\"."
)
.into());
}
Ok(())
}

#[cfg(test)]
mod tests {
use std::convert::TryInto;

use super::valid_label_name;
use super::{valid_label_name, validate_endpoint};
use crate::sinks::util::UriSerde;

#[test]
fn valid_label_names() {
Expand All @@ -299,4 +320,22 @@ mod tests {

assert!(valid_label_name(&"{{field}}".try_into().unwrap()));
}

#[test]
fn validates_endpoint() {
let parse = |s: &str| s.parse::<UriSerde>().unwrap();

// Valid absolute URLs.
assert!(validate_endpoint(&parse("http://localhost:3100")).is_ok());
assert!(validate_endpoint(&parse("https://loki.example.com/")).is_ok());

// Scheme-less values (such as a host name with a typo) are rejected with
// a clear error instead of failing later with "invalid format".
let error = validate_endpoint(&parse("typo-host-no-scheme"))
.unwrap_err()
.to_string();
assert!(error.contains("not an absolute URL"), "{error}");

assert!(validate_endpoint(&parse("/loki/api/v1/push")).is_err());
}
}
Loading