Skip to content

Commit e43e373

Browse files
committed
Add API to get single cluster status
1 parent c5270dc commit e43e373

File tree

4 files changed

+70
-13
lines changed

4 files changed

+70
-13
lines changed

CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ All notable changes to this project will be documented in this file.
66

77
### Added
88

9-
- Support activating and deactivation Trino clusters via API calls to `/admin/activate-cluster/{cluster_name}` and `/admin/deactivate-cluster/{cluster_name}` respectively. For this to work you need to authenticate yourself at trino-lb via basic auth ([#95]).
10-
- Expose cluster statistics at `/admin/cluster-status` ([#95]).
9+
- Support activating and deactivation Trino clusters via API calls to `/admin/clusters/{cluster_name}/activate` and `/admin/clusters/{cluster_name}/deactivate` respectively. For this to work you need to authenticate yourself at trino-lb via basic auth ([#95]).
10+
- Expose cluster statistics at `/admin/clusters/{cluster_name}/status` and `/admin/clusters/status` ([#95]).
1111

1212
### Changed
1313

docs/design.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,10 @@ A deactivated cluster continues to process already running queries, but no new q
8888

8989
To safely update a running Trino cluster you can
9090

91-
1. Deactivate the Trino cluster using `POST /admin/deactivate-cluster/{cluster_name}`
92-
2. Wait until all running queries have finished. Tip: You can use `GET /admin/cluster-status` to fetch the current query counter or talk to the Trino cluster directly.
91+
1. Deactivate the Trino cluster using `POST /admin/clusters/{cluster_name}/deactivate`
92+
2. Wait until all running queries have finished. Tip: You can use `GET /admin/clusters/{cluster_name}/status` (or `GET /admin/clusters/status`) to fetch the current query counter or talk to the Trino cluster directly.
9393
3. Safely do modifications to the Trino cluster without any user impact
94-
4. Once you are done with your changes re-activate the Trino cluster again using `POST /admin/activate-cluster/{cluster_name}`
94+
4. Once you are done with your changes re-activate the Trino cluster again using `POST /admin/clusters/{cluster_name}/activate`
9595

9696
Important: To activate/deactivate a Trino cluster you need to authenticate against trino-lb.
9797
Currently only Basic Auth is supported, you can configure the credentials like this:

trino-lb/src/http_server/admin/mod.rs

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,24 @@ pub enum Error {
3535
#[snafu(display("Unknown Trino cluster {cluster:?}"))]
3636
UnknownCluster { cluster: TrinoClusterName },
3737

38+
#[snafu(display("Failed to get cluster state for cluster {cluster:?} from persistence"))]
39+
GetClusterStateFromPersistence {
40+
source: trino_lb_persistence::Error,
41+
cluster: TrinoClusterName,
42+
},
43+
3844
#[snafu(display("Failed to set cluster state for cluster {cluster:?} in persistence"))]
3945
SetClusterStateInPersistence {
4046
source: trino_lb_persistence::Error,
4147
cluster: TrinoClusterName,
4248
},
4349

50+
#[snafu(display("Failed to get the query counter for cluster {cluster:?} from persistence"))]
51+
GetQueryCounterForGroup {
52+
source: trino_lb_persistence::Error,
53+
cluster: TrinoClusterName,
54+
},
55+
4456
#[snafu(display("Failed to get all cluster states"))]
4557
GetAllClusterStates {
4658
source: cluster_group_manager::Error,
@@ -54,7 +66,9 @@ impl IntoResponse for Error {
5466
Error::NoAdminAuthenticationMethodDefined => StatusCode::UNAUTHORIZED,
5567
Error::InvalidAdminCredentials => StatusCode::UNAUTHORIZED,
5668
Error::UnknownCluster { .. } => StatusCode::NOT_FOUND,
69+
Error::GetClusterStateFromPersistence { .. } => StatusCode::INTERNAL_SERVER_ERROR,
5770
Error::SetClusterStateInPersistence { .. } => StatusCode::INTERNAL_SERVER_ERROR,
71+
Error::GetQueryCounterForGroup { .. } => StatusCode::INTERNAL_SERVER_ERROR,
5872
Error::GetAllClusterStates { .. } => StatusCode::INTERNAL_SERVER_ERROR,
5973
};
6074
(status_code, format!("{self}")).into_response()
@@ -64,7 +78,7 @@ impl IntoResponse for Error {
6478
/// (Re)-Activates a Trino Cluster, so that it receives new queries.
6579
///
6680
/// This is useful for maintenance actions (in combination with deactivation).
67-
#[instrument(name = "POST /admin/activate-cluster/{cluster_name}", skip(state))]
81+
#[instrument(name = "POST /admin/clusters/{cluster_name}/activate", skip(state))]
6882
pub async fn post_activate_cluster(
6983
TypedHeader(Authorization(basic_auth)): TypedHeader<Authorization<Basic>>,
7084
State(state): State<Arc<AppState>>,
@@ -81,7 +95,7 @@ pub async fn post_activate_cluster(
8195
/// Deactivate a Trino Cluster, so that it doesn't receive any new queries.
8296
///
8397
/// This is useful for maintenance actions (in combination with activation).
84-
#[instrument(name = "POST /admin/deactivate-cluster/{cluster_name}", skip(state))]
98+
#[instrument(name = "POST /admin/clusters/{cluster_name}/deactivate", skip(state))]
8599
pub async fn post_deactivate_cluster(
86100
TypedHeader(Authorization(basic_auth)): TypedHeader<Authorization<Basic>>,
87101
State(state): State<Arc<AppState>>,
@@ -95,16 +109,55 @@ pub async fn post_deactivate_cluster(
95109
set_cluster_activation(state, basic_auth, &cluster_name, false).await
96110
}
97111

98-
/// Get the status of the Trino clusters
99-
#[instrument(name = "GET /admin/cluster-status", skip(state))]
112+
/// Get the status of a single Trino clusters
113+
#[instrument(name = "/admin/clusters/{cluster_name}/status", skip(state))]
100114
pub async fn get_cluster_status(
101115
State(state): State<Arc<AppState>>,
102-
) -> Result<Json<BTreeMap<TrinoClusterName, ClusterStats>>, Error> {
116+
Path(cluster_name): Path<TrinoClusterName>,
117+
) -> Result<Json<ClusterStats>, Error> {
103118
state
104119
.metrics
105120
.http_counter
106121
.add(1, &[KeyValue::new("resource", "get_cluster_status")]);
107122

123+
ensure!(
124+
state.config.is_cluster_in_config(&cluster_name),
125+
UnknownClusterSnafu {
126+
cluster: cluster_name
127+
}
128+
);
129+
130+
let cluster_state = state
131+
.persistence
132+
.get_cluster_state(&cluster_name)
133+
.await
134+
.context(GetClusterStateFromPersistenceSnafu {
135+
cluster: &cluster_name,
136+
})?;
137+
let cluster_query_counter = state
138+
.persistence
139+
.get_cluster_query_count(&cluster_name)
140+
.await
141+
.context(GetQueryCounterForGroupSnafu {
142+
cluster: &cluster_name,
143+
})?;
144+
145+
Ok(Json(ClusterStats {
146+
state: cluster_state,
147+
query_counter: cluster_query_counter,
148+
}))
149+
}
150+
151+
/// Get the status of all Trino clusters
152+
#[instrument(name = "/admin/clusters/status", skip(state))]
153+
pub async fn get_all_cluster_status(
154+
State(state): State<Arc<AppState>>,
155+
) -> Result<Json<BTreeMap<TrinoClusterName, ClusterStats>>, Error> {
156+
state
157+
.metrics
158+
.http_counter
159+
.add(1, &[KeyValue::new("resource", "get_all_cluster_status")]);
160+
108161
let cluster_stats = state
109162
.cluster_group_manager
110163
.get_all_cluster_stats()

trino-lb/src/http_server/mod.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,14 +123,18 @@ pub async fn start_http_server(
123123
delete(v1::statement::delete_trino_executing_statement),
124124
)
125125
.route(
126-
"/admin/activate-cluster/{cluster_name}",
126+
"/admin/clusters/{cluster_name}/activate",
127127
post(admin::post_activate_cluster),
128128
)
129129
.route(
130-
"/admin/deactivate-cluster/{cluster_name}",
130+
"/admin/clusters/{cluster_name}/deactivate",
131131
post(admin::post_deactivate_cluster),
132132
)
133-
.route("/admin/cluster-status", get(admin::get_cluster_status))
133+
.route(
134+
"/admin/clusters/{cluster_name}/status",
135+
get(admin::get_cluster_status),
136+
)
137+
.route("/admin/clusters/status", get(admin::get_all_cluster_status))
134138
.route("/ui/index.html", get(ui::index::get_ui_index))
135139
.route("/ui/query.html", get(ui::query::get_ui_query))
136140
.layer(TraceLayer::new_for_http())

0 commit comments

Comments
 (0)