From 0b35063474e61e4e3fdce174b0106bd909f305ee Mon Sep 17 00:00:00 2001 From: jonaro00 <54029719+jonaro00@users.noreply.github.com> Date: Thu, 9 Nov 2023 10:15:03 +0100 Subject: [PATCH] refactor: make admin compile, scope project models to backends (#1371) --- .gitignore | 2 +- admin/src/args.rs | 5 ++--- admin/src/client.rs | 11 ++++------- common/src/models/admin.rs | 12 ++++++++++++ common/src/models/error.rs | 16 ++++++++++++++-- common/src/models/mod.rs | 2 ++ common/src/models/project.rs | 25 ++----------------------- gateway/src/api/latest.rs | 5 +++-- gateway/src/lib.rs | 2 +- 9 files changed, 41 insertions(+), 39 deletions(-) create mode 100644 common/src/models/admin.rs diff --git a/.gitignore b/.gitignore index 7a7539ae0..22648dc01 100644 --- a/.gitignore +++ b/.gitignore @@ -17,7 +17,7 @@ recipe.json .idea/ # Credentials for running ACME commands -acme.json +acme*.json # VS Code .vscode/ diff --git a/admin/src/args.rs b/admin/src/args.rs index c9a943b45..13a8845e9 100644 --- a/admin/src/args.rs +++ b/admin/src/args.rs @@ -1,7 +1,6 @@ use std::{fs, io, path::PathBuf}; use clap::{Error, Parser, Subcommand}; -use shuttle_common::models::project::ProjectName; #[derive(Parser, Debug)] pub struct Args { @@ -54,7 +53,7 @@ pub enum AcmeCommand { /// Project to request certificate for #[arg(long)] - project: ProjectName, + project: String, /// Path to acme credentials file /// This should have been created with `acme create-account` @@ -70,7 +69,7 @@ pub enum AcmeCommand { /// Project to renew the certificate for #[arg(long)] - project: ProjectName, + project: String, /// Path to acme credentials file /// This should have been created with `acme create-account` diff --git a/admin/src/client.rs b/admin/src/client.rs index 86da73cd8..185a41b17 100644 --- a/admin/src/client.rs +++ b/admin/src/client.rs @@ -1,9 +1,6 @@ use anyhow::{Context, Result}; use serde::{de::DeserializeOwned, Serialize}; -use shuttle_common::models::{ - project::{AdminResponse, ProjectName}, - stats, ToJson, -}; +use shuttle_common::models::{admin::ProjectResponse, stats, ToJson}; use tracing::trace; pub struct Client { @@ -36,7 +33,7 @@ impl Client { pub async fn acme_request_certificate( &self, fqdn: &str, - project_name: &ProjectName, + project_name: &str, credentials: &serde_json::Value, ) -> Result { let path = format!("/admin/acme/request/{project_name}/{fqdn}"); @@ -46,7 +43,7 @@ impl Client { pub async fn acme_renew_custom_domain_certificate( &self, fqdn: &str, - project_name: &ProjectName, + project_name: &str, credentials: &serde_json::Value, ) -> Result { let path = format!("/admin/acme/renew/{project_name}/{fqdn}"); @@ -61,7 +58,7 @@ impl Client { self.post(&path, Some(credentials)).await } - pub async fn get_projects(&self) -> Result> { + pub async fn get_projects(&self) -> Result> { self.get("/admin/projects").await } diff --git a/common/src/models/admin.rs b/common/src/models/admin.rs new file mode 100644 index 000000000..ca03bdb5d --- /dev/null +++ b/common/src/models/admin.rs @@ -0,0 +1,12 @@ +use serde::{Deserialize, Serialize}; + +#[cfg(feature = "openapi")] +use utoipa::ToSchema; + +#[derive(Deserialize, Serialize)] +#[cfg_attr(feature = "openapi", derive(ToSchema))] +#[cfg_attr(feature = "openapi", schema(as = shuttle_common::models::admin::ProjectResponse))] +pub struct ProjectResponse { + pub project_name: String, + pub account_name: String, +} diff --git a/common/src/models/error.rs b/common/src/models/error.rs index a64c72c8a..8be5d9d09 100644 --- a/common/src/models/error.rs +++ b/common/src/models/error.rs @@ -5,8 +5,6 @@ use http::StatusCode; use serde::{Deserialize, Serialize}; use tracing::{error, warn}; -use super::project::InvalidProjectName; - #[derive(Serialize, Deserialize, Debug)] pub struct ApiError { pub message: String, @@ -170,6 +168,20 @@ impl From for ApiError { } } +// Note: The string "Invalid project name" is used by cargo-shuttle to determine what type of error was returned. +// Changing it is breaking. +#[derive(Debug, Clone, PartialEq, thiserror::Error)] +#[error( + "Invalid project name. Project names must: + 1. only contain lowercase alphanumeric characters or dashes `-`. + 2. not start or end with a dash. + 3. not be empty. + 4. be shorter than 64 characters. + 5. not contain any profanities. + 6. not be a reserved word." +)] +pub struct InvalidProjectName; + #[cfg(feature = "backend")] pub mod axum { use async_trait::async_trait; diff --git a/common/src/models/mod.rs b/common/src/models/mod.rs index 220f58fa5..7dddc72de 100644 --- a/common/src/models/mod.rs +++ b/common/src/models/mod.rs @@ -1,5 +1,7 @@ +pub mod admin; pub mod deployment; pub mod error; +#[cfg(feature = "backend")] pub mod project; pub mod resource; pub mod secret; diff --git a/common/src/models/project.rs b/common/src/models/project.rs index f839dfcd4..d4c000a77 100644 --- a/common/src/models/project.rs +++ b/common/src/models/project.rs @@ -17,10 +17,11 @@ use strum::EnumString; #[cfg(feature = "openapi")] use crate::ulid_type; - #[cfg(feature = "openapi")] use utoipa::ToSchema; +use super::error::InvalidProjectName; + /// Timeframe before a project is considered idle pub const DEFAULT_IDLE_MINUTES: u64 = 30; @@ -188,14 +189,6 @@ pub struct Config { pub idle_minutes: u64, } -#[derive(Deserialize, Serialize)] -#[cfg_attr(feature = "openapi", derive(ToSchema))] -#[cfg_attr(feature = "openapi", schema(as = shuttle_common::models::project::AdminResponse))] -pub struct AdminResponse { - pub project_name: String, - pub account_name: String, -} - pub fn get_projects_table( projects: &Vec, page: u32, @@ -317,20 +310,6 @@ impl ProjectName { } } -// Note: The string "Invalid project name" is used by cargo-shuttle to determine what type of error was returned. -// Changing it is breaking. -#[derive(Debug, Clone, PartialEq, thiserror::Error)] -#[error( - "Invalid project name. Project names must: - 1. only contain lowercase alphanumeric characters or dashes `-`. - 2. not start or end with a dash. - 3. not be empty. - 4. be shorter than 64 characters. - 5. not contain any profanities. - 6. not be a reserved word." -)] -pub struct InvalidProjectName; - impl std::ops::Deref for ProjectName { type Target = String; diff --git a/gateway/src/api/latest.rs b/gateway/src/api/latest.rs index dd2d65b34..0f8e1d81e 100644 --- a/gateway/src/api/latest.rs +++ b/gateway/src/api/latest.rs @@ -25,6 +25,7 @@ use shuttle_common::constants::limits::{MAX_PROJECTS_DEFAULT, MAX_PROJECTS_EXTRA use shuttle_common::models::error::axum::CustomErrorPath; use shuttle_common::models::error::ErrorKind; use shuttle_common::models::{ + admin::ProjectResponse, project::{self, ProjectName}, stats, }; @@ -844,7 +845,7 @@ async fn renew_gateway_acme_certificate( )] async fn get_projects( State(RouterState { service, .. }): State, -) -> Result>, Error> { +) -> Result>, Error> { let projects = service .iter_projects_detailed() .await? @@ -891,7 +892,7 @@ impl Modify for SecurityAddon { components(schemas( shuttle_common::models::project::Response, shuttle_common::models::stats::LoadResponse, - shuttle_common::models::project::AdminResponse, + shuttle_common::models::admin::ProjectResponse, shuttle_common::models::stats::LoadResponse, shuttle_common::models::project::State )) diff --git a/gateway/src/lib.rs b/gateway/src/lib.rs index 1061c716e..65c1b88fc 100644 --- a/gateway/src/lib.rs +++ b/gateway/src/lib.rs @@ -160,7 +160,7 @@ pub struct ProjectDetails { pub account_name: AccountName, } -impl From for shuttle_common::models::project::AdminResponse { +impl From for shuttle_common::models::admin::ProjectResponse { fn from(project: ProjectDetails) -> Self { Self { project_name: project.project_name.to_string(),