-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Added ready subcommand to cli (#267)
Co-authored-by: Simon Hornby <[email protected]>
- Loading branch information
Showing
10 changed files
with
236 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
use crate::cli::ReadyCheckArgs; | ||
use crate::error::EdgeError; | ||
use crate::internal_backstage::EdgeStatus; | ||
use crate::tls::build_upstream_certificate; | ||
use crate::types::Status; | ||
use reqwest::{ClientBuilder, Url}; | ||
|
||
fn build_ready_url(url: &Url) -> Url { | ||
let mut with_path = url.clone(); | ||
with_path | ||
.path_segments_mut() | ||
.expect("Could not build ready url") | ||
.push("internal-backstage") | ||
.push("ready"); | ||
with_path | ||
} | ||
|
||
pub async fn check_ready(ready_check_args: ReadyCheckArgs) -> Result<(), EdgeError> { | ||
let client = match build_upstream_certificate(ready_check_args.ca_certificate_file)? { | ||
Some(cert) => ClientBuilder::new() | ||
.add_root_certificate(cert) | ||
.build() | ||
.expect("Failed to build ready check client"), | ||
None => reqwest::Client::default(), | ||
}; | ||
let base_url = Url::parse(&ready_check_args.edge_url) | ||
.map_err(|p| EdgeError::ReadyCheckError(format!("Invalid ready check url: {p:?}")))?; | ||
let ready_check_url = build_ready_url(&base_url); | ||
let r = client | ||
.get(ready_check_url.clone()) | ||
.send() | ||
.await | ||
.map_err(|e| { | ||
EdgeError::ReadyCheckError(format!( | ||
"Failed to connect to ready endpoint at {}. Failed with status {:?}", | ||
ready_check_url, | ||
e.status() | ||
)) | ||
})?; | ||
if r.status() == 200 { | ||
let ready_check_result: EdgeStatus = r.json().await.map_err(|e| { | ||
EdgeError::ReadyCheckError(format!( | ||
"Ready check endpoint returned data we didn't understand. {e:?}" | ||
)) | ||
})?; | ||
match ready_check_result.status { | ||
Status::Ready => { | ||
println!("OK"); | ||
Ok(()) | ||
} | ||
_ => Err(EdgeError::ReadyCheckError(format!( | ||
"Ready check returned a different status than READY. It returned {:?}", | ||
ready_check_result | ||
))), | ||
} | ||
} else { | ||
Err(EdgeError::ReadyCheckError(format!( | ||
"Ready check did not return 200 for {}. It returned {}", | ||
ready_check_url, | ||
r.status() | ||
))) | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use crate::cli::ReadyCheckArgs; | ||
use crate::internal_backstage::ready; | ||
use crate::ready_checker::check_ready; | ||
use actix_http::HttpService; | ||
use actix_http_test::test_server; | ||
use actix_service::map_config; | ||
use actix_web::dev::AppConfig; | ||
use actix_web::{web, App, HttpResponse}; | ||
use dashmap::DashMap; | ||
use std::sync::Arc; | ||
use unleash_types::client_features::{ClientFeature, ClientFeatures}; | ||
|
||
#[tokio::test] | ||
pub async fn runs_ready_check() { | ||
let features = ClientFeatures { | ||
features: vec![ClientFeature { | ||
name: "test".to_string(), | ||
..ClientFeature::default() | ||
}], | ||
query: None, | ||
segments: None, | ||
version: 2, | ||
}; | ||
let client_features: DashMap<String, ClientFeatures> = DashMap::default(); | ||
client_features.insert( | ||
"testproject:testenvironment.testtoken".into(), | ||
features.clone(), | ||
); | ||
let client_features_arc = Arc::new(client_features); | ||
let srv = test_server(move || { | ||
HttpService::new(map_config( | ||
App::new() | ||
.app_data(web::Data::from(client_features_arc.clone())) | ||
.service(web::scope("/internal-backstage").service(ready)), | ||
|_| AppConfig::default(), | ||
)) | ||
.tcp() | ||
}) | ||
.await; | ||
let url = srv.url("/"); | ||
let check_result = check_ready(ReadyCheckArgs { | ||
ca_certificate_file: None, | ||
edge_url: url, | ||
}) | ||
.await; | ||
assert!(check_result.is_ok()); | ||
} | ||
|
||
#[tokio::test] | ||
pub async fn errors_if_ready_check_fails() { | ||
let check_result = check_ready(ReadyCheckArgs { | ||
ca_certificate_file: None, | ||
edge_url: "http://bogusurl".into(), | ||
}) | ||
.await; | ||
assert!(check_result.is_err()); | ||
} | ||
|
||
async fn conflict() -> HttpResponse { | ||
HttpResponse::Conflict().finish() | ||
} | ||
|
||
#[tokio::test] | ||
pub async fn errors_if_ready_check_returns_different_status_than_200() { | ||
let srv = test_server(move || { | ||
HttpService::new(map_config( | ||
App::new().service( | ||
web::scope("/internal-backstage").route("/ready", web::get().to(conflict)), | ||
), | ||
|_| AppConfig::default(), | ||
)) | ||
.tcp() | ||
}) | ||
.await; | ||
let url = srv.url("/"); | ||
let check_result = check_ready(ReadyCheckArgs { | ||
ca_certificate_file: None, | ||
edge_url: url, | ||
}) | ||
.await; | ||
assert!(check_result.is_err()); | ||
} | ||
|
||
#[tokio::test] | ||
pub async fn fails_if_given_an_invalid_url() { | ||
let check_result = check_ready(ReadyCheckArgs { | ||
ca_certificate_file: None, | ||
edge_url: ":\\///\\/".into(), | ||
}) | ||
.await; | ||
assert!(check_result.is_err()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.