diff --git a/Cargo.lock b/Cargo.lock
index 73f037995c..b8d869de0b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1424,16 +1424,19 @@ dependencies = [
"bytes",
"clap",
"hex",
+ "hyper",
"lazy_static",
"md5",
"parking_lot",
"rand",
"reqwest",
+ "routerify",
"rustls 0.19.1",
"serde",
"serde_json",
"tokio",
"tokio-postgres",
+ "zenith_metrics",
"zenith_utils",
]
diff --git a/proxy/Cargo.toml b/proxy/Cargo.toml
index 42287b04bb..6efd1d674d 100644
--- a/proxy/Cargo.toml
+++ b/proxy/Cargo.toml
@@ -13,6 +13,8 @@ lazy_static = "1.4.0"
md5 = "0.7.0"
rand = "0.8.3"
hex = "0.4.3"
+hyper = "0.14"
+routerify = "2"
parking_lot = "0.11.2"
serde = "1"
serde_json = "1"
@@ -23,3 +25,4 @@ rustls = "0.19.1"
reqwest = { version = "0.11", default-features = false, features = ["blocking", "json", "rustls-tls"] }
zenith_utils = { path = "../zenith_utils" }
+zenith_metrics = { path = "../zenith_metrics" }
diff --git a/proxy/src/http.rs b/proxy/src/http.rs
new file mode 100644
index 0000000000..7a65d76e6d
--- /dev/null
+++ b/proxy/src/http.rs
@@ -0,0 +1,15 @@
+use hyper::{Body, Request, Response, StatusCode};
+use routerify::RouterBuilder;
+
+use zenith_utils::http::endpoint;
+use zenith_utils::http::error::ApiError;
+use zenith_utils::http::json::json_response;
+
+async fn status_handler(_: Request
) -> Result, ApiError> {
+ Ok(json_response(StatusCode::OK, "")?)
+}
+
+pub fn make_router() -> RouterBuilder {
+ let router = endpoint::make_router();
+ router.get("/v1/status", status_handler)
+}
diff --git a/proxy/src/main.rs b/proxy/src/main.rs
index 8b397c4444..0f7a6981f1 100644
--- a/proxy/src/main.rs
+++ b/proxy/src/main.rs
@@ -9,15 +9,18 @@ use anyhow::bail;
use clap::{App, Arg};
use state::{ProxyConfig, ProxyState};
use std::thread;
+use zenith_utils::http::endpoint;
use zenith_utils::{tcp_listener, GIT_VERSION};
mod cplane_api;
+mod http;
mod mgmt;
mod proxy;
mod state;
mod waiters;
fn main() -> anyhow::Result<()> {
+ zenith_metrics::set_common_metrics_prefix("zenith_proxy");
let arg_matches = App::new("Zenith proxy/router")
.version(GIT_VERSION)
.arg(
@@ -36,6 +39,14 @@ fn main() -> anyhow::Result<()> {
.help("listen for management callback connection on ip:port")
.default_value("127.0.0.1:7000"),
)
+ .arg(
+ Arg::with_name("http")
+ .short("h")
+ .long("http")
+ .takes_value(true)
+ .help("listen for incoming http connections (metrics, etc) on ip:port")
+ .default_value("127.0.0.1:7001"),
+ )
.arg(
Arg::with_name("uri")
.short("u")
@@ -82,6 +93,7 @@ fn main() -> anyhow::Result<()> {
let config = ProxyConfig {
proxy_address: arg_matches.value_of("proxy").unwrap().parse()?,
mgmt_address: arg_matches.value_of("mgmt").unwrap().parse()?,
+ http_address: arg_matches.value_of("http").unwrap().parse()?,
redirect_uri: arg_matches.value_of("uri").unwrap().parse()?,
auth_endpoint: arg_matches.value_of("auth-endpoint").unwrap().parse()?,
ssl_config,
@@ -91,6 +103,9 @@ fn main() -> anyhow::Result<()> {
println!("Version: {}", GIT_VERSION);
// Check that we can bind to address before further initialization
+ println!("Starting http on {}", state.conf.http_address);
+ let http_listener = tcp_listener::bind(state.conf.http_address)?;
+
println!("Starting proxy on {}", state.conf.proxy_address);
let pageserver_listener = tcp_listener::bind(state.conf.proxy_address)?;
@@ -98,6 +113,12 @@ fn main() -> anyhow::Result<()> {
let mgmt_listener = tcp_listener::bind(state.conf.mgmt_address)?;
let threads = [
+ thread::Builder::new()
+ .name("Http thread".into())
+ .spawn(move || {
+ let router = http::make_router();
+ endpoint::serve_thread_main(router, http_listener)
+ })?,
// Spawn a thread to listen for connections. It will spawn further threads
// for each connection.
thread::Builder::new()
diff --git a/proxy/src/state.rs b/proxy/src/state.rs
index 191dd5a902..04726a0756 100644
--- a/proxy/src/state.rs
+++ b/proxy/src/state.rs
@@ -10,8 +10,12 @@ pub struct ProxyConfig {
/// main entrypoint for users to connect to
pub proxy_address: SocketAddr,
- /// http management endpoint. Upon user account creation control plane
+ /// internally used for status and prometheus metrics
+ pub http_address: SocketAddr,
+
+ /// management endpoint. Upon user account creation control plane
/// will notify us here, so that we can 'unfreeze' user session.
+ /// TODO It uses postgres protocol over TCP but should be migrated to http.
pub mgmt_address: SocketAddr,
/// send unauthenticated users to this URI