1pub mod catalog;
2mod kv;
3pub mod locking;
4mod with_index;
5
6use std::fs::File;
7use std::io::Read;
8
9use anyhow::{bail, Result};
10
11pub use with_index::WithIndex;
12
13pub struct Config {
15 pub addr: String,
17 pub ca_cert: Option<String>,
19 pub client_cert: Option<String>,
21 pub client_key: Option<String>,
23 pub tls_skip_verify: bool,
25}
26
27#[derive(Clone)]
31pub struct Consul {
32 client: reqwest::Client,
33
34 url: String,
35 kv_prefix: String,
36}
37
38impl Consul {
39 pub fn new(config: Config, kv_prefix: &str) -> Result<Self> {
40 let client = match (&config.client_cert, &config.client_key) {
41 (Some(client_cert), Some(client_key)) => {
42 let mut client_cert_buf = vec![];
43 File::open(client_cert)?.read_to_end(&mut client_cert_buf)?;
44
45 let mut client_key_buf = vec![];
46 File::open(client_key)?.read_to_end(&mut client_key_buf)?;
47
48 let identity = reqwest::Identity::from_pem(
49 &[&client_cert_buf[..], &client_key_buf[..]].concat()[..],
50 )?;
51
52 if config.tls_skip_verify {
53 reqwest::Client::builder()
54 .use_rustls_tls()
55 .danger_accept_invalid_certs(true)
56 .identity(identity)
57 .build()?
58 } else if let Some(ca_cert) = &config.ca_cert {
59 let mut ca_cert_buf = vec![];
60 File::open(ca_cert)?.read_to_end(&mut ca_cert_buf)?;
61
62 reqwest::Client::builder()
63 .use_rustls_tls()
64 .add_root_certificate(reqwest::Certificate::from_pem(&ca_cert_buf[..])?)
65 .identity(identity)
66 .build()?
67 } else {
68 reqwest::Client::builder()
69 .use_rustls_tls()
70 .identity(identity)
71 .build()?
72 }
73 }
74 (None, None) => reqwest::Client::new(),
75 _ => bail!("Incomplete Consul TLS configuration parameters"),
76 };
77
78 Ok(Self {
79 client,
80 url: config.addr.trim_end_matches('/').to_string(),
81 kv_prefix: kv_prefix.to_string(),
82 })
83 }
84}