a (hacky, wip) multi-tenant oidc-terminating reverse proxy, written in anger on top of pingora
1//! _grumbles_ ketama doesn't support uds _grumbles_
2//!
3//! (also this lets us add an option to choose in the future)
4
5use std::sync::Arc;
6
7use pingora::lb::selection::BackendSelection;
8use pingora::lb::selection::consistent::{KetamaConfig, KetamaHashing};
9use pingora::lb::{self, Backend};
10use pingora::prelude::*;
11
12pub enum SelectionChoice {
13 Ketama(Arc<KetamaHashing>),
14 RoundRobin(Arc<RoundRobin>),
15}
16
17#[allow(
18 dead_code,
19 reason = "required for trait impl, will use the in the future"
20)]
21pub enum SelectionConfig {
22 Ketama(KetamaConfig),
23 RoundRobin(()),
24}
25pub enum SelectionIter {
26 Ketama(<KetamaHashing as BackendSelection>::Iter),
27 RoundRobin(<RoundRobin as BackendSelection>::Iter),
28}
29impl lb::selection::BackendIter for SelectionIter {
30 fn next(&mut self) -> Option<&Backend> {
31 match self {
32 SelectionIter::Ketama(k) => k.next(),
33 SelectionIter::RoundRobin(rr) => rr.next(),
34 }
35 }
36}
37impl BackendSelection for SelectionChoice {
38 type Iter = SelectionIter;
39
40 type Config = SelectionConfig;
41
42 fn build(backends: &std::collections::BTreeSet<lb::Backend>) -> Self {
43 // need the arc here for iter
44 if backends
45 .iter()
46 .any(|b| matches!(b.addr, pingora::protocols::l4::socket::SocketAddr::Unix(_)))
47 {
48 // ketama does not support unix domain sockets
49 Self::RoundRobin(Arc::new(RoundRobin::build(backends)))
50 } else {
51 Self::Ketama(Arc::new(KetamaHashing::build(backends)))
52 }
53 }
54
55 fn iter(self: &std::sync::Arc<Self>, key: &[u8]) -> Self::Iter
56 where
57 Self::Iter: lb::selection::BackendIter,
58 {
59 match &**self {
60 SelectionChoice::Ketama(k) => SelectionIter::Ketama(k.iter(key)),
61 SelectionChoice::RoundRobin(rr) => SelectionIter::RoundRobin(rr.iter(key)),
62 }
63 }
64
65 fn build_with_config(
66 backends: &std::collections::BTreeSet<Backend>,
67 config: &Self::Config,
68 ) -> Self {
69 // need the arc here for iter
70 match config {
71 SelectionConfig::Ketama(ketama) => {
72 Self::Ketama(Arc::new(KetamaHashing::build_with_config(backends, ketama)))
73 }
74 SelectionConfig::RoundRobin(rr) => {
75 Self::RoundRobin(Arc::new(RoundRobin::build_with_config(backends, rr)))
76 }
77 }
78 }
79}