a (hacky, wip) multi-tenant oidc-terminating reverse proxy, written in anger on top of pingora
1use std::path::Path;
2use std::sync::LazyLock;
3
4use color_eyre::eyre::Context as _;
5use prost_reflect::DescriptorPool;
6
7#[allow(unused, reason = "for prost-reflect-build")]
8static DESCRIPTOR_POOL: LazyLock<DescriptorPool> = LazyLock::new(|| {
9 DescriptorPool::decode(
10 include_bytes!(concat!(env!("OUT_DIR"), "/file_descriptor_set.bin")).as_ref(),
11 )
12 .unwrap()
13});
14
15pub mod format {
16 include!(concat!(env!("OUT_DIR"), "/config.format.rs"));
17
18 impl From<&Pingora> for pingora::server::configuration::ServerConf {
19 fn from(raw: &Pingora) -> Self {
20 let default = pingora::server::configuration::ServerConf::default();
21 Self {
22 version: raw.version.map(|v| v as usize).unwrap_or(default.version),
23 daemon: raw.daemon.unwrap_or(default.daemon),
24 error_log: raw.error_log.clone(),
25 pid_file: raw.pid_file.clone().unwrap_or(default.pid_file),
26 upgrade_sock: raw.upgrade_sock.clone().unwrap_or(default.upgrade_sock),
27 user: raw.user.clone(),
28 group: raw.group.clone(),
29 threads: raw.threads.map(|t| t as usize).unwrap_or(default.threads),
30 listener_tasks_per_fd: raw
31 .listener_tasks_per_fd
32 .map(|t| t as usize)
33 .unwrap_or(default.listener_tasks_per_fd),
34 work_stealing: raw.work_stealing.unwrap_or(default.work_stealing),
35 ca_file: raw.ca_file.clone(),
36 grace_period_seconds: raw.grace_period_seconds,
37 graceful_shutdown_timeout_seconds: raw.graceful_shutdown_timeout_seconds,
38 client_bind_to_ipv4: raw.client_bind_to_ipv4.clone(),
39 client_bind_to_ipv6: raw.client_bind_to_ipv6.clone(),
40 upstream_keepalive_pool_size: raw
41 .upstream_keepalive_pool_size
42 .map(|s| s as usize)
43 .unwrap_or(default.upstream_keepalive_pool_size),
44 upstream_connect_offload_threadpools: raw
45 .upstream_connect_offload_threadpools
46 .map(|x| x as usize),
47 upstream_connect_offload_thread_per_pool: raw
48 .upstream_connect_offload_thread_per_pool
49 .map(|x| x as usize),
50 upstream_debug_ssl_keylog: raw
51 .upstream_debug_ssl_keylog
52 .unwrap_or(default.upstream_debug_ssl_keylog),
53 max_retries: raw
54 .max_retries
55 .map(|r| r as usize)
56 .unwrap_or(default.max_retries),
57 upgrade_sock_connect_accept_max_retries: raw
58 .upgrade_sock_connect_accept_max_retries
59 .map(|x| x as usize),
60 }
61 }
62 }
63}
64
65/// load the config from the given file
66pub fn load(src: impl AsRef<Path>) -> color_eyre::Result<format::Config> {
67 use prost_reflect::{DynamicMessage, ReflectMessage as _};
68
69 let dynamic = DynamicMessage::parse_text_format(
70 format::Config::default().descriptor(),
71 &std::fs::read_to_string(src).context("reading config file")?,
72 )
73 .context("parsing config")?;
74
75 dynamic.transcode_to().context("validating config")
76}