Author: Kevin Schoon [me@kevinschoon.com]
Hash: a3eef0ac6dcfaff7eabb9f156ae0c598d292771d
Timestamp: Wed, 24 Apr 2024 16:27:53 +0000 (3 weeks ago)

+52 -14 +/-7 browse
add ping api route for container healthchecks
1diff --git a/ayllu/src/web2/routes/rest/mod.rs b/ayllu/src/web2/routes/rest/mod.rs
2index fc4b5cb..cfdb010 100644
3--- a/ayllu/src/web2/routes/rest/mod.rs
4+++ b/ayllu/src/web2/routes/rest/mod.rs
5 @@ -1 +1,2 @@
6 pub mod discovery;
7+ pub mod ping;
8 diff --git a/ayllu/src/web2/routes/rest/ping.rs b/ayllu/src/web2/routes/rest/ping.rs
9new file mode 100644
10index 0000000..faccfb0
11--- /dev/null
12+++ b/ayllu/src/web2/routes/rest/ping.rs
13 @@ -0,0 +1,9 @@
14+ use axum::response::Json;
15+
16+ use crate::web2::error::Error;
17+
18+ use ayllu_api::ping::Status;
19+
20+ pub async fn serve() -> Result<Json<Status>, Error> {
21+ Ok(Json(Status { ok: true }))
22+ }
23 diff --git a/ayllu/src/web2/server.rs b/ayllu/src/web2/server.rs
24index 4ef8e00..770b355 100644
25--- a/ayllu/src/web2/server.rs
26+++ b/ayllu/src/web2/server.rs
27 @@ -43,6 +43,7 @@ use crate::web2::routes::mail;
28 use crate::web2::routes::refs;
29 use crate::web2::routes::repo;
30 use crate::web2::routes::rest::discovery;
31+ use crate::web2::routes::rest::ping;
32 use crate::web2::routes::robots;
33 use crate::web2::routes::rss;
34 use crate::web2::routes::xmpp;
35 @@ -179,7 +180,9 @@ pub async fn serve(cfg: &Config) -> Result<(), Box<dyn Error>> {
36 )
37 .nest(
38 "/0",
39- Router::new().route("/index", routing::get(discovery::serve)),
40+ Router::new()
41+ .route("/index", routing::get(discovery::serve))
42+ .route("/ping", routing::get(ping::serve)),
43 )
44 .nest(
45 "/mail",
46 diff --git a/crates/api/src/lib.rs b/crates/api/src/lib.rs
47index cc02f23..8164279 100644
48--- a/crates/api/src/lib.rs
49+++ b/crates/api/src/lib.rs
50 @@ -3,4 +3,5 @@ pub mod discovery;
51 pub mod error;
52 pub mod jobs;
53 pub mod mail;
54+ pub mod ping;
55 pub mod xmpp;
56 diff --git a/crates/api/src/ping.rs b/crates/api/src/ping.rs
57new file mode 100644
58index 0000000..aa9fb72
59--- /dev/null
60+++ b/crates/api/src/ping.rs
61 @@ -0,0 +1,7 @@
62+ use serde::{Deserialize, Serialize};
63+
64+ #[derive(Debug, Deserialize, Serialize)]
65+ /// The status of the server
66+ pub struct Status {
67+ pub ok: bool
68+ }
69 diff --git a/quipu/src/client_rest.rs b/quipu/src/client_rest.rs
70index e0d4f1d..aa49e95 100644
71--- a/quipu/src/client_rest.rs
72+++ b/quipu/src/client_rest.rs
73 @@ -1,7 +1,7 @@
74 use reqwest::{Client, ClientBuilder};
75 use url::Url;
76
77- use ayllu_api::discovery::Collection;
78+ use ayllu_api::{discovery::Collection, ping::Status};
79
80 use crate::error::QuipuError;
81
82 @@ -29,4 +29,13 @@ impl Quipu {
83 .await?;
84 Ok(response.json().await?)
85 }
86+
87+ pub async fn ping(&self) -> Result<Status, QuipuError> {
88+ let response = self
89+ .client
90+ .get(self.endpoint.join("/0/ping")?)
91+ .send()
92+ .await?;
93+ Ok(response.json().await?)
94+ }
95 }
96 diff --git a/quipu/src/main.rs b/quipu/src/main.rs
97index f1defe2..6da65c6 100644
98--- a/quipu/src/main.rs
99+++ b/quipu/src/main.rs
100 @@ -27,6 +27,13 @@ struct Cli {
101 #[arg(short, long, value_name = "LEVEL")]
102 level: Option<Level>,
103
104+ #[arg(short, long)]
105+ /// instance name from your quipu configuration
106+ instance: Option<String>,
107+ #[arg(short, long)]
108+ /// alternative url to contact
109+ url: Option<Url>,
110+
111 #[command(subcommand)]
112 command: Commands,
113 }
114 @@ -47,15 +54,11 @@ enum Commands {
115 },
116 /// get resources from a remote Ayllu server
117 Get {
118- #[arg(short, long)]
119- /// instance name from your quipu configuration
120- instance: Option<String>,
121- #[arg(short, long)]
122- /// alternative url to contact
123- url: Option<Url>,
124 /// resource to request from remote server
125 resource: Resource,
126 },
127+ /// verify the remote server is functional
128+ Ping,
129 }
130
131 fn print_completions<G: Generator>(gen: G, cmd: &mut Command) {
132 @@ -108,16 +111,21 @@ async fn main() -> Result<(), error::QuipuError> {
133 print_completions(shell, &mut cmd);
134 Ok(())
135 }
136- Commands::Get {
137- instance,
138- url,
139- resource: _,
140- } => {
141- let instance = get_instance(&cfg, url, instance)?;
142+ Commands::Get { resource: _ } => {
143+ let instance = get_instance(&cfg, cli.url, cli.instance)?;
144 let client = client_rest::Quipu::new(instance.url);
145 let collections = client.get_index().await?;
146 output::pretty(output::Resource::Collections(collections))?;
147 Ok(())
148 }
149+ Commands::Ping => {
150+ let instance = get_instance(&cfg, cli.url, cli.instance)?;
151+ let client = client_rest::Quipu::new(instance.url);
152+ let status = client.ping().await?;
153+ if !status.ok {
154+ return Err(error::QuipuError::Message("server is not ready".to_string()));
155+ }
156+ Ok(())
157+ }
158 }
159 }