Move the Rust gRPC bindings to a dedicated crate (#275)

The proxy depends on `protoc`-generated gRPC bindings to communicate
with the controller. In order to generate these bindings, build-time
dependencies must be compiled.

In order to support a more granular, cacheable build scheme, a new crate
has been created to house these gRPC bindings,
`conduit-proxy-controller-grpc`.

Because `TryFrom` and `TryInto` conversions are implemented for
protobuf-defined types, the `convert` module also had to be moved to
into a dedicated crate.

Furthermore, because the proxy's tests require that
`quickcheck::Aribtrary` be implemented for protobuf types, the
`conduit-proxy-controller-grpc` crate supports an _arbitrary_ feature
fla protobuf types, the `conduit-proxy-controller-grpc` crate supports
an _arbitrary_ feature flag.

While we're moving these libraries around, the `tower-router` crate has
been moved to `proxy/router` and renamed to `conduit-proxy-router.`
`futures-mpsc-lossy` has been moved into the proxy directory but has not
been renamed.

Finally, the `proxy/Dockerfile-deps` image has been updated to avoid the
wasteful building of dependency artifacts, as they are not actually used
by `proxy/Dockerfile`.
This commit is contained in:
Oliver Gould 2018-02-06 10:31:48 -08:00 committed by GitHub
parent c52600eb78
commit e2093e37f8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 686 additions and 613 deletions

View File

@ -51,13 +51,6 @@ written in Go. The dashboard UI is a React application.
- [`proxy`](proxy): High-performance data plane, injected as a sidecar with
every service.
- [`tower-grpc`](tower-grpc): A client and server gRPC implementation based on
Tower.
- [`tower-grpc-examples`](tower-grpc-examples): Demonstrates how to use Tower
gRPC clients and servers with code generation.
- [`tower-h2`](tower-h2): Tower `Service` abstractions for HTTP/2 and Rust.
- [`tower-router`](tower-router): A Tower middleware that routes requests to
one of a set of inner services using a request predicate.
# Components

56
Cargo.lock generated
View File

@ -128,6 +128,9 @@ dependencies = [
"abstract-ns 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"conduit-proxy-controller-grpc 0.2.0",
"conduit-proxy-router 0.2.0",
"convert 0.2.0",
"domain 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
@ -142,9 +145,8 @@ dependencies = [
"ns-dns-tokio 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ordermap 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
"prost 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"prost-derive 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"prost-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"quickcheck 0.4.2 (git+https://github.com/BurntSushi/quickcheck?rev=a1658ce)",
"quickcheck 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-connect 0.1.0 (git+https://github.com/carllerche/tokio-connect)",
"tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
@ -153,14 +155,43 @@ dependencies = [
"tower-buffer 0.1.0 (git+https://github.com/tower-rs/tower)",
"tower-discover 0.1.0 (git+https://github.com/tower-rs/tower)",
"tower-grpc 0.1.0 (git+https://github.com/tower-rs/tower-grpc)",
"tower-grpc-build 0.1.0 (git+https://github.com/tower-rs/tower-grpc)",
"tower-h2 0.1.0 (git+https://github.com/tower-rs/tower-h2)",
"tower-reconnect 0.1.0 (git+https://github.com/tower-rs/tower)",
"tower-router 0.2.0",
"tower-util 0.1.0 (git+https://github.com/tower-rs/tower)",
"url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "conduit-proxy-controller-grpc"
version = "0.2.0"
dependencies = [
"bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"convert 0.2.0",
"futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
"h2 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"http 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"prost 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"prost-derive 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"prost-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"quickcheck 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-grpc 0.1.0 (git+https://github.com/tower-rs/tower-grpc)",
"tower-grpc-build 0.1.0 (git+https://github.com/tower-rs/tower-grpc)",
"tower-h2 0.1.0 (git+https://github.com/tower-rs/tower-h2)",
]
[[package]]
name = "conduit-proxy-router"
version = "0.2.0"
dependencies = [
"futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
"ordermap 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
"tower 0.1.0 (git+https://github.com/tower-rs/tower)",
]
[[package]]
name = "convert"
version = "0.2.0"
[[package]]
name = "crc"
version = "1.7.0"
@ -710,12 +741,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "quickcheck"
version = "0.4.2"
source = "git+https://github.com/BurntSushi/quickcheck?rev=a1658ce#a1658ce9fc9ab41fd3aa1faeaa326fcf28dfcd45"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1051,15 +1082,6 @@ dependencies = [
"tower 0.1.0 (git+https://github.com/tower-rs/tower)",
]
[[package]]
name = "tower-router"
version = "0.2.0"
dependencies = [
"futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
"ordermap 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
"tower 0.1.0 (git+https://github.com/tower-rs/tower)",
]
[[package]]
name = "tower-util"
version = "0.1.0"
@ -1272,7 +1294,7 @@ dependencies = [
"checksum prost-derive 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc57900c837af0e8bf5917e3d1fa45109cde500b36dc65621eb2775acde0d54d"
"checksum prost-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dc53b19b9de90ddbcdaa34120141cdcca68ad5f0de4859cc94f5417878958fc2"
"checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4"
"checksum quickcheck 0.4.2 (git+https://github.com/BurntSushi/quickcheck?rev=a1658ce)" = "<none>"
"checksum quickcheck 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "13f4460d3daa06eb1c4b9a3c55dffe65cb030dd70cf1bfdd482532f48ab24f74"
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
"checksum quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eca14c727ad12702eb4b6bfb5a232287dcf8385cb8ca83a3eeaf6519c44c408"
"checksum rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" = "512870020642bb8c221bf68baa1b2573da814f6ccfe5c9699b1c303047abe9b1"

View File

@ -1,6 +1,8 @@
[workspace]
members = [
"futures-mpsc-lossy",
"proxy",
"tower-router",
"proxy/convert",
"proxy/controller-grpc",
"proxy/futures-mpsc-lossy",
"proxy/router",
]

View File

@ -5,6 +5,11 @@ authors = ["Oliver Gould <ver@buoyant.io>"]
publish = false
[dependencies]
convert = { path = "./convert" }
conduit-proxy-controller-grpc = { path = "./controller-grpc" }
futures-mpsc-lossy = { path = "./futures-mpsc-lossy" }
conduit-proxy-router = { path = "./router" }
bytes = "0.4"
chrono = "0.4"
domain = "0.2.2"
@ -23,7 +28,6 @@ tokio-core = "0.1"
tokio-io = "0.1"
prost = "0.3.0"
prost-derive = "0.3.0"
prost-types = "0.3.0"
abstract-ns = "0.4"
@ -41,17 +45,9 @@ tower-h2 = { git = "https://github.com/tower-rs/tower-h2" }
tower-reconnect = { git = "https://github.com/tower-rs/tower" }
tower-util = { git = "https://github.com/tower-rs/tower" }
futures-mpsc-lossy = { path = "../futures-mpsc-lossy" }
tower-router = { path = "../tower-router" }
[target.'cfg(target_os = "linux")'.dependencies]
libc = "0.2"
[build-dependencies]
tower-grpc-build = { git = "https://github.com/tower-rs/tower-grpc" }
[dev-dependencies]
# Quickcheck 0.4.1, on crates.io, is missng useful Arbitrary implementations that exist on
# master.
quickcheck = { git = "https://github.com/BurntSushi/quickcheck", rev = "a1658ce" }
quickcheck = "0.6"
conduit-proxy-controller-grpc = { path = "./controller-grpc" , features = ["arbitrary"] }

View File

@ -5,12 +5,10 @@
## Build the rust proxy into a binary.
#
# If the RELEASE arg is set and non-empty, a release artifact is built.
FROM gcr.io/runconduit/proxy-deps:b84ed5d0 as build
FROM gcr.io/runconduit/proxy-deps:673c53de as build
WORKDIR /usr/src/conduit
# Ranked roughly from least to most likely to change. Cargo.lock is the least likely
# because it is supposed to be cached in the deps base image.
COPY futures-mpsc-lossy ./futures-mpsc-lossy
COPY tower-router ./tower-router
COPY proto ./proto
COPY proxy ./proxy
ARG RELEASE

View File

@ -10,21 +10,15 @@
# compile.
FROM rust:1.23.0 as build
WORKDIR /usr/src/conduit
COPY futures-mpsc-lossy ./futures-mpsc-lossy
COPY tower-router ./tower-router
COPY Cargo.toml Cargo.lock ./
COPY proto ./proto
COPY proxy ./proxy
RUN cargo fetch --locked
RUN cargo build --frozen -p conduit-proxy
RUN cargo build --frozen -p conduit-proxy --release
# Preserve dependency sources and build artifacts without maintaining conduit
# sources/artifacts.
FROM rust:1.23.0
WORKDIR /usr/src/conduit
COPY --from=build $CARGO_HOME $CARGO_HOME
COPY --from=build /usr/src/conduit/target/debug/deps target/debug/deps
COPY --from=build /usr/src/conduit/target/release/deps target/release/deps
COPY --from=build /usr/src/conduit/Cargo.toml Cargo.toml
COPY --from=build /usr/src/conduit/Cargo.lock Cargo.lock

View File

@ -0,0 +1,29 @@
[package]
name = "conduit-proxy-controller-grpc"
version = "0.2.0"
publish = false
[features]
default = []
arbitrary = ["quickcheck"]
[dependencies]
convert = { path = "../convert" }
bytes = "0.4"
futures = "0.1"
h2 = "0.1"
http = "0.1"
prost = "0.3.0"
prost-derive = "0.3.0"
prost-types = "0.3.0"
tower-grpc = { git = "https://github.com/tower-rs/tower-grpc" }
tower-h2 = { git = "https://github.com/tower-rs/tower-h2" }
quickcheck = { version = "0.6", optional = true }
[build-dependencies]
tower-grpc-build = { git = "https://github.com/tower-rs/tower-grpc" }

View File

@ -6,12 +6,12 @@ fn main() {
fn build_control() {
let client_files = &[
"../proto/common/common.proto",
"../proto/proxy/destination/destination.proto",
"../proto/proxy/telemetry/telemetry.proto",
"../../proto/common/common.proto",
"../../proto/proxy/destination/destination.proto",
"../../proto/proxy/telemetry/telemetry.proto",
];
let server_files = &["../proto/proxy/tap/tap.proto"];
let dirs = &["../proto"];
let server_files = &["../../proto/proxy/tap/tap.proto"];
let dirs = &["../../proto"];
tower_grpc_build::Config::new()
.enable_client(true)

View File

@ -0,0 +1,202 @@
#![cfg(feature = "arbitrary")]
use std::boxed::Box;
use quickcheck::*;
use super::common::*;
use super::tap::*;
impl Arbitrary for ObserveRequest {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
ObserveRequest {
limit: g.gen(),
match_: Arbitrary::arbitrary(g),
}
}
}
impl Arbitrary for observe_request::Match {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
observe_request::Match {
match_: Arbitrary::arbitrary(g),
}
}
}
impl Arbitrary for observe_request::match_::Match {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
match g.gen::<u32>() % 6 {
0 => observe_request::match_::Match::All(Arbitrary::arbitrary(g)),
1 => observe_request::match_::Match::Any(Arbitrary::arbitrary(g)),
2 => observe_request::match_::Match::Not(Box::new(Arbitrary::arbitrary(g))),
3 => observe_request::match_::Match::Source(Arbitrary::arbitrary(g)),
4 => observe_request::match_::Match::Destination(Arbitrary::arbitrary(g)),
5 => observe_request::match_::Match::Http(Arbitrary::arbitrary(g)),
_ => unreachable!(),
}
}
}
impl Arbitrary for observe_request::match_::Seq {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
observe_request::match_::Seq {
matches: Arbitrary::arbitrary(g),
}
}
fn shrink(&self) -> Box<Iterator<Item = Self>> {
Box::new(self.matches.shrink().map(|matches| {
observe_request::match_::Seq {
matches,
}
}))
}
}
impl Arbitrary for observe_request::match_::Tcp {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
observe_request::match_::Tcp {
match_: Arbitrary::arbitrary(g),
}
}
}
impl Arbitrary for observe_request::match_::tcp::Match {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
use self::observe_request::match_::tcp;
if g.gen::<bool>() {
tcp::Match::Netmask(Arbitrary::arbitrary(g))
} else {
tcp::Match::Ports(Arbitrary::arbitrary(g))
}
}
}
impl Arbitrary for observe_request::match_::tcp::PortRange {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
observe_request::match_::tcp::PortRange {
min: g.gen(),
max: g.gen(),
}
}
}
impl Arbitrary for observe_request::match_::tcp::Netmask {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
let ip: Option<IpAddress> = Arbitrary::arbitrary(g);
let mask = match ip.as_ref().and_then(|a| a.ip.as_ref()) {
Some(&ip_address::Ip::Ipv4(_)) => g.gen::<u32>() % 32 + 1,
Some(&ip_address::Ip::Ipv6(_)) => g.gen::<u32>() % 128 + 1,
None => 0u32,
};
observe_request::match_::tcp::Netmask {
ip,
mask,
}
}
}
impl Arbitrary for observe_request::match_::Http {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
observe_request::match_::Http {
match_: Arbitrary::arbitrary(g),
}
}
}
impl Arbitrary for observe_request::match_::http::Match {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
use self::observe_request::match_::http;
match g.gen::<u32>() % 4 {
0 => http::Match::Scheme(Scheme::arbitrary(g)),
1 => http::Match::Method(HttpMethod::arbitrary(g)),
2 => http::Match::Authority(http::StringMatch::arbitrary(g)),
3 => http::Match::Path(http::StringMatch::arbitrary(g)),
_ => unreachable!(),
}
}
}
impl Arbitrary for observe_request::match_::http::StringMatch {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
observe_request::match_::http::StringMatch {
match_: Arbitrary::arbitrary(g),
}
}
}
impl Arbitrary for observe_request::match_::http::string_match::Match {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
use self::observe_request::match_::http::string_match;
match g.gen::<u32>() % 2 {
0 => string_match::Match::Exact(String::arbitrary(g)),
1 => string_match::Match::Prefix(String::arbitrary(g)),
_ => unreachable!(),
}
}
}
impl Arbitrary for IpAddress {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
IpAddress {
ip: Arbitrary::arbitrary(g),
}
}
}
impl Arbitrary for ip_address::Ip {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
if g.gen::<bool>() {
ip_address::Ip::Ipv4(g.gen())
} else {
ip_address::Ip::Ipv6(IPv6::arbitrary(g))
}
}
}
impl Arbitrary for IPv6 {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
IPv6 {
first: g.gen(),
last: g.gen(),
}
}
}
impl Arbitrary for HttpMethod {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
HttpMethod {
type_: Arbitrary::arbitrary(g),
}
}
}
impl Arbitrary for http_method::Type {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
match g.gen::<u16>() % 9 {
8 => http_method::Type::Unregistered(String::arbitrary(g)),
n => http_method::Type::Registered(i32::from(n).into()),
}
}
}
impl Arbitrary for Scheme {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
Scheme {
type_: Arbitrary::arbitrary(g),
}
}
}
impl Arbitrary for scheme::Type {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
match g.gen::<u16>() % 3 {
3 => scheme::Type::Unregistered(String::arbitrary(g)),
n => scheme::Type::Registered(i32::from(n).into()),
}
}
}

View File

@ -0,0 +1,343 @@
extern crate convert;
extern crate h2;
extern crate http;
extern crate prost;
#[macro_use]
extern crate prost_derive;
extern crate prost_types;
#[cfg(feature = "arbitrary")]
extern crate quickcheck;
extern crate tower_grpc;
use convert::{TryFrom, TryInto};
use std::{fmt, hash};
use std::error::Error;
#[cfg(feature = "arbitrary")]
pub mod arbitrary;
pub use self::gen::*;
// The generated code requires two tiers of outer modules so that references between
// modules resolve properly.
mod gen {
pub mod common {
include!(concat!(env!("OUT_DIR"), "/conduit.common.rs"));
}
pub mod destination {
include!(concat!(env!("OUT_DIR"), "/conduit.proxy.destination.rs"));
}
pub mod tap {
include!(concat!(env!("OUT_DIR"), "/conduit.proxy.tap.rs"));
}
pub mod telemetry {
include!(concat!(env!("OUT_DIR"), "/conduit.proxy.telemetry.rs"));
}
}
/// Converts a Rust Duration to a Protobuf Duration.
pub fn pb_duration(d: &::std::time::Duration) -> ::prost_types::Duration {
let seconds = if d.as_secs() > ::std::i64::MAX as u64 {
::std::i64::MAX
} else {
d.as_secs() as i64
};
let nanos = if d.subsec_nanos() > ::std::i32::MAX as u32 {
::std::i32::MAX
} else {
d.subsec_nanos() as i32
};
::prost_types::Duration {
seconds,
nanos,
}
}
/// Indicates an HTTP Method could not be decoded.
#[derive(Debug, Clone)]
pub struct InvalidMethod;
/// Indicates a URI Scheme could not be decoded.
#[derive(Debug, Clone)]
pub struct InvalidScheme;
// ===== impl common::Eos =====
impl From<h2::Reason> for common::Eos {
fn from(reason: h2::Reason) -> Self {
let end = common::eos::End::ResetErrorCode(reason.into());
common::Eos { end: Some(end) }
}
}
impl common::Eos {
pub fn from_grpc_status(code: u32) -> Self {
let end = common::eos::End::GrpcStatusCode(code);
common::Eos { end: Some(end) }
}
}
// ===== impl common::IpAddress =====
impl<T> From<T> for common::IpAddress
where
common::ip_address::Ip: From<T>,
{
#[inline]
fn from(ip: T) -> Self {
Self {
ip: Some(ip.into()),
}
}
}
impl From<::std::net::IpAddr> for common::IpAddress {
fn from(ip: ::std::net::IpAddr) -> Self {
match ip {
::std::net::IpAddr::V4(v4) => Self {
ip: Some(v4.into()),
},
::std::net::IpAddr::V6(v6) => Self {
ip: Some(v6.into()),
},
}
}
}
impl From<[u8; 4]> for common::ip_address::Ip {
fn from(octets: [u8; 4]) -> Self {
common::ip_address::Ip::Ipv4(
u32::from(octets[0]) << 24 | u32::from(octets[1]) << 16 | u32::from(octets[2]) << 8
| u32::from(octets[3]),
)
}
}
// ===== impl common::ip_address:Ip =====
impl From<::std::net::Ipv4Addr> for common::ip_address::Ip {
#[inline]
fn from(v4: ::std::net::Ipv4Addr) -> Self {
Self::from(v4.octets())
}
}
impl<T> From<T> for common::ip_address::Ip
where
common::IPv6: From<T>,
{
#[inline]
fn from(t: T) -> Self {
common::ip_address::Ip::Ipv6(common::IPv6::from(t))
}
}
// ===== impl common::IPv6 =====
impl From<[u8; 16]> for common::IPv6 {
fn from(octets: [u8; 16]) -> Self {
let first = (u64::from(octets[0]) << 56) + (u64::from(octets[1]) << 48)
+ (u64::from(octets[2]) << 40) + (u64::from(octets[3]) << 32)
+ (u64::from(octets[4]) << 24) + (u64::from(octets[5]) << 16)
+ (u64::from(octets[6]) << 8) + u64::from(octets[7]);
let last = (u64::from(octets[8]) << 56) + (u64::from(octets[9]) << 48)
+ (u64::from(octets[10]) << 40) + (u64::from(octets[11]) << 32)
+ (u64::from(octets[12]) << 24) + (u64::from(octets[13]) << 16)
+ (u64::from(octets[14]) << 8) + u64::from(octets[15]);
Self {
first,
last,
}
}
}
impl From<::std::net::Ipv6Addr> for common::IPv6 {
#[inline]
fn from(v6: ::std::net::Ipv6Addr) -> Self {
Self::from(v6.octets())
}
}
impl<'a> From<&'a common::IPv6> for ::std::net::Ipv6Addr {
fn from(ip: &'a common::IPv6) -> ::std::net::Ipv6Addr {
::std::net::Ipv6Addr::new(
(ip.first >> 48) as u16,
(ip.first >> 32) as u16,
(ip.first >> 16) as u16,
(ip.first) as u16,
(ip.last >> 48) as u16,
(ip.last >> 32) as u16,
(ip.last >> 16) as u16,
(ip.last) as u16,
)
}
}
// ===== impl common::TcpAddress =====
impl<'a> From<&'a ::std::net::SocketAddr> for common::TcpAddress {
fn from(sa: &::std::net::SocketAddr) -> common::TcpAddress {
common::TcpAddress {
ip: Some(sa.ip().into()),
port: u32::from(sa.port()),
}
}
}
// ===== impl common::Protocol =====
impl hash::Hash for common::Protocol {
// it's necessary to implement Hash for Protocol as it's a field on
// ctx::Transport, which derives Hash.
fn hash<H: hash::Hasher>(&self, state: &mut H) {
(*self as i32).hash(state)
}
}
// ===== impl common::scheme::Type =====
impl<'a> TryInto<String> for &'a common::scheme::Type {
type Err = InvalidScheme;
fn try_into(self) -> Result<String, Self::Err> {
use self::common::scheme::*;
match *self {
Type::Registered(reg) => if reg == Registered::Http.into() {
Ok("http".into())
} else if reg == Registered::Https.into() {
Ok("https".into())
} else {
Err(InvalidScheme)
},
Type::Unregistered(ref s) => Ok(s.clone()),
}
}
}
// ===== impl common::HttpMethod =====
impl<'a> TryFrom<&'a common::http_method::Type> for http::Method {
type Err = InvalidMethod;
fn try_from(m: &'a common::http_method::Type) -> Result<Self, Self::Err> {
use self::common::http_method::*;
use http::HttpTryFrom;
match *m {
Type::Registered(reg) => if reg == Registered::Get.into() {
Ok(http::Method::GET)
} else if reg == Registered::Post.into() {
Ok(http::Method::POST)
} else if reg == Registered::Put.into() {
Ok(http::Method::PUT)
} else if reg == Registered::Delete.into() {
Ok(http::Method::DELETE)
} else if reg == Registered::Patch.into() {
Ok(http::Method::PATCH)
} else if reg == Registered::Options.into() {
Ok(http::Method::OPTIONS)
} else if reg == Registered::Connect.into() {
Ok(http::Method::CONNECT)
} else if reg == Registered::Head.into() {
Ok(http::Method::HEAD)
} else if reg == Registered::Trace.into() {
Ok(http::Method::TRACE)
} else {
Err(InvalidMethod)
},
Type::Unregistered(ref m) => {
HttpTryFrom::try_from(m.as_str()).map_err(|_| InvalidMethod)
}
}
}
}
impl<'a> From<&'a http::Method> for common::http_method::Type {
fn from(m: &'a http::Method) -> Self {
use self::common::http_method::*;
match *m {
http::Method::GET => Type::Registered(Registered::Get.into()),
http::Method::POST => Type::Registered(Registered::Post.into()),
http::Method::PUT => Type::Registered(Registered::Put.into()),
http::Method::DELETE => Type::Registered(Registered::Delete.into()),
http::Method::HEAD => Type::Registered(Registered::Head.into()),
http::Method::OPTIONS => Type::Registered(Registered::Options.into()),
http::Method::CONNECT => Type::Registered(Registered::Connect.into()),
http::Method::TRACE => Type::Registered(Registered::Trace.into()),
ref method => Type::Unregistered(method.as_str().into()),
}
}
}
impl<'a> From<&'a http::Method> for common::HttpMethod {
fn from(m: &'a http::Method) -> Self {
common::HttpMethod {
type_: Some(m.into()),
}
}
}
// ===== impl InvalidMethod =====
impl fmt::Display for InvalidMethod {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "invalid http method")
}
}
impl Error for InvalidMethod {
#[inline]
fn description(&self) -> &str {
"invalid http method"
}
}
// ===== impl common::Scheme =====
impl<'a> From<&'a http::uri::Scheme> for common::Scheme {
fn from(scheme: &'a http::uri::Scheme) -> Self {
scheme.as_ref().into()
}
}
impl<'a> From<&'a str> for common::scheme::Type {
fn from(s: &'a str) -> Self {
use self::common::scheme::*;
match s {
"http" => Type::Registered(Registered::Http.into()),
"https" => Type::Registered(Registered::Https.into()),
s => Type::Unregistered(s.into()),
}
}
}
impl<'a> From<&'a str> for common::Scheme {
fn from(s: &'a str) -> Self {
common::Scheme {
type_: Some(s.into()),
}
}
}
// ===== impl InvalidScheme =====
impl fmt::Display for InvalidScheme {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "invalid http scheme")
}
}
impl Error for InvalidScheme {
#[inline]
fn description(&self) -> &str {
"invalid http scheme"
}
}

4
proxy/convert/Cargo.toml Normal file
View File

@ -0,0 +1,4 @@
[package]
name = "convert"
version = "0.2.0"
publish = false

View File

@ -1,5 +1,5 @@
[package]
name = "tower-router"
name = "conduit-proxy-router"
version = "0.2.0"
authors = ["Carl Lerche <me@carllerche.com>"]
publish = false

View File

@ -10,6 +10,7 @@ use tower;
use tower_h2;
use tower_reconnect::Reconnect;
use conduit_proxy_controller_grpc;
use control;
use ctx;
use telemetry::{self, sensor};
@ -143,7 +144,7 @@ where
let client_ctx = ctx::transport::Client::new(
&self.ctx,
addr,
control::pb::proxy::common::Protocol::Http,
conduit_proxy_controller_grpc::common::Protocol::Http,
);
// Map a socket address to a connection.

View File

@ -12,10 +12,10 @@ use tower_grpc as grpc;
use fully_qualified_authority::FullyQualifiedAuthority;
use super::pb::common::{Destination, TcpAddress};
use super::pb::proxy::destination::Update as PbUpdate;
use super::pb::proxy::destination::update::Update as PbUpdate2;
use super::pb::proxy::destination::client::{Destination as DestinationSvc};
use conduit_proxy_controller_grpc::common::{Destination, TcpAddress};
use conduit_proxy_controller_grpc::destination::Update as PbUpdate;
use conduit_proxy_controller_grpc::destination::update::Update as PbUpdate2;
use conduit_proxy_controller_grpc::destination::client::{Destination as DestinationSvc};
/// A handle to start watching a destination for address changes.
#[derive(Clone, Debug)]
@ -415,7 +415,7 @@ where T: HttpService<RequestBody = BoxBody, ResponseBody = RecvBody>,
// ===== impl RxError =====
fn pb_to_sock_addr(pb: TcpAddress) -> Option<SocketAddr> {
use super::pb::common::ip_address::Ip;
use conduit_proxy_controller_grpc::common::ip_address::Ip;
use std::net::{Ipv4Addr, Ipv6Addr};
/*
current structure is:
@ -432,7 +432,6 @@ fn pb_to_sock_addr(pb: TcpAddress) -> Option<SocketAddr> {
port: u32,
}
*/
// oh gawd i wish ? worked with Options already...
match pb.ip {
Some(ip) => match ip.ip {
Some(Ip::Ipv4(octets)) => {
@ -465,4 +464,4 @@ fn pb_to_sock_addr(pb: TcpAddress) -> Option<SocketAddr> {
},
None => None,
}
}
}

View File

@ -28,7 +28,7 @@ mod telemetry;
use self::discovery::{Background as DiscoBg, Discovery, Watch};
pub use self::discovery::Bind;
pub use self::observe::Observe;
use self::pb::proxy::telemetry::ReportRequest;
use conduit_proxy_controller_grpc::telemetry::ReportRequest;
use self::telemetry::Telemetry;
pub struct Control {

View File

@ -5,8 +5,8 @@ use futures_mpsc_lossy;
use ordermap::OrderMap;
use tower_grpc::{self as grpc, Response};
use control::pb::common::TapEvent;
use control::pb::proxy::tap::{server, ObserveRequest};
use conduit_proxy_controller_grpc::common::TapEvent;
use conduit_proxy_controller_grpc::tap::{server, ObserveRequest};
use convert::*;
use ctx;
use telemetry::Event;

View File

@ -2,71 +2,14 @@
#![cfg_attr(feature = "cargo-clippy", allow(clippy))]
use std::error::Error;
use std::{fmt, hash};
use std::fmt;
use std::sync::Arc;
use http;
use h2;
use conduit_proxy_controller_grpc::*;
use convert::*;
use ctx;
use telemetry::{event, Event};
// re-export proxy here since we dont care about the other dirs
pub use self::proxy::*;
pub mod proxy {
// this is the struct expected by protoc, so make imports happy
pub mod common {
include!(concat!(env!("OUT_DIR"), "/conduit.common.rs"));
}
pub mod destination {
include!(concat!(env!("OUT_DIR"), "/conduit.proxy.destination.rs"));
}
pub mod tap {
include!(concat!(env!("OUT_DIR"), "/conduit.proxy.tap.rs"));
}
pub mod telemetry {
include!(concat!(env!("OUT_DIR"), "/conduit.proxy.telemetry.rs"));
}
}
#[derive(Debug, Clone)]
// TODO: do we want to carry the string if there is one?
pub struct InvalidMethod;
impl fmt::Display for InvalidMethod {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "invalid http method")
}
}
impl Error for InvalidMethod {
#[inline]
fn description(&self) -> &str {
"invalid http method"
}
}
#[derive(Debug, Clone)]
pub struct InvalidScheme;
impl fmt::Display for InvalidScheme {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "invalid http scheme")
}
}
impl Error for InvalidScheme {
#[inline]
fn description(&self) -> &str {
"invalid http scheme"
}
}
#[derive(Debug, Clone)]
pub struct UnknownEvent;
@ -85,7 +28,7 @@ impl Error for UnknownEvent {
impl event::StreamResponseEnd {
fn to_tap_event(&self, ctx: &Arc<ctx::http::Request>) -> common::TapEvent {
use self::common::{tap_event, Eos};
use ::conduit_proxy_controller_grpc::common::{tap_event, Eos};
let eos = self.grpc_status
.map(Eos::from_grpc_status)
@ -232,258 +175,3 @@ impl<'a> TryFrom<&'a Event> for common::TapEvent {
Ok(tap_ev)
}
}
impl<'a> TryFrom<&'a common::http_method::Type> for http::Method {
type Err = InvalidMethod;
fn try_from(m: &'a common::http_method::Type) -> Result<Self, Self::Err> {
use self::common::http_method::*;
use http::HttpTryFrom;
match *m {
Type::Registered(reg) => if reg == Registered::Get.into() {
Ok(http::Method::GET)
} else if reg == Registered::Post.into() {
Ok(http::Method::POST)
} else if reg == Registered::Put.into() {
Ok(http::Method::PUT)
} else if reg == Registered::Delete.into() {
Ok(http::Method::DELETE)
} else if reg == Registered::Patch.into() {
Ok(http::Method::PATCH)
} else if reg == Registered::Options.into() {
Ok(http::Method::OPTIONS)
} else if reg == Registered::Connect.into() {
Ok(http::Method::CONNECT)
} else if reg == Registered::Head.into() {
Ok(http::Method::HEAD)
} else if reg == Registered::Trace.into() {
Ok(http::Method::TRACE)
} else {
Err(InvalidMethod)
},
Type::Unregistered(ref m) => {
HttpTryFrom::try_from(m.as_str()).map_err(|_| InvalidMethod)
}
}
}
}
impl<'a> TryInto<String> for &'a common::scheme::Type {
type Err = InvalidScheme;
fn try_into(self) -> Result<String, Self::Err> {
use self::common::scheme::*;
match *self {
Type::Registered(reg) => if reg == Registered::Http.into() {
Ok("http".into())
} else if reg == Registered::Https.into() {
Ok("https".into())
} else {
Err(InvalidScheme)
},
Type::Unregistered(ref s) => Ok(s.clone()),
}
}
}
impl<'a> From<&'a http::Method> for common::http_method::Type {
fn from(m: &'a http::Method) -> Self {
use self::common::http_method::*;
match *m {
http::Method::GET => Type::Registered(Registered::Get.into()),
http::Method::POST => Type::Registered(Registered::Post.into()),
http::Method::PUT => Type::Registered(Registered::Put.into()),
http::Method::DELETE => Type::Registered(Registered::Delete.into()),
http::Method::HEAD => Type::Registered(Registered::Head.into()),
http::Method::OPTIONS => Type::Registered(Registered::Options.into()),
http::Method::CONNECT => Type::Registered(Registered::Connect.into()),
http::Method::TRACE => Type::Registered(Registered::Trace.into()),
ref method => Type::Unregistered(method.as_str().into()),
}
}
}
impl<'a> From<&'a http::Method> for common::HttpMethod {
fn from(m: &'a http::Method) -> Self {
common::HttpMethod {
type_: Some(m.into()),
}
}
}
impl<'a> From<&'a http::uri::Scheme> for common::Scheme {
fn from(scheme: &'a http::uri::Scheme) -> Self {
scheme.as_ref().into()
}
}
impl<'a> From<&'a str> for common::scheme::Type {
fn from(s: &'a str) -> Self {
use self::common::scheme::*;
match s {
"http" => Type::Registered(Registered::Http.into()),
"https" => Type::Registered(Registered::Https.into()),
s => Type::Unregistered(s.into()),
}
}
}
impl<'a> From<&'a str> for common::Scheme {
fn from(s: &'a str) -> Self {
common::Scheme {
type_: Some(s.into()),
}
}
}
// ===== impl common::Eos =====
impl From<h2::Reason> for common::Eos {
fn from(reason: h2::Reason) -> Self {
let end = common::eos::End::ResetErrorCode(reason.into());
common::Eos { end: Some(end) }
}
}
impl common::Eos {
fn from_grpc_status(code: u32) -> Self {
let end = common::eos::End::GrpcStatusCode(code);
common::Eos { end: Some(end) }
}
}
// ===== impl common::IpAddress =====
impl<T> From<T> for common::IpAddress
where
common::ip_address::Ip: From<T>,
{
#[inline]
fn from(ip: T) -> Self {
Self {
ip: Some(ip.into()),
}
}
}
impl From<::std::net::IpAddr> for common::IpAddress {
fn from(ip: ::std::net::IpAddr) -> Self {
match ip {
::std::net::IpAddr::V4(v4) => Self {
ip: Some(v4.into()),
},
::std::net::IpAddr::V6(v6) => Self {
ip: Some(v6.into()),
},
}
}
}
// ===== impl common::IPv6 =====
impl From<[u8; 16]> for common::IPv6 {
fn from(octets: [u8; 16]) -> Self {
let first = (u64::from(octets[0]) << 56) + (u64::from(octets[1]) << 48)
+ (u64::from(octets[2]) << 40) + (u64::from(octets[3]) << 32)
+ (u64::from(octets[4]) << 24) + (u64::from(octets[5]) << 16)
+ (u64::from(octets[6]) << 8) + u64::from(octets[7]);
let last = (u64::from(octets[8]) << 56) + (u64::from(octets[9]) << 48)
+ (u64::from(octets[10]) << 40) + (u64::from(octets[11]) << 32)
+ (u64::from(octets[12]) << 24) + (u64::from(octets[13]) << 16)
+ (u64::from(octets[14]) << 8) + u64::from(octets[15]);
Self {
first,
last,
}
}
}
impl From<::std::net::Ipv6Addr> for common::IPv6 {
#[inline]
fn from(v6: ::std::net::Ipv6Addr) -> Self {
Self::from(v6.octets())
}
}
impl<'a> From<&'a common::IPv6> for ::std::net::Ipv6Addr {
fn from(ip: &'a common::IPv6) -> ::std::net::Ipv6Addr {
::std::net::Ipv6Addr::new(
(ip.first >> 48) as u16,
(ip.first >> 32) as u16,
(ip.first >> 16) as u16,
(ip.first) as u16,
(ip.last >> 48) as u16,
(ip.last >> 32) as u16,
(ip.last >> 16) as u16,
(ip.last) as u16,
)
}
}
// ===== impl common::ip_address::Ip =====
impl From<[u8; 4]> for common::ip_address::Ip {
fn from(octets: [u8; 4]) -> Self {
common::ip_address::Ip::Ipv4(
u32::from(octets[0]) << 24 | u32::from(octets[1]) << 16 | u32::from(octets[2]) << 8
| u32::from(octets[3]),
)
}
}
impl From<::std::net::Ipv4Addr> for common::ip_address::Ip {
#[inline]
fn from(v4: ::std::net::Ipv4Addr) -> Self {
Self::from(v4.octets())
}
}
impl<T> From<T> for common::ip_address::Ip
where
common::IPv6: From<T>,
{
#[inline]
fn from(t: T) -> Self {
common::ip_address::Ip::Ipv6(common::IPv6::from(t))
}
}
impl<'a> From<&'a ::std::net::SocketAddr> for common::TcpAddress {
fn from(sa: &::std::net::SocketAddr) -> common::TcpAddress {
common::TcpAddress {
ip: Some(sa.ip().into()),
port: u32::from(sa.port()),
}
}
}
impl hash::Hash for common::Protocol {
// it's necessary to implement Hash for Protocol as it's a field on
// ctx::Transport, which derives Hash.
fn hash<H: hash::Hasher>(&self, state: &mut H) {
(*self as i32).hash(state)
}
}
fn pb_duration(d: &::std::time::Duration) -> ::prost_types::Duration {
let seconds = if d.as_secs() > ::std::i64::MAX as u64 {
::std::i64::MAX
} else {
d.as_secs() as i64
};
let nanos = if d.subsec_nanos() > ::std::i32::MAX as u32 {
::std::i32::MAX
} else {
d.subsec_nanos() as i32
};
::prost_types::Duration {
seconds,
nanos,
}
}

View File

@ -6,8 +6,8 @@ use tokio_core::reactor::Handle;
use tower_h2::{HttpService, BoxBody};
use tower_grpc as grpc;
use super::pb::proxy::telemetry::{ReportRequest, ReportResponse};
use super::pb::proxy::telemetry::client::Telemetry as TelemetrySvc;
use conduit_proxy_controller_grpc::telemetry::{ReportRequest, ReportResponse};
use conduit_proxy_controller_grpc::telemetry::client::Telemetry as TelemetrySvc;
use ::timeout::{Timeout, TimeoutFuture};
type TelemetryStream<F, B> = grpc::client::unary::ResponseFuture<

View File

@ -8,7 +8,7 @@
//! be stored in `http::Extensions`, for instance. Furthermore, because these contexts
//! will be sent to a telemetry processing thread, we want to avoid excessive cloning.
use config;
use control::pb::proxy::telemetry as proto;
use conduit_proxy_controller_grpc::telemetry as proto;
use std::sync::Arc;
pub mod http;
pub mod transport;

View File

@ -1,7 +1,7 @@
use std::net::{IpAddr, SocketAddr};
use std::sync::Arc;
use control::pb::common::Protocol;
use conduit_proxy_controller_grpc::common::Protocol;
use ctx;

View File

@ -5,7 +5,7 @@ use http;
use tower;
use tower_buffer::{self, Buffer};
use tower_h2;
use tower_router::Recognize;
use conduit_proxy_router::Recognize;
use bind;
use ctx;
@ -87,10 +87,10 @@ mod tests {
use http;
use tokio_core::reactor::Core;
use tower_router::Recognize;
use conduit_proxy_router::Recognize;
use super::Inbound;
use control::pb::common::Protocol;
use conduit_proxy_controller_grpc::common::Protocol;
use bind::{self, Bind};
use ctx;

View File

@ -5,6 +5,8 @@
extern crate abstract_ns;
extern crate bytes;
extern crate chrono;
extern crate conduit_proxy_controller_grpc;
extern crate convert;
extern crate domain;
extern crate env_logger;
#[macro_use]
@ -22,8 +24,6 @@ extern crate log;
extern crate ns_dns_tokio;
extern crate ordermap;
extern crate prost;
#[macro_use]
extern crate prost_derive;
extern crate prost_types;
#[cfg(test)]
#[macro_use]
@ -38,7 +38,7 @@ extern crate tower_discover;
extern crate tower_grpc;
extern crate tower_h2;
extern crate tower_reconnect;
extern crate tower_router;
extern crate conduit_proxy_router;
extern crate tower_util;
extern crate url;
@ -53,14 +53,13 @@ use std::time::Duration;
use tokio_core::reactor::{Core, Handle};
use tower::NewService;
use tower_fn::*;
use tower_router::{Recognize, Router};
use conduit_proxy_router::{Recognize, Router};
pub mod app;
mod bind;
pub mod config;
mod connection;
pub mod control;
pub mod convert;
mod ctx;
mod dns;
mod fully_qualified_authority;
@ -244,7 +243,7 @@ where
thread::Builder::new()
.name("controller-client".into())
.spawn(move || {
use control::pb::proxy::tap::server::TapServer;
use conduit_proxy_controller_grpc::tap::server::TapServer;
let mut core = Core::new().expect("initialize controller core");
let executor = core.handle();

View File

@ -6,7 +6,7 @@ use tower;
use tower_balance::{self, choose, Balance};
use tower_buffer::Buffer;
use tower_h2;
use tower_router::Recognize;
use conduit_proxy_router::Recognize;
use bind::{self, Bind, Protocol};
use control::{self, discovery};

View File

@ -9,7 +9,7 @@ use tokio_core::reactor::{Handle, Timeout};
use super::event::Event;
use super::metrics::Metrics;
use super::tap::Taps;
use control::pb::telemetry::ReportRequest;
use conduit_proxy_controller_grpc::telemetry::ReportRequest;
use ctx;
/// A `Control` which has been configured but not initialized.

View File

@ -6,12 +6,12 @@ use std::time::Duration;
use http;
use ordermap::OrderMap;
use control::pb::common::{
use conduit_proxy_controller_grpc::common::{
HttpMethod,
TcpAddress,
Protocol,
};
use control::pb::proxy::telemetry::{
use conduit_proxy_controller_grpc::telemetry::{
ClientTransport,
eos_ctx,
EosCtx,

View File

@ -6,8 +6,8 @@ use http;
use ipnet::{Contains, Ipv4Net, Ipv6Net};
use super::Event;
use control::pb::common::ip_address;
use control::pb::tap::observe_request;
use conduit_proxy_controller_grpc::common::ip_address;
use conduit_proxy_controller_grpc::tap::observe_request;
use convert::*;
use ctx;
@ -136,7 +136,7 @@ impl<'a> TryFrom<&'a observe_request::match_::Match> for Match {
#[allow(unconditional_recursion)]
fn try_from(m: &observe_request::match_::Match) -> Result<Self, Self::Err> {
use control::pb::proxy::tap::observe_request::match_;
use conduit_proxy_controller_grpc::tap::observe_request::match_;
let match_ = match *m {
match_::Match::All(ref seq) => Match::All(Self::from_seq(seq)?),
@ -177,7 +177,7 @@ impl<'a> TryFrom<&'a observe_request::match_::Tcp> for TcpMatch {
type Err = InvalidMatch;
fn try_from(m: &observe_request::match_::Tcp) -> Result<Self, InvalidMatch> {
use control::pb::proxy::tap::observe_request::match_::tcp;
use conduit_proxy_controller_grpc::tap::observe_request::match_::tcp;
let m = match m.match_.as_ref() {
None => return Err(InvalidMatch::Empty),
@ -280,7 +280,7 @@ impl HttpMatch {
string_match: &observe_request::match_::http::string_match::Match,
value: &str,
) -> bool {
use control::pb::proxy::tap::observe_request::match_::http::string_match::Match::*;
use conduit_proxy_controller_grpc::tap::observe_request::match_::http::string_match::Match::*;
match *string_match {
Exact(ref exact) => value == exact,
@ -292,7 +292,7 @@ impl HttpMatch {
impl<'a> TryFrom<&'a observe_request::match_::Http> for HttpMatch {
type Err = InvalidMatch;
fn try_from(m: &'a observe_request::match_::Http) -> Result<Self, InvalidMatch> {
use control::pb::proxy::tap::observe_request::match_::http::Match as Pb;
use conduit_proxy_controller_grpc::tap::observe_request::match_::http::Match as Pb;
m.match_
.as_ref()
@ -331,209 +331,11 @@ impl<'a> TryFrom<&'a observe_request::match_::Http> for HttpMatch {
#[cfg(test)]
mod tests {
use std::boxed::Box;
use std::net;
use ipnet::{Contains, Ipv4Net, Ipv6Net};
use quickcheck::*;
use super::*;
use control::pb::common::*;
use control::pb::proxy::tap::*;
impl Arbitrary for ObserveRequest {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
ObserveRequest {
limit: g.gen(),
match_: Arbitrary::arbitrary(g),
}
}
}
impl Arbitrary for observe_request::Match {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
observe_request::Match {
match_: Arbitrary::arbitrary(g),
}
}
}
impl Arbitrary for observe_request::match_::Match {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
match g.gen::<u32>() % 6 {
0 => observe_request::match_::Match::All(Arbitrary::arbitrary(g)),
1 => observe_request::match_::Match::Any(Arbitrary::arbitrary(g)),
2 => observe_request::match_::Match::Not(Box::new(Arbitrary::arbitrary(g))),
3 => observe_request::match_::Match::Source(Arbitrary::arbitrary(g)),
4 => observe_request::match_::Match::Destination(Arbitrary::arbitrary(g)),
5 => observe_request::match_::Match::Http(Arbitrary::arbitrary(g)),
_ => unreachable!(),
}
}
}
impl Arbitrary for observe_request::match_::Seq {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
observe_request::match_::Seq {
matches: Arbitrary::arbitrary(g),
}
}
fn shrink(&self) -> Box<Iterator<Item = Self>> {
Box::new(self.matches.shrink().map(|matches| {
observe_request::match_::Seq {
matches,
}
}))
}
}
impl Arbitrary for observe_request::match_::Tcp {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
observe_request::match_::Tcp {
match_: Arbitrary::arbitrary(g),
}
}
}
impl Arbitrary for observe_request::match_::tcp::Match {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
use self::observe_request::match_::tcp;
if g.gen::<bool>() {
tcp::Match::Netmask(Arbitrary::arbitrary(g))
} else {
tcp::Match::Ports(Arbitrary::arbitrary(g))
}
}
}
impl Arbitrary for observe_request::match_::tcp::PortRange {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
observe_request::match_::tcp::PortRange {
min: g.gen(),
max: g.gen(),
}
}
}
impl Arbitrary for observe_request::match_::tcp::Netmask {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
let ip: Option<IpAddress> = Arbitrary::arbitrary(g);
let mask = match ip.as_ref().and_then(|a| a.ip.as_ref()) {
Some(&ip_address::Ip::Ipv4(_)) => g.gen::<u32>() % 32 + 1,
Some(&ip_address::Ip::Ipv6(_)) => g.gen::<u32>() % 128 + 1,
None => 0u32,
};
observe_request::match_::tcp::Netmask {
ip,
mask,
}
}
}
impl Arbitrary for observe_request::match_::Http {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
observe_request::match_::Http {
match_: Arbitrary::arbitrary(g),
}
}
}
impl Arbitrary for observe_request::match_::http::Match {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
use self::observe_request::match_::http;
match g.gen::<u32>() % 4 {
0 => http::Match::Scheme(Scheme::arbitrary(g)),
1 => http::Match::Method(HttpMethod::arbitrary(g)),
2 => http::Match::Authority(http::StringMatch::arbitrary(g)),
3 => http::Match::Path(http::StringMatch::arbitrary(g)),
_ => unreachable!(),
}
}
}
impl Arbitrary for observe_request::match_::http::StringMatch {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
observe_request::match_::http::StringMatch {
match_: Arbitrary::arbitrary(g),
}
}
}
impl Arbitrary for observe_request::match_::http::string_match::Match {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
use self::observe_request::match_::http::string_match;
match g.gen::<u32>() % 2 {
0 => string_match::Match::Exact(String::arbitrary(g)),
1 => string_match::Match::Prefix(String::arbitrary(g)),
_ => unreachable!(),
}
}
}
impl Arbitrary for IpAddress {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
IpAddress {
ip: Arbitrary::arbitrary(g),
}
}
}
impl Arbitrary for ip_address::Ip {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
if g.gen::<bool>() {
ip_address::Ip::Ipv4(g.gen())
} else {
ip_address::Ip::Ipv6(IPv6::arbitrary(g))
}
}
}
impl Arbitrary for IPv6 {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
IPv6 {
first: g.gen(),
last: g.gen(),
}
}
}
impl Arbitrary for HttpMethod {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
HttpMethod {
type_: Arbitrary::arbitrary(g),
}
}
}
impl Arbitrary for http_method::Type {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
match g.gen::<u16>() % 9 {
8 => http_method::Type::Unregistered(String::arbitrary(g)),
n => http_method::Type::Registered(i32::from(n).into()),
}
}
}
impl Arbitrary for Scheme {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
Scheme {
type_: Arbitrary::arbitrary(g),
}
}
}
impl Arbitrary for scheme::Type {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
match g.gen::<u16>() % 3 {
3 => scheme::Type::Unregistered(String::arbitrary(g)),
n => scheme::Type::Registered(i32::from(n).into()),
}
}
}
use conduit_proxy_controller_grpc::*;
impl Arbitrary for TcpMatch {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
@ -560,7 +362,6 @@ mod tests {
}
}
}
quickcheck! {
fn tcp_from_proto(tcp: observe_request::match_::Tcp) -> bool {
use self::observe_request::match_::tcp;
@ -609,7 +410,7 @@ mod tests {
Some(&http::Match::Method(ref m)) => {
match m.type_.as_ref() {
None => Some(InvalidMatch::Empty),
Some(&http_method::Type::Unregistered(ref m)) => if m.len() <= 15 {
Some(&common::http_method::Type::Unregistered(ref m)) => if m.len() <= 15 {
let mut err = None;
for c in m.bytes() {
let ok =
@ -625,7 +426,7 @@ mod tests {
} else {
Some(InvalidMatch::InvalidHttpMethod)
}
Some(&http_method::Type::Registered(m)) => if m < 9 {
Some(&common::http_method::Type::Registered(m)) => if m < 9 {
None
} else {
Some(InvalidMatch::InvalidHttpMethod)
@ -635,8 +436,8 @@ mod tests {
Some(&http::Match::Scheme(ref m)) => {
match m.type_.as_ref() {
None => Some(InvalidMatch::Empty),
Some(&scheme::Type::Unregistered(_)) => None,
Some(&scheme::Type::Registered(m)) => {
Some(&common::scheme::Type::Unregistered(_)) => None,
Some(&common::scheme::Type::Registered(m)) => {
if m < 2 {
None
} else {

View File

@ -1,7 +1,7 @@
use futures_mpsc_lossy;
use ordermap::OrderMap;
use control::pb::tap::observe_request;
use conduit_proxy_controller_grpc::tap::observe_request;
use super::Event;

View File

@ -10,7 +10,7 @@ use tokio_core::reactor::Handle;
use tower::NewService;
use tower_h2;
use control;
use conduit_proxy_controller_grpc::common;
use connection::Connection;
use ctx::Proxy as ProxyCtx;
use ctx::transport::{Server as ServerCtx};
@ -108,7 +108,7 @@ where
&local_addr,
&remote_addr,
&orig_dst,
control::pb::proxy::common::Protocol::Http,
common::Protocol::Http,
);
// record telemetry
@ -144,7 +144,7 @@ where
&local_addr,
&remote_addr,
&orig_dst,
control::pb::proxy::common::Protocol::Tcp,
common::Protocol::Tcp,
);
// record telemetry

View File

@ -7,7 +7,7 @@ use tokio_core::reactor::Handle;
use tokio_io::{AsyncRead, AsyncWrite};
use tokio_io::io::copy;
use control;
use conduit_proxy_controller_grpc::common;
use ctx::transport::{Client as ClientCtx, Server as ServerCtx};
use telemetry::Sensors;
use timeout::Timeout;
@ -59,7 +59,7 @@ impl Proxy {
let client_ctx = ClientCtx::new(
&srv_ctx.proxy,
&orig_dst,
control::pb::proxy::common::Protocol::Tcp,
common::Protocol::Tcp,
);
let c = Timeout::new(
transport::Connect::new(orig_dst, &self.executor),

View File

@ -5,8 +5,8 @@ use support::*;
use std::net::IpAddr;
use std::sync::{Arc, Mutex};
use conduit_proxy_controller_grpc as pb;
use self::bytes::BufMut;
use self::conduit_proxy::control::pb;
use self::futures::sync::mpsc;
use self::prost::Message;

View File

@ -1,7 +1,9 @@
#![allow(unused)]
extern crate bytes;
pub extern crate conduit_proxy_controller_grpc;
extern crate conduit_proxy;
pub extern crate convert;
extern crate futures;
extern crate h2;
pub extern crate http;

View File

@ -2,7 +2,7 @@ use support::*;
use std::sync::{Arc, Mutex};
use support::conduit_proxy::convert::TryFrom;
use convert::TryFrom;
pub fn new() -> Proxy {
Proxy::new()