mirror of
https://github.com/neondatabase/neon.git
synced 2026-05-18 13:40:37 +00:00
The compute_ctl HTTP server has the following purposes: - Allow management via the control plane - Provide an endpoint for scaping metrics - Provide APIs for compute internal clients - Neon Postgres extension for installing remote extensions - local_proxy for installing extensions and adding grants The first two purposes require the HTTP server to be available outside the compute. The Neon threat model is a bad actor within our internal network. We need to reduce the surface area of attack. By exposing unnecessary unauthenticated HTTP endpoints to the internal network, we increase the surface area of attack. For endpoints described in the third bullet point, we can just run an extra HTTP server, which is only bound to the loopback interface since all consumers of those endpoints are within the compute.
55 lines
1.6 KiB
Rust
55 lines
1.6 KiB
Rust
use axum::{body::Body, response::Response};
|
|
use compute_api::responses::{ComputeStatus, GenericAPIError};
|
|
use http::{header::CONTENT_TYPE, StatusCode};
|
|
use serde::Serialize;
|
|
use tracing::error;
|
|
|
|
mod extract;
|
|
mod routes;
|
|
pub mod server;
|
|
|
|
/// Convenience response builder for JSON responses
|
|
struct JsonResponse;
|
|
|
|
impl JsonResponse {
|
|
/// Helper for actually creating a response
|
|
fn create_response(code: StatusCode, body: impl Serialize) -> Response {
|
|
Response::builder()
|
|
.status(code)
|
|
.header(CONTENT_TYPE.as_str(), "application/json")
|
|
.body(Body::from(serde_json::to_string(&body).unwrap()))
|
|
.unwrap()
|
|
}
|
|
|
|
/// Create a successful error response
|
|
pub(self) fn success(code: StatusCode, body: impl Serialize) -> Response {
|
|
assert!({
|
|
let code = code.as_u16();
|
|
|
|
(200..300).contains(&code)
|
|
});
|
|
|
|
Self::create_response(code, body)
|
|
}
|
|
|
|
/// Create an error response
|
|
pub(self) fn error(code: StatusCode, error: impl ToString) -> Response {
|
|
assert!(code.as_u16() >= 400);
|
|
|
|
let message = error.to_string();
|
|
error!(message);
|
|
|
|
Self::create_response(code, &GenericAPIError { error: message })
|
|
}
|
|
|
|
/// Create an error response related to the compute being in an invalid state
|
|
pub(self) fn invalid_status(status: ComputeStatus) -> Response {
|
|
Self::create_response(
|
|
StatusCode::PRECONDITION_FAILED,
|
|
&GenericAPIError {
|
|
error: format!("invalid compute status: {status}"),
|
|
},
|
|
)
|
|
}
|
|
}
|