Skip to content

Commit

Permalink
Add health endpoint (#808)
Browse files Browse the repository at this point in the history
We currently use `/ctrl/status` as a health check endpoint. The
introduction of auth delegation (#804) applies, when enabled, to all
`/ctrl` endpoints, including the health check. That means that the
health checker needs to have credentials.

Instead, this adds a separate health check endpoint `/pub/health` which
is part of the `/pub` path, which is not credentialed. This does not
include the version information returned by the `/ctrl/status` endpoint,
but does a health check.
  • Loading branch information
paulgb authored Sep 10, 2024
1 parent 908205f commit b9c4d53
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 1 deletion.
2 changes: 1 addition & 1 deletion plane/plane-tests/tests/docker_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ async fn test_resource_limits() {
let docker = bollard::Docker::connect_with_local_defaults().unwrap();
let backend_name = BackendName::new_random();
let _container_id = ContainerId::from(format!("plane-test-{}", backend_name));
let mut executor_config = DockerExecutorConfig::from_image_with_defaults("debian:bookworm");
let mut executor_config = DockerExecutorConfig::from_image_with_defaults("alpine:latest");

let resource_limits: ResourceLimits = serde_json::from_value(serde_json::json!( {
"cpu_period": 1000000,
Expand Down
13 changes: 13 additions & 0 deletions plane/plane-tests/tests/health.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use common::test_env::TestEnvironment;
use plane_test_macro::plane_test;

mod common;

#[plane_test]
async fn controller_health_check(env: TestEnvironment) {
let controller = env.controller().await;
let client = controller.client();
let result = client.health_check().await;

assert!(result.is_ok());
}
6 changes: 6 additions & 0 deletions plane/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,12 @@ impl PlaneClient {
let cluster_state: ClusterState = authed_get(&self.client, &url).await?;
Ok(cluster_state)
}

pub async fn health_check(&self) -> Result<(), PlaneClientError> {
let url = self.controller_address.join("/pub/health");
self.client.get(url.url).send().await?;
Ok(())
}
}

async fn get_response<T: DeserializeOwned>(response: Response) -> Result<T, PlaneClientError> {
Expand Down
14 changes: 14 additions & 0 deletions plane/src/controller/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ use axum::{
use forward_auth::forward_layer;
use futures_util::never::Never;
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
use std::net::{SocketAddr, TcpListener};
use tokio::{
sync::oneshot::{self},
Expand Down Expand Up @@ -80,6 +81,18 @@ pub async fn status(
}))
}

pub async fn health(State(controller): State<Controller>) -> Result<Json<Value>, Response> {
controller
.db
.health_check()
.await
.or_internal_error("Database health check failed")?;

Ok(Json(json!({
"status": "ok"
})))
}

struct HeartbeatSender {
handle: JoinHandle<Never>,
db: PlaneDatabase,
Expand Down Expand Up @@ -243,6 +256,7 @@ impl ControllerServer {
"/b/:backend/status-stream",
get(handle_backend_status_stream),
)
.route("/health", get(health))
.layer(cors_public.clone());

let app = Router::new()
Expand Down

0 comments on commit b9c4d53

Please sign in to comment.