aboutsummaryrefslogtreecommitdiff
path: root/src/util/config.rs
blob: fe6ab97910b31690ec1d9ad0541f3ca231363767 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
use std::fmt;
use std::io::Read;
use std::net::SocketAddr;
use std::path::PathBuf;

use serde::{de, Deserialize};

use crate::error::Error;

#[derive(Deserialize, Debug, Clone)]
pub struct Config {
	pub metadata_dir: PathBuf,
	pub data_dir: PathBuf,

	#[serde(deserialize_with = "deserialize_addr")]
	pub rpc_bind_addr: SocketAddr,

	#[serde(deserialize_with = "deserialize_vec_addr")]
	pub bootstrap_peers: Vec<SocketAddr>,
	pub consul_host: Option<String>,
	pub consul_service_name: Option<String>,

	#[serde(default = "default_max_concurrent_rpc_requests")]
	pub max_concurrent_rpc_requests: usize,

	#[serde(default = "default_block_size")]
	pub block_size: usize,

	#[serde(default = "default_control_write_max_faults")]
	pub control_write_max_faults: usize,

	#[serde(default = "default_replication_factor")]
	pub meta_replication_factor: usize,

	#[serde(default = "default_replication_factor")]
	pub data_replication_factor: usize,

	pub rpc_tls: Option<TlsConfig>,

	pub s3_api: ApiConfig,

	pub s3_web: WebConfig,
}

#[derive(Deserialize, Debug, Clone)]
pub struct TlsConfig {
	pub ca_cert: String,
	pub node_cert: String,
	pub node_key: String,
}

#[derive(Deserialize, Debug, Clone)]
pub struct ApiConfig {
	#[serde(deserialize_with = "deserialize_addr")]
	pub api_bind_addr: SocketAddr,
	pub s3_region: String,
}

#[derive(Deserialize, Debug, Clone)]
pub struct WebConfig {
	#[serde(deserialize_with = "deserialize_addr")]
	pub bind_addr: SocketAddr,
	pub root_domain: String,
	pub index: String,
}

fn default_max_concurrent_rpc_requests() -> usize {
	12
}
fn default_block_size() -> usize {
	1048576
}
fn default_replication_factor() -> usize {
	3
}
fn default_control_write_max_faults() -> usize {
	1
}

pub fn read_config(config_file: PathBuf) -> Result<Config, Error> {
	let mut file = std::fs::OpenOptions::new()
		.read(true)
		.open(config_file.as_path())?;

	let mut config = String::new();
	file.read_to_string(&mut config)?;

	Ok(toml::from_str(&config)?)
}

fn deserialize_addr<'de, D>(deserializer: D) -> Result<SocketAddr, D::Error>
where
	D: de::Deserializer<'de>,
{
	struct AddrVisitor;

	impl<'de> de::Visitor<'de> for AddrVisitor {
		type Value = SocketAddr;

		fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
			formatter.write_str("a string representing a socket address")
		}

		fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
		where
			E: de::Error,
		{
			use std::net::ToSocketAddrs;
			s.to_socket_addrs()
				.map_err(|_| de::Error::custom("could not resolve to a socket address"))?
				.next()
				.ok_or(de::Error::custom("could not resolve to a socket address"))
		}
	}

	deserializer.deserialize_any(AddrVisitor)
}

fn deserialize_vec_addr<'de, D>(deserializer: D) -> Result<Vec<SocketAddr>, D::Error>
where
	D: de::Deserializer<'de>,
{
	use std::net::ToSocketAddrs;

	let mut res = vec![];
	for s in <Vec<String>>::deserialize(deserializer)? {
		res.push(
			s.to_socket_addrs()
				.map_err(|_| de::Error::custom("could not resolve to a socket address"))?
				.next()
				.ok_or(de::Error::custom("could not resolve to a socket address"))?,
		);
	}
	Ok(res)
}