Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add CLI option to get the json schema of inventory file. #559

Merged
merged 2 commits into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
_This paragraph may describe WIP/unreleased features. They are merged to main branch but not tagged._

- [Doc: reference Boavizta methodology paper. · Issue #552 · Boavizta/cloud-scanner](https://github.com/Boavizta/cloud-scanner/issues/552)
- [Expose the json schema of the inventory format · Issue #558 · Boavizta/cloud-scanner](https://github.com/Boavizta/cloud-scanner/issues/558). Use `cargo run inventory --print-json-schema` with CLI to get the schema on stdout.

## [3.0.1]-2024-06-19

Expand Down
29 changes: 29 additions & 0 deletions cloud-scanner-cli/src/inventory_exporter.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use anyhow::Context;
use schemars::schema_for;

use crate::model::Inventory;

Expand All @@ -13,3 +14,31 @@ pub async fn print_inventory(inventory: &Inventory) -> anyhow::Result<()> {
println!("{}", json_inventory);
Ok(())
}

/// Returns the json schema of an inventory as String
pub fn get_inventory_schema() -> anyhow::Result<String> {
let schema = schema_for!(Inventory);
let st = serde_json::to_string_pretty(&schema)?;
Ok(st)
}

/// Print inventory schema on stdout
pub fn print_inventory_schema() -> anyhow::Result<()> {
let s = get_inventory_schema()?;
println!("{}", s);
Ok(())
}

#[cfg(test)]
mod tests {
use crate::inventory_exporter::get_inventory_schema;
const INVENTORY_JSON_SCHEMA: &str = include_str!("../test-data/INVENTORY_JSON_SCHEMA.json");

#[test]
pub fn generate_inventory_schema() {
let s = get_inventory_schema().unwrap();
println!("{}", s);

assert_eq!(s, INVENTORY_JSON_SCHEMA, "schema do not match");
}
}
22 changes: 17 additions & 5 deletions cloud-scanner-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ enum SubCommand {
#[arg(long, short = 'b', action)]
/// Experimental feature: include block storage in the inventory
include_block_storage: bool,

/// Print the json schema of the inventory (instead of performing inventory)
#[arg(short = 's', long)]
print_json_schema: bool,
},
/// Run as a standalone server.
/// Access metrics (e.g. http://localhost:8000/metrics?aws_region=eu-west-3), inventory or impacts (see http://localhost:8000/swagger-ui)
Expand Down Expand Up @@ -168,12 +172,20 @@ async fn main() -> Result<()> {
}
SubCommand::Inventory {
include_block_storage,
print_json_schema,
} => {
info!("Using filter tags {:?}", &args.filter_tags);
let inventory =
cloud_scanner_cli::get_inventory(&args.filter_tags, &region, include_block_storage)
.await?;
print_inventory(&inventory).await?;
if print_json_schema {
cloud_scanner_cli::inventory_exporter::print_inventory_schema()?;
} else {
info!("Using filter tags {:?}", &args.filter_tags);
let inventory = cloud_scanner_cli::get_inventory(
&args.filter_tags,
&region,
include_block_storage,
)
.await?;
print_inventory(&inventory).await?;
}
}
SubCommand::Serve {} => cloud_scanner_cli::serve_metrics(&api_url).await?,
}
Expand Down
10 changes: 7 additions & 3 deletions cloud-scanner-cli/src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use std::{fmt, fs};
use crate::impact_provider::CloudResourceWithImpacts;
use crate::usage_location::UsageLocation;

/// Statistics about program execution
/// Statistics about program execution
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub struct ExecutionStatistics {
Expand All @@ -27,7 +27,7 @@ impl fmt::Display for ExecutionStatistics {
}
}

/// Inventory: a list of resources
/// A list of cloud resources and metadata that describes the inventory itself
#[derive(Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub struct Inventory {
Expand All @@ -39,10 +39,13 @@ pub struct Inventory {
#[derive(Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub struct InventoryMetadata {
/// The date when the inventory was generated
pub inventory_date: Option<DateTime<Utc>>,
/// A free text description of the inventory
pub description: Option<String>,
/// The version of the cloud scanner that generated the inventory
pub cloud_scanner_version: Option<String>,
/// Statistics about program execution
pub execution_statistics: Option<ExecutionStatistics>,
}

Expand All @@ -67,11 +70,12 @@ pub struct EstimatedInventory {
pub execution_statistics: Option<ExecutionStatistics>,
}

/// A cloud resource (could be an instance, function or any other resource)
/// A cloud resource (could be an instance, block storage or any other resource)
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct CloudResource {
pub provider: CloudProvider,
pub id: String,
/// The location where cloud resources are running.
pub location: UsageLocation,
pub resource_details: ResourceDetails,
pub tags: Vec<CloudResourceTag>,
Expand Down
Loading