Skip to content

Commit b5cfbf4

Browse files
authored
inbound: Include server labels in tap responses (#1239)
This change modifies the inbound tapping behavior so that server & authorization labels are included in tap metadata for HTTP requests.
1 parent 29c22af commit b5cfbf4

File tree

6 files changed

+52
-23
lines changed

6 files changed

+52
-23
lines changed

linkerd/app/core/src/metrics/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,12 @@ impl FmtLabels for InboundEndpointLabels {
280280
}
281281
}
282282

283+
impl fmt::Display for ServerLabel {
284+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
285+
self.0.fmt(f)
286+
}
287+
}
288+
283289
impl FmtLabels for ServerLabel {
284290
fn fmt_labels(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
285291
write!(f, "srv_name=\"{}\"", self.0)

linkerd/app/inbound/src/http/router.rs

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ struct LogicalPerRequest {
2626
server: Remote<ServerAddr>,
2727
tls: tls::ConditionalServerTls,
2828
permit: policy::Permit,
29+
labels: tap::Labels,
2930
}
3031

3132
/// Describes a logical request target.
@@ -37,6 +38,7 @@ struct Logical {
3738
http: http::Version,
3839
tls: tls::ConditionalServerTls,
3940
permit: policy::Permit,
41+
labels: tap::Labels,
4042
}
4143

4244
/// Describes a resolved profile for a logical service.
@@ -222,12 +224,7 @@ impl<C> Inbound<C> {
222224
// dispatches the request. NewRouter moves the NewService into the service type, so
223225
// minimize it's type footprint with a Box.
224226
.push(svc::BoxNewService::layer())
225-
.push(svc::NewRouter::layer(|(permit, t): (_, T)| LogicalPerRequest {
226-
client: t.param(),
227-
server: t.param(),
228-
tls: t.param(),
229-
permit,
230-
}))
227+
.push(svc::NewRouter::layer(LogicalPerRequest::from))
231228
.push(policy::NewAuthorizeHttp::layer(rt.metrics.http_authz.clone()))
232229
// Used by tap.
233230
.push_http_insert_target::<tls::ConditionalServerTls>()
@@ -239,6 +236,31 @@ impl<C> Inbound<C> {
239236

240237
// === impl LogicalPerRequest ===
241238

239+
impl<T> From<(policy::Permit, T)> for LogicalPerRequest
240+
where
241+
T: Param<Remote<ServerAddr>>,
242+
T: Param<Remote<ClientAddr>>,
243+
T: Param<tls::ConditionalServerTls>,
244+
{
245+
fn from((permit, t): (policy::Permit, T)) -> Self {
246+
let labels = vec![
247+
("srv_name".to_string(), permit.labels.server.to_string()),
248+
("saz_name".to_string(), permit.labels.authz.to_string()),
249+
];
250+
251+
Self {
252+
client: t.param(),
253+
server: t.param(),
254+
tls: t.param(),
255+
permit,
256+
labels: labels
257+
.into_iter()
258+
.collect::<std::collections::BTreeMap<_, _>>()
259+
.into(),
260+
}
261+
}
262+
}
263+
242264
impl<A> svc::stack::RecognizeRoute<http::Request<A>> for LogicalPerRequest {
243265
type Key = Logical;
244266

@@ -274,6 +296,7 @@ impl<A> svc::stack::RecognizeRoute<http::Request<A>> for LogicalPerRequest {
274296
.version()
275297
.try_into()
276298
.expect("HTTP version must be valid"),
299+
labels: self.labels.clone(),
277300
})
278301
}
279302
}
@@ -344,16 +367,15 @@ impl tap::Inspect for Logical {
344367
Some(self.addr.into())
345368
}
346369

347-
fn dst_labels<B>(&self, _: &http::Request<B>) -> Option<&tap::Labels> {
348-
// TODO include policy labels here.
349-
None
370+
fn dst_labels<B>(&self, _: &http::Request<B>) -> Option<tap::Labels> {
371+
Some(self.labels.clone())
350372
}
351373

352374
fn dst_tls<B>(&self, _: &http::Request<B>) -> tls::ConditionalClientTls {
353375
tls::ConditionalClientTls::None(tls::NoClientTls::Loopback)
354376
}
355377

356-
fn route_labels<B>(&self, req: &http::Request<B>) -> Option<std::sync::Arc<tap::Labels>> {
378+
fn route_labels<B>(&self, req: &http::Request<B>) -> Option<tap::Labels> {
357379
req.extensions()
358380
.get::<dst::Route>()
359381
.map(|r| r.route.labels().clone())

linkerd/app/outbound/src/http/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use linkerd_app_core::{
1717
transport_header::SessionProtocol,
1818
Addr, Conditional, CANONICAL_DST_HEADER,
1919
};
20-
use std::{net::SocketAddr, str::FromStr, sync::Arc};
20+
use std::{net::SocketAddr, str::FromStr};
2121

2222
pub type Accept = crate::Accept<Version>;
2323
pub type Logical = crate::logical::Logical<Version>;
@@ -174,15 +174,15 @@ impl tap::Inspect for Endpoint {
174174
Some(self.addr.into())
175175
}
176176

177-
fn dst_labels<B>(&self, _: &Request<B>) -> Option<&tap::Labels> {
177+
fn dst_labels<B>(&self, _: &Request<B>) -> Option<tap::Labels> {
178178
Some(self.metadata.labels())
179179
}
180180

181181
fn dst_tls<B>(&self, _: &Request<B>) -> tls::ConditionalClientTls {
182182
self.tls.clone()
183183
}
184184

185-
fn route_labels<B>(&self, req: &Request<B>) -> Option<Arc<tap::Labels>> {
185+
fn route_labels<B>(&self, req: &Request<B>) -> Option<tap::Labels> {
186186
req.extensions()
187187
.get::<dst::Route>()
188188
.map(|r| r.route.labels().clone())

linkerd/proxy/api-resolve/src/metadata.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use linkerd_tls::client::ServerId;
33
use std::collections::BTreeMap;
44

55
/// Endpoint labels are lexographically ordered by key.
6-
pub type Labels = BTreeMap<String, String>;
6+
pub type Labels = std::sync::Arc<BTreeMap<String, String>>;
77

88
/// Metadata describing an endpoint.
99
#[derive(Clone, Debug, Eq, PartialEq)]
@@ -56,7 +56,7 @@ impl Metadata {
5656
authority_override: Option<Authority>,
5757
) -> Self {
5858
Self {
59-
labels: labels.into_iter().collect(),
59+
labels: labels.into_iter().collect::<BTreeMap<_, _>>().into(),
6060
protocol_hint,
6161
opaque_transport_port,
6262
identity,
@@ -65,8 +65,8 @@ impl Metadata {
6565
}
6666

6767
/// Returns the endpoint's labels from the destination service, if it has them.
68-
pub fn labels(&self) -> &Labels {
69-
&self.labels
68+
pub fn labels(&self) -> Labels {
69+
self.labels.clone()
7070
}
7171

7272
pub fn protocol_hint(&self) -> ProtocolHint {

linkerd/proxy/tap/src/grpc/match_.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
use crate::{Inspect, Labels};
1+
use crate::Inspect;
22
use ipnet::{Ipv4Net, Ipv6Net};
33
use linkerd2_proxy_api::net::ip_address;
44
use linkerd2_proxy_api::tap::observe_request;
55
use std::{
66
boxed::Box,
7+
collections::BTreeMap,
78
convert::{TryFrom, TryInto},
89
net,
910
str::FromStr,
@@ -90,7 +91,7 @@ impl Match {
9091
.unwrap_or(false),
9192
Match::DestinationLabel(ref lbl) => inspect
9293
.dst_labels(req)
93-
.map(|l| lbl.matches(l))
94+
.map(|l| lbl.matches(&*l))
9495
.unwrap_or(false),
9596
Match::RouteLabel(ref lbl) => inspect
9697
.route_labels(req)
@@ -138,7 +139,7 @@ impl TryFrom<observe_request::r#match::Match> for Match {
138139
// ===== impl LabelMatch ======
139140

140141
impl LabelMatch {
141-
fn matches(&self, labels: &Labels) -> bool {
142+
fn matches(&self, labels: &BTreeMap<String, String>) -> bool {
142143
labels.get(&self.key) == Some(&self.value)
143144
}
144145
}

linkerd/proxy/tap/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ pub fn new() -> (Registry, grpc::Server) {
2525
}
2626

2727
/// Endpoint labels are lexicographically ordered by key.
28-
pub type Labels = std::collections::BTreeMap<String, String>;
28+
pub type Labels = Arc<std::collections::BTreeMap<String, String>>;
2929

3030
/// Inspects a request for a `Stack`.
3131
///
@@ -37,11 +37,11 @@ pub trait Inspect {
3737

3838
fn dst_addr<B>(&self, req: &http::Request<B>) -> Option<net::SocketAddr>;
3939

40-
fn dst_labels<B>(&self, req: &http::Request<B>) -> Option<&Labels>;
40+
fn dst_labels<B>(&self, req: &http::Request<B>) -> Option<Labels>;
4141

4242
fn dst_tls<B>(&self, req: &http::Request<B>) -> tls::ConditionalClientTls;
4343

44-
fn route_labels<B>(&self, req: &http::Request<B>) -> Option<Arc<Labels>>;
44+
fn route_labels<B>(&self, req: &http::Request<B>) -> Option<Labels>;
4545

4646
fn is_outbound<B>(&self, req: &http::Request<B>) -> bool;
4747

0 commit comments

Comments
 (0)