소스 검색

bigtable: allow forward proxy in gRPC connection (#25918)

* bigtable: allow forward proxy in tonic connection

* bigtable: try fixing ci

* bigtable: cargo fmt

* bigtable: add docs for BIGTABLE_PROXY env var

* bigtable: fix readme header level

Co-authored-by: Tyera Eulberg <teulberg@gmail.com>

Co-authored-by: Tyera Eulberg <teulberg@gmail.com>
lwus 3 년 전
부모
커밋
d12e566a4c
5개의 변경된 파일126개의 추가작업 그리고 1개의 파일을 삭제
  1. 47 0
      Cargo.lock
  2. 47 0
      programs/bpf/Cargo.lock
  3. 4 0
      storage-bigtable/Cargo.toml
  4. 5 0
      storage-bigtable/README.md
  5. 23 1
      storage-bigtable/src/bigtable.rs

+ 47 - 0
Cargo.lock

@@ -1737,6 +1737,31 @@ dependencies = [
  "ahash",
 ]
 
+[[package]]
+name = "headers"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4cff78e5788be1e0ab65b04d306b2ed5092c815ec97ec70f4ebd5aee158aa55d"
+dependencies = [
+ "base64 0.13.0",
+ "bitflags",
+ "bytes",
+ "headers-core",
+ "http",
+ "httpdate",
+ "mime",
+ "sha-1 0.10.0",
+]
+
+[[package]]
+name = "headers-core"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429"
+dependencies = [
+ "http",
+]
+
 [[package]]
 name = "heck"
 version = "0.3.3"
@@ -1884,6 +1909,24 @@ dependencies = [
  "want",
 ]
 
+[[package]]
+name = "hyper-proxy"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca815a891b24fdfb243fa3239c86154392b0953ee584aa1a2a1f66d20cbe75cc"
+dependencies = [
+ "bytes",
+ "futures 0.3.21",
+ "headers",
+ "http",
+ "hyper",
+ "hyper-tls",
+ "native-tls",
+ "tokio",
+ "tokio-native-tls",
+ "tower-service",
+]
+
 [[package]]
 name = "hyper-rustls"
 version = "0.23.0"
@@ -5999,11 +6042,15 @@ version = "1.11.2"
 dependencies = [
  "backoff",
  "bincode",
+ "bytes",
  "bzip2",
  "enum-iterator",
  "flate2",
  "futures 0.3.21",
  "goauth",
+ "http",
+ "hyper",
+ "hyper-proxy",
  "log",
  "openssl",
  "prost 0.10.4",

+ 47 - 0
programs/bpf/Cargo.lock

@@ -1501,6 +1501,31 @@ dependencies = [
  "ahash",
 ]
 
+[[package]]
+name = "headers"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4cff78e5788be1e0ab65b04d306b2ed5092c815ec97ec70f4ebd5aee158aa55d"
+dependencies = [
+ "base64 0.13.0",
+ "bitflags",
+ "bytes",
+ "headers-core",
+ "http",
+ "httpdate",
+ "mime",
+ "sha-1 0.10.0",
+]
+
+[[package]]
+name = "headers-core"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429"
+dependencies = [
+ "http",
+]
+
 [[package]]
 name = "heck"
 version = "0.3.3"
@@ -1631,6 +1656,24 @@ dependencies = [
  "want",
 ]
 
+[[package]]
+name = "hyper-proxy"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca815a891b24fdfb243fa3239c86154392b0953ee584aa1a2a1f66d20cbe75cc"
+dependencies = [
+ "bytes",
+ "futures 0.3.21",
+ "headers",
+ "http",
+ "hyper",
+ "hyper-tls",
+ "native-tls",
+ "tokio",
+ "tokio-native-tls",
+ "tower-service",
+]
+
 [[package]]
 name = "hyper-rustls"
 version = "0.23.0"
@@ -5310,11 +5353,15 @@ version = "1.11.2"
 dependencies = [
  "backoff",
  "bincode",
+ "bytes",
  "bzip2",
  "enum-iterator",
  "flate2",
  "futures 0.3.21",
  "goauth",
+ "http",
+ "hyper",
+ "hyper-proxy",
  "log",
  "openssl",
  "prost 0.10.4",

+ 4 - 0
storage-bigtable/Cargo.toml

@@ -12,11 +12,15 @@ edition = "2021"
 [dependencies]
 backoff = { version = "0.4.0", features = ["tokio"] }
 bincode = "1.3.3"
+bytes = "1.0"
 bzip2 = "0.4.3"
 enum-iterator = "0.8.1"
 flate2 = "1.0.24"
 futures = "0.3.21"
 goauth = "0.13.0"
+http = "0.2.6"
+hyper = "0.14.14"
+hyper-proxy = "0.9.1"
 log = "0.4.17"
 prost = "0.10.4"
 prost-types = "0.10.0"

+ 5 - 0
storage-bigtable/README.md

@@ -20,3 +20,8 @@ Depending on what operation mode is required, either the
 `https://www.googleapis.com/auth/bigtable.data` or
 `https://www.googleapis.com/auth/bigtable.data.readonly` OAuth scope will be
 requested using the provided credentials.
+
+#### Forward proxy
+Export `BIGTABLE_PROXY` environment variable for the forward proxy as you would
+for `HTTP_PROXY`. This will establish a tunnel through the forward proxy for
+gRPC traffic (the tunneled traffic will still use TLS as normal).

+ 23 - 1
storage-bigtable/src/bigtable.rs

@@ -122,6 +122,9 @@ impl BigTableConnection {
     ///
     /// The BIGTABLE_EMULATOR_HOST environment variable is also respected.
     ///
+    /// The BIGTABLE_PROXY environment variable is used to configure the gRPC connection through a
+    /// forward proxy (see HTTP_PROXY).
+    ///
     pub async fn new(
         instance_name: &str,
         app_profile_id: &str,
@@ -180,9 +183,28 @@ impl BigTableConnection {
                     }
                 };
 
+                let mut http = hyper::client::HttpConnector::new();
+                http.enforce_http(false);
+                let channel = match std::env::var("BIGTABLE_PROXY") {
+                    Ok(proxy_uri) => {
+                        let proxy = hyper_proxy::Proxy::new(
+                            hyper_proxy::Intercept::All,
+                            proxy_uri
+                                .parse::<http::Uri>()
+                                .map_err(|err| Error::InvalidUri(proxy_uri, err.to_string()))?,
+                        );
+                        let mut proxy_connector =
+                            hyper_proxy::ProxyConnector::from_proxy(http, proxy)?;
+                        // tonic handles TLS as a separate layer
+                        proxy_connector.set_tls(None);
+                        endpoint.connect_with_connector_lazy(proxy_connector)
+                    }
+                    _ => endpoint.connect_with_connector_lazy(http),
+                };
+
                 Ok(Self {
                     access_token: Some(access_token),
-                    channel: endpoint.connect_lazy(),
+                    channel,
                     table_prefix,
                     app_profile_id: app_profile_id.to_string(),
                     timeout,