|
1 | 1 | use super::make::MakeGateway; |
2 | | -use indexmap::IndexSet; |
3 | | -use linkerd2_app_core::proxy::http; |
4 | | -use linkerd2_app_core::{dns, transport::tls, Error}; |
| 2 | +use linkerd2_app_core::{ |
| 3 | + discovery_rejected, profiles, proxy::http, svc, transport::tls, Error, NameAddr, NameMatch, |
| 4 | +}; |
5 | 5 | use linkerd2_app_inbound::endpoint as inbound; |
6 | 6 | use linkerd2_app_outbound::endpoint as outbound; |
7 | | -use std::net::IpAddr; |
| 7 | +use std::net::SocketAddr; |
8 | 8 |
|
9 | 9 | #[derive(Clone, Debug, Default)] |
10 | 10 | pub struct Config { |
11 | | - pub suffixes: IndexSet<dns::Suffix>, |
| 11 | + pub allow_discovery: NameMatch, |
12 | 12 | } |
13 | 13 |
|
| 14 | +#[derive(Clone, Debug)] |
| 15 | +struct Allow(NameMatch); |
| 16 | + |
14 | 17 | impl Config { |
15 | | - pub fn build<R, O, S>( |
| 18 | + pub fn build<O, P, S>( |
16 | 19 | self, |
17 | | - resolve: R, |
18 | 20 | outbound: O, |
| 21 | + profiles: P, |
| 22 | + default_addr: SocketAddr, |
19 | 23 | local_id: tls::PeerIdentity, |
20 | | - ) -> impl Clone |
21 | | - + Send |
22 | | - + tower::Service< |
| 24 | + ) -> impl svc::NewService< |
23 | 25 | inbound::Target, |
24 | | - Error = impl Into<Error>, |
25 | | - Future = impl Send + 'static, |
26 | | - Response = impl Send |
27 | | - + tower::Service< |
| 26 | + Service = impl tower::Service< |
28 | 27 | http::Request<http::boxed::Payload>, |
29 | 28 | Response = http::Response<http::boxed::Payload>, |
30 | 29 | Error = impl Into<Error>, |
31 | 30 | Future = impl Send, |
32 | | - > + 'static, |
33 | | - > |
| 31 | + > + Send |
| 32 | + + 'static, |
| 33 | + > + Clone |
| 34 | + + Send |
34 | 35 | where |
35 | | - R: tower::Service<dns::Name, Response = (dns::Name, IpAddr)> + Send + Clone, |
36 | | - R::Error: Into<Error> + 'static, |
37 | | - R::Future: Send + 'static, |
38 | | - O: tower::Service<outbound::HttpLogical, Response = S> + Send + Clone + 'static, |
39 | | - O::Error: Into<Error> + Send + 'static, |
40 | | - O::Future: Send + 'static, |
41 | | - S: Send |
42 | | - + tower::Service< |
| 36 | + P: profiles::GetProfile<NameAddr> + Clone + Send + 'static, |
| 37 | + P::Future: Send + 'static, |
| 38 | + P::Error: Send, |
| 39 | + O: svc::NewService<outbound::HttpLogical, Service = S> + Clone + Send + 'static, |
| 40 | + S: tower::Service< |
43 | 41 | http::Request<http::boxed::Payload>, |
44 | 42 | Response = http::Response<http::boxed::Payload>, |
45 | | - > + 'static, |
46 | | - S::Error: Into<Error> + Send + 'static, |
47 | | - S::Future: Send, |
| 43 | + > + Send |
| 44 | + + 'static, |
| 45 | + S::Error: Into<Error>, |
| 46 | + S::Future: Send + 'static, |
48 | 47 | { |
49 | | - MakeGateway::new(resolve, outbound, local_id, self.suffixes.clone()) |
| 48 | + svc::stack(MakeGateway::new(outbound, default_addr, local_id)) |
| 49 | + .check_new_service::<super::make::Target, http::Request<http::boxed::Payload>>() |
| 50 | + .push(profiles::discover::layer( |
| 51 | + profiles, |
| 52 | + Allow(self.allow_discovery), |
| 53 | + )) |
| 54 | + .check_new_service::<inbound::Target, http::Request<http::boxed::Payload>>() |
| 55 | + .into_inner() |
| 56 | + } |
| 57 | +} |
| 58 | + |
| 59 | +impl svc::stack::FilterRequest<inbound::Target> for Allow { |
| 60 | + type Request = NameAddr; |
| 61 | + |
| 62 | + fn filter(&self, target: inbound::Target) -> Result<NameAddr, Error> { |
| 63 | + // Skip discovery when the client does not have an identity. |
| 64 | + if target.tls_client_id.is_some() { |
| 65 | + // Discovery needs to have resolved a service name. |
| 66 | + if let Some(addr) = target.dst.into_name_addr() { |
| 67 | + // The service name needs to exist in the configured set of suffixes. |
| 68 | + if self.0.matches(addr.name()) { |
| 69 | + return Ok(addr); |
| 70 | + } |
| 71 | + } |
| 72 | + } |
| 73 | + |
| 74 | + Err(discovery_rejected().into()) |
50 | 75 | } |
51 | 76 | } |
0 commit comments