Skip to content

Commit

Permalink
admin: added command to automate certificate renewal
Browse files Browse the repository at this point in the history
Signed-off-by: Iulian Barbu <iulianbarbu2@gmail.com>
  • Loading branch information
iulianbarbu committed Feb 19, 2023
1 parent 2384988 commit a6a669e
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 10 deletions.
16 changes: 16 additions & 0 deletions admin/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,22 @@ pub enum AcmeCommand {
#[arg(long)]
credentials: PathBuf,
},

/// Automate certificate renewal for a FQDN
AutomateCertificateRenewal {
/// Fqdn to automate certificate renewal for
#[arg(long)]
fqdn: String,

/// Project to automate certificate renewal for
#[arg(long)]
project: ProjectName,

/// Path to acme credentials file
/// This should have been created with `acme create-account`
#[arg(long)]
credentials: PathBuf,
},
}

#[derive(Subcommand, Debug)]
Expand Down
10 changes: 10 additions & 0 deletions admin/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,16 @@ impl Client {
self.post(&path, Some(credentials)).await
}

pub async fn acme_renew_certificate(
&self,
fqdn: &str,
project_name: &ProjectName,
credentials: &serde_json::Value,
) -> Result<String> {
let path = format!("/admin/acme/renew/{project_name}/{fqdn}");
self.post(&path, Some(credentials)).await
}

pub async fn get_projects(&self) -> Result<Vec<project::AdminResponse>> {
self.get("/admin/projects").await
}
Expand Down
14 changes: 14 additions & 0 deletions admin/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,20 @@ async fn main() {
.await
.expect("to get a certificate challenge response")
}
Command::Acme(AcmeCommand::AutomateCertificateRenewal {
fqdn,
project,
credentials,
}) => {
let credentials = fs::read_to_string(credentials).expect("to read credentials file");
let credentials =
serde_json::from_str(&credentials).expect("to parse content of credentials file");

client
.acme_renew_certificate(&fqdn, &project, &credentials)
.await
.expect("to get a certificate challenge response")
}
Command::ProjectNames => {
let projects = client
.get_projects()
Expand Down
20 changes: 12 additions & 8 deletions gateway/src/acme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use futures::future::BoxFuture;
use hyper::server::conn::AddrStream;
use hyper::{Body, Request};
use instant_acme::{
Account, Authorization, AuthorizationStatus, Challenge, ChallengeType, Identifier,
KeyAuthorization, LetsEncrypt, NewAccount, NewOrder, Order, OrderStatus, AccountCredentials,
Account, AccountCredentials, Authorization, AuthorizationStatus, Challenge, ChallengeType,
Identifier, KeyAuthorization, LetsEncrypt, NewAccount, NewOrder, Order, OrderStatus,
};
use rcgen::{Certificate, CertificateParams, DistinguishedName};
use tokio::sync::Mutex;
Expand Down Expand Up @@ -286,12 +286,16 @@ pub struct AccountWrapper(pub Account);

impl<'a> From<AccountCredentials<'a>> for AccountWrapper {
fn from(value: AccountCredentials<'a>) -> Self {
AccountWrapper(Account::from_credentials(value).map_err(|error| {
error!(
error = &error as &dyn std::error::Error,
"failed to convert acme credentials into account"
);
}).expect("Account credentials malformed"))
AccountWrapper(
Account::from_credentials(value)
.map_err(|error| {
error!(
error = &error as &dyn std::error::Error,
"failed to convert acme credentials into account"
);
})
.expect("Account credentials malformed"),
)
}
}

Expand Down
2 changes: 1 addition & 1 deletion gateway/src/api/latest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use uuid::Uuid;
use x509_parser::parse_x509_certificate;
use x509_parser::time::ASN1Time;

use crate::acme::{AcmeClient, AcmeClientError, CustomDomain, AccountWrapper};
use crate::acme::{AccountWrapper, AcmeClient, AcmeClientError, CustomDomain};
use crate::auth::{Admin, ScopedUser, User};
use crate::project::{Project, ProjectCreating};
use crate::task::{self, BoxedTask, TaskResult};
Expand Down
2 changes: 1 addition & 1 deletion gateway/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use fqdn::FQDN;
use futures::prelude::*;
use instant_acme::{Account, AccountCredentials, ChallengeType};
use opentelemetry::global;
use shuttle_gateway::acme::{AcmeClient, AcmeClientError, CustomDomain, AccountWrapper};
use shuttle_gateway::acme::{AccountWrapper, AcmeClient, AcmeClientError, CustomDomain};
use shuttle_gateway::api::latest::{ApiBuilder, SVC_DEGRADED_THRESHOLD};
use shuttle_gateway::args::StartArgs;
use shuttle_gateway::args::{Args, Commands, InitArgs, UseTls};
Expand Down

0 comments on commit a6a669e

Please sign in to comment.