internal: Spilt app from linkerd2-proxy (#375)

* internal: internal: Spilt app from linkerd2-proxy

The `linkerd2-proxy crate currently comprises the entirety of the
application logic for the proxy. This unfortunately leads to exceedingly
high compile times (35+ minutes to compile the application with tests).

Specifically:
* Any change to the inbound or outbound proxy configuration necessitated
  recompiling the other; and this compilation could not be parallelized.
* Integration tests depended on the `linkerd2-proxy` executable, adding
  about 10 minutes to every build.
* The tests/support module (which is also extremely costly to build) was
  compiled _for each integration test_.

This change restructures the crates in this repository to allow `cargo`
to cache intermediate code that was otherwise being compiled
redundantly or serially:

* The `linkerd2-proxy` crate now contains _only_ the executable and need
  not be built during tests.
* The `linkerd2-app` crate exposes the app's `Main`, but uses
  `linkerd2-app-inbound` and `linkerd2-app-outbound` subcrates to
  improve parellization/cacheability.
* The rest of the  top-level application code
* The `linkerd2-app-integration` crate now contains all of the
  integration test support code (as well as the tests themselves), so
  that the tests only need to compile the support library once.

All in all, this reduces compile time to under 20 minutes.
This commit is contained in:
Oliver Gould 2019-10-16 15:39:39 -07:00 committed by GitHub
parent b0c7181407
commit d213c1373f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
256 changed files with 1553 additions and 1053 deletions

View File

@ -5,6 +5,14 @@ name = "adler32"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "aho-corasick"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "aho-corasick"
version = "0.6.4"
@ -491,10 +499,180 @@ dependencies = [
"linkerd2-dns-name 0.1.0",
]
[[package]]
name = "linkerd2-app"
version = "0.1.0"
dependencies = [
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
"h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
"http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.12.34 (registry+https://github.com/rust-lang/crates.io-index)",
"linkerd2-app-core 0.1.0",
"linkerd2-app-inbound 0.1.0",
"linkerd2-app-outbound 0.1.0",
"linkerd2-metrics 0.1.0",
"linkerd2-proxy-api 0.1.10 (git+https://github.com/linkerd/linkerd2-proxy-api?tag=v0.1.10)",
"linkerd2-task 0.1.0",
"net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)",
"opencensus-proto 0.1.0",
"quickcheck 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)",
"ring 0.16.7 (registry+https://github.com/rust-lang/crates.io-index)",
"rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-connect 0.1.0 (git+https://github.com/carllerche/tokio-connect)",
"tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-rustls 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tower 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-grpc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tracing 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"tracing-futures 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"webpki 0.21.0 (git+https://github.com/seanmonstar/webpki?branch=cert-dns-names-0.21)",
]
[[package]]
name = "linkerd2-app-core"
version = "0.1.0"
dependencies = [
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
"http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.12.34 (registry+https://github.com/rust-lang/crates.io-index)",
"indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"ipnet 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
"linkerd2-addr 0.1.0",
"linkerd2-conditional 0.1.0",
"linkerd2-dns 0.1.0",
"linkerd2-drain 0.1.0",
"linkerd2-duplex 0.1.0",
"linkerd2-error 0.1.0",
"linkerd2-exp-backoff 0.1.0",
"linkerd2-fallback 0.1.0",
"linkerd2-identity 0.1.0",
"linkerd2-metrics 0.1.0",
"linkerd2-opencensus 0.1.0",
"linkerd2-proxy-api 0.1.10 (git+https://github.com/linkerd/linkerd2-proxy-api?tag=v0.1.10)",
"linkerd2-proxy-api-resolve 0.1.0",
"linkerd2-proxy-core 0.1.0",
"linkerd2-proxy-discover 0.1.0",
"linkerd2-proxy-http 0.1.0",
"linkerd2-proxy-resolve 0.1.0",
"linkerd2-proxy-transport 0.1.0",
"linkerd2-reconnect 0.1.0",
"linkerd2-request-filter 0.1.0",
"linkerd2-router 0.1.0",
"linkerd2-stack 0.1.0",
"linkerd2-task 0.1.0",
"linkerd2-timeout 0.1.0",
"linkerd2-trace-context 0.1.0",
"opencensus-proto 0.1.0",
"procinfo 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"prost-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"quickcheck 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
"tower 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-balance 0.1.0 (git+https://github.com/tower-rs/tower)",
"tower-grpc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-load 0.1.0 (git+https://github.com/tower-rs/tower)",
"tower-request-modifier 0.1.0 (git+https://github.com/tower-rs/tower-http)",
"tower-spawn-ready 0.1.0 (git+https://github.com/tower-rs/tower)",
"tracing 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"tracing-futures 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tracing-log 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tracing-subscriber 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "linkerd2-app-inbound"
version = "0.1.0"
dependencies = [
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
"http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"linkerd2-app-core 0.1.0",
"opencensus-proto 0.1.0",
"quickcheck 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)",
"tower 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-grpc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tracing 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "linkerd2-app-integration"
version = "0.1.0"
dependencies = [
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
"h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
"http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.12.34 (registry+https://github.com/rust-lang/crates.io-index)",
"linkerd2-app 0.1.0",
"linkerd2-app-core 0.1.0",
"linkerd2-metrics 0.1.0",
"linkerd2-proxy-api 0.1.10 (git+https://github.com/linkerd/linkerd2-proxy-api?tag=v0.1.10)",
"linkerd2-task 0.1.0",
"net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)",
"opencensus-proto 0.1.0",
"quickcheck 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)",
"ring 0.16.7 (registry+https://github.com/rust-lang/crates.io-index)",
"rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-connect 0.1.0 (git+https://github.com/carllerche/tokio-connect)",
"tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-rustls 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tower 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-grpc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tracing 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"tracing-futures 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"webpki 0.21.0 (git+https://github.com/seanmonstar/webpki?branch=cert-dns-names-0.21)",
]
[[package]]
name = "linkerd2-app-outbound"
version = "0.1.0"
dependencies = [
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
"http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"linkerd2-app-core 0.1.0",
"opencensus-proto 0.1.0",
"quickcheck 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)",
"tower 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-grpc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tracing 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "linkerd2-conditional"
version = "0.1.0"
[[package]]
name = "linkerd2-dns"
version = "0.1.0"
dependencies = [
"futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
"linkerd2-dns-name 0.1.0",
"tracing 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"tracing-futures 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"trust-dns-resolver 0.10.2 (git+https://github.com/bluejekyll/trust-dns?rev=7c8a0739dad495bf5a4fddfe86b8bbe2aa52d060)",
]
[[package]]
name = "linkerd2-dns-name"
version = "0.1.0"
@ -511,6 +689,16 @@ dependencies = [
"linkerd2-error 0.1.0",
]
[[package]]
name = "linkerd2-duplex"
version = "0.1.0"
dependencies = [
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)",
"tracing 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "linkerd2-error"
version = "0.1.0"
@ -583,76 +771,9 @@ dependencies = [
name = "linkerd2-proxy"
version = "0.1.0"
dependencies = [
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
"h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
"http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.12.34 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper-balance 0.1.0",
"indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"ipnet 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
"linkerd2-addr 0.1.0",
"linkerd2-conditional 0.1.0",
"linkerd2-dns-name 0.1.0",
"linkerd2-drain 0.1.0",
"linkerd2-error 0.1.0",
"linkerd2-exp-backoff 0.1.0",
"linkerd2-fallback 0.1.0",
"linkerd2-identity 0.1.0",
"linkerd2-metrics 0.1.0",
"linkerd2-opencensus 0.1.0",
"linkerd2-proxy-api 0.1.10 (git+https://github.com/linkerd/linkerd2-proxy-api?tag=v0.1.10)",
"linkerd2-proxy-api-resolve 0.1.0",
"linkerd2-proxy-core 0.1.0",
"linkerd2-proxy-discover 0.1.0",
"linkerd2-proxy-resolve 0.1.0",
"linkerd2-proxy-transport 0.1.0",
"linkerd2-reconnect 0.1.0",
"linkerd2-request-filter 0.1.0",
"linkerd2-router 0.1.0",
"linkerd2-app 0.1.0",
"linkerd2-signal 0.1.0",
"linkerd2-stack 0.1.0",
"linkerd2-task 0.1.0",
"linkerd2-timeout 0.1.0",
"linkerd2-trace-context 0.1.0",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)",
"opencensus-proto 0.1.0",
"procinfo 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"prost 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"prost-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"quickcheck 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ring 0.16.7 (registry+https://github.com/rust-lang/crates.io-index)",
"rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-connect 0.1.0 (git+https://github.com/carllerche/tokio-connect)",
"tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-rustls 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
"tower 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-balance 0.1.0 (git+https://github.com/tower-rs/tower)",
"tower-discover 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-grpc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-load 0.1.0 (git+https://github.com/tower-rs/tower)",
"tower-request-modifier 0.1.0 (git+https://github.com/tower-rs/tower-http)",
"tower-service 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-spawn-ready 0.1.0 (git+https://github.com/tower-rs/tower)",
"tower-util 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tracing 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"tracing-futures 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tracing-log 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tracing-subscriber 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"trust-dns-resolver 0.10.2 (git+https://github.com/bluejekyll/trust-dns?rev=7c8a0739dad495bf5a4fddfe86b8bbe2aa52d060)",
"try-lock 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"webpki 0.21.0 (git+https://github.com/seanmonstar/webpki?branch=cert-dns-names-0.21)",
]
[[package]]
@ -706,7 +827,6 @@ dependencies = [
"indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"linkerd2-error 0.1.0",
"linkerd2-proxy-core 0.1.0",
"linkerd2-task 0.1.0",
"tokio 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)",
"tower 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-util 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -714,6 +834,46 @@ dependencies = [
"tracing-futures 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "linkerd2-proxy-http"
version = "0.1.0"
dependencies = [
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
"h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
"http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.12.34 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper-balance 0.1.0",
"indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"linkerd2-addr 0.1.0",
"linkerd2-dns 0.1.0",
"linkerd2-drain 0.1.0",
"linkerd2-duplex 0.1.0",
"linkerd2-error 0.1.0",
"linkerd2-fallback 0.1.0",
"linkerd2-identity 0.1.0",
"linkerd2-metrics 0.1.0",
"linkerd2-proxy-transport 0.1.0",
"linkerd2-router 0.1.0",
"linkerd2-stack 0.1.0",
"linkerd2-timeout 0.1.0",
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-connect 0.1.0 (git+https://github.com/carllerche/tokio-connect)",
"tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
"tower 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-balance 0.1.0 (git+https://github.com/tower-rs/tower)",
"tower-discover 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-grpc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-load 0.1.0 (git+https://github.com/tower-rs/tower)",
"tower-util 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tracing 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"tracing-futures 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"try-lock 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "linkerd2-proxy-resolve"
version = "0.1.0"
@ -802,9 +962,6 @@ version = "0.1.0"
dependencies = [
"futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
"linkerd2-error 0.1.0",
"linkerd2-task 0.1.0",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-layer 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-service 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -875,6 +1032,14 @@ name = "matches"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "memchr"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "memchr"
version = "2.0.1"
@ -1259,6 +1424,18 @@ name = "redox_syscall"
version = "0.1.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "regex"
version = "0.1.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex"
version = "1.0.0"
@ -1281,6 +1458,11 @@ dependencies = [
"utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex-syntax"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "regex-syntax"
version = "0.6.11"
@ -1456,6 +1638,23 @@ dependencies = [
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "thread-id"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "thread_local"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "thread_local"
version = "0.3.5"
@ -2047,6 +2246,11 @@ dependencies = [
"percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "utf8-ranges"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "utf8-ranges"
version = "1.0.0"
@ -2235,6 +2439,7 @@ dependencies = [
[metadata]
"checksum adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6cbd0b9af8587c72beadc9f72d35b9fbb070982c9e6203e46e93f10df25f8f45"
"checksum aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ca972c2ea5f742bfce5687b9aef75506a764f61d37f8f649047846a9686ddb66"
"checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4"
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
@ -2297,6 +2502,7 @@ dependencies = [
"checksum lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4d06ff7ff06f729ce5f4e227876cb88d10bc59cd4ae1e09fbb2bde15c850dc21"
"checksum matchers 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1"
"checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376"
"checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20"
"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
"checksum memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce6075db033bbbb7ee5a0bbd3a3186bbae616f57fb001c485c7ff77955f8177f"
"checksum miniz_oxide 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aaa2d3ad070f428fffbd7d3ca2ea20bb0d8cffe9024405c44e1840bc1418b398"
@ -2339,8 +2545,10 @@ dependencies = [
"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd"
"checksum regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f"
"checksum regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75ecf88252dce580404a22444fc7d626c01815debba56a7f4f536772a5ff19d3"
"checksum regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "92b73c2a1770c255c240eaa4ee600df1704a38dc3feaa6e949e7fcd4f8dc09f9"
"checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957"
"checksum regex-syntax 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b143cceb2ca5e56d5671988ef8b15615733e7ee16cd348e064333b251b89343f"
"checksum remove_dir_all 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dfc5b3ce5d5ea144bb04ebd093a9e14e9765bcfec866aecda9b6dec43b3d1e24"
"checksum resolv-conf 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8e1b086bb6a2659d6ba66e4aa21bde8a53ec03587cd5c80b83bdc3a330f35cab"
@ -2363,6 +2571,8 @@ dependencies = [
"checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf"
"checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f"
"checksum tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "7e91405c14320e5c79b3d148e1c86f40749a36e490642202a31689cb1a3452b2"
"checksum thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03"
"checksum thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5"
"checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963"
"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098"
"checksum tokio 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "94a1f9396aec29d31bb16c24d155cfa144d1af91c40740125db3131bdaf76da8"
@ -2416,6 +2626,7 @@ dependencies = [
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
"checksum untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60369ef7a31de49bcb3f6ca728d4ba7300d9a1658f94c727d4cab8c8d9f4aece"
"checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a"
"checksum utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f"
"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"

View File

@ -1,142 +1,40 @@
[workspace]
members = [
".",
"lib/hyper-balance",
"lib/linkerd2-addr",
"lib/linkerd2-conditional",
"lib/linkerd2-dns-name",
"lib/linkerd2-drain",
"lib/linkerd2-error",
"lib/linkerd2-exp-backoff",
"lib/linkerd2-fallback",
"lib/linkerd2-identity",
"lib/linkerd2-metrics",
"lib/linkerd2-opencensus",
"lib/linkerd2-proxy-api-resolve",
"lib/linkerd2-proxy-core",
"lib/linkerd2-proxy-discover",
"lib/linkerd2-proxy-resolve",
"lib/linkerd2-proxy-transport",
"lib/linkerd2-request-filter",
"lib/linkerd2-reconnect",
"lib/linkerd2-router",
"lib/linkerd2-signal",
"lib/linkerd2-stack",
"lib/linkerd2-task",
"lib/linkerd2-timeout",
"lib/opencensus-proto",
"hyper-balance",
"linkerd/addr",
"linkerd/app/core",
"linkerd/app/inbound",
"linkerd/app/integration",
"linkerd/app/outbound",
"linkerd/app",
"linkerd/conditional",
"linkerd/dns/name",
"linkerd/dns",
"linkerd/drain",
"linkerd/duplex",
"linkerd/error",
"linkerd/exp-backoff",
"linkerd/fallback",
"linkerd/identity",
"linkerd/metrics",
"linkerd/opencensus",
"linkerd/proxy/api-resolve",
"linkerd/proxy/core",
"linkerd/proxy/discover",
"linkerd/proxy/http",
"linkerd/proxy/resolve",
"linkerd/proxy/transport",
"linkerd/request-filter",
"linkerd/reconnect",
"linkerd/router",
"linkerd/signal",
"linkerd/stack",
"linkerd/task",
"linkerd/timeout",
"linkerd2-proxy",
"opencensus-proto",
]
[package]
name = "linkerd2-proxy"
version = "0.1.0"
authors = ["Linkerd Developers <cncf-linkerd-dev@lists.cncf.io>"]
edition = "2018"
publish = false
[features]
default = ["flaky_tests"]
# Disable to skip certain tests that should not be run on CI.
flaky_tests = []
[dependencies]
hyper-balance = { path = "lib/hyper-balance" }
linkerd2-addr = { path = "lib/linkerd2-addr" }
linkerd2-conditional = { path = "lib/linkerd2-conditional" }
linkerd2-dns-name = { path = "lib/linkerd2-dns-name" }
linkerd2-drain = { path = "lib/linkerd2-drain" }
linkerd2-error = { path = "lib/linkerd2-error" }
linkerd2-exp-backoff = { path = "lib/linkerd2-exp-backoff" }
linkerd2-fallback = { path = "lib/linkerd2-fallback" }
linkerd2-identity = { path = "lib/linkerd2-identity" }
linkerd2-metrics = { path = "lib/linkerd2-metrics" }
linkerd2-opencensus = { path = "lib/linkerd2-opencensus" }
linkerd2-proxy-core = { path = "lib/linkerd2-proxy-core" }
linkerd2-proxy-api-resolve = { path = "lib/linkerd2-proxy-api-resolve" }
linkerd2-proxy-discover = { path = "lib/linkerd2-proxy-discover" }
linkerd2-proxy-resolve = { path = "lib/linkerd2-proxy-resolve" }
linkerd2-proxy-transport = { path = "lib/linkerd2-proxy-transport" }
linkerd2-reconnect = { path = "lib/linkerd2-reconnect" }
linkerd2-request-filter = { path = "lib/linkerd2-request-filter" }
linkerd2-router = { path = "lib/linkerd2-router" }
linkerd2-signal = { path = "lib/linkerd2-signal" }
linkerd2-stack = { path = "lib/linkerd2-stack" }
linkerd2-task = { path = "lib/linkerd2-task" }
linkerd2-timeout = { path = "lib/linkerd2-timeout" }
linkerd2-trace-context = { path = "lib/linkerd2-trace-context" }
opencensus-proto = { path = "lib/opencensus-proto" }
linkerd2-proxy-api = { git = "https://github.com/linkerd/linkerd2-proxy-api", tag = "v0.1.10" }
bytes = "0.4"
futures = "0.1"
h2 = "0.1.15"
http = "0.1"
http-body = "0.1"
httparse = "1.2"
hyper = "0.12.3"
ipnet = "1.0"
log = { version = "0.4.1", features = ["std"] }
indexmap = "1.0.0"
prost = "0.5.0"
prost-types = "0.5.0"
rand = "0.6.3"
try-lock = "0.2"
# for config parsing
regex = "1.0.0"
# networking
tokio = "0.1.14"
tokio-timer = "0.2.6" # for tokio_timer::clock
tower = "0.1"
tower-discover = "0.1"
tower-service = "0.2"
tower-util = "0.1"
tokio-connect = { git = "https://github.com/carllerche/tokio-connect" }
tower-balance = { git = "https://github.com/tower-rs/tower" }
tower-load = { git = "https://github.com/tower-rs/tower" }
tower-request-modifier = { git = "https://github.com/tower-rs/tower-http" }
tower-spawn-ready = { git = "https://github.com/tower-rs/tower" }
tower-grpc = { version = "0.1", default-features = false, features = ["protobuf"] }
# FIXME update to a release when available (>0.11)
trust-dns-resolver = { git = "https://github.com/bluejekyll/trust-dns", rev = "7c8a0739dad495bf5a4fddfe86b8bbe2aa52d060", default-features = false }
# tracing
tracing = "0.1.9"
tracing-futures = "0.1"
tracing-log = "0.1"
# tls
ring = "0.16"
webpki = "0.21"
rustls = "0.16"
tokio-rustls = "0.10"
untrusted = "0.7"
[dependencies.tracing-subscriber]
version = "0.1.4"
# we don't need ANSI colors or `chrono` time formatting
default-features = false
features = ["env-filter", "fmt", "smallvec", "tracing-log"]
[target.'cfg(target_os = "linux")'.dependencies]
libc = "0.2"
procinfo = "0.4.2"
[dev-dependencies]
net2 = "0.2"
quickcheck = { version = "0.8", default-features = false }
linkerd2-metrics = { path = "./lib/linkerd2-metrics", features = ["test_util"] }
linkerd2-task = { path = "lib/linkerd2-task", features = ["test_util"] }
linkerd2-proxy-api = { git = "https://github.com/linkerd/linkerd2-proxy-api", features = ["arbitrary"], tag = "v0.1.10" }
flate2 = { version = "1.0.1", default-features = false, features = ["rust_backend"] }
# `tokio-io` is needed for TCP tests, because `tokio::io` doesn't re-export
# the `read` function.
tokio-io = "0.1.6"
tokio-current-thread = "0.1.4"
# Debug symbols end up chewing up several GB of disk space, so better to just
# disable them.
[profile.dev]
@ -146,4 +44,3 @@ debug = false
[patch.crates-io]
webpki = { git = "https://github.com/seanmonstar/webpki", branch = "cert-dns-names-0.21" }

View File

@ -16,17 +16,12 @@ FROM $RUST_IMAGE as build
WORKDIR /usr/src/linkerd2-proxy
# Fetch external dependencies.
RUN mkdir -p src && touch src/lib.rs
COPY Cargo.toml Cargo.lock ./
COPY lib lib
COPY . .
RUN cargo fetch --locked
COPY src src
RUN if [ -n "$PROXY_UNOPTIMIZED" ]; \
then \
cargo build -p linkerd2-proxy --bin linkerd2-proxy --frozen && \
mv target/debug/linkerd1-proxy target/linkerd2-proxy ; \
mv target/debug/linkerd2-proxy target/linkerd2-proxy ; \
else \
cargo build -p linkerd2-proxy --bin linkerd2-proxy --frozen --release && \
mv target/release/linkerd2-proxy target/linkerd2-proxy ; \

View File

@ -18,7 +18,7 @@ SHASUM = shasum -a 256
CARGO ?= cargo
CARGO_BUILD = $(CARGO) build --frozen $(RELEASE)
CARGO_TEST = $(CARGO) test --all --frozen $(RELEASE)
CARGO_TEST = $(CARGO) test --frozen $(RELEASE)
CARGO_FMT = $(CARGO) fmt --all
DOCKER = docker
@ -74,18 +74,18 @@ fmt:
.PHONY: test-lib
test-lib:: fetch
$(CARGO_TEST) --lib --no-default-features
$(CARGO_TEST) --lib
.PHONY: test-integration
test-integration: fetch
$(CARGO_TEST) --tests --no-default-features
$(CARGO_TEST) --tests
.PHONY: test
test: test-lib test-integration
.PHONY: test-flakey
test-flakey: fetch
$(CARGO_TEST)
$(CARGO_TEST) --features linkerd-app-integration/flaky_tests
.PHONY: package
package: $(PKG_ROOT)/$(PKG)

View File

@ -52,6 +52,21 @@ Usually, [Cargo][cargo], Rust's package manager, is used to build and test this
project. If you don't have Cargo installed, we suggest getting it via
https://rustup.rs/.
### Repository Structure
This project is broken into many small libraries, or _crates_, so that
components may be compiled & tested independently. The following crate
targets are especially important:
* [`linkerd2-proxy`] contains the proxy executable;
* [`linkerd2-app-integration`] contains the proxy's integration tests;
* [`linkerd2-app`] bundles the [`linkerd2-app-inbound`] and [`linkerd2-app-outbound`] crates so that they may be run by the executable or integration tests.
[`linkerd2-proxy`]: linkerd2-proxy
[`linkerd2-app`]: linkerd/app
[`linkerd2-app-integration`]: linkerd/app/integration
[`linkerd2-app-inbound`]: linkerd/app/inbound
[`linkerd2-app-outbound`]: linkerd/app/outbound
## Code of conduct

View File

@ -1,33 +0,0 @@
[package]
name = "linkerd2-proxy-transport"
version = "0.1.0"
authors = ["Linkerd Developers <cncf-linkerd-dev@lists.cncf.io>"]
edition = "2018"
publish = false
[dependencies]
bytes = "0.4"
futures = "0.1"
indexmap = "1.0.0"
linkerd2-conditional = { path = "../linkerd2-conditional" }
linkerd2-dns-name = { path = "../linkerd2-dns-name" }
linkerd2-error = { path = "../linkerd2-error" }
linkerd2-identity = { path = "../linkerd2-identity" }
linkerd2-metrics = { path = "../linkerd2-metrics" }
linkerd2-proxy-core = { path = "../linkerd2-proxy-core" }
ring = "0.16"
rustls = "0.16"
tokio = "0.1.14"
tokio-rustls = "0.10"
tower = "0.1"
tracing = "0.1.9"
webpki = "0.21"
untrusted = "0.7"
[target.'cfg(target_os = "linux")'.dependencies]
libc = "0.2"
[dev-dependencies]
linkerd2-identity = { path = "../linkerd2-identity", features = ["test-util"] }
tower-util = "0.1"
tracing-subscriber = "0.1"

View File

@ -1,35 +0,0 @@
use std::time::Duration;
use tokio::net::TcpStream;
mod addr_info;
pub mod connect;
mod io;
mod listen;
pub mod metrics;
mod peek;
mod prefixed;
mod source;
pub mod tls;
pub use self::{
addr_info::{AddrInfo, GetOriginalDst, SoOriginalDst},
io::BoxedIo,
listen::Listen,
peek::Peek,
source::Source,
tls::Connection,
};
// Misc.
fn set_nodelay_or_warn(socket: &TcpStream) {
if let Err(e) = socket.set_nodelay(true) {
tracing::warn!("failed to set nodelay: {}", e);
}
}
fn set_keepalive_or_warn(tcp: &TcpStream, ka: Option<Duration>) {
if let Err(e) = tcp.set_keepalive(ka) {
tracing::warn!("failed to set keepalive: {}", e);
}
}

View File

@ -7,4 +7,4 @@ publish = false
[dependencies]
http = "0.1"
linkerd2-dns-name = { path = "../linkerd2-dns-name" }
linkerd2-dns-name = { path = "../dns/name" }

View File

@ -1,3 +1,5 @@
#![deny(warnings, rust_2018_idioms)]
use http;
use linkerd2_dns_name::Name;
use std::convert::TryFrom;

43
linkerd/app/Cargo.toml Normal file
View File

@ -0,0 +1,43 @@
[package]
name = "linkerd2-app"
version = "0.1.0"
authors = ["Linkerd Developers <cncf-linkerd-dev@lists.cncf.io>"]
edition = "2018"
publish = false
description = """
Configures and executes the proxy
This is used by tests and the executable.
"""
[dependencies]
futures = "0.1"
linkerd2-app-core = { path = "./core" }
linkerd2-app-inbound = { path = "./inbound" }
linkerd2-app-outbound = { path = "./outbound" }
opencensus-proto = { path = "../../opencensus-proto" }
tokio = "0.1.14"
tracing = "0.1.9"
tracing-futures = "0.1"
[dev-dependencies]
bytes = "0.4"
h2 = "0.1"
http = "0.1"
http-body = "0.1"
hyper = "0.12"
linkerd2-metrics = { path = "../metrics", features = ["test_util"] }
linkerd2-task = { path = "../task", features = ["test_util"] }
linkerd2-proxy-api = { git = "https://github.com/linkerd/linkerd2-proxy-api", features = ["arbitrary"], tag = "v0.1.10" }
regex = "0.1"
net2 = "0.2"
quickcheck = { version = "0.8", default-features = false }
ring = "0.16"
rustls = "0.16"
tokio-connect = { git = "https://github.com/carllerche/tokio-connect" }
tokio-io = "0.1.6"
tokio-current-thread = "0.1.4"
tokio-rustls = "0.10"
tower = "0.1"
tower-grpc = { version = "0.1", default-features = false, features = ["protobuf"] }
webpki = "0.21"

View File

@ -0,0 +1,75 @@
[package]
name = "linkerd2-app-core"
version = "0.1.0"
authors = ["Linkerd Developers <cncf-linkerd-dev@lists.cncf.io>"]
edition = "2018"
publish = false
description = """
Core infrastructure for the proxy application
This crate conglomerates proxy configuration, runtime administration, etc,
independently of the inbound and outbound proxy logic.
"""
[dependencies]
bytes = "0.4"
http = "0.1"
httparse = "1.2"
hyper = "0.12"
futures = "0.1"
indexmap = "1.0"
ipnet = "1.0"
linkerd2-addr = { path = "../../addr" }
linkerd2-conditional = { path = "../../conditional" }
linkerd2-dns = { path = "../../dns" }
linkerd2-drain = { path = "../../drain" }
linkerd2-duplex = { path = "../../duplex" }
linkerd2-error = { path = "../../error" }
linkerd2-exp-backoff = { path = "../../exp-backoff" }
linkerd2-fallback = { path = "../../fallback" }
linkerd2-identity = { path = "../../identity" }
linkerd2-metrics = { path = "../../metrics" }
linkerd2-opencensus = { path = "../../opencensus" }
linkerd2-proxy-core = { path = "../../proxy/core" }
linkerd2-proxy-api = { git = "https://github.com/linkerd/linkerd2-proxy-api", tag = "v0.1.10" }
linkerd2-proxy-api-resolve = { path = "../../proxy/api-resolve" }
linkerd2-proxy-discover = { path = "../../proxy/discover" }
linkerd2-proxy-http = { path = "../../proxy/http" }
linkerd2-proxy-resolve = { path = "../../proxy/resolve" }
linkerd2-proxy-transport = { path = "../../proxy/transport" }
linkerd2-reconnect = { path = "../../reconnect" }
linkerd2-request-filter = { path = "../../request-filter" }
linkerd2-router = { path = "../../router" }
linkerd2-stack = { path = "../../stack" }
linkerd2-task = { path = "../../task" }
linkerd2-timeout = { path = "../../timeout" }
linkerd2-trace-context = { path = "../../trace-context" }
opencensus-proto = { path = "../../../opencensus-proto" }
rand = "0.6"
regex = "1.0.0"
tokio = "0.1.14"
tokio-timer = "0.2"
tower = "0.1"
tower-balance = { git = "https://github.com/tower-rs/tower" }
tower-load = { git = "https://github.com/tower-rs/tower" }
tower-request-modifier = { git = "https://github.com/tower-rs/tower-http" }
tower-spawn-ready = { git = "https://github.com/tower-rs/tower" }
tower-grpc = { version = "0.1", default-features = false, features = ["protobuf"] }
tracing = "0.1.9"
tracing-futures = "0.1"
tracing-log = "0.1"
[dependencies.tracing-subscriber]
version = "0.1.4"
# we don't need ANSI colors or `chrono` time formatting
default-features = false
features = ["env-filter", "fmt", "smallvec", "tracing-log"]
[target.'cfg(target_os = "linux")'.dependencies]
libc = "0.2"
procinfo = "0.4.2"
[dev-dependencies]
linkerd2-proxy-api = { git = "https://github.com/linkerd/linkerd2-proxy-api", features = ["arbitrary"], tag = "v0.1.10" }
prost-types = "0.5.0"
quickcheck = { version = "0.8", default-features = false }

View File

@ -1,6 +1,6 @@
use crate::core::listen::Accept;
use crate::{Error, Never};
use futures::{future, Future, Poll};
use linkerd2_error::{Error, Never};
use linkerd2_proxy_core::listen::Accept;
use tracing;
pub struct AcceptError<A>(A);

View File

@ -3,12 +3,12 @@
//! * `/metrics` -- reports prometheus-formatted metrics.
//! * `/ready` -- returns 200 when the proxy is ready to participate in meshed traffic.
use crate::metrics::{self, FmtMetrics};
use crate::{svc, transport::tls};
use futures::{future, Future, Poll};
use http::StatusCode;
use hyper::service::{service_fn, Service};
use hyper::{Body, Request, Response};
use linkerd2_metrics::{self as metrics, FmtMetrics};
use std::io;
mod readiness;
@ -116,8 +116,8 @@ fn rsp(status: StatusCode, body: impl Into<Body>) -> Response<Body> {
#[cfg(test)]
mod tests {
use super::*;
use crate::task::test_util::BlockOnFor;
use http::method::Method;
use linkerd2_task::test_util::BlockOnFor;
use std::time::Duration;
use tokio::runtime::current_thread::Runtime;

View File

@ -1,7 +1,7 @@
pub use crate::proxy::http::metrics::classify::{self, layer, CanClassify};
use crate::proxy::http::{profiles, timeout, HasH2Reason};
use crate::Error;
use http;
use linkerd2_error::Error;
pub use linkerd2_proxy_http::metrics::classify::{self, layer, CanClassify};
use linkerd2_proxy_http::{profiles, timeout, HasH2Reason};
use std::borrow::Cow;
use tracing::trace;

View File

@ -1,11 +1,12 @@
use super::control::ControlAddr;
use super::identity;
use crate::addr::{self, Addr};
pub use crate::proxy::http::h2::Settings as H2Settings;
use crate::transport::tls;
use crate::{dns, Conditional};
use indexmap::IndexSet;
use linkerd2_addr::Addr;
use linkerd2_conditional::Conditional;
use linkerd2_dns as dns;
use linkerd2_exp_backoff::ExponentialBackoff;
use linkerd2_proxy_http::h2::Settings as H2Settings;
use linkerd2_proxy_transport::tls;
use std::collections::HashMap;
use std::convert::TryFrom;
use std::iter::FromIterator;
@ -175,7 +176,7 @@ pub enum ParseError {
NotANumber,
HostIsNotAnIpAddress,
NotUnicode,
AddrError(addr::Error),
AddrError(linkerd2_addr::Error),
NameError,
InvalidTokenSource,
InvalidTrustAnchors,
@ -735,7 +736,7 @@ fn parse_socket_addr(s: &str) -> Result<SocketAddr, ParseError> {
}
fn parse_addr(s: &str) -> Result<Addr, ParseError> {
addr::Addr::from_str(s).map_err(|e| {
Addr::from_str(s).map_err(|e| {
error!("Not a valid address: {}", s);
ParseError::AddrError(e)
})

View File

@ -146,10 +146,10 @@ pub mod add_origin {
/// Resolves the controller's `addr` once before building a client.
pub mod resolve {
use super::{client, ControlAddr};
use crate::dns;
use crate::svc;
use futures::{try_ready, Future, Poll};
use linkerd2_addr::Addr;
use linkerd2_dns as dns;
use std::net::SocketAddr;
use std::{error, fmt};
use tracing::info_span;
@ -292,10 +292,10 @@ pub mod resolve {
/// Creates a client suitable for gRPC.
pub mod client {
use super::super::config::H2Settings;
use crate::transport::{connect, tls};
use crate::{proxy::http, svc};
use futures::Poll;
use linkerd2_proxy_http::h2::Settings as H2Settings;
use std::net::SocketAddr;
#[derive(Clone, Debug)]

View File

@ -1,11 +1,11 @@
use super::classify;
use crate::proxy::http::{
use http;
use indexmap::IndexMap;
use linkerd2_addr::{Addr, NameAddr};
use linkerd2_proxy_http::{
metrics::classify::{CanClassify, Classify, ClassifyEos, ClassifyResponse},
profiles, retry, settings, timeout,
};
use crate::{Addr, NameAddr};
use http;
use indexmap::IndexMap;
use std::fmt;
use std::sync::Arc;
use std::time::Duration;
@ -33,7 +33,7 @@ pub struct DstAddr {
dst_logical: Addr,
dst_concrete: Addr,
direction: Direction,
pub(super) http_settings: settings::Settings,
pub http_settings: settings::Settings,
}
// === impl Route ===

View File

@ -1,10 +1,10 @@
//! Layer to map HTTP service errors into appropriate `http::Response`s.
use crate::proxy::http::HasH2Reason;
use crate::svc;
use futures::{Future, Poll};
use http::{header, Request, Response, StatusCode, Version};
use linkerd2_error::Error;
use linkerd2_proxy_http::HasH2Reason;
use tracing::{debug, error, warn};
/// Layer to map HTTP service errors into appropriate `http::Response`s.

View File

@ -1,6 +1,6 @@
use super::metric_labels::Direction;
use crate::metrics::{FmtMetrics, Metric};
use crate::proxy::http::metrics::handle_time;
use linkerd2_metrics::{FmtMetrics, Metric};
use std::{fmt, iter};
#[derive(Clone, Debug)]

View File

@ -1,8 +1,8 @@
use crate::api::identity as api;
pub use crate::identity::{Crt, CrtKey, Csr, InvalidName, Key, Name, TokenSource, TrustAnchors};
use crate::transport::tls;
use crate::Never;
use futures::{try_ready, Async, Future, Poll};
use linkerd2_error::Never;
pub use linkerd2_identity::{Crt, CrtKey, Csr, InvalidName, Key, Name, TokenSource, TrustAnchors};
use linkerd2_proxy_api::identity as api;
use std::sync::Arc;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use tokio::sync::watch;

112
linkerd/app/core/src/lib.rs Normal file
View File

@ -0,0 +1,112 @@
//! Core infrastructure for the proxy application.
//!
//! Conglomerates:
//! - Configuration
//! - Runtime initialization
//! - Admin interfaces
//! - Tap
//! - Metric labeling
#![deny(warnings, rust_2018_idioms)]
pub use linkerd2_addr::{self as addr, Addr, NameAddr};
pub use linkerd2_conditional::Conditional;
pub use linkerd2_dns as dns;
pub use linkerd2_drain as drain;
pub use linkerd2_error::{Error, Never, Recover};
pub use linkerd2_exp_backoff as exp_backoff;
pub use linkerd2_metrics as metrics;
pub use linkerd2_opencensus as opencensus;
pub use linkerd2_proxy_api_resolve as api_resolve;
pub use linkerd2_proxy_core as core;
pub use linkerd2_proxy_discover as discover;
pub use linkerd2_proxy_resolve as resolve;
pub use linkerd2_reconnect as reconnect;
pub use linkerd2_request_filter as request_filter;
pub use linkerd2_task as task;
pub use linkerd2_trace_context as trace_context;
pub mod accept_error;
pub mod admin;
pub mod classify;
pub mod config;
pub mod control;
pub mod dst;
pub mod errors;
pub mod handle_time;
pub mod identity;
pub mod metric_labels;
pub mod profiles;
pub mod proxy;
pub mod serve;
pub mod spans;
pub mod svc;
pub mod tap;
pub mod telemetry;
pub mod trace;
pub mod transport;
pub const CANONICAL_DST_HEADER: &'static str = "l5d-dst-canonical";
pub const DST_OVERRIDE_HEADER: &'static str = "l5d-dst-override";
pub const L5D_REMOTE_IP: &'static str = "l5d-remote-ip";
pub const L5D_SERVER_ID: &'static str = "l5d-server-id";
pub const L5D_CLIENT_ID: &'static str = "l5d-client-id";
pub const L5D_REQUIRE_ID: &'static str = "l5d-require-id";
pub fn init() -> Result<(config::Config, trace::LevelHandle), linkerd2_error::Error> {
let trace_admin = trace::init()?;
let cfg = config::Config::parse(&config::Env)?;
Ok((cfg, trace_admin))
}
const DEFAULT_PORT: u16 = 80;
pub fn http_request_l5d_override_dst_addr<B>(req: &http::Request<B>) -> Result<Addr, addr::Error> {
proxy::http::authority_from_header(req, DST_OVERRIDE_HEADER)
.ok_or(addr::Error::InvalidHost)
.and_then(|a| Addr::from_authority_and_default_port(&a, DEFAULT_PORT))
}
pub fn http_request_authority_addr<B>(req: &http::Request<B>) -> Result<Addr, addr::Error> {
req.uri()
.authority_part()
.ok_or(addr::Error::InvalidHost)
.and_then(|a| Addr::from_authority_and_default_port(a, DEFAULT_PORT))
}
pub fn http_request_host_addr<B>(req: &http::Request<B>) -> Result<Addr, addr::Error> {
use crate::proxy::http::h1;
h1::authority_from_host(req)
.ok_or(addr::Error::InvalidHost)
.and_then(|a| Addr::from_authority_and_default_port(&a, DEFAULT_PORT))
}
pub fn http_request_orig_dst_addr<B>(req: &http::Request<B>) -> Result<Addr, addr::Error> {
use crate::transport::Source;
req.extensions()
.get::<Source>()
.and_then(|src| src.orig_dst_if_not_local())
.map(Addr::Socket)
.ok_or(addr::Error::InvalidHost)
}
#[derive(Copy, Clone, Debug)]
pub struct DispatchDeadline(std::time::Instant);
impl DispatchDeadline {
pub fn after(allowance: std::time::Duration) -> DispatchDeadline {
DispatchDeadline(tokio_timer::clock::now() + allowance)
}
pub fn extract<A>(req: &http::Request<A>) -> Option<std::time::Instant> {
req.extensions().get::<DispatchDeadline>().map(|d| d.0)
}
}
pub type HttpEndpointMetricsRegistry =
linkerd2_proxy_http::metrics::SharedRegistry<metric_labels::EndpointLabels, classify::Class>;
pub type HttpRouteMetricsRegistry =
linkerd2_proxy_http::metrics::SharedRegistry<metric_labels::RouteLabels, classify::Class>;

View File

@ -1,8 +1,11 @@
use crate::identity;
use crate::transport::{labels::TlsStatus, tls};
use crate::{identity, metrics::FmtLabels, Addr, Conditional, NameAddr};
use linkerd2_addr::{Addr, NameAddr};
use linkerd2_conditional::Conditional;
use linkerd2_metrics::FmtLabels;
use std::fmt::{self, Write};
use super::{classify, control, dst, inbound, outbound};
use super::{classify, control, dst};
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct ControlLabels {
@ -12,11 +15,11 @@ pub struct ControlLabels {
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct EndpointLabels {
direction: Direction,
tls_id: Conditional<TlsId, tls::ReasonForNoIdentity>,
dst_logical: Option<NameAddr>,
dst_concrete: Option<NameAddr>,
labels: Option<String>,
pub direction: Direction,
pub tls_id: Conditional<TlsId, tls::ReasonForNoIdentity>,
pub dst_logical: Option<NameAddr>,
pub dst_concrete: Option<NameAddr>,
pub labels: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
@ -26,13 +29,13 @@ pub struct RouteLabels {
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub(in crate::app) enum Direction {
pub enum Direction {
In,
Out,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
enum TlsId {
pub enum TlsId {
ClientId(identity::Name),
ServerId(identity::Name),
}
@ -85,43 +88,6 @@ impl FmtLabels for RouteLabels {
// === impl EndpointLabels ===
impl From<inbound::Endpoint> for EndpointLabels {
fn from(ep: inbound::Endpoint) -> Self {
Self {
dst_logical: ep.dst_name.clone(),
dst_concrete: ep.dst_name,
direction: Direction::In,
tls_id: ep.tls_client_id.map(TlsId::ClientId),
labels: None,
}
}
}
fn prefix_labels<'i, I>(prefix: &str, mut labels_iter: I) -> Option<String>
where
I: Iterator<Item = (&'i String, &'i String)>,
{
let (k0, v0) = labels_iter.next()?;
let mut out = format!("{}_{}=\"{}\"", prefix, k0, v0);
for (k, v) in labels_iter {
write!(out, ",{}_{}=\"{}\"", prefix, k, v).expect("label concat must succeed");
}
Some(out)
}
impl From<outbound::Endpoint> for EndpointLabels {
fn from(ep: outbound::Endpoint) -> Self {
Self {
dst_logical: ep.dst_logical,
dst_concrete: ep.dst_concrete,
direction: Direction::Out,
tls_id: ep.identity.as_ref().map(|id| TlsId::ServerId(id.clone())),
labels: prefix_labels("dst", ep.metadata.labels().into_iter()),
}
}
}
impl FmtLabels for EndpointLabels {
fn fmt_labels(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let authority = self.dst_logical.as_ref().map(Authority);
@ -207,3 +173,16 @@ impl FmtLabels for TlsId {
}
}
}
pub fn prefix_labels<'i, I>(prefix: &str, mut labels_iter: I) -> Option<String>
where
I: Iterator<Item = (&'i String, &'i String)>,
{
let (k0, v0) = labels_iter.next()?;
let mut out = format!("{}_{}=\"{}\"", prefix, k0, v0);
for (k, v) in labels_iter {
write!(out, ",{}_{}=\"{}\"", prefix, k, v).expect("label concat must succeed");
}
Some(out)
}

View File

@ -1,10 +1,10 @@
use crate::api::destination as api;
use crate::proxy::http::{profiles, retry::Budget};
use crate::NameAddr;
use crate::Never;
use futures::sync::{mpsc, oneshot};
use futures::{Async, AsyncSink, Future, Poll, Sink, Stream};
use http;
use linkerd2_addr::NameAddr;
use linkerd2_error::Never;
use linkerd2_proxy_api::destination as api;
use regex::Regex;
use std::sync::Arc;
use std::time::Duration;
@ -437,7 +437,7 @@ mod tests {
let proto = api::RetryBudget {
min_retries_per_second,
retry_ratio,
ttl: Some(::prost_types::Duration {
ttl: Some(prost_types::Duration {
seconds,
nanos,
}),

View File

@ -1,8 +1,8 @@
//! Tools for building a transparent TCP/HTTP proxy.
pub use linkerd2_proxy_http::{self as http, grpc};
pub mod buffer;
pub mod grpc;
pub mod http;
pub mod pending;
mod protocol;
pub mod server;

View File

@ -1,6 +1,6 @@
use crate::svc::{self, ServiceExt};
use crate::Error;
use futures::{try_ready, Future, Poll};
use linkerd2_error::Error;
use linkerd2_router as rt;
#[derive(Copy, Clone, Debug)]

View File

@ -1,5 +1,3 @@
use super::http::h2::Settings as H2Settings;
use crate::core::listen::Accept;
use crate::proxy::http::{
glue::{HttpBody, HyperServerSvc},
upgrade,
@ -16,6 +14,8 @@ use http;
use hyper;
use linkerd2_drain as drain;
use linkerd2_error::{Error, Never};
use linkerd2_proxy_core::listen::Accept;
use linkerd2_proxy_http::h2::Settings as H2Settings;
use std::marker::PhantomData;
use std::net::SocketAddr;
use std::{error, fmt};

View File

@ -0,0 +1,29 @@
use crate::svc::{self, ServiceExt};
use futures::Future;
use linkerd2_duplex::Duplex;
use linkerd2_error::Error;
use std::fmt;
use tokio::io::{AsyncRead, AsyncWrite};
/// Attempt to proxy the `server_io` stream to a `T`-typed target.
///
/// If the target is not valid, an error is logged and the server stream is
/// dropped.
pub(super) fn forward<I, C, T>(
server_io: I,
connect: C,
target: T,
) -> impl Future<Item = (), Error = Error> + Send + 'static
where
T: Send + 'static,
I: AsyncRead + AsyncWrite + fmt::Debug + Send + 'static,
C: svc::Service<T> + Send + 'static,
C::Error: Into<Error>,
C::Future: Send + 'static,
C::Response: AsyncRead + AsyncWrite + fmt::Debug + Send + 'static,
{
connect
.oneshot(target)
.map_err(Into::into)
.and_then(move |io| Duplex::new(server_io, io).map_err(Into::into))
}

View File

@ -1,5 +1,5 @@
use crate::trace_context;
use linkerd2_error::Error;
use linkerd2_trace_context as trace_context;
use opencensus_proto::trace::v1 as oc;
use std::collections::HashMap;
use std::{error, fmt};

View File

@ -1,6 +1,6 @@
use crate::proxy::{buffer, pending};
pub use linkerd2_router::Make;
pub use linkerd2_stack::{self as stack, layer, map_target, shared, Layer, LayerExt};
pub use linkerd2_stack::{self as stack, layer, map_target, Layer, LayerExt, Shared};
pub use linkerd2_timeout::stack as timeout;
use std::time::Duration;
use tower::layer::util::{Identity, Stack as Pair};

View File

@ -1,12 +1,12 @@
use crate::api::tap::server::{Tap, TapServer};
use crate::identity;
use crate::proxy::grpc::{req_box_body, res_body_as_payload};
use crate::proxy::http::HyperServerSvc;
use crate::svc::Service;
use crate::transport::tls::{self, HasPeerIdentity};
use crate::Error;
use futures::{Future, Poll};
use indexmap::IndexSet;
use linkerd2_error::Error;
use linkerd2_proxy_api::tap::server::{Tap, TapServer};
#[derive(Clone, Debug)]
pub struct AcceptPermittedClients {
@ -90,8 +90,8 @@ impl Future for ServeFuture {
}
pub mod unauthenticated {
use crate::api::tap as api;
use futures::{future, stream};
use linkerd2_proxy_api::tap as api;
use tower_grpc::{Code, Request, Response, Status};
#[derive(Clone, Debug, Default)]

View File

@ -1,7 +1,7 @@
use super::iface::Tap;
use crate::Never;
use futures::sync::{mpsc, oneshot};
use futures::{try_ready, Async, Future, Poll, Stream};
use linkerd2_error::Never;
use tracing::{debug, trace, warn};
pub fn new<T>() -> (Daemon<T>, Register<T>, Subscribe<T>) {

View File

@ -1,9 +1,9 @@
use crate::api::net::ip_address;
use crate::api::tap::observe_request;
use crate::tap::Inspect;
use http;
use indexmap::IndexMap;
use ipnet::{Contains, Ipv4Net, Ipv6Net};
use linkerd2_proxy_api::net::ip_address;
use linkerd2_proxy_api::tap::observe_request;
use std::boxed::Box;
use std::convert::TryFrom;
use std::net;
@ -108,7 +108,7 @@ impl TryFrom<observe_request::r#match::Match> for Match {
#[allow(unconditional_recursion)]
fn try_from(m: observe_request::r#match::Match) -> Result<Self, Self::Error> {
use crate::api::tap::observe_request::r#match;
use linkerd2_proxy_api::tap::observe_request::r#match;
match m {
r#match::Match::All(seq) => Self::from_seq(seq).map(Match::All),
@ -169,7 +169,7 @@ impl TryFrom<observe_request::r#match::Tcp> for TcpMatch {
type Error = InvalidMatch;
fn try_from(m: observe_request::r#match::Tcp) -> Result<Self, InvalidMatch> {
use crate::api::tap::observe_request::r#match::tcp;
use linkerd2_proxy_api::tap::observe_request::r#match::tcp;
m.r#match.ok_or(InvalidMatch::Empty).and_then(|t| match t {
tcp::Match::Ports(range) => {
@ -261,7 +261,7 @@ impl HttpMatch {
string_match: &observe_request::r#match::http::string_match::Match,
value: &str,
) -> bool {
use crate::api::tap::observe_request::r#match::http::string_match::Match::*;
use linkerd2_proxy_api::tap::observe_request::r#match::http::string_match::Match::*;
match string_match {
Exact(ref exact) => value == exact,
@ -273,8 +273,8 @@ impl HttpMatch {
impl TryFrom<observe_request::r#match::Http> for HttpMatch {
type Error = InvalidMatch;
fn try_from(m: observe_request::r#match::Http) -> Result<Self, InvalidMatch> {
use crate::api::http_types::scheme::{Registered, Type};
use crate::api::tap::observe_request::r#match::http::Match as Pb;
use linkerd2_proxy_api::http_types::scheme::{Registered, Type};
use linkerd2_proxy_api::tap::observe_request::r#match::http::Match as Pb;
m.r#match.ok_or(InvalidMatch::Empty).and_then(|m| match m {
Pb::Scheme(s) => s.r#type.ok_or(InvalidMatch::Empty).and_then(|s| match s {
@ -317,7 +317,7 @@ mod tests {
use std::collections::HashMap;
use super::*;
use crate::api::http_types;
use linkerd2_proxy_api::http_types;
impl Arbitrary for LabelMatch {
fn arbitrary<G: Gen>(g: &mut G) -> Self {

View File

@ -1,13 +1,13 @@
use super::match_::Match;
use crate::api::{http_types, pb_duration, tap as api};
use crate::proxy::http::HasH2Reason;
use crate::tap::{iface, Inspect};
use crate::transport::labels::TlsStatus;
use crate::Conditional;
use bytes::Buf;
use futures::sync::mpsc;
use futures::{future, Async, Future, Poll, Stream};
use hyper::body::Payload;
use linkerd2_conditional::Conditional;
use linkerd2_proxy_api::{http_types, pb_duration, tap as api};
use std::convert::TryFrom;
use std::iter;
use std::sync::atomic::{AtomicUsize, Ordering};

View File

@ -1,8 +1,8 @@
use crate::identity;
use crate::transport::tls::ReasonForNoIdentity;
use crate::Conditional;
use http;
use indexmap::IndexMap;
use linkerd2_conditional::Conditional;
use std::net;
use std::sync::Arc;

View File

@ -1,5 +1,5 @@
use self::system::System;
use crate::metrics::{metrics, FmtMetrics, Gauge};
use linkerd2_metrics::{metrics, FmtMetrics, Gauge};
use std::fmt;
use std::time::{SystemTime, UNIX_EPOCH};
use tracing::debug;
@ -52,8 +52,8 @@ impl FmtMetrics for Report {
#[cfg(target_os = "linux")]
mod system {
use crate::metrics::{metrics, Counter, FmtMetrics, Gauge};
use libc::{self, pid_t};
use linkerd2_metrics::{metrics, Counter, FmtMetrics, Gauge};
use procinfo::pid;
use std::fmt;
use std::{fs, io};

View File

@ -1,6 +1,6 @@
use super::tls;
use crate::metrics::FmtLabels;
use crate::Conditional;
use linkerd2_conditional::Conditional;
use linkerd2_metrics::FmtLabels;
use std::fmt;
/// Describes a class of transport.

View File

@ -0,0 +1,24 @@
[package]
name = "linkerd2-app-inbound"
version = "0.1.0"
authors = ["Linkerd Developers <cncf-linkerd-dev@lists.cncf.io>"]
edition = "2018"
publish = false
description = """
Configures and runs the inbound proxy
"""
[dependencies]
bytes = "0.4"
http = "0.1"
futures = "0.1"
indexmap = "1.0"
linkerd2-app-core = { path = "../core" }
opencensus-proto = { path = "../../../opencensus-proto" }
tokio = "0.1.14"
tower = "0.1"
tower-grpc = { version = "0.1", default-features = false, features = ["protobuf"] }
tracing = "0.1.9"
[dev-dependencies]
quickcheck = { version = "0.8", default-features = false }

View File

@ -1,10 +1,15 @@
use super::super::dst::{DstAddr, Route};
use super::super::{classify, identity};
use crate::proxy::http::{router, settings};
use crate::transport::{connect, tls, Source};
use crate::{tap, Conditional, NameAddr};
use http;
use indexmap::IndexMap;
use linkerd2_app_core::{
classify,
dst::{DstAddr, Route},
identity,
metric_labels::EndpointLabels,
proxy::http::{router, settings},
tap,
transport::{connect, tls, Source},
Conditional, NameAddr,
};
use std::fmt;
use std::net::SocketAddr;
use std::sync::Arc;
@ -154,10 +159,12 @@ impl<A> router::Recognize<http::Request<A>> for RecognizeEndpoint {
#[cfg(test)]
mod tests {
use super::{Endpoint, RecognizeEndpoint};
use crate::proxy::http::{router::Recognize, Settings};
use crate::transport::{tls, Source};
use crate::Conditional;
use http;
use linkerd2_app_core::{
proxy::http::{router::Recognize, Settings},
transport::{tls, Source},
Conditional,
};
use quickcheck::quickcheck;
use std::net;
@ -172,8 +179,7 @@ mod tests {
}
fn dst_addr(req: &mut http::Request<()>) {
use crate::app::dst::DstAddr;
use crate::Addr;
use linkerd2_app_core::{dst::DstAddr, Addr};
req.extensions_mut().insert(DstAddr::inbound(
Addr::Socket(([0, 0, 0, 0], 0).into()),
Settings::Http2,
@ -204,8 +210,9 @@ mod tests {
remote: net::SocketAddr
) -> bool {
let mut req = http::Request::new(());
let src = Source { remote, local, orig_dst: None, tls_peer: TLS_DISABLED } ;
req.extensions_mut()
.insert(Source { remote, local, orig_dst: None, tls_peer: TLS_DISABLED });
.insert(src);
dst_addr(&mut req);
RecognizeEndpoint::new(default).recognize(&req) == default.map(make_test_endpoint)
@ -223,11 +230,25 @@ mod tests {
remote: net::SocketAddr
) -> bool {
let mut req = http::Request::new(());
let src = Source { remote, local, orig_dst: Some(local), tls_peer: TLS_DISABLED } ;
req.extensions_mut()
.insert(Source { remote, local, orig_dst: Some(local), tls_peer: TLS_DISABLED });
.insert(src);
dst_addr(&mut req);
RecognizeEndpoint::new(default).recognize(&req) == default.map(make_test_endpoint)
}
}
}
impl Into<EndpointLabels> for Endpoint {
fn into(self) -> EndpointLabels {
use linkerd2_app_core::metric_labels::{Direction, TlsId};
EndpointLabels {
dst_logical: self.dst_name.clone(),
dst_concrete: self.dst_name,
direction: Direction::In,
tls_id: self.tls_client_id.map(TlsId::ClientId),
labels: None,
}
}
}

View File

@ -1,15 +1,29 @@
use super::spans::SpanConverter;
use super::{
classify, config::Config, dst::DstAddr, errors, identity, serve, trace, DispatchDeadline,
//! Configures and runs the inbound proxy.
//!
//! The inbound proxy is responsible for terminating traffic from other network
//! endpoints inbound to the local application.
#![deny(warnings, rust_2018_idioms)]
use linkerd2_app_core::{
classify,
config::Config,
drain,
dst::DstAddr,
errors, http_request_authority_addr, http_request_host_addr,
http_request_l5d_override_dst_addr, http_request_orig_dst_addr, identity,
proxy::http::{
client, insert, metrics as http_metrics, normalize_uri, profiles, router, settings,
strip_header,
},
proxy::Server,
reconnect, serve,
spans::SpanConverter,
svc, trace, trace_context,
transport::{self as transport, connect, tls, Source},
Addr, DispatchDeadline, CANONICAL_DST_HEADER, DST_OVERRIDE_HEADER, L5D_CLIENT_ID,
L5D_REMOTE_IP, L5D_SERVER_ID,
};
use crate::proxy::http::{
client, insert, metrics as http_metrics, normalize_uri, profiles, router, settings,
strip_header,
};
use crate::proxy::Server;
use crate::transport::{self, connect, tls, Source};
use crate::{drain, svc, trace_context, Addr};
use linkerd2_reconnect as reconnect;
use opencensus_proto::trace::v1 as oc;
use std::collections::HashMap;
use tokio::sync::mpsc;
@ -31,12 +45,12 @@ pub fn spawn<P>(
local_identity: tls::Conditional<identity::Local>,
listen: transport::Listen,
get_original_dst: impl transport::GetOriginalDst + Send + 'static,
profiles_client: super::profiles::Client<P>,
tap_layer: crate::tap::Layer,
profiles_client: linkerd2_app_core::profiles::Client<P>,
tap_layer: linkerd2_app_core::tap::Layer,
handle_time: http_metrics::handle_time::Scope,
endpoint_http_metrics: super::HttpEndpointMetricsRegistry,
route_http_metrics: super::HttpRouteMetricsRegistry,
transport_metrics: transport::MetricsRegistry,
endpoint_http_metrics: linkerd2_app_core::HttpEndpointMetricsRegistry,
route_http_metrics: linkerd2_app_core::HttpRouteMetricsRegistry,
transport_metrics: linkerd2_app_core::transport::MetricsRegistry,
span_sink: Option<mpsc::Sender<oc::Span>>,
drain: drain::Watch,
) where
@ -122,7 +136,7 @@ pub fn spawn<P>(
// per-route policy.
// 2. Annotates the request with the `DstAddr` so that
// `RecognizeEndpoint` can use the value.
let dst_stack = svc::stack(svc::shared(endpoint_router))
let dst_stack = svc::stack(svc::Shared::new(endpoint_router))
.push(insert::target::layer())
.push_buffer_pending(max_in_flight, DispatchDeadline::extract)
.push(profiles::router::layer(
@ -130,7 +144,7 @@ pub fn spawn<P>(
profiles_client,
dst_route_layer,
))
.push(strip_header::request::layer(super::DST_OVERRIDE_HEADER))
.push(strip_header::request::layer(DST_OVERRIDE_HEADER))
.push(trace::layer(
|dst: &DstAddr| info_span!("logical", dst = %dst.dst_logical()),
));
@ -160,26 +174,26 @@ pub fn spawn<P>(
|req: &http::Request<_>| {
let dst = req
.headers()
.get(super::CANONICAL_DST_HEADER)
.get(CANONICAL_DST_HEADER)
.and_then(|dst| {
dst.to_str().ok().and_then(|d| {
Addr::from_str(d).ok().map(|a| {
debug!("using {}", super::CANONICAL_DST_HEADER);
debug!("using {}", CANONICAL_DST_HEADER);
a
})
})
})
.or_else(|| {
super::http_request_l5d_override_dst_addr(req)
http_request_l5d_override_dst_addr(req)
.ok()
.map(|override_addr| {
debug!("using {}", super::DST_OVERRIDE_HEADER);
debug!("using {}", DST_OVERRIDE_HEADER);
override_addr
})
})
.or_else(|| super::http_request_authority_addr(req).ok())
.or_else(|| super::http_request_host_addr(req).ok())
.or_else(|| super::http_request_orig_dst_addr(req).ok())
.or_else(|| http_request_authority_addr(req).ok())
.or_else(|| http_request_host_addr(req).ok())
.or_else(|| http_request_orig_dst_addr(req).ok())
.map(|addr| DstAddr::inbound(addr, settings::Settings::from_request(req)));
debug!(dst.logical = ?dst);
dst
@ -203,16 +217,16 @@ pub fn spawn<P>(
// Furthermore, HTTP/2 requests may be downgraded to HTTP/1.1 per
// `orig-proto` headers. This happens in the source stack so that
// the router need not detect whether a request _will be_ downgraded.
let source_stack = svc::stack(svc::shared(admission_control))
let source_stack = svc::stack(svc::Shared::new(admission_control))
.serves::<Source>()
.push(orig_proto_downgrade::layer())
.push(insert::target::layer())
// disabled due to information leagkage
//.push(set_remote_ip_on_req::layer())
//.push(set_client_id_on_req::layer())
.push(strip_header::request::layer(super::L5D_REMOTE_IP))
.push(strip_header::request::layer(super::L5D_CLIENT_ID))
.push(strip_header::response::layer(super::L5D_SERVER_ID))
.push(strip_header::request::layer(L5D_REMOTE_IP))
.push(strip_header::request::layer(L5D_CLIENT_ID))
.push(strip_header::response::layer(L5D_SERVER_ID))
.push(insert::layer(move || {
DispatchDeadline::after(dispatch_timeout)
}))

View File

@ -1,8 +1,6 @@
use crate::proxy::http::orig_proto;
use crate::svc;
use crate::transport::Source;
use futures::{Future, Poll};
use http;
use linkerd2_app_core::{proxy::http::orig_proto, svc, transport::Source};
use std::marker::PhantomData;
use tracing::trace;

View File

@ -2,7 +2,7 @@
//! with the same port still set.
use super::Endpoint;
use crate::svc::stack::map_target;
use linkerd2_app_core::svc::map_target;
use std::net::SocketAddr;
use tracing::debug;

View File

@ -1,11 +1,12 @@
//! Adds `l5d-client-id` headers to http::Requests derived from the
//! TlsIdentity of a `Source`.
use super::super::L5D_CLIENT_ID;
use crate::proxy::http::add_header::{self, request::ReqHeader, Layer};
use crate::transport::Source;
use crate::Conditional;
use http::header::HeaderValue;
use linkerd2_app_core::{
proxy::http::add_header::{self, request::ReqHeader, Layer},
transport::Source,
Conditional, L5D_CLIENT_ID,
};
use tracing::{debug, warn};
pub fn layer() -> Layer<&'static str, Source, ReqHeader> {

View File

@ -1,11 +1,13 @@
//! Adds `l5d-remote-ip` headers to http::Requests derived from the
//! `remote` of a `Source`.
use super::super::L5D_REMOTE_IP;
use crate::proxy::http::add_header::{self, request::ReqHeader, Layer};
use crate::transport::Source;
use bytes::Bytes;
use http::header::HeaderValue;
use linkerd2_app_core::{
proxy::http::add_header::{self, request::ReqHeader, Layer},
transport::Source,
L5D_REMOTE_IP,
};
pub fn layer() -> Layer<&'static str, Source, ReqHeader> {
add_header::request::layer(L5D_REMOTE_IP, |source: &Source| {

View File

@ -0,0 +1,48 @@
[package]
name = "linkerd2-app-integration"
version = "0.1.0"
authors = ["Linkerd Developers <cncf-linkerd-dev@lists.cncf.io>"]
edition = "2018"
publish = false
description = """
Proxy integration tests
The test utilities can be very costly to compile, so they are extracted into
a dedicated crate to help the compiler cache dependencies properly.
"""
[features]
# Disable to skip certain tests that should not be run on CI.
flaky_tests = []
[dependencies]
bytes = "0.4"
futures = "0.1"
h2 = "0.1"
http = "0.1"
http-body = "0.1"
hyper = "0.12"
linkerd2-app = { path = ".." }
linkerd2-app-core = { path = "../core" }
linkerd2-metrics = { path = "../../metrics", features = ["test_util"] }
linkerd2-task = { path = "../../task", features = ["test_util"] }
linkerd2-proxy-api = { git = "https://github.com/linkerd/linkerd2-proxy-api", features = ["arbitrary"], tag = "v0.1.10" }
opencensus-proto = { path = "../../../opencensus-proto" }
regex = "0.1"
net2 = "0.2"
quickcheck = { version = "0.8", default-features = false }
ring = "0.16"
rustls = "0.16"
tokio = "0.1.14"
tokio-connect = { git = "https://github.com/carllerche/tokio-connect" }
tokio-io = "0.1.6"
tokio-current-thread = "0.1.4"
tokio-rustls = "0.10"
tower = "0.1"
tower-grpc = { version = "0.1", default-features = false, features = ["protobuf"] }
tracing = "0.1.9"
tracing-futures = "0.1"
webpki = "0.21"
[dev-dependencies]
flate2 = { version = "1.0.1", default-features = false, features = ["rust_backend"] }

View File

@ -1,11 +1,14 @@
use crate::support::*;
use super::*;
use bytes::IntoBuf;
use futures::sync::{mpsc, oneshot};
use rustls::ClientConfig;
use std::io;
use std::sync::Arc;
use std::sync::Mutex;
use tokio::executor::DefaultExecutor;
use tokio::net::TcpStream;
use tracing::info_span;
use tracing_futures::Instrument;
use webpki::{DNSName, DNSNameRef};
type ClientError = hyper::Error;
@ -223,7 +226,9 @@ fn run(addr: SocketAddr, version: Run, tls: Option<TlsConfig>) -> (Sender, Runni
Run::Http2 => true,
};
let span = info_span!("test client", peer_addr = %addr);
let client = hyper::Client::builder()
.executor(DefaultExecutor::current().instrument(span.clone()))
.http2_only(http2_only)
.build::<Conn, hyper::Body>(conn);
@ -235,12 +240,14 @@ fn run(addr: SocketAddr, version: Run, tls: Option<TlsConfig>) -> (Sender, Runni
let _ = cb.send(result);
Ok(())
});
tokio::spawn(fut);
tokio::spawn(fut.in_current_span());
Ok(())
})
.map_err(|e| println!("client error: {:?}", e));
runtime.block_on(work).expect("support client runtime");
runtime
.block_on(work.instrument(span))
.expect("support client runtime");
})
.expect("thread spawn");
(tx, running_rx)

View File

@ -1,4 +1,4 @@
use crate::support::*;
use super::*;
use bytes::IntoBuf;
use hyper::body::Payload;
use linkerd2_proxy_api::destination as pb;
@ -43,7 +43,7 @@ pub struct Controller {
pub struct Listening {
pub addr: SocketAddr,
shutdown: Shutdown,
_shutdown: Shutdown,
}
#[derive(Clone, Debug, Default)]
@ -300,7 +300,7 @@ impl pb::server::Destination for Controller {
}
}
pub(in crate::support) fn run<T, B>(
pub(in crate) fn run<T, B>(
svc: T,
name: &'static str,
delay: Option<Box<dyn Future<Item = (), Error = ()> + Send>>,
@ -363,7 +363,10 @@ where
listening_rx.wait().expect("listening_rx");
println!("{} listening; addr={:?}", name, addr);
Listening { addr, shutdown: tx }
Listening {
addr,
_shutdown: tx,
}
}
pub enum Hint {

View File

@ -1,5 +1,4 @@
use crate::support::*;
use super::*;
use std::{
collections::VecDeque,
fs, io,
@ -120,8 +119,7 @@ impl Identity {
.unwrap()
};
let mut id = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
id.push("tests");
id.push("support");
id.push("src");
id.push("data");
id.push("ca1.pem");

View File

@ -1,18 +1,15 @@
// The support mod is compiled for all the integration tests, which are each
// compiled as separate crates. Each only uses a subset of this module, which
// means some of it is unused.
//
// Note, lints like `unused_variable` should not be ignored.
//! Shared infrastructure for integration tests
#![deny(warnings, rust_2018_idioms)]
#![allow(dead_code)]
#![type_length_limit = "1070525"]
pub use bytes::Bytes;
pub use futures::sync::oneshot;
pub use futures::{future::Executor, *};
pub use http::{HeaderMap, Request, Response, StatusCode};
use http_body::Body as HttpBody;
pub use linkerd2_proxy::*;
pub use linkerd2_task::LazyExecutor;
pub use http_body::Body as HttpBody;
pub use linkerd2_app::Main;
pub use linkerd2_app_core::{self as app, task::LazyExecutor};
pub use std::collections::HashMap;
use std::fmt;
use std::io;
@ -24,8 +21,8 @@ use tokio::io::{AsyncRead, AsyncWrite};
use tokio::{net::TcpListener, reactor, runtime};
use tokio_connect::Connect;
use tokio_current_thread as current_thread;
pub use tower::Service;
pub use tower_grpc as grpc;
pub use tower_service::Service;
pub use tracing::*;
/// Environment variable for overriding the test patience.
@ -36,25 +33,24 @@ pub type Error = Box<dyn std::error::Error + Send + Sync + 'static>;
/// By default, disable logging in modules that are expected to error in tests.
const DEFAULT_LOG: &'static str = "error,\
linkerd2_proxy::proxy::canonicalize=off,\
linkerd2_proxy::proxy::http::router=off,\
linkerd2_proxy::proxy::tcp=off";
linkerd2_proxy_http=off,\
linkerd2_proxy_transport=off";
pub fn init_env() -> app::config::TestEnv {
let _ = trace_init();
app::config::TestEnv::new()
}
pub fn trace_init() -> (Dispatch, trace::LevelHandle) {
pub fn trace_init() -> (Dispatch, app::trace::LevelHandle) {
use std::env;
let log = env::var("LINKERD2_PROXY_LOG")
.or_else(|_| env::var("RUST_LOG"))
.unwrap_or_else(|_| DEFAULT_LOG.to_owned());
env::set_var("RUST_LOG", &log);
env::set_var("LINKERD2_PROXY_LOG", &log);
let _ = trace::init_log_compat();
trace::with_filter(&log)
// This may fail, since the global log compat layer may have been
// initialized by another test.
let _ = app::trace::init_log_compat();
app::trace::with_filter(&log)
}
/// Retry an assertion up to a specified number of times, waiting
@ -82,7 +78,7 @@ macro_rules! assert_eventually {
use std::time::{Instant, Duration};
use std::str::FromStr;
// TODO: don't do this *every* time eventually is called (lazy_static?)
let patience = env::var($crate::support::ENV_TEST_PATIENCE_MS).ok()
let patience = env::var($crate::ENV_TEST_PATIENCE_MS).ok()
.map(|s| {
let millis = u64::from_str(&s)
.expect(
@ -91,7 +87,7 @@ macro_rules! assert_eventually {
);
Duration::from_millis(millis)
})
.unwrap_or($crate::support::DEFAULT_TEST_PATIENCE);
.unwrap_or($crate::DEFAULT_TEST_PATIENCE);
let start_t = Instant::now();
for i in 0..($retries + 1) {
if $cond {
@ -99,7 +95,7 @@ macro_rules! assert_eventually {
} else if i == $retries {
panic!(
"assertion failed after {} (retried {} times): {}",
crate::support::HumanDuration(start_t.elapsed()),
crate::HumanDuration(start_t.elapsed()),
i,
format_args!($($arg)+)
)
@ -182,12 +178,12 @@ impl AsyncWrite for RunningIo {
}
pub fn shutdown_signal() -> (Shutdown, ShutdownRx) {
let (tx, rx) = oneshot::channel();
(Shutdown { tx }, Box::new(rx.then(|_| Ok(()))))
let (_tx, rx) = oneshot::channel();
(Shutdown { _tx }, Box::new(rx.then(|_| Ok(()))))
}
pub struct Shutdown {
tx: oneshot::Sender<()>,
_tx: oneshot::Sender<()>,
}
impl Shutdown {

View File

@ -1,5 +1,4 @@
use crate::support::*;
use super::*;
use std::sync::{Arc, Mutex};
pub fn new() -> Proxy {
@ -35,7 +34,7 @@ pub struct Listening {
pub outbound_server: Option<server::Listening>,
pub inbound_server: Option<server::Listening>,
shutdown: Shutdown,
_shutdown: Shutdown,
}
impl Proxy {
@ -148,11 +147,8 @@ struct DstInner {
outbound_local_addr: Option<SocketAddr>,
}
impl linkerd2_proxy_transport::GetOriginalDst for MockOriginalDst {
fn get_original_dst(
&self,
sock: &dyn linkerd2_proxy_transport::AddrInfo,
) -> Option<SocketAddr> {
impl app::transport::GetOriginalDst for MockOriginalDst {
fn get_original_dst(&self, sock: &dyn app::transport::AddrInfo) -> Option<SocketAddr> {
sock.local_addr().ok().and_then(|local| {
let inner = self.0.lock().unwrap();
if inner.inbound_local_addr == Some(local) {
@ -245,6 +241,7 @@ fn run(proxy: Proxy, mut env: app::config::TestEnv) -> Listening {
}
let config = app::config::Config::parse(&env).unwrap();
let (trace, trace_handle) = super::trace_init();
let (running_tx, running_rx) = oneshot::channel();
let (tx, mut rx) = shutdown_signal();
@ -257,52 +254,51 @@ fn run(proxy: Proxy, mut env: app::config::TestEnv) -> Listening {
::std::thread::Builder::new()
.name(tname)
.spawn(move || {
let _c = controller;
let _i = identity;
tracing::dispatcher::with_default(&trace, || {
let _c = controller;
let _i = identity;
let mock_orig_dst = MockOriginalDst(Arc::new(Mutex::new(mock_orig_dst)));
// TODO: a mock timer could be injected here?
let runtime =
tokio::runtime::current_thread::Runtime::new().expect("initialize main runtime");
// TODO: it would be nice for this to not be stubbed out, so that it
// can be tested.
let trace_handle = super::trace::LevelHandle::dangling();
let main = linkerd2_proxy::app::Main::new(config, trace_handle, runtime)
.with_original_dst_from(mock_orig_dst.clone());
let mock_orig_dst = MockOriginalDst(Arc::new(Mutex::new(mock_orig_dst)));
// TODO: a mock timer could be injected here?
let runtime = tokio::runtime::current_thread::Runtime::new()
.expect("initialize main runtime");
let main = linkerd2_app::Main::new(config, trace_handle, runtime)
.with_original_dst_from(mock_orig_dst.clone());
let control_addr = main.control_addr();
let identity_addr = identity_addr;
let inbound_addr = main.inbound_addr();
let outbound_addr = main.outbound_addr();
let metrics_addr = main.metrics_addr();
let control_addr = main.control_addr();
let identity_addr = identity_addr;
let inbound_addr = main.inbound_addr();
let outbound_addr = main.outbound_addr();
let metrics_addr = main.metrics_addr();
{
let mut inner = mock_orig_dst.0.lock().unwrap();
inner.inbound_local_addr = Some(inbound_addr);
inner.outbound_local_addr = Some(outbound_addr);
}
// slip the running tx into the shutdown future, since the first time
// the shutdown future is polled, that means all of the proxy is now
// running.
let addrs = (
control_addr,
identity_addr,
inbound_addr,
outbound_addr,
metrics_addr,
);
let mut running = Some((running_tx, addrs));
let on_shutdown = future::poll_fn(move || {
if let Some((tx, addrs)) = running.take() {
let _ = tx.send(addrs);
{
let mut inner = mock_orig_dst.0.lock().unwrap();
inner.inbound_local_addr = Some(inbound_addr);
inner.outbound_local_addr = Some(outbound_addr);
}
try_ready!(rx.poll());
Ok(().into())
});
// slip the running tx into the shutdown future, since the first time
// the shutdown future is polled, that means all of the proxy is now
// running.
let addrs = (
control_addr,
identity_addr,
inbound_addr,
outbound_addr,
metrics_addr,
);
let mut running = Some((running_tx, addrs));
let on_shutdown = future::poll_fn(move || {
if let Some((tx, addrs)) = running.take() {
let _ = tx.send(addrs);
}
main.run_until(on_shutdown);
try_ready!(rx.poll());
Ok(().into())
});
main.run_until(on_shutdown);
})
})
.unwrap();
@ -339,6 +335,6 @@ fn run(proxy: Proxy, mut env: app::config::TestEnv) -> Listening {
outbound_server: proxy.outbound_server,
inbound_server: proxy.inbound_server,
shutdown: tx,
_shutdown: tx,
}
}

View File

@ -1,4 +1,4 @@
use crate::support::*;
use super::*;
use futures::future::Either;
use rustls::ServerConfig;
use std::collections::HashMap;
@ -8,7 +8,6 @@ use std::sync::Arc;
use std::thread;
use tokio::net::TcpStream;
use tokio_rustls::TlsAcceptor;
use RunningIo;
pub fn new() -> Server {
http2()
@ -42,7 +41,7 @@ pub struct Server {
pub struct Listening {
pub addr: SocketAddr,
pub(super) shutdown: Shutdown,
pub(super) _shutdown: Shutdown,
pub(super) conn_count: Arc<AtomicUsize>,
}
@ -222,7 +221,7 @@ impl Server {
Listening {
addr,
shutdown: tx,
_shutdown: tx,
conn_count,
}
}

View File

@ -1,5 +1,4 @@
use crate::support::*;
use super::*;
use bytes::{BufMut, BytesMut};
use linkerd2_proxy_api::tap as pb;
@ -189,7 +188,7 @@ impl TapEventExt for pb::TapEvent {
struct SyncSvc(client::Client);
impl<B> tower_service::Service<http::Request<B>> for SyncSvc
impl<B> tower::Service<http::Request<B>> for SyncSvc
where
B: grpc::Body,
{

View File

@ -1,4 +1,4 @@
use crate::support::*;
use super::*;
use futures::sync::{mpsc, oneshot};
use std::collections::VecDeque;
use std::io;
@ -272,7 +272,7 @@ fn run_server(tcp: TcpServer) -> server::Listening {
server::Listening {
addr,
shutdown: tx,
_shutdown: tx,
conn_count,
}
}

View File

@ -1,11 +1,8 @@
#![deny(warnings, rust_2018_idioms)]
#![recursion_limit = "128"]
#![type_length_limit = "1070525"]
#![type_length_limit = "1110183"]
#[macro_use]
mod support;
use self::support::*;
use linkerd2_app_integration::*;
macro_rules! generate_tests {
(server: $make_server:path, client: $make_client:path) => {
@ -653,7 +650,7 @@ macro_rules! generate_tests {
}
mod http2 {
use super::support::*;
use linkerd2_app_integration::*;
generate_tests! { server: server::new, client: client::new }
@ -710,14 +707,14 @@ mod http2 {
}
mod http1 {
use super::support::*;
use linkerd2_app_integration::*;
generate_tests! {
server: server::http1, client: client::http1
}
mod absolute_uris {
use super::super::support::*;
use linkerd2_app_integration::*;
generate_tests! {
server: server::http1,

View File

@ -1,11 +1,8 @@
#![deny(warnings, rust_2018_idioms)]
#![recursion_limit = "128"]
#![type_length_limit = "1070525"]
#![type_length_limit = "1110183"]
#[macro_use]
mod support;
use self::support::*;
use linkerd2_app_integration::*;
use std::{
sync::{
atomic::{AtomicBool, Ordering},

View File

@ -1,10 +1,8 @@
#![deny(warnings, rust_2018_idioms)]
#![recursion_limit = "128"]
#![type_length_limit = "1070525"]
#![type_length_limit = "1110183"]
mod support;
use self::support::*;
use linkerd2_app_integration::*;
use linkerd2_proxy_api::destination as pb;
use std::sync::atomic::{AtomicUsize, Ordering};

View File

@ -1,10 +1,8 @@
#![deny(warnings, rust_2018_idioms)]
#![recursion_limit = "128"]
#![type_length_limit = "1070525"]
mod support;
use self::support::*;
#![type_length_limit = "1110183"]
use linkerd2_app_integration::*;
use std::sync::atomic::{AtomicUsize, Ordering};
macro_rules! profile_test {

View File

@ -1,9 +1,8 @@
#![deny(warnings, rust_2018_idioms)]
#![recursion_limit = "128"]
#![type_length_limit = "1070525"]
#![type_length_limit = "1110183"]
mod support;
use self::support::*;
use linkerd2_app_integration::*;
#[test]
fn h2_goaways_connections() {

View File

@ -1,11 +1,9 @@
#![deny(warnings, rust_2018_idioms)]
#![recursion_limit = "128"]
#![type_length_limit = "1070525"]
#![type_length_limit = "1110183"]
mod support;
use self::support::*;
use crate::support::tap::TapEventExt;
use linkerd2_app_integration::tap::TapEventExt;
use linkerd2_app_integration::*;
use std::time::SystemTime;
#[test]

View File

@ -1,12 +1,13 @@
#![deny(warnings, rust_2018_idioms)]
#![recursion_limit = "128"]
#![type_length_limit = "1070525"]
#![type_length_limit = "1110183"]
// The compiler cannot figure out that the `use linkerd2_app_integration::*`
// import is actually used, and putting the allow attribute on that import in
// particular appears to do nothing... T_T
#![allow(unused_imports)]
#[macro_use]
mod support;
use self::support::*;
use bytes::IntoBuf;
use linkerd2_app_integration::*;
use std::io::Read;
struct Fixture {
@ -143,8 +144,8 @@ fn metrics_endpoint_outbound_request_count() {
}
mod response_classification {
use super::support::*;
use super::Fixture;
use linkerd2_app_integration::*;
use tracing::info;
const REQ_STATUS_HEADER: &'static str = "x-test-status-requested";
@ -431,9 +432,9 @@ fn metrics_endpoint_outbound_response_latency() {
// Tests for destination labels provided by control plane service discovery.
mod outbound_dst_labels {
use super::support::*;
use super::Fixture;
use controller::DstSender;
use linkerd2_app_integration::*;
fn fixture(dest: &str) -> (Fixture, SocketAddr, DstSender) {
info!("running test server");
@ -728,8 +729,8 @@ fn metrics_has_start_time() {
}
mod transport {
use super::support::*;
use super::*;
use linkerd2_app_integration::*;
#[test]
fn inbound_http_accept() {

View File

@ -1,10 +1,8 @@
#![deny(warnings, rust_2018_idioms)]
#![recursion_limit = "128"]
#![type_length_limit = "1070525"]
#![type_length_limit = "1110183"]
#[macro_use]
mod support;
use self::support::*;
use linkerd2_app_integration::*;
use std::error::Error as _;
use std::sync::mpsc;
@ -890,13 +888,13 @@ macro_rules! http1_tests {
}
mod one_proxy {
use super::support::*;
use linkerd2_app_integration::*;
http1_tests! { proxy: |srv| proxy::new().inbound(srv).run() }
}
mod proxy_to_proxy {
use super::support::*;
use linkerd2_app_integration::*;
struct ProxyToProxy {
// Held to prevent closing, to reduce controller request noise during

View File

@ -0,0 +1,24 @@
[package]
name = "linkerd2-app-outbound"
version = "0.1.0"
authors = ["Linkerd Developers <cncf-linkerd-dev@lists.cncf.io>"]
edition = "2018"
publish = false
description = """
Configures and runs the outbound proxy
"""
[dependencies]
bytes = "0.4"
http = "0.1"
futures = "0.1"
indexmap = "1.0"
linkerd2-app-core = { path = "../core" }
opencensus-proto = { path = "../../../opencensus-proto" }
tokio = "0.1.14"
tower = "0.1"
tower-grpc = { version = "0.1", default-features = false, features = ["protobuf"] }
tracing = "0.1.9"
[dev-dependencies]
quickcheck = { version = "0.8", default-features = false }

View File

@ -1,11 +1,13 @@
//! Adds `l5d-remote-ip` headers to http::Responses derived from the
//! `remote` of a `Source`.
use super::super::L5D_REMOTE_IP;
use super::Endpoint;
use crate::proxy::http::add_header::{self, response::ResHeader, Layer};
use bytes::Bytes;
use http::header::HeaderValue;
use linkerd2_app_core::{
proxy::http::add_header::{self, response::ResHeader, Layer},
L5D_REMOTE_IP,
};
pub fn layer() -> Layer<&'static str, Endpoint, ResHeader> {
add_header::response::layer(L5D_REMOTE_IP, |endpoint: &Endpoint| {

View File

@ -1,11 +1,12 @@
//! Adds `l5d-server-id` headers to http::Responses derived from the
//! TlsIdentity of an `Endpoint`.
use super::super::L5D_SERVER_ID;
use super::Endpoint;
use crate::proxy::http::add_header::{self, response::ResHeader, Layer};
use crate::Conditional;
use http::header::HeaderValue;
use linkerd2_app_core::{
proxy::http::add_header::{self, response::ResHeader, Layer},
Conditional, L5D_SERVER_ID,
};
use tracing::{debug, warn};
pub fn layer() -> Layer<&'static str, Endpoint, ResHeader> {

View File

@ -1,12 +1,15 @@
use crate::api_resolve::{Metadata, ProtocolHint};
use crate::app::dst::{DstAddr, Route};
use crate::app::L5D_REQUIRE_ID;
use crate::proxy::http::{identity_from_header, settings};
use crate::transport::{connect, tls, Source};
use crate::{identity, tap};
use crate::{Conditional, NameAddr};
use indexmap::IndexMap;
use linkerd2_proxy_resolve::map_endpoint::MapEndpoint;
use linkerd2_app_core::{
api_resolve::{Metadata, ProtocolHint},
dst::{DstAddr, Route},
identity,
metric_labels::{prefix_labels, EndpointLabels},
proxy::http::{identity_from_header, settings},
resolve::map_endpoint::MapEndpoint,
tap,
transport::{connect, tls, Source},
Conditional, NameAddr, L5D_REQUIRE_ID,
};
use std::net::SocketAddr;
use std::sync::Arc;
@ -172,3 +175,16 @@ impl MapEndpoint<DstAddr, Metadata> for FromMetadata {
}
}
}
impl Into<EndpointLabels> for Endpoint {
fn into(self) -> EndpointLabels {
use linkerd2_app_core::metric_labels::{Direction, TlsId};
EndpointLabels {
dst_logical: self.dst_logical,
dst_concrete: self.dst_concrete,
direction: Direction::Out,
tls_id: self.identity.as_ref().map(|id| TlsId::ServerId(id.clone())),
labels: prefix_labels("dst", self.metadata.labels().into_iter()),
}
}
}

View File

@ -1,15 +1,30 @@
use super::spans::SpanConverter;
use super::{classify, config::Config, dst::DstAddr, errors, identity, serve, DispatchDeadline};
use crate::core::resolve::Resolve;
use crate::proxy::http::{
balance, canonicalize, client, fallback, header_from_target, insert, metrics as http_metrics,
normalize_uri, profiles, retry, router, settings, strip_header,
//! Configures and runs the outbound proxy.
//!
//! The outound proxy is responsible for routing traffic from the local
//! application to external network endpoints.
#![deny(warnings, rust_2018_idioms)]
use linkerd2_app_core::{
classify,
config::Config,
core::resolve::Resolve,
discover, dns, drain,
dst::DstAddr,
errors, http_request_authority_addr, http_request_host_addr,
http_request_l5d_override_dst_addr, http_request_orig_dst_addr, identity,
proxy::http::{
balance, canonicalize, client, fallback, header_from_target, insert,
metrics as http_metrics, normalize_uri, profiles, retry, router, settings, strip_header,
},
proxy::{self, Server},
reconnect, serve,
spans::SpanConverter,
svc, trace, trace_context,
transport::{self as transport, connect, tls, Source},
Addr, Conditional, DispatchDeadline, CANONICAL_DST_HEADER, DST_OVERRIDE_HEADER, L5D_CLIENT_ID,
L5D_REMOTE_IP, L5D_REQUIRE_ID, L5D_SERVER_ID,
};
use crate::proxy::{self, Server};
use crate::transport::{self, connect, tls, Source};
use crate::{drain, svc, trace, trace_context, Addr, Conditional};
use linkerd2_proxy_discover as discover;
use linkerd2_reconnect as reconnect;
use opencensus_proto::trace::v1 as oc;
use std::collections::HashMap;
use std::time::Duration;
@ -38,14 +53,14 @@ pub fn spawn<R, P>(
listen: transport::Listen,
get_original_dst: impl transport::GetOriginalDst + Send + 'static,
resolve: R,
dns_resolver: crate::dns::Resolver,
profiles_client: super::profiles::Client<P>,
tap_layer: crate::tap::Layer,
dns_resolver: dns::Resolver,
profiles_client: linkerd2_app_core::profiles::Client<P>,
tap_layer: linkerd2_app_core::tap::Layer,
handle_time: http_metrics::handle_time::Scope,
endpoint_http_metrics: super::HttpEndpointMetricsRegistry,
route_http_metrics: super::HttpRouteMetricsRegistry,
retry_http_metrics: super::HttpRouteMetricsRegistry,
transport_metrics: transport::MetricsRegistry,
endpoint_http_metrics: linkerd2_app_core::HttpEndpointMetricsRegistry,
route_http_metrics: linkerd2_app_core::HttpRouteMetricsRegistry,
retry_http_metrics: linkerd2_app_core::HttpRouteMetricsRegistry,
transport_metrics: linkerd2_app_core::transport::MetricsRegistry,
span_sink: Option<mpsc::Sender<oc::Span>>,
drain: drain::Watch,
) where
@ -104,9 +119,9 @@ pub fn spawn<R, P>(
// the server, before we apply our own.
let endpoint_stack = client_stack
.serves::<Endpoint>()
.push(strip_header::response::layer(super::L5D_REMOTE_IP))
.push(strip_header::response::layer(super::L5D_SERVER_ID))
.push(strip_header::request::layer(super::L5D_REQUIRE_ID))
.push(strip_header::response::layer(L5D_REMOTE_IP))
.push(strip_header::response::layer(L5D_SERVER_ID))
.push(strip_header::request::layer(L5D_REQUIRE_ID))
// disabled due to information leagkage
//.push(add_remote_ip_on_rsp::layer())
//.push(add_server_id_on_rsp::layer())
@ -191,7 +206,7 @@ pub fn spawn<R, P>(
profiles_client,
dst_route_layer,
))
.push(header_from_target::layer(super::CANONICAL_DST_HEADER));
.push(header_from_target::layer(CANONICAL_DST_HEADER));
// Routes request using the `DstAddr` extension.
//
@ -217,7 +232,7 @@ pub fn spawn<R, P>(
// Canonicalizes the request-specified `Addr` via DNS, and
// annotates each request with a refined `Addr` so that it may be
// routed by the dst_router.
let addr_stack = svc::stack(svc::shared(dst_router))
let addr_stack = svc::stack(svc::Shared::new(dst_router))
.push(canonicalize::layer(dns_resolver, canonicalize_timeout));
// Routes requests to an `Addr`:
@ -236,22 +251,22 @@ pub fn spawn<R, P>(
// 5. Finally, if the Source had an SO_ORIGINAL_DST, this TCP
// address is used.
let addr_router = addr_stack
.push(strip_header::request::layer(super::L5D_CLIENT_ID))
.push(strip_header::request::layer(super::DST_OVERRIDE_HEADER))
.push(strip_header::request::layer(L5D_CLIENT_ID))
.push(strip_header::request::layer(DST_OVERRIDE_HEADER))
.push(insert::target::layer())
.push(trace::layer(|addr: &Addr| info_span!("addr", %addr)))
.push_buffer_pending(max_in_flight, DispatchDeadline::extract)
.push(router::layer(
router::Config::new(capacity, max_idle_age),
|req: &http::Request<_>| {
super::http_request_l5d_override_dst_addr(req)
http_request_l5d_override_dst_addr(req)
.map(|override_addr| {
debug!("using dst-override");
override_addr
})
.or_else(|_| super::http_request_authority_addr(req))
.or_else(|_| super::http_request_host_addr(req))
.or_else(|_| super::http_request_orig_dst_addr(req))
.or_else(|_| http_request_authority_addr(req))
.or_else(|_| http_request_host_addr(req))
.or_else(|_| http_request_orig_dst_addr(req))
.ok()
},
))
@ -270,7 +285,7 @@ pub fn spawn<R, P>(
// Instantiates an HTTP service for each `Source` using the
// shared `addr_router`. The `Source` is stored in the request's
// extensions so that it can be used by the `addr_router`.
let server_stack = svc::stack(svc::shared(admission_control))
let server_stack = svc::stack(svc::Shared::new(admission_control))
.push(insert::layer(move || {
DispatchDeadline::after(dispatch_timeout)
}))

View File

@ -1,20 +1,17 @@
use super::super::L5D_REQUIRE_ID;
use super::Endpoint;
use crate::proxy::http::{identity_from_header, HasH2Reason};
use crate::transport::tls::{self, HasPeerIdentity};
use crate::{identity, svc, Conditional, Error};
use futures::{
future::{self, Either, FutureResult},
try_ready, Async, Future, Poll,
};
use linkerd2_app_core::{
errors,
proxy::http::identity_from_header,
svc,
transport::tls::{self, HasPeerIdentity},
Conditional, Error, L5D_REQUIRE_ID,
};
use std::marker::PhantomData;
use tracing::{debug, warn};
#[derive(Debug)]
pub struct RequireIdentityError {
require_identity: identity::Name,
peer_identity: Option<identity::Name>,
}
use tracing::debug;
pub struct Layer<A, B>(PhantomData<fn(A) -> B>);
@ -155,22 +152,25 @@ where
match self.peer_identity {
Conditional::Some(ref peer_identity) => {
if require_identity != *peer_identity {
warn!(
"require identity check failed; found peer_identity={:?}",
peer_identity
let message = format!(
"require identity check failed; require={:?} found={:?}",
require_identity, peer_identity
);
return Either::A(future::err(RequireIdentityError::new(
require_identity,
Some(peer_identity.clone()),
)));
let e = errors::StatusError {
message,
status: http::StatusCode::FORBIDDEN,
};
return Either::A(future::err(e.into()));
}
}
Conditional::None(_) => {
warn!("require identity check failed; no peer_identity found");
return Either::A(future::err(RequireIdentityError::new(
require_identity,
None,
)));
let message =
"require identity check failed; no peer_identity found".to_string();
let e = errors::StatusError {
message,
status: http::StatusCode::FORBIDDEN,
};
return Either::A(future::err(e.into()));
}
}
}
@ -178,34 +178,3 @@ where
Either::B(self.inner.call(request).map_err(Into::into))
}
}
// ===== impl RequireIdentityError =====
impl RequireIdentityError {
fn new(require_identity: identity::Name, peer_identity: Option<identity::Name>) -> Error {
let error = RequireIdentityError {
require_identity,
peer_identity,
};
error.into()
}
}
impl std::error::Error for RequireIdentityError {}
impl std::fmt::Display for RequireIdentityError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"require identity check failed; require={:?} found={:?}",
self.require_identity, self.peer_identity
)
}
}
impl HasH2Reason for RequireIdentityError {
fn h2_reason(&self) -> Option<h2::Reason> {
(self as &(dyn std::error::Error + 'static)).h2_reason()
}
}

View File

@ -1,13 +1,15 @@
use super::endpoint;
use crate::api_resolve::Metadata;
use crate::app::dst::DstAddr;
use crate::dns::Suffix;
use indexmap::IndexSet;
use linkerd2_error::{Error, Recover};
use linkerd2_exp_backoff::{ExponentialBackoff, ExponentialBackoffStream};
use linkerd2_proxy_core::{resolve, Resolve};
use linkerd2_proxy_resolve::{map_endpoint, recover};
use linkerd2_request_filter as request_filter;
use linkerd2_app_core::{
api_resolve::Metadata,
core::{resolve, Resolve},
dns::Suffix,
dst::DstAddr,
exp_backoff::{ExponentialBackoff, ExponentialBackoffStream},
request_filter,
resolve::{map_endpoint, recover},
Error, Recover,
};
use std::sync::Arc;
use tower_grpc as grpc;

View File

@ -1,19 +1,28 @@
use super::admin::{Admin, Readiness};
use super::classify::{self, Class};
use super::config::Config;
use super::metric_labels::{ControlLabels, EndpointLabels, RouteLabels};
use super::profiles::Client as ProfilesClient;
use super::{control, handle_time, identity, inbound, outbound, serve};
use crate::opencensus::SpanExporter;
use crate::proxy::{self, http::metrics as http_metrics};
use crate::svc::{self, LayerExt};
use crate::transport::{self, connect, tls, GetOriginalDst, Listen};
use crate::{
api_resolve, dns, drain, metrics::FmtMetrics, tap, task, telemetry, trace, Conditional,
};
//! Configures and executes the proxy
#![deny(warnings, rust_2018_idioms)]
use futures::{self, future, Future};
use linkerd2_opencensus as opencensus;
use linkerd2_reconnect as reconnect;
pub use linkerd2_app_core::init;
use linkerd2_app_core::{
admin::{Admin, Readiness},
api_resolve,
classify::{self, Class},
config::Config,
control, dns, drain, handle_time, identity,
metric_labels::{ControlLabels, EndpointLabels, RouteLabels},
metrics::FmtMetrics,
opencensus::{self, SpanExporter},
profiles::Client as ProfilesClient,
proxy::{self, http::metrics as http_metrics},
reconnect, serve,
svc::{self, LayerExt},
tap, task, telemetry, trace,
transport::{self, connect, tls, GetOriginalDst, Listen},
Conditional,
};
use linkerd2_app_inbound as inbound;
use linkerd2_app_outbound as outbound;
use opencensus_proto::agent::common::v1 as oc;
use std::net::SocketAddr;
use std::thread;
@ -406,7 +415,7 @@ where
info_span!("dns").in_scope(|| {
trace!("spawning");
tokio::spawn(dns_bg.in_current_span());
tokio::spawn(dns_bg);
});
if let Some(d) = identity_daemon {

View File

@ -1,3 +1,5 @@
#![deny(warnings, rust_2018_idioms)]
/// Like `std::option::Option<C>` but `None` carries a reason why the value
/// isn't available.
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]

14
linkerd/dns/Cargo.toml Normal file
View File

@ -0,0 +1,14 @@
[package]
name = "linkerd2-dns"
version = "0.1.0"
authors = ["Linkerd Developers <cncf-linkerd-dev@lists.cncf.io>"]
edition = "2018"
publish = false
[dependencies]
futures = "0.1"
linkerd2-dns-name = { path = "./name" }
# FIXME update to a release when available (>0.11)
trust-dns-resolver = { git = "https://github.com/bluejekyll/trust-dns", rev = "7c8a0739dad495bf5a4fddfe86b8bbe2aa52d060", default-features = false }
tracing = "0.1"
tracing-futures = "0.1"

Some files were not shown because too many files have changed in this diff Show More