cloud_scanner_cli/
standalone_server.rs

1//! An HTTP endpoint that exposes the results of cloud-scanner like inventory, impacts or metrics.
2
3use crate::model::{EstimatedInventory, Inventory};
4use rocket::State;
5use rocket::{get, serde::json::Json};
6use rocket_okapi::{openapi, openapi_get_routes, swagger_ui::*};
7
8///  Configuration for the metric server
9pub struct Config {
10    pub boavizta_url: String,
11}
12
13/// Start the server
14pub async fn run(config: Config) -> Result<(), rocket::Error> {
15    let _rocket = rocket::build()
16        .mount(
17            "/",
18            openapi_get_routes![
19                index,
20                metrics,
21                inventory,
22                impacts,
23                impacts_from_arbitrary_inventory
24            ],
25        )
26        .mount(
27            "/swagger-ui/",
28            make_swagger_ui(&SwaggerUIConfig {
29                url: "../openapi.json".to_owned(),
30                ..Default::default()
31            }),
32        )
33        .manage(config)
34        .launch()
35        .await?;
36    Ok(())
37}
38
39/// Just display help
40#[openapi(skip)]
41#[get("/")]
42fn index(config: &State<Config>) -> String {
43    warn!("Getting request on /");
44    let version: String = crate::get_version();
45    format!("Cloud scanner metric server  {} is running.\n\nUsing Boavizta API at: {}.\nMetrics are exposed on /metrics path and require passing a **region** in query string.\n e.g.  http://localhost:8000/metrics?aws_region=eu-west-3 \n See also /swagger-ui .", version, config.boavizta_url)
46}
47
48/// # Returns Prometheus metrics.
49///
50/// Region is mandatory. Filter_tags (if any) should be written as string containing tag_name=tag_value
51///
52/// Results are estimated for one hour of use by default.
53///
54/// Example query: http://localhost:8000/metrics?aws_region=eu-west-3&filter_tag=Name=boatest&filter_tag=OtherTag=other-value&use_duration_hours=1.0&include_storage=true
55#[openapi(tag = "metrics")]
56#[get("/metrics?<aws_region>&<filter_tags>&<use_duration_hours>&<include_block_storage>")]
57async fn metrics(
58    config: &State<Config>,
59    aws_region: &str,
60    filter_tags: Option<Vec<String>>,
61    use_duration_hours: Option<f32>,
62    include_block_storage: Option<bool>,
63) -> String {
64    warn!("Getting something on /metrics");
65    let hours_use_time = use_duration_hours.unwrap_or(1.0);
66    warn!("Filtering on tags {:?}", filter_tags);
67    let metrics = crate::get_impacts_as_metrics(
68        &hours_use_time,
69        &filter_tags.unwrap_or_default(),
70        aws_region,
71        &config.boavizta_url,
72        include_block_storage.unwrap_or(false),
73    )
74    .await;
75    metrics.unwrap()
76}
77
78/// # Returns current inventory.
79///
80/// Region is mandatory. Filter_tags (if any) should be written as string containing tag_name=tag_value
81///
82/// Example query: http://localhost:8000/inventory?aws_region=eu-west-3&filter_tag=Name=boatest&filter_tag=OtherTag=other-value
83#[openapi(tag = "inventory")]
84#[get("/inventory?<aws_region>&<filter_tags>&<include_block_storage>")]
85async fn inventory(
86    _config: &State<Config>,
87    aws_region: &str,
88    filter_tags: Option<Vec<String>>,
89    include_block_storage: Option<bool>,
90) -> Json<Inventory> {
91    warn!("Getting something on /inventory");
92    warn!("Filtering on tags {:?}", filter_tags);
93    Json(
94        crate::get_inventory(
95            &filter_tags.unwrap_or_default(),
96            aws_region,
97            include_block_storage.unwrap_or(false),
98        )
99        .await
100        .unwrap(),
101    )
102}
103
104/// # Returns the impacts of current inventory.
105///
106/// Region is mandatory. Filter_tags (if any) should be written as string containing tag_name=tag_value
107///
108/// Example query: http://localhost:8000/impacts?aws_region=eu-west-3&filter_tag=Name=boatest&filter_tag=OtherTag=other-value&use_duration_hours=1.0
109#[openapi(tag = "impacts")]
110#[get(
111    "/impacts?<aws_region>&<filter_tags>&<use_duration_hours>&<verbose_output>&<include_block_storage>"
112)]
113async fn impacts(
114    _config: &State<Config>,
115    aws_region: &str,
116    filter_tags: Option<Vec<String>>,
117    use_duration_hours: Option<f32>,
118    verbose_output: Option<bool>,
119    include_block_storage: Option<bool>,
120) -> Json<EstimatedInventory> {
121    let hours_use_time = use_duration_hours.unwrap_or(1.0);
122    //let hours_use_time: f32 = 1.0;
123    warn!(
124        "Requesting /impacts for a duration of {} hours",
125        hours_use_time
126    );
127    warn!("Filtering on tags {:?}", filter_tags);
128    let res = crate::estimate_impacts(
129        &hours_use_time,
130        &filter_tags.unwrap_or_default(),
131        aws_region,
132        &_config.boavizta_url,
133        verbose_output.unwrap_or(false),
134        include_block_storage.unwrap_or(false),
135    )
136    .await
137    .unwrap();
138    Json(res)
139}
140/*
141#[post(
142"/impacts-from-json?<aws_region>&<use_duration_hours>", data = "<task>"
143)]*/
144/// # Retrieve the impacts of arbitrary inventory.
145///
146/// This can be used to evaluate impacts of a not yet implemented architecture.
147///
148/// The inventory is passed as json data in the request body.
149#[openapi(tag = "impacts")]
150#[post(
151    "/impacts-from-arbitrary-inventory?<use_duration_hours>&<verbose_output>",
152    data = "<inventory>"
153)]
154async fn impacts_from_arbitrary_inventory(
155    _config: &State<Config>,
156    use_duration_hours: Option<f32>,
157    verbose_output: Option<bool>,
158    inventory: Json<Inventory>,
159) -> Json<EstimatedInventory> {
160    let hours_use_time = use_duration_hours.unwrap_or(1.0);
161    let res = crate::estimate_impacts_of_inventory(
162        &hours_use_time,
163        &_config.boavizta_url,
164        verbose_output.unwrap_or(false),
165        inventory.into_inner(),
166    )
167    .await
168    .unwrap();
169    Json(res)
170}