Skip to content

Commit

Permalink
refactor: switch to resource endpoint (#748)
Browse files Browse the repository at this point in the history
  • Loading branch information
chesedo authored Mar 24, 2023
1 parent 97dd1a7 commit a69dc27
Show file tree
Hide file tree
Showing 14 changed files with 311 additions and 325 deletions.
9 changes: 9 additions & 0 deletions cargo-shuttle/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ pub enum Command {
/// manage deployments of a shuttle service
#[command(subcommand)]
Deployment(DeploymentCommand),
/// manage resources of a shuttle project
#[command(subcommand)]
Resource(ResourceCommand),
/// create a new shuttle service
Init(InitArgs),
/// generate shell completions
Expand Down Expand Up @@ -105,6 +108,12 @@ pub enum DeploymentCommand {
},
}

#[derive(Parser)]
pub enum ResourceCommand {
/// list all the resources for a project
List,
}

#[derive(Parser)]
pub enum ProjectCommand {
/// create an environment for this project on shuttle
Expand Down
20 changes: 16 additions & 4 deletions cargo-shuttle/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use reqwest_retry::RetryTransientMiddleware;
use serde::{Deserialize, Serialize};
use shuttle_common::models::{deployment, project, secret, service, ToJson};
use shuttle_common::project::ProjectName;
use shuttle_common::{ApiKey, ApiUrl, LogItem};
use shuttle_common::{resource, ApiKey, ApiUrl, LogItem};
use tokio::net::TcpStream;
use tokio_tungstenite::tungstenite::client::IntoClientRequest;
use tokio_tungstenite::{connect_async, MaybeTlsStream, WebSocketStream};
Expand Down Expand Up @@ -75,7 +75,7 @@ impl Client {
self.delete(path).await
}

pub async fn get_service_details(&self, project: &ProjectName) -> Result<service::Detailed> {
pub async fn get_service(&self, project: &ProjectName) -> Result<service::Summary> {
let path = format!(
"/projects/{}/services/{}",
project.as_str(),
Expand All @@ -85,9 +85,12 @@ impl Client {
self.get(path).await
}

pub async fn get_service_summary(&self, project: &ProjectName) -> Result<service::Summary> {
pub async fn get_service_resources(
&self,
project: &ProjectName,
) -> Result<Vec<resource::Response>> {
let path = format!(
"/projects/{}/services/{}/summary",
"/projects/{}/services/{}/resources",
project.as_str(),
project.as_str()
);
Expand Down Expand Up @@ -184,6 +187,15 @@ impl Client {
self.ws_get(path).await
}

pub async fn get_deployments(
&self,
project: &ProjectName,
) -> Result<Vec<deployment::Response>> {
let path = format!("/projects/{}/deployments", project.as_str());

self.get(path).await
}

pub async fn get_deployment_details(
&self,
project: &ProjectName,
Expand Down
38 changes: 29 additions & 9 deletions cargo-shuttle/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ mod provisioner_server;

use cargo::util::ToSemver;
use indicatif::ProgressBar;
use shuttle_common::models::deployment::get_deployments_table;
use shuttle_common::models::project::{State, IDLE_MINUTES};
use shuttle_common::models::service::get_resources_table;
use shuttle_common::models::resource::get_resources_table;
use shuttle_common::project::ProjectName;
use shuttle_common::resource;
use shuttle_proto::runtime::{self, LoadRequest, StartRequest, SubscribeLogsRequest};
Expand Down Expand Up @@ -43,7 +44,7 @@ use tar::Builder;
use tracing::{error, trace, warn};
use uuid::Uuid;

use crate::args::{DeploymentCommand, ProjectCommand};
use crate::args::{DeploymentCommand, ProjectCommand, ResourceCommand};
use crate::client::Client;
use crate::provisioner_server::LocalProvisioner;

Expand All @@ -66,6 +67,7 @@ impl Shuttle {
args.cmd,
Command::Deploy(..)
| Command::Deployment(..)
| Command::Resource(..)
| Command::Project(..)
| Command::Stop
| Command::Clean
Expand Down Expand Up @@ -102,6 +104,7 @@ impl Shuttle {
Command::Deployment(DeploymentCommand::Status { id }) => {
self.deployment_get(&client, id).await
}
Command::Resource(ResourceCommand::List) => self.resources_list(&client).await,
Command::Stop => self.stop(&client).await,
Command::Clean => self.clean(&client).await,
Command::Secrets => self.secrets(&client).await,
Expand Down Expand Up @@ -300,7 +303,7 @@ impl Shuttle {
}

progress_bar.set_message(format!("Stopping {}", deployment.id));
service = client.get_service_summary(self.ctx.project_name()).await?;
service = client.get_service(self.ctx.project_name()).await?;
}
progress_bar.finish_and_clear();

Expand All @@ -326,7 +329,7 @@ impl Shuttle {
}

async fn status(&self, client: &Client) -> Result<()> {
let summary = client.get_service_summary(self.ctx.project_name()).await?;
let summary = client.get_service(self.ctx.project_name()).await?;

println!("{summary}");

Expand Down Expand Up @@ -358,7 +361,7 @@ impl Shuttle {
let id = if let Some(id) = id {
id
} else {
let summary = client.get_service_summary(self.ctx.project_name()).await?;
let summary = client.get_service(self.ctx.project_name()).await?;

if let Some(deployment) = summary.deployment {
deployment.id
Expand Down Expand Up @@ -389,9 +392,10 @@ impl Shuttle {
}

async fn deployments_list(&self, client: &Client) -> Result<()> {
let details = client.get_service_details(self.ctx.project_name()).await?;
let deployments = client.get_deployments(self.ctx.project_name()).await?;
let table = get_deployments_table(&deployments, self.ctx.project_name().as_str());

println!("{details}");
println!("{table}");

Ok(())
}
Expand All @@ -406,6 +410,17 @@ impl Shuttle {
Ok(())
}

async fn resources_list(&self, client: &Client) -> Result<()> {
let resources = client
.get_service_resources(self.ctx.project_name())
.await?;
let table = get_resources_table(&resources);

println!("{table}");

Ok(())
}

async fn local_run(&self, run_args: RunArgs) -> Result<()> {
trace!("starting a local run for a service: {run_args:?}");

Expand Down Expand Up @@ -673,11 +688,16 @@ impl Shuttle {
}
}

let service = client.get_service_summary(self.ctx.project_name()).await?;
let service = client.get_service(self.ctx.project_name()).await?;

// A deployment will only exist if there is currently one in the running state
if let Some(ref new_deployment) = service.deployment {
println!("{service}");
let resources = client
.get_service_resources(self.ctx.project_name())
.await?;
let resources = get_resources_table(&resources);

println!("{resources}{service}");

Ok(match new_deployment.state {
shuttle_common::deployment::State::Crashed => CommandOutcome::DeploymentFailure,
Expand Down
7 changes: 7 additions & 0 deletions common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ pub enum ParseError {
Serde(#[from] serde_json::Error),
}

/// Holds the output for a DB resource
#[derive(Deserialize, Serialize)]
pub enum DbOutput {
Info(DatabaseReadyInfo),
Local(String),
}

/// Holds the details for a database connection
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DatabaseReadyInfo {
Expand Down
45 changes: 44 additions & 1 deletion common/src/models/deployment.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use std::fmt::Display;

use chrono::{DateTime, Utc};
use comfy_table::Color;
use comfy_table::{
modifiers::UTF8_ROUND_CORNERS, presets::UTF8_FULL, Cell, CellAlignment, Color,
ContentArrangement, Table,
};
use crossterm::style::Stylize;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
Expand Down Expand Up @@ -42,3 +45,43 @@ impl State {
}
}
}

pub fn get_deployments_table(deployments: &Vec<Response>, service_name: &str) -> String {
if deployments.is_empty() {
format!(
"{}\n",
"No deployments are linked to this service".yellow().bold()
)
} else {
let mut table = Table::new();
table
.load_preset(UTF8_FULL)
.apply_modifier(UTF8_ROUND_CORNERS)
.set_content_arrangement(ContentArrangement::DynamicFullWidth)
.set_header(vec![
Cell::new("ID").set_alignment(CellAlignment::Center),
Cell::new("Status").set_alignment(CellAlignment::Center),
Cell::new("Last updated").set_alignment(CellAlignment::Center),
]);

for deploy in deployments.iter() {
table.add_row(vec![
Cell::new(deploy.id),
Cell::new(&deploy.state)
.fg(deploy.state.get_color())
.set_alignment(CellAlignment::Center),
Cell::new(deploy.last_update.format("%Y-%m-%dT%H:%M:%SZ"))
.set_alignment(CellAlignment::Center),
]);
}

format!(
r#"
Most recent deploys for {}
{}
"#,
service_name.bold(),
table,
)
}
}
1 change: 1 addition & 0 deletions common/src/models/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod deployment;
pub mod error;
pub mod project;
pub mod resource;
pub mod secret;
pub mod service;
pub mod stats;
Expand Down
Loading

0 comments on commit a69dc27

Please sign in to comment.