Skip to content

Commit

Permalink
wip: refactor returned results to expose an OpenAPI spec.
Browse files Browse the repository at this point in the history
  • Loading branch information
DE MERINGO Olivier committed Jul 26, 2023
1 parent b6c65e8 commit 27bb2fe
Show file tree
Hide file tree
Showing 9 changed files with 279 additions and 21 deletions.
126 changes: 126 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[workspace]
resolver = "2"

default-members = [
"cloud-scanner-cli",
Expand Down
13 changes: 12 additions & 1 deletion cloud-scanner-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ authors = ["boavizta.org", "Olivier de Meringo <[email protected]>"]
edition = "2021"
name = "cloud-scanner-cli"
version = "0.3.0-alpha3"

[dependencies]
aws-types = "0.55.3"
chrono = "^0.4"
Expand All @@ -15,10 +16,20 @@ serde = "^1.0"
serde_derive = "^1.0"
serde_json = "^1.0"
anyhow = "1.0.65"
rocket = "0.5.0-rc.2"

async-trait = "0.1.58"
assert-json-diff = "2.0.2"

rocket = { version ="0.5.0-rc.3", default-features = false, features = ["json"]}
rocket_okapi = { version="0.8.0-rc.3", features = ["swagger", "rapidoc"]}

# schemars = { version = "0.8.10" }
# okapi = { version = "0.7", features = ["derive_json_schema"] }


# okapi = { version = "0.4", features = ["derive_json_schema"] }


[dependencies.boavizta_api_sdk]
version = "0.3.0-alpha2"
# path = "../../boaviztapi-sdk-rust"
Expand Down
8 changes: 5 additions & 3 deletions cloud-scanner-cli/src/cloud_resource.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use crate::UsageLocation;
//use anyhow::{Context, Result};
use rocket_okapi::okapi::schemars;
use rocket_okapi::okapi::schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::{collections::HashMap, fmt};

/// A cloud resource (could be an instance, function or any other resource)
#[derive(Clone, Debug, Serialize, Deserialize)]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct CloudResource {
pub provider: String,
pub id: String,
Expand All @@ -22,14 +24,14 @@ impl fmt::Display for CloudResource {
}

/// Usage of a cloud resource
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, JsonSchema)]
pub struct CloudResourceUsage {
pub average_cpu_load: f64,
pub usage_duration_seconds: u32,
}

/// A tag (just a mandatory key + optional value)
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
pub struct CloudResourceTag {
pub key: String,
pub value: Option<String>,
Expand Down
8 changes: 5 additions & 3 deletions cloud-scanner-cli/src/impact_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
use crate::cloud_resource::*;
use anyhow::Result;
use async_trait::async_trait;
use rocket_okapi::okapi::schemars;
use rocket_okapi::okapi::schemars::JsonSchema;
use serde::{Deserialize, Serialize};

/// A ImpactProvider trait that yu should implement for a specific impact API
Expand All @@ -24,7 +26,7 @@ pub trait ImpactProvider {
) -> Result<Vec<CloudResourceWithImpacts>>;
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct CloudResourceWithImpacts {
pub cloud_resource: CloudResource,
/// The impacts
Expand All @@ -34,7 +36,7 @@ pub struct CloudResourceWithImpacts {
}

/// Impacts of an individual resource
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
pub struct ResourceImpacts {
pub adp_manufacture_kgsbeq: f64,
pub adp_use_kgsbeq: f64,
Expand All @@ -45,7 +47,7 @@ pub struct ResourceImpacts {
}

/// The aggregated impacts and meta data about the scan results
#[derive(Clone, Debug, Serialize, Deserialize)]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct ImpactsSummary {
pub number_of_instances_total: u32,
pub number_of_instances_assessed: u32,
Expand Down
39 changes: 33 additions & 6 deletions cloud-scanner-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! A command line application that performs inventory of your cloud account and combines it with Boavizta API to return an estimation of its environmental impact.
//!
use crate::model::ExecutionStatistics;
use crate::model::{ExecutionStatistics, ResourcesWithImpacts};
use crate::usage_location::*;
use aws_inventory::*;
use boavizta_api_v1::*;
Expand All @@ -18,6 +18,7 @@ extern crate rocket;

#[macro_use]
extern crate log;
use model::Inventory;
use pkg_version::*;
use std::time::{Duration, Instant};
pub mod aws_inventory;
Expand All @@ -37,20 +38,20 @@ async fn standard_scan(
tags: &[String],
aws_region: &str,
api_url: &str,
) -> Result<Vec<CloudResourceWithImpacts>> {
) -> Result<ResourcesWithImpacts> {
let start = Instant::now();

let inventory: AwsInventory = AwsInventory::new(aws_region).await;
let cloud_resources: Vec<CloudResource> = inventory
.list_resources(tags)
.await
.context("Cannot perform resouces inventory")?;
.context("Cannot perform resources inventory")?;

let inventory_duration = start.elapsed();

let impact_start = Instant::now();
let api: BoaviztaApiV1 = BoaviztaApiV1::new(api_url);
let res = api
let vec = api
.get_impacts(cloud_resources, hours_use_time)
.await
.context("Failure while retrieving impacts")?;
Expand All @@ -66,10 +67,15 @@ async fn standard_scan(

info!("{}", stats);

let res: ResourcesWithImpacts = ResourcesWithImpacts {
impacts: vec,
execution_statistics: stats,
};

Ok(res)
}

/// Returns default impacts as json
/// Returns default impacts as json string
pub async fn get_default_impacts_as_json_string(
hours_use_time: &f32,
tags: &[String],
Expand Down Expand Up @@ -98,7 +104,7 @@ pub async fn get_default_impacts_as_metrics(
let summary: ImpactsSummary = ImpactsSummary::new(
String::from(aws_region),
usage_location.iso_country_code,
instances_with_impacts,
instances_with_impacts.impacts,
(*hours_use_time).into(),
);
debug!("Summary: {:#?}", summary);
Expand Down Expand Up @@ -153,6 +159,27 @@ pub async fn get_inventory_as_json(tags: &[String], aws_region: &str) -> Result<
serde_json::to_string(&cloud_resources).context("Cannot format inventory as json")
}

pub async fn get_inventory(tags: &[String], aws_region: &str) -> Result<Inventory> {
let start = Instant::now();
let aws_inventory: AwsInventory = AwsInventory::new(aws_region).await;
let cloud_resources: Vec<CloudResource> = aws_inventory
.list_resources(tags)
.await
.context("Cannot perform inventory.")?;
let stats = ExecutionStatistics {
inventory_duration: start.elapsed(),
impact_duration: Duration::from_millis(0),
total_duration: start.elapsed(),
};
warn!("{:?}", stats);

let inventory = Inventory {
resources: cloud_resources,
execution_statistics: stats,
};
Ok(inventory)
}

/// List instances and metadata to standard output
pub async fn show_inventory(tags: &[String], aws_region: &str) -> Result<()> {
let json_inventory: String = get_inventory_as_json(tags, aws_region).await?;
Expand Down
Loading

0 comments on commit 27bb2fe

Please sign in to comment.