From 16ed13fce0c5e4a5f1e19ac0a86d77898ca5f440 Mon Sep 17 00:00:00 2001 From: Edoardo Marangoni Date: Mon, 29 Jul 2024 14:01:05 +0200 Subject: [PATCH 1/3] feat(cli/secrets): Add flag and logic to redeploy an app after changing secrets --- lib/backend-api/schema.graphql | 20 +++++++++++++- lib/backend-api/src/query.rs | 14 ++++++++++ lib/backend-api/src/types.rs | 17 ++++++++++++ lib/cli/src/commands/app/secrets/create.rs | 31 ++++++++++++++++++---- lib/cli/src/commands/app/secrets/update.rs | 30 +++++++++++++++++---- 5 files changed, 101 insertions(+), 11 deletions(-) diff --git a/lib/backend-api/schema.graphql b/lib/backend-api/schema.graphql index 1ca851e4a04..7c630ead9b1 100644 --- a/lib/backend-api/schema.graphql +++ b/lib/backend-api/schema.graphql @@ -2995,6 +2995,9 @@ type Mutation { """Delete secret with given ID""" deleteAppSecret(input: DeleteAppSecretInput!): DeleteAppSecretPayload + + """Redeploy the active version of an app.""" + redeployActiveVersion(input: RedeployActiveVersionInput!): RedeployActiveVersionPayload tokenAuth(input: ObtainJSONWebTokenInput!): ObtainJSONWebTokenPayload generateDeployToken(input: GenerateDeployTokenInput!): GenerateDeployTokenPayload verifyAccessToken(token: String): Verify @@ -3011,6 +3014,8 @@ type Mutation { updateUserInfo(input: UpdateUserInfoInput!): UpdateUserInfoPayload validateUserPassword(input: ValidateUserPasswordInput!): ValidateUserPasswordPayload generateApiToken(input: GenerateAPITokenInput!): GenerateAPITokenPayload + + """Request To revoke an API token; these start with 'wap_'.""" revokeApiToken(input: RevokeAPITokenInput!): RevokeAPITokenPayload checkUserExists(input: CheckUserExistsInput!): CheckUserExistsPayload readNotification(input: ReadNotificationInput!): ReadNotificationPayload @@ -3439,6 +3444,18 @@ input DeleteAppSecretInput { clientMutationId: String } +"""Redeploy the active version of an app.""" +type RedeployActiveVersionPayload { + app: DeployApp! + clientMutationId: String +} + +input RedeployActiveVersionInput { + """ID of the app to redeploy.""" + id: ID! + clientMutationId: String +} + type ObtainJSONWebTokenPayload { payload: GenericScalar! refreshExpiresIn: Int! @@ -3656,6 +3673,7 @@ input GenerateAPITokenInput { clientMutationId: String } +"""Request To revoke an API token; these start with 'wap_'.""" type RevokeAPITokenPayload { token: APIToken success: Boolean @@ -3664,7 +3682,7 @@ type RevokeAPITokenPayload { input RevokeAPITokenInput { """The API token ID""" - tokenId: ID! + token: String! clientMutationId: String } diff --git a/lib/backend-api/src/query.rs b/lib/backend-api/src/query.rs index db0aaccfa16..23cc209dbf3 100644 --- a/lib/backend-api/src/query.rs +++ b/lib/backend-api/src/query.rs @@ -15,6 +15,20 @@ use crate::{ GraphQLApiFailure, WasmerClient, }; +pub async fn redeploy_app_by_id( + client: &WasmerClient, + app_id: impl Into, +) -> Result, anyhow::Error> { + client + .run_graphql_strict(types::RedeployActiveApp::build( + RedeployActiveAppVariables { + id: types::Id::from(app_id), + }, + )) + .await + .map(|v| v.redeploy_active_version.map(|v| v.app)) +} + pub async fn get_app_secret_value_by_id( client: &WasmerClient, secret_id: impl Into, diff --git a/lib/backend-api/src/types.rs b/lib/backend-api/src/types.rs index 124c3899394..49fff8ea732 100644 --- a/lib/backend-api/src/types.rs +++ b/lib/backend-api/src/types.rs @@ -1021,6 +1021,23 @@ mod queries { pub apps: DeployAppConnection, } + #[derive(cynic::QueryVariables, Debug)] + pub struct RedeployActiveAppVariables { + pub id: cynic::Id, + } + + #[derive(cynic::QueryFragment, Debug)] + #[cynic(graphql_type = "Mutation", variables = "RedeployActiveAppVariables")] + pub struct RedeployActiveApp { + #[arguments(input: { id: $id })] + pub redeploy_active_version: Option, + } + + #[derive(cynic::QueryFragment, Debug)] + pub struct RedeployActiveVersionPayload { + pub app: DeployApp, + } + #[derive(cynic::QueryVariables, Debug)] pub struct PublishDeployAppVars { pub config: String, diff --git a/lib/cli/src/commands/app/secrets/create.rs b/lib/cli/src/commands/app/secrets/create.rs index 4fe5ffd30f2..c2da90b928c 100644 --- a/lib/cli/src/commands/app/secrets/create.rs +++ b/lib/cli/src/commands/app/secrets/create.rs @@ -44,6 +44,10 @@ pub struct CmdAppSecretsCreate { #[clap(long, name = "from-file", conflicts_with = "name")] pub from_file: Option, + /// Whether or not to redeploy the app after creating the secrets. + #[clap(long)] + pub redeploy: bool, + /* --- Parameters --- */ /// The name of the secret to create. #[clap(name = "name")] @@ -157,13 +161,30 @@ impl CmdAppSecretsCreate { } else { if !self.quiet { eprintln!("Succesfully created secret(s):"); - for secret in secrets { + for secret in &secrets { eprintln!("{}", secret.name.bold()); } - eprintln!( - "{}: In order for secrets to appear in your app, re-deploy it.", - "Info".bold() - ); + + let should_redeploy = self.redeploy || { + if !self.non_interactive && secrets.len() > 1 { + let theme = ColorfulTheme::default(); + dialoguer::Confirm::with_theme(&theme) + .with_prompt("Do you want to redeploy your app?") + .interact()? + } else { + false + } + }; + + if should_redeploy { + wasmer_api::query::redeploy_app_by_id(client, app_id).await?; + eprintln!("{} Deployment complete", "ð–¥”".yellow().bold()); + } else { + eprintln!( + "{}: In order for secrets to appear in your app, re-deploy it.", + "Info".bold() + ); + } } Ok(()) diff --git a/lib/cli/src/commands/app/secrets/update.rs b/lib/cli/src/commands/app/secrets/update.rs index ecf438e7641..d7f34cf182e 100644 --- a/lib/cli/src/commands/app/secrets/update.rs +++ b/lib/cli/src/commands/app/secrets/update.rs @@ -49,6 +49,10 @@ pub struct CmdAppSecretsUpdate { )] pub from_file: Option, + /// Whether or not to redeploy the app after creating the secrets. + #[clap(long)] + pub redeploy: bool, + /* --- Parameters --- */ /// The name of the secret to update. #[clap(name = "name")] @@ -151,14 +155,30 @@ impl CmdAppSecretsUpdate { } else { if !self.quiet { eprintln!("Succesfully updated secret(s):"); - for secret in secrets { + for secret in &secrets { eprintln!("{}", secret.name.bold()); } - eprintln!( - "{}: In order for secrets to appear in your app, re-deploy it.", - "Info".bold() - ); + let should_redeploy = self.redeploy || { + if !self.non_interactive && secrets.len() > 1 { + let theme = ColorfulTheme::default(); + dialoguer::Confirm::with_theme(&theme) + .with_prompt("Do you want to redeploy your app?") + .interact()? + } else { + false + } + }; + + if should_redeploy { + wasmer_api::query::redeploy_app_by_id(client, app_id).await?; + eprintln!("{} Deployment complete", "ð–¥”".yellow().bold()); + } else { + eprintln!( + "{}: In order for secrets to appear in your app, re-deploy it.", + "Info".bold() + ); + } } Ok(()) From 047b277b4fc59de53b7faadc78a341531da95d13 Mon Sep 17 00:00:00 2001 From: Edoardo Marangoni Date: Mon, 29 Jul 2024 16:12:37 +0200 Subject: [PATCH 2/3] fix(cli/secrets): Redeploy when `from_file` flag is used --- lib/cli/src/commands/app/secrets/create.rs | 2 +- lib/cli/src/commands/app/secrets/update.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/cli/src/commands/app/secrets/create.rs b/lib/cli/src/commands/app/secrets/create.rs index 70fac67c094..77301e752c9 100644 --- a/lib/cli/src/commands/app/secrets/create.rs +++ b/lib/cli/src/commands/app/secrets/create.rs @@ -162,7 +162,7 @@ impl CmdAppSecretsCreate { } let should_redeploy = self.redeploy || { - if !self.non_interactive && secrets.len() > 1 { + if !self.non_interactive && self.from_file.is_some() { let theme = ColorfulTheme::default(); dialoguer::Confirm::with_theme(&theme) .with_prompt("Do you want to redeploy your app?") diff --git a/lib/cli/src/commands/app/secrets/update.rs b/lib/cli/src/commands/app/secrets/update.rs index 50ac7513b83..32c20bd586d 100644 --- a/lib/cli/src/commands/app/secrets/update.rs +++ b/lib/cli/src/commands/app/secrets/update.rs @@ -156,7 +156,7 @@ impl CmdAppSecretsUpdate { } let should_redeploy = self.redeploy || { - if !self.non_interactive && secrets.len() > 1 { + if !self.non_interactive && self.from_file.is_some() { let theme = ColorfulTheme::default(); dialoguer::Confirm::with_theme(&theme) .with_prompt("Do you want to redeploy your app?") From a9a0e9f412c6b5107d3ee89f1aa421cd69eb5b16 Mon Sep 17 00:00:00 2001 From: Edoardo Marangoni Date: Mon, 29 Jul 2024 19:07:16 +0200 Subject: [PATCH 3/3] chore: Make linter happy --- lib/backend-api/src/query.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/backend-api/src/query.rs b/lib/backend-api/src/query.rs index 8c20ab74699..f85d86d4de6 100644 --- a/lib/backend-api/src/query.rs +++ b/lib/backend-api/src/query.rs @@ -27,7 +27,7 @@ pub async fn redeploy_app_by_id( )) .await .map(|v| v.redeploy_active_version.map(|v| v.app)) -} +} /// Revoke an existing token pub async fn revoke_token(