Skip to content

Commit 35e3716

Browse files
committed
Prometheus push gateway: opt-out of the default tls provider
This is a follow up to metrics-rs#516, metrics-rs#516 (comment). This change makes it possible for downstream projects to opt-out of the default rustls provider (aws-lc-rs). Hopefully closes metrics-rs#515
1 parent a44949c commit 35e3716

File tree

7 files changed

+44
-31
lines changed

7 files changed

+44
-31
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ hashbrown = { version = "0.15", default-features = false, features = ["default-h
3434
hdrhistogram = { version = "7.2", default-features = false }
3535
http-body-util = { version = "0.1", default-features = false }
3636
hyper = { version = "1.1", default-features = false, features = ["server", "client"] }
37-
hyper-rustls = { version = "0.27", default-features = false, features = ["aws-lc-rs", "http1", "rustls-native-certs"] }
37+
hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "rustls-native-certs"] }
3838
hyper-util = { version = "0.1", default-features = false, features = ["tokio", "service", "client", "client-legacy", "http1"] }
3939
indexmap = { version = "2.6", default-features = false, features = ["std"] }
4040
ipnet = { version = "2", default-features = false, features = ["std"] }
@@ -66,6 +66,7 @@ radix_trie = { version = "0.2", default-features = false }
6666
rand = { version = "0.9", default-features = false, features = [ "thread_rng" ] }
6767
rand_xoshiro = { version = "0.7", default-features = false }
6868
ratatui = { version = "0.28", default-features = false }
69+
rustls = { version = "0.23", default-features = false }
6970
sketches-ddsketch = { version = "0.3", default-features = false }
7071
thiserror = { version = "2", default-features = false }
7172
tokio = { version = "1", default-features = false, features = ["rt", "net", "time", "rt-multi-thread"] }

metrics-exporter-prometheus/Cargo.toml

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,16 @@ default = ["http-listener", "push-gateway"]
2020
async-runtime = ["tokio", "hyper-util/tokio"]
2121
http-listener = ["async-runtime", "ipnet", "tracing", "_hyper-server"]
2222
uds-listener = ["http-listener"]
23-
push-gateway = ["async-runtime", "tracing", "_hyper-client"]
23+
push-gateway = ["_push-gateway-common", "hyper-rustls/aws-lc-rs"]
24+
push-gateway-no-tls-provider = ["_push-gateway-common"]
2425
protobuf = ["mime", "prost", "prost-types", "prost-build"]
2526
_hyper-server = ["http-body-util", "hyper/server", "hyper-util/server-auto"]
27+
_push-gateway-common = [
28+
"async-runtime",
29+
"rustls",
30+
"tracing",
31+
"_hyper-client",
32+
]
2633
_hyper-client = [
2734
"http-body-util",
2835
"hyper/client",
@@ -34,10 +41,12 @@ _hyper-client = [
3441

3542
[dependencies]
3643
base64 = { workspace = true }
37-
http-body-util = { workspace = true, optional = true }
44+
quanta = { workspace = true }
45+
thiserror = { workspace = true }
3846

3947
# Optional
4048
hyper = { workspace = true, optional = true }
49+
http-body-util = { workspace = true, optional = true }
4150
hyper-rustls = { workspace = true, optional = true }
4251
hyper-util = { workspace = true, optional = true }
4352
indexmap = { workspace = true }
@@ -48,8 +57,7 @@ metrics-util = { version = "^0.20", path = "../metrics-util", default-features =
4857
"registry",
4958
"storage",
5059
] }
51-
quanta = { workspace = true }
52-
thiserror = { workspace = true }
60+
rustls = { workspace = true, optional = true }
5361
tokio = { workspace = true, optional = true }
5462
tracing = { workspace = true, optional = true }
5563

metrics-exporter-prometheus/src/exporter/builder.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
use std::collections::HashMap;
2-
#[cfg(feature = "push-gateway")]
2+
#[cfg(any(feature = "push-gateway", feature = "push-gateway-no-tls-provider"))]
33
use std::convert::TryFrom;
44
#[cfg(feature = "http-listener")]
55
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
66
use std::num::NonZeroU32;
77
use std::sync::RwLock;
8-
#[cfg(any(feature = "http-listener", feature = "push-gateway"))]
8+
#[cfg(any(feature = "http-listener", feature = "push-gateway", feature = "push-gateway-no-tls-provider"))]
99
use std::thread;
1010
use std::time::Duration;
1111

12-
#[cfg(feature = "push-gateway")]
12+
#[cfg(any(feature = "push-gateway", feature = "push-gateway-no-tls-provider"))]
1313
use hyper::Uri;
1414
use indexmap::IndexMap;
1515
#[cfg(feature = "http-listener")]
@@ -29,13 +29,13 @@ use crate::registry::AtomicStorage;
2929
use crate::{common::BuildError, PrometheusHandle};
3030

3131
use super::ExporterConfig;
32-
#[cfg(any(feature = "http-listener", feature = "push-gateway"))]
32+
#[cfg(any(feature = "http-listener", feature = "push-gateway", feature = "push-gateway-no-tls-provider"))]
3333
use super::ExporterFuture;
3434

3535
/// Builder for creating and installing a Prometheus recorder/exporter.
3636
#[derive(Debug)]
3737
pub struct PrometheusBuilder {
38-
#[cfg_attr(not(any(feature = "http-listener", feature = "push-gateway")), allow(dead_code))]
38+
#[cfg_attr(not(any(feature = "http-listener", feature = "push-gateway", feature = "push-gateway-no-tls-provider")), allow(dead_code))]
3939
exporter_config: ExporterConfig,
4040
#[cfg(feature = "http-listener")]
4141
allowed_addresses: Option<Vec<IpNet>>,
@@ -120,8 +120,8 @@ impl PrometheusBuilder {
120120
/// If the given endpoint cannot be parsed into a valid URI, an error variant will be returned describing the error.
121121
///
122122
/// [push gateway]: https://prometheus.io/docs/instrumenting/pushing/
123-
#[cfg(feature = "push-gateway")]
124-
#[cfg_attr(docsrs, doc(cfg(feature = "push-gateway")))]
123+
#[cfg(any(feature = "push-gateway", feature = "push-gateway-no-tls-provider"))]
124+
#[cfg_attr(docsrs, doc(cfg(any(feature = "push-gateway", feature = "push-gateway-no-tls-provider"))))]
125125
pub fn with_push_gateway<T>(
126126
mut self,
127127
endpoint: T,
@@ -399,8 +399,8 @@ impl PrometheusBuilder {
399399
///
400400
/// If there is an error while either building the recorder and exporter, or installing the recorder and exporter,
401401
/// an error variant will be returned describing the error.
402-
#[cfg(any(feature = "http-listener", feature = "push-gateway"))]
403-
#[cfg_attr(docsrs, doc(cfg(any(feature = "http-listener", feature = "push-gateway"))))]
402+
#[cfg(any(feature = "http-listener", feature = "push-gateway", feature = "push-gateway-no-tls-provider"))]
403+
#[cfg_attr(docsrs, doc(cfg(any(feature = "http-listener", feature = "push-gateway", feature = "push-gateway-no-tls-provider"))))]
404404
pub fn install(self) -> Result<(), BuildError> {
405405
use tokio::runtime;
406406

@@ -476,8 +476,8 @@ impl PrometheusBuilder {
476476
/// If there is an error while building the recorder and exporter, an error variant will be returned describing the
477477
/// error.
478478
#[warn(clippy::too_many_lines)]
479-
#[cfg(any(feature = "http-listener", feature = "push-gateway"))]
480-
#[cfg_attr(docsrs, doc(cfg(any(feature = "http-listener", feature = "push-gateway"))))]
479+
#[cfg(any(feature = "http-listener", feature = "push-gateway", feature = "push-gateway-no-tls-provider"))]
480+
#[cfg_attr(docsrs, doc(cfg(any(feature = "http-listener", feature = "push-gateway", feature = "push-gateway-no-tls-provider"))))]
481481
#[cfg_attr(not(feature = "http-listener"), allow(unused_mut))]
482482
pub fn build(mut self) -> Result<(PrometheusRecorder, ExporterFuture), BuildError> {
483483
#[cfg(feature = "http-listener")]
@@ -516,7 +516,7 @@ impl PrometheusBuilder {
516516
}
517517
},
518518

519-
#[cfg(feature = "push-gateway")]
519+
#[cfg(any(feature = "push-gateway", feature = "push-gateway-no-tls-provider"))]
520520
ExporterConfig::PushGateway {
521521
endpoint,
522522
interval,

metrics-exporter-prometheus/src/exporter/mod.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
11
#[cfg(feature = "http-listener")]
22
use http_listener::HttpListeningError;
3-
#[cfg(any(feature = "http-listener", feature = "push-gateway"))]
3+
#[cfg(any(feature = "http-listener", feature = "push-gateway", feature = "push-gateway-no-tls-provider"))]
44
use std::future::Future;
55
#[cfg(feature = "http-listener")]
66
use std::net::SocketAddr;
7-
#[cfg(any(feature = "http-listener", feature = "push-gateway"))]
7+
#[cfg(any(feature = "http-listener", feature = "push-gateway", feature = "push-gateway-no-tls-provider"))]
88
use std::pin::Pin;
9-
#[cfg(feature = "push-gateway")]
9+
#[cfg(any(feature = "push-gateway", feature = "push-gateway-no-tls-provider"))]
1010
use std::time::Duration;
1111

12-
#[cfg(feature = "push-gateway")]
12+
#[cfg(any(feature = "push-gateway", feature = "push-gateway-no-tls-provider"))]
1313
use hyper::Uri;
1414

1515
/// Error types possible from an exporter
16-
#[cfg(any(feature = "http-listener", feature = "push-gateway"))]
16+
#[cfg(any(feature = "http-listener", feature = "push-gateway", feature = "push-gateway-no-tls-provider"))]
1717
#[derive(Debug)]
1818
pub enum ExporterError {
1919
#[cfg(feature = "http-listener")]
2020
HttpListener(HttpListeningError),
2121
PushGateway(()),
2222
}
2323
/// Convenience type for Future implementing an exporter.
24-
#[cfg(any(feature = "http-listener", feature = "push-gateway"))]
24+
#[cfg(any(feature = "http-listener", feature = "push-gateway", feature = "push-gateway-no-tls-provider"))]
2525
pub type ExporterFuture = Pin<Box<dyn Future<Output = Result<(), ExporterError>> + Send + 'static>>;
2626

2727
#[cfg(feature = "http-listener")]
@@ -40,7 +40,7 @@ enum ExporterConfig {
4040

4141
// Run a push gateway task sending to the given `endpoint` after `interval` time has elapsed,
4242
// infinitely.
43-
#[cfg(feature = "push-gateway")]
43+
#[cfg(any(feature = "push-gateway", feature = "push-gateway-no-tls-provider"))]
4444
PushGateway {
4545
endpoint: Uri,
4646
interval: Duration,
@@ -54,12 +54,12 @@ enum ExporterConfig {
5454
}
5555

5656
impl ExporterConfig {
57-
#[cfg_attr(not(any(feature = "http-listener", feature = "push-gateway")), allow(dead_code))]
57+
#[cfg_attr(not(any(feature = "http-listener", feature = "push-gateway", feature = "push-gateway-no-tls-provider")), allow(dead_code))]
5858
fn as_type_str(&self) -> &'static str {
5959
match self {
6060
#[cfg(feature = "http-listener")]
6161
Self::HttpListener { .. } => "http-listener",
62-
#[cfg(feature = "push-gateway")]
62+
#[cfg(any(feature = "push-gateway", feature = "push-gateway-no-tls-provider"))]
6363
Self::PushGateway { .. } => "push-gateway",
6464
Self::Unconfigured => "unconfigured,",
6565
}
@@ -69,7 +69,7 @@ impl ExporterConfig {
6969
#[cfg(feature = "http-listener")]
7070
mod http_listener;
7171

72-
#[cfg(feature = "push-gateway")]
72+
#[cfg(any(feature = "push-gateway", feature = "push-gateway-no-tls-provider"))]
7373
mod push_gateway;
7474

7575
pub(crate) mod builder;

metrics-exporter-prometheus/src/exporter/push_gateway.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use http_body_util::{BodyExt, Collected, Full};
44
use hyper::body::Bytes;
55
use hyper::{header::HeaderValue, Method, Request, Uri};
66
use hyper_util::{client::legacy::Client, rt::TokioExecutor};
7+
use rustls::crypto::CryptoProvider;
78
use tracing::error;
89

910
use super::ExporterFuture;
@@ -20,8 +21,10 @@ pub(super) fn new_push_gateway(
2021
) -> ExporterFuture {
2122
let http_method = if use_http_post_method { Method::POST } else { Method::PUT };
2223
Box::pin(async move {
24+
let provider = CryptoProvider::get_default()
25+
.expect("no process-level CryptoProvider available -- call rustls' CryptoProvider::install_default() before this point");
2326
let https = hyper_rustls::HttpsConnectorBuilder::new()
24-
.with_native_roots()
27+
.with_provider_and_native_roots(provider.clone())
2528
.expect("no native root CA certificates found")
2629
.https_or_http()
2730
.enable_http1()
@@ -79,7 +82,7 @@ pub(super) fn new_push_gateway(
7982
})
8083
}
8184

82-
#[cfg(feature = "push-gateway")]
85+
#[cfg(any(feature = "push-gateway", feature = "push-gateway-no-tls-provider"))]
8386
fn basic_auth(username: &str, password: Option<&str>) -> HeaderValue {
8487
use base64::prelude::BASE64_STANDARD;
8588
use base64::write::EncoderWriter;

metrics-exporter-prometheus/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,8 @@ pub use distribution::{Distribution, DistributionBuilder};
126126

127127
mod exporter;
128128
pub use self::exporter::builder::PrometheusBuilder;
129-
#[cfg(any(feature = "http-listener", feature = "push-gateway"))]
130-
#[cfg_attr(docsrs, doc(cfg(any(feature = "http-listener", feature = "push-gateway"))))]
129+
#[cfg(any(feature = "http-listener", feature = "push-gateway", feature = "push-gateway-no-tls-provider"))]
130+
#[cfg_attr(docsrs, doc(cfg(any(feature = "http-listener", feature = "push-gateway", feature = "push-gateway-no-tls-provider"))))]
131131
pub use self::exporter::ExporterFuture;
132132

133133
pub mod formatting;

0 commit comments

Comments
 (0)