Skip to content

Commit 80c6549

Browse files
authored
inbound: Expose permit labels on HTTP metrics (#1216)
This change follows #1215, which exposes policy labels on inbound TCP server metrics, by adding these same labels to HTTP metrics. The HTTP router target types are updated to take a `Permit` which includes server and authz labels so that the inbound HTTP metrics can include these labels. This will enable `linkerd viz stat` to work on these resources. This change shouldn't impact metrics cardinality, since client IDs are already exposed in metrics labeling.
1 parent 7e5207e commit 80c6549

File tree

9 files changed

+60
-28
lines changed

9 files changed

+60
-28
lines changed

linkerd/app/admin/src/stack.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ impl Param<metrics::EndpointLabels> for Http {
181181
tls: self.tcp.tls.clone(),
182182
authority: None,
183183
target_addr: self.tcp.addr.into(),
184+
policy: Default::default(),
184185
}
185186
.into()
186187
}

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use crate::{
1414
use linkerd_addr::Addr;
1515
use linkerd_metrics::FmtLabels;
1616
pub use linkerd_metrics::*;
17+
use linkerd_server_policy as policy;
1718
use std::{
1819
fmt::{self, Write},
1920
net::SocketAddr,
@@ -67,6 +68,13 @@ pub struct InboundEndpointLabels {
6768
pub tls: tls::ConditionalServerTls,
6869
pub authority: Option<http::uri::Authority>,
6970
pub target_addr: SocketAddr,
71+
pub policy: PolicyLabels,
72+
}
73+
74+
#[derive(Clone, Debug, Default, Eq, PartialEq, Hash)]
75+
pub struct PolicyLabels {
76+
pub server: policy::Labels,
77+
pub authz: policy::Labels,
7078
}
7179

7280
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
@@ -285,6 +293,13 @@ impl FmtLabels for InboundEndpointLabels {
285293

286294
(TargetAddr(self.target_addr), TlsAccept::from(&self.tls)).fmt_labels(f)?;
287295

296+
for (k, v) in self.policy.server.iter() {
297+
write!(f, ",srv_{}=\"{}\"", k, v)?;
298+
}
299+
for (k, v) in self.policy.authz.iter() {
300+
write!(f, ",saz_{}=\"{}\"", k, v)?;
301+
}
302+
288303
Ok(())
289304
}
290305
}

linkerd/app/core/src/transport/labels.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
pub use crate::metrics::{Direction, OutboundEndpointLabels};
1+
pub use crate::metrics::{Direction, OutboundEndpointLabels, PolicyLabels};
22
use linkerd_conditional::Conditional;
33
use linkerd_metrics::FmtLabels;
44
use linkerd_server_policy as policy;
@@ -34,12 +34,6 @@ pub(crate) struct TlsConnect<'t>(&'t tls::ConditionalClientTls);
3434
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
3535
pub(crate) struct TargetAddr(pub(crate) SocketAddr);
3636

37-
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
38-
pub(crate) struct PolicyLabels {
39-
server: policy::Labels,
40-
authz: policy::Labels,
41-
}
42-
4337
// === impl Key ===
4438

4539
impl Key {

linkerd/app/inbound/src/detect.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,12 @@ impl svc::Param<Option<identity::Name>> for Http {
299299
}
300300
}
301301

302+
impl svc::Param<Permit> for Http {
303+
fn param(&self) -> Permit {
304+
self.tls.permit.clone()
305+
}
306+
}
307+
302308
// === TlsParams ===
303309

304310
impl<T> svc::ExtractParam<tls::server::Timeout, T> for TlsParams {

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ fn trace_labels() -> std::collections::HashMap<String, String> {
1414
pub mod fuzz {
1515
use crate::{
1616
http::router::Http,
17+
policy,
1718
test_util::{
1819
support::{connect::Connect, http_util, profile, resolver},
1920
*,
@@ -200,9 +201,14 @@ pub mod fuzz {
200201
}
201202
}
202203

203-
impl svc::Param<tls::ConditionalServerTls> for Target {
204-
fn param(&self) -> tls::ConditionalServerTls {
205-
tls::ConditionalServerTls::None(tls::NoServerTls::NoClientHello)
204+
impl svc::Param<policy::Permit> for Target {
205+
fn param(&self) -> policy::Permit {
206+
policy::Permit {
207+
protocol: policy::Protocol::Http1,
208+
tls: tls::ConditionalServerTls::None(tls::NoServerTls::NoClientHello),
209+
server_labels: Default::default(),
210+
authz_labels: Default::default(),
211+
}
206212
}
207213
}
208214

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

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{stack_labels, Inbound};
1+
use crate::{policy, stack_labels, Inbound};
22
use linkerd_app_core::{
33
classify, dst, http_tracing, io, metrics,
44
profiles::{self, DiscoveryRejected},
@@ -16,14 +16,14 @@ use tracing::{debug, debug_span};
1616
pub struct Http {
1717
port: u16,
1818
settings: http::client::Settings,
19-
tls: tls::ConditionalServerTls,
19+
permit: policy::Permit,
2020
}
2121

2222
/// Builds `Logical` targets for each HTTP request.
2323
#[derive(Clone, Debug)]
2424
struct LogicalPerRequest {
2525
addr: Remote<ServerAddr>,
26-
tls: tls::ConditionalServerTls,
26+
permit: policy::Permit,
2727
}
2828

2929
/// Describes a logical request target.
@@ -33,7 +33,7 @@ struct Logical {
3333
logical: Option<NameAddr>,
3434
addr: Remote<ServerAddr>,
3535
http: http::Version,
36-
tls: tls::ConditionalServerTls,
36+
permit: policy::Permit,
3737
}
3838

3939
/// Describes a resolved profile for a logical service.
@@ -47,7 +47,7 @@ struct Profile {
4747
// === impl Inbound ===
4848

4949
impl<C> Inbound<C> {
50-
pub fn push_http_router<T, P>(
50+
pub(crate) fn push_http_router<T, P>(
5151
self,
5252
profiles: P,
5353
) -> Inbound<
@@ -65,7 +65,7 @@ impl<C> Inbound<C> {
6565
T: Param<http::Version>
6666
+ Param<Remote<ServerAddr>>
6767
+ Param<Remote<ClientAddr>>
68-
+ Param<tls::ConditionalServerTls>,
68+
+ Param<policy::Permit>,
6969
T: Clone + Send + 'static,
7070
P: profiles::GetProfile<profiles::LookupAddr> + Clone + Send + Sync + 'static,
7171
P::Future: Send,
@@ -219,10 +219,10 @@ impl<C> Inbound<C> {
219219
.push(svc::BoxNewService::layer())
220220
.push(svc::NewRouter::layer(|t: T| LogicalPerRequest {
221221
addr: t.param(),
222-
tls: t.param(),
222+
permit: t.param(),
223223
}))
224224
// Used by tap.
225-
.push_http_insert_target::<tls::ConditionalServerTls>()
225+
.push_http_insert_target::<policy::Permit>()
226226
.push_http_insert_target::<Remote<ClientAddr>>()
227227
.push(svc::BoxNewService::layer())
228228
})
@@ -259,7 +259,7 @@ impl<A> svc::stack::RecognizeRoute<http::Request<A>> for LogicalPerRequest {
259259
Ok(Logical {
260260
logical,
261261
addr: self.addr,
262-
tls: self.tls.clone(),
262+
permit: self.permit.clone(),
263263
// Use the request's HTTP version (i.e. as modified by orig-proto downgrading).
264264
http: req
265265
.version()
@@ -300,9 +300,13 @@ impl Param<transport::labels::Key> for Logical {
300300
impl Param<metrics::EndpointLabels> for Logical {
301301
fn param(&self) -> metrics::EndpointLabels {
302302
metrics::InboundEndpointLabels {
303-
tls: self.tls.clone(),
303+
tls: self.permit.tls.clone(),
304304
authority: self.logical.as_ref().map(|d| d.as_http_authority()),
305305
target_addr: self.addr.into(),
306+
policy: metrics::PolicyLabels {
307+
server: self.permit.server_labels.clone(),
308+
authz: self.permit.authz_labels.clone(),
309+
},
306310
}
307311
.into()
308312
}
@@ -325,8 +329,8 @@ impl tap::Inspect for Logical {
325329

326330
fn src_tls<B>(&self, req: &http::Request<B>) -> tls::ConditionalServerTls {
327331
req.extensions()
328-
.get::<tls::ConditionalServerTls>()
329-
.cloned()
332+
.get::<policy::Permit>()
333+
.map(|p| p.tls.clone())
330334
.unwrap_or_else(|| tls::ConditionalServerTls::None(tls::NoServerTls::Disabled))
331335
}
332336

@@ -372,7 +376,7 @@ impl From<Logical> for Http {
372376
Self {
373377
port: l.addr.as_ref().port(),
374378
settings: l.http.into(),
375-
tls: l.tls,
379+
permit: l.permit,
376380
}
377381
}
378382
}

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::{
2+
policy,
23
test_util::{
34
support::{connect::Connect, http_util, profile, resolver},
45
*,
@@ -403,9 +404,14 @@ impl svc::Param<http::Version> for Target {
403404
}
404405
}
405406

406-
impl svc::Param<tls::ConditionalServerTls> for Target {
407-
fn param(&self) -> tls::ConditionalServerTls {
408-
tls::ConditionalServerTls::None(tls::NoServerTls::NoClientHello)
407+
impl svc::Param<policy::Permit> for Target {
408+
fn param(&self) -> policy::Permit {
409+
policy::Permit {
410+
protocol: policy::Protocol::Http1,
411+
tls: tls::ConditionalServerTls::None(tls::NoServerTls::Disabled),
412+
server_labels: Default::default(),
413+
authz_labels: Default::default(),
414+
}
409415
}
410416
}
411417

linkerd/app/inbound/src/policy/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pub(crate) struct AllowPolicy {
3434
server: Arc<ServerPolicy>,
3535
}
3636

37-
#[derive(Clone, Debug, PartialEq, Eq)]
37+
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
3838
pub(crate) struct Permit {
3939
pub protocol: Protocol,
4040
pub tls: tls::ConditionalServerTls,

linkerd/server-policy/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub struct ServerPolicy {
2020
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
2121
pub struct Labels(Arc<BTreeMap<String, String>>);
2222

23-
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
23+
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
2424
pub enum Protocol {
2525
Detect { timeout: time::Duration },
2626
Http1,

0 commit comments

Comments
 (0)