-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proxy: Add TLS client infrastructure. #1158
Changes from all commits
592a976
677e28b
57dc99a
b90eff6
9fa7d6d
ba9d2e6
d90dad9
548e28c
b005c80
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
use std; | ||
|
||
/// Like `std::option::Option<C>` but `None` carries a reason why the value | ||
/// isn't available. | ||
#[derive(Clone, Debug)] | ||
pub enum Conditional<C, R> | ||
where | ||
C: Clone + std::fmt::Debug, | ||
R: Clone + std::fmt::Debug, | ||
{ | ||
Some(C), | ||
None(R), | ||
} | ||
|
||
impl<C, R> Copy for Conditional<C, R> | ||
where | ||
C: Copy + Clone + std::fmt::Debug, | ||
R: Copy + Clone + std::fmt::Debug, | ||
{ | ||
} | ||
|
||
impl<C, R> Eq for Conditional<C, R> | ||
where | ||
C: Eq + Clone + std::fmt::Debug, | ||
R: Eq + Clone + std::fmt::Debug, | ||
{ | ||
} | ||
|
||
impl<C, R> PartialEq for Conditional<C, R> | ||
where | ||
C: PartialEq + Clone + std::fmt::Debug, | ||
R: PartialEq + Clone + std::fmt::Debug, | ||
{ | ||
fn eq(&self, other: &Conditional<C, R>) -> bool { | ||
use self::Conditional::*; | ||
match (self, other) { | ||
(Some(a), Some(b)) => a.eq(b), | ||
(None(a), None(b)) => a.eq(b), | ||
_ => false, | ||
} | ||
} | ||
} | ||
|
||
impl<C, R> std::hash::Hash for Conditional<C, R> | ||
where | ||
C: std::hash::Hash + Clone + std::fmt::Debug, | ||
R: std::hash::Hash + Clone + std::fmt::Debug, | ||
{ | ||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) { | ||
match self { | ||
Conditional::Some(c) => c.hash(state), | ||
Conditional::None(r) => r.hash(state), | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,16 +10,20 @@ | |
use config; | ||
use std::time::SystemTime; | ||
use std::sync::Arc; | ||
use transport::tls; | ||
|
||
pub mod http; | ||
pub mod transport; | ||
|
||
/// Describes a single running proxy instance. | ||
#[derive(Clone, Debug, PartialEq, Eq)] | ||
#[derive(Clone, Debug)] | ||
pub struct Process { | ||
/// Identifies the Kubernetes namespace in which this proxy is process. | ||
pub scheduled_namespace: String, | ||
|
||
pub start_time: SystemTime, | ||
|
||
tls_client_config: tls::ClientConfigWatch, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure if the process context is the right place to put configurations. As per @olix0r in #1050 (comment), the On the other hand, I'm not sure where else we'd put this, besides passing it around everywhere... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While it's true that this was initially intended to be "just the metadata" -- every ctx object throughout the proxy ends up with a reference back to this thing -- i don't yet have an opinion on whether there are better approaches for this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Right. If we don't put it in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah. at the very least, let's not let this block things There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Alright, that's fair, I just wanted to bring it up since Oliver mentioned something similar while reviewing my PR. |
||
} | ||
|
||
/// Indicates the orientation of traffic, relative to a sidecar proxy. | ||
|
@@ -29,27 +33,30 @@ pub struct Process { | |
/// local instance. | ||
/// - The _outbound_ proxy receives traffic from the local instance and forwards it to a | ||
/// remove service. | ||
#[derive(Clone, Debug, PartialEq, Eq)] | ||
#[derive(Clone, Debug)] | ||
pub enum Proxy { | ||
Inbound(Arc<Process>), | ||
Outbound(Arc<Process>), | ||
} | ||
|
||
impl Process { | ||
#[cfg(test)] | ||
// Test-only, but we can't use `#[cfg(test)]` because it is used by the | ||
// benchmarks | ||
pub fn test(ns: &str) -> Arc<Self> { | ||
Arc::new(Self { | ||
scheduled_namespace: ns.into(), | ||
start_time: SystemTime::now(), | ||
tls_client_config: tls::ClientConfig::no_tls(), | ||
}) | ||
} | ||
|
||
/// Construct a new `Process` from environment variables. | ||
pub fn new(config: &config::Config) -> Arc<Self> { | ||
pub fn new(config: &config::Config, tls_client_config: tls::ClientConfigWatch) -> Arc<Self> { | ||
let start_time = SystemTime::now(); | ||
Arc::new(Self { | ||
scheduled_namespace: config.namespaces.pod.clone(), | ||
start_time, | ||
tls_client_config, | ||
}) | ||
} | ||
} | ||
|
@@ -73,6 +80,12 @@ impl Proxy { | |
pub fn is_outbound(&self) -> bool { | ||
!self.is_inbound() | ||
} | ||
|
||
pub fn tls_client_config_watch(&self) -> &tls::ClientConfigWatch { | ||
match self { | ||
Proxy::Inbound(process) | Proxy::Outbound(process) => &process.tls_client_config | ||
} | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
|
@@ -82,7 +95,6 @@ pub mod test_util { | |
fmt, | ||
net::SocketAddr, | ||
sync::Arc, | ||
time::SystemTime, | ||
}; | ||
|
||
use ctx; | ||
|
@@ -94,10 +106,7 @@ pub mod test_util { | |
} | ||
|
||
pub fn process() -> Arc<ctx::Process> { | ||
Arc::new(ctx::Process { | ||
scheduled_namespace: "test".into(), | ||
start_time: SystemTime::now(), | ||
}) | ||
ctx::Process::test("test") | ||
} | ||
|
||
pub fn server( | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From that description, this basically sounds like a
Result
.I understand why you didn't want to use a type which implies one case is an "error" here, though...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also don't like the introduction of
Conditional
much but this shouldn't beResult
sinceResult
should be used strictly for errors.Either
makes more sense but I don't want to import another library. Note that this is basically yourEither
type that you implementedStream
on. We could moveEither
to a more generic place and then use that instead?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think "a reason we were not able to do TLS" falls into a (sufficiently broad) definition of "error";
Err
is used elsewhere for signalling that something is not available. However, I'm not going to press that because I think the discussion is just semantics at this point. :)I would be fine with that as well, but (coming at it from another direction) I think
Conditional
does better encode the meaning of each branch, so, having thought about it a bit, I'm ready to put a green check on this as it is.