From ad9982f5f4c4506b3b2066584f39087029bcbe2e Mon Sep 17 00:00:00 2001 From: Sascha Eglau Date: Sat, 17 Feb 2024 14:43:11 +0100 Subject: [PATCH] feat: add list services command --- src/api/mod.rs | 98 +++++++++++++++----------------------------- src/api/types.rs | 10 ++++- src/commands/apps.rs | 43 +++++++++++++++++-- src/main.rs | 6 +-- 4 files changed, 85 insertions(+), 72 deletions(-) diff --git a/src/api/mod.rs b/src/api/mod.rs index b441e5b..b4dfaef 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -1,6 +1,7 @@ use std::collections::HashMap; +use reqwest::blocking::Response; -use self::types::{ListOrganizationResponse, Organization, CreateEnvironmentResponse}; +use self::types::{ListOrganizationResponse, Organization, CreateEnvironmentResponse, ListServicesResponse}; pub mod types; @@ -24,15 +25,7 @@ impl APIClient { token: &str, ) -> Result { let url = format!("{}/orgs", self.base_url); - - let response = self.client - .get(url) - .header("User-Agent", self.user_agent.as_str()) - .header("Authorization", format!("Bearer {}", token)) - .header("Content-Type", "application/json") - .send()? - .error_for_status()?; - + let response = self.get(&url, token)?; response.json() } @@ -42,32 +35,18 @@ impl APIClient { name: &str ) -> Result { let url = format!("{}/organization", self.base_url); - - let response = self.client - .get(url) - .header("User-Agent", self.user_agent.as_str()) - .header("Authorization", format!("Bearer {}", token)) - .header("Content-Type", "application/json") - .send()? - .error_for_status()?; - + let response = self.get(&url, token)?; response.json() } - pub fn get_applications( + pub fn get_services( &self, token: &str, - ) -> Result { - let url = format!("{}/organization", self.base_url); - - let response = self.client - .get(url) - .header("User-Agent", self.user_agent.as_str()) - .header("Authorization", format!("Bearer {}", token)) - .header("Content-Type", "application/json") - .send()? - .error_for_status()?; - + org_name: &str, + env_name: &str + ) -> Result { + let url = format!("{}/orgs/{}/envs/{}/svcs", self.base_url, org_name, env_name); + let response = self.get(&url, token)?; response.json() } @@ -78,21 +57,10 @@ impl APIClient { billing_email: &str, ) -> Result { let url = format!("{}/orgs", self.base_url); - let mut body = HashMap::new(); body.insert("name", name); body.insert("billing_email", billing_email); - - let response = self - .client - .post(url) - .header("User-Agent", self.user_agent.as_str()) - .header("Authorization", format!("Bearer {}", token)) - .header("Content-Type", "application/json") - .json(&body) - .send()? - .error_for_status()?; - + let response = self.post(&url, token, &body)?; response.json() } @@ -102,15 +70,7 @@ impl APIClient { org_name: &str ) -> Result, reqwest::Error> { let url = format!("{}/orgs/{}/envs", self.base_url, org_name); - - let response = self.client - .get(url) - .header("User-Agent", self.user_agent.as_str()) - .header("Authorization", format!("Bearer {}", token)) - .header("Content-Type", "application/json") - .send()? - .error_for_status()?; - + let response = self.get(&url, token)?; response.json() } @@ -121,20 +81,9 @@ impl APIClient { org_name: &str ) -> Result { let url = format!("{}/orgs/{}/envs", self.base_url, org_name); - let mut body = HashMap::new(); body.insert("name", name); - - let response = self - .client - .post(url) - .header("User-Agent", self.user_agent.as_str()) - .header("Authorization", format!("Bearer {}", token)) - .header("Content-Type", "application/json") - .json(&body) - .send()? - .error_for_status()?; - + let response = self.post(&url, token, &body)?; response.json() } @@ -145,4 +94,25 @@ impl APIClient { response.json() } + + fn get(&self, url: &str, token: &str) -> Result { + return self.client + .get(url) + .header("User-Agent", self.user_agent.as_str()) + .header("Authorization", format!("Bearer {}", token)) + .header("Content-Type", "application/json") + .send()? + .error_for_status(); + } + + fn post(&self, url: &str, token: &str, body: &HashMap<&str, &str>) -> Result { + return self.client + .post(url) + .header("User-Agent", self.user_agent.as_str()) + .header("Authorization", format!("Bearer {}", token)) + .header("Content-Type", "application/json") + .json(&body) + .send()? + .error_for_status(); + } } diff --git a/src/api/types.rs b/src/api/types.rs index c7cbec1..9ff9f1f 100644 --- a/src/api/types.rs +++ b/src/api/types.rs @@ -19,7 +19,13 @@ pub struct CreateEnvironmentResponse { } #[derive(Serialize, Deserialize, Debug)] -pub struct Application { +pub struct ListServicesResponse { + pub services: Vec +} + +#[derive(Serialize, Deserialize, Debug, Tabled)] +pub struct Service { name: String, - organization_id: String, + image: String, + container_port: u16, } diff --git a/src/commands/apps.rs b/src/commands/apps.rs index 0b8a80a..022333f 100644 --- a/src/commands/apps.rs +++ b/src/commands/apps.rs @@ -3,6 +3,7 @@ use clap::{Parser, Subcommand}; use dialoguer::{FuzzySelect, Input}; use std::path::Path; use super::CommandBase; +use tabled::Table; use crate::config::{ application::{Build, HttpService}, @@ -19,16 +20,17 @@ use crate::config::{ subcommand_required = true, arg_required_else_help = true )] -pub struct Apps { +pub struct Services { #[command(subcommand)] pub command: Option, } -impl Apps { +impl Services { pub fn execute(&self, base: &mut CommandBase) -> Result<()> { match &self.command { Some(Commands::Deploy(depl)) => depl.execute(base), Some(Commands::Initialize(init)) => init.execute(base), + Some(Commands::List(list)) => list.execute(base), None => Ok(()) } } @@ -42,6 +44,8 @@ pub enum Commands { Deploy(Deploy), /// Generate Dockerfile and Molnett manifest Initialize(Initialize), + /// List services + List(List) } #[derive(Parser)] @@ -72,7 +76,6 @@ impl Deploy { // 4. submit change Ok(()) } - } #[derive(Parser, Debug)] @@ -294,3 +297,37 @@ impl InitPlan { InitPlanBuilder::new(base) } } + +#[derive(Parser)] +#[derive(Debug)] +pub struct List { + #[arg(long, help = "Organization to list the services of")] + org: Option, + #[arg(long, help = "Environment to list the services of")] + env: String, +} + +impl List { + pub fn execute(&self, base: &CommandBase) -> Result<()> { + let org_name = if self.org.is_some() { + self.org.clone().unwrap() + } else { + base.user_config().get_default_org().unwrap().to_string() + }; + let token = base + .user_config() + .get_token() + .ok_or_else(|| anyhow!("No token found. Please login first."))?; + + let response = base.api_client().get_services( + token, + &org_name, + &self.env + )?; + + let table = Table::new(response.services).to_string(); + println!("{}", table); + + Ok(()) + } +} diff --git a/src/main.rs b/src/main.rs index 68d374a..f03d188 100644 --- a/src/main.rs +++ b/src/main.rs @@ -36,8 +36,8 @@ enum Commands { Orgs(commands::orgs::Orgs), /// Login to Molnett Auth(commands::auth::Auth), - /// Deploy and manage apps - Apps(commands::apps::Apps), + /// Deploy and manage services + Services(commands::apps::Services), /// Create and manage environments Environments(commands::environments::Environments), } @@ -53,7 +53,7 @@ fn main() -> Result<()> { let mut base = CommandBase::new(&mut config); match cli.command { - Some(Commands::Apps(apps)) => apps.execute(&mut base), + Some(Commands::Services(svcs)) => svcs.execute(&mut base), Some(Commands::Auth(auth)) => auth.execute(&mut base), Some(Commands::Environments(environments)) => environments.execute(&mut base), Some(Commands::Orgs(orgs)) => orgs.execute(&mut base),