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(cargo-shuttle): beta flag, remove project list pagination logic #1732

Merged
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
6 changes: 3 additions & 3 deletions cargo-shuttle/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ version = "0.43.0"
edition.workspace = true
license.workspace = true
repository.workspace = true
description = "A cargo command for the shuttle platform (https://www.shuttle.rs/)"
description = "A cargo command for the Shuttle platform (https://www.shuttle.rs/)"
homepage = "https://www.shuttle.rs"

[dependencies]
Expand Down Expand Up @@ -32,10 +32,10 @@ gix = { version = "0.55.2", default-features = false, features = [
"worktree-mutation",
] }
globset = "0.4.13"
home = { workspace = true }
headers = { workspace = true }
indicatif = "0.17.3"
home = { workspace = true }
ignore = "0.4.20"
indicatif = "0.17.3"
indoc = "2.0.1"
percent-encoding = { workspace = true }
portpicker = { workspace = true }
Expand Down
9 changes: 6 additions & 3 deletions cargo-shuttle/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ pub struct ShuttleArgs {
/// Turn on tracing output for cargo-shuttle and shuttle libraries.
#[arg(long, env = "SHUTTLE_DEBUG")]
pub debug: bool,
/// Target Shuttle's development environment
#[arg(long, env = "SHUTTLE_BETA")]
pub beta: bool,

#[command(subcommand)]
pub cmd: Command,
Expand Down Expand Up @@ -158,7 +161,7 @@ pub enum DeploymentCommand {
limit: u32,

#[arg(long, default_value_t = false)]
/// Output table in `raw` format
/// Output table without borders
raw: bool,
},
/// View status of a deployment
Expand All @@ -173,7 +176,7 @@ pub enum ResourceCommand {
/// List all the resources for a project
List {
#[arg(long, default_value_t = false)]
/// Output table in `raw` format
/// Output table without borders
raw: bool,

#[arg(
Expand Down Expand Up @@ -219,7 +222,7 @@ pub enum ProjectCommand {
limit: u32,

#[arg(long, default_value_t = false)]
/// Output table in `raw` format
/// Output table without borders
raw: bool,
},
/// Delete a project and all linked data
Expand Down
76 changes: 40 additions & 36 deletions cargo-shuttle/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,25 @@ use serde::{Deserialize, Serialize};
use shuttle_common::constants::headers::X_CARGO_SHUTTLE_VERSION;
use shuttle_common::models::deployment::DeploymentRequest;
use shuttle_common::models::{deployment, project, service, ToJson};
use shuttle_common::secrets::Secret;
use shuttle_common::{resource, ApiKey, ApiUrl, LogItem, VersionInfo};
use shuttle_common::{resource, ApiKey, LogItem, VersionInfo};
use tokio::net::TcpStream;
use tokio_tungstenite::tungstenite::client::IntoClientRequest;
use tokio_tungstenite::{connect_async, MaybeTlsStream, WebSocketStream};
use tracing::error;
use uuid::Uuid;

#[derive(Clone)]
pub struct Client {
api_url: ApiUrl,
api_key: Option<Secret<ApiKey>>,
pub struct ShuttleApiClient {
client: reqwest::Client,
api_url: String,
api_key: Option<ApiKey>,
/// alter behaviour to interact with the new platform
beta: bool,
}

impl Client {
pub fn new(api_url: ApiUrl) -> Self {
impl ShuttleApiClient {
pub fn new(api_url: String, api_key: Option<ApiKey>, beta: bool) -> Self {
Self {
api_url,
api_key: None,
client: reqwest::Client::builder()
.default_headers(
HeaderMap::try_from(&HashMap::from([(
Expand All @@ -42,11 +41,22 @@ impl Client {
.timeout(Duration::from_secs(60))
.build()
.unwrap(),
api_url,
api_key,
beta,
}
}

pub fn set_api_key(&mut self, api_key: ApiKey) {
self.api_key = Some(Secret::new(api_key));
self.api_key = Some(api_key);
}

fn set_auth_bearer(&self, builder: RequestBuilder) -> RequestBuilder {
if let Some(ref api_key) = self.api_key {
builder.bearer_auth(api_key.as_ref())
} else {
builder
}
}

pub async fn get_api_versions(&self) -> Result<VersionInfo> {
Expand Down Expand Up @@ -79,13 +89,17 @@ impl Client {
project: &str,
deployment_req: DeploymentRequest,
) -> Result<deployment::Response> {
let path = format!("/projects/{project}/services/{project}");
let path = if self.beta {
format!("/projects/{project}")
} else {
format!("/projects/{project}/services/{project}")
};
let deployment_req = rmp_serde::to_vec(&deployment_req)
.context("serialize DeploymentRequest as a MessagePack byte vector")?;

let url = format!("{}{}", self.api_url, path);
let mut builder = self.client.post(url);
builder = self.set_builder_auth(builder);
builder = self.set_auth_bearer(builder);

builder
.header("Transfer-Encoding", "chunked")
Expand Down Expand Up @@ -161,10 +175,8 @@ impl Client {
self.get(path).await
}

pub async fn get_projects_list(&self, page: u32, limit: u32) -> Result<Vec<project::Response>> {
let path = format!("/projects?page={}&limit={}", page.saturating_sub(1), limit);

self.get(path).await
pub async fn get_projects_list(&self) -> Result<Vec<project::Response>> {
self.get("/projects".to_owned()).await
}

pub async fn stop_project(&self, project: &str) -> Result<project::Response> {
Expand All @@ -174,7 +186,11 @@ impl Client {
}

pub async fn delete_project(&self, project: &str) -> Result<String> {
let path = format!("/projects/{project}/delete");
let path = if self.beta {
format!("/projects/{project}")
} else {
format!("/projects/{project}/delete")
};

self.delete(path).await
}
Expand Down Expand Up @@ -228,12 +244,12 @@ impl Client {
}

async fn ws_get(&self, path: String) -> Result<WebSocketStream<MaybeTlsStream<TcpStream>>> {
let ws_scheme = self.api_url.clone().replace("http", "ws");
let url = format!("{ws_scheme}{path}");
let ws_url = self.api_url.clone().replace("http", "ws");
let url = format!("{ws_url}{path}");
let mut request = url.into_client_request()?;

if let Some(ref api_key) = self.api_key {
let auth_header = Authorization::bearer(api_key.expose().as_ref())?;
let auth_header = Authorization::bearer(api_key.as_ref())?;
request.headers_mut().typed_insert(auth_header);
}

Expand All @@ -252,8 +268,7 @@ impl Client {
let url = format!("{}{}", self.api_url, path);

let mut builder = self.client.get(url);

builder = self.set_builder_auth(builder);
builder = self.set_auth_bearer(builder);

builder
.send()
Expand All @@ -267,8 +282,7 @@ impl Client {
let url = format!("{}{}", self.api_url, path);

let mut builder = self.client.post(url);

builder = self.set_builder_auth(builder);
builder = self.set_auth_bearer(builder);

if let Some(body) = body {
let body = serde_json::to_string(&body)?;
Expand All @@ -283,8 +297,7 @@ impl Client {
let url = format!("{}{}", self.api_url, path);

let mut builder = self.client.put(url);

builder = self.set_builder_auth(builder);
builder = self.set_auth_bearer(builder);

if let Some(body) = body {
let body = serde_json::to_string(&body)?;
Expand All @@ -302,8 +315,7 @@ impl Client {
let url = format!("{}{}", self.api_url, path);

let mut builder = self.client.delete(url);

builder = self.set_builder_auth(builder);
builder = self.set_auth_bearer(builder);

builder
.send()
Expand All @@ -312,12 +324,4 @@ impl Client {
.to_json()
.await
}

fn set_builder_auth(&self, builder: RequestBuilder) -> RequestBuilder {
if let Some(ref api_key) = self.api_key {
builder.bearer_auth(api_key.expose().as_ref())
} else {
builder
}
}
}
8 changes: 4 additions & 4 deletions cargo-shuttle/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::path::{Path, PathBuf};

use anyhow::{anyhow, Context, Result};
use serde::{Deserialize, Serialize};
use shuttle_common::{constants::API_URL_DEFAULT, ApiKey, ApiUrl};
use shuttle_common::{constants::API_URL_DEFAULT, ApiKey};
use tracing::trace;

use crate::args::ProjectArgs;
Expand Down Expand Up @@ -122,7 +122,7 @@ impl ConfigManager for LocalConfigManager {
#[derive(Deserialize, Serialize, Default)]
pub struct GlobalConfig {
api_key: Option<String>,
pub api_url: Option<ApiUrl>,
pub api_url: Option<String>,
}

impl GlobalConfig {
Expand All @@ -138,7 +138,7 @@ impl GlobalConfig {
self.api_key = None;
}

pub fn api_url(&self) -> Option<ApiUrl> {
pub fn api_url(&self) -> Option<String> {
self.api_url.clone()
}
}
Expand Down Expand Up @@ -315,7 +315,7 @@ impl RequestContext {
self.api_url = api_url;
}

pub fn api_url(&self) -> ApiUrl {
pub fn api_url(&self) -> String {
if let Some(api_url) = self.api_url.clone() {
api_url
} else if let Some(api_url) = self.global.as_ref().unwrap().api_url() {
Expand Down
Loading