pub struct CertificateManager<D: AcmeDnsChallenge> {
store: CertStore,
dns: Arc<D>,
account: Account,
environment: Environment,
domains: Vec<String>,
policy: RenewalPolicy,
tracker: Mutex<RenewalTracker>,
cert: Arc<SwappableCert>,
provider: CryptoProvider,
}Expand description
The PDS’s own certificate: issuance, renewal and the live rustls state, in one place.
Fields§
§store: CertStore§dns: Arc<D>§account: Account§environment: Environment§domains: Vec<String>§policy: RenewalPolicy§tracker: Mutex<RenewalTracker>§cert: Arc<SwappableCert>§provider: CryptoProviderImplementations§
Source§impl<D: AcmeDnsChallenge + 'static> CertificateManager<D>
impl<D: AcmeDnsChallenge + 'static> CertificateManager<D>
Sourcepub async fn bootstrap(
data_dir: &Path,
zone: &str,
environment: Environment,
contact: &[&str],
policy: RenewalPolicy,
dns: Arc<D>,
) -> Result<Arc<Self>, BootstrapError>
pub async fn bootstrap( data_dir: &Path, zone: &str, environment: Environment, contact: &[&str], policy: RenewalPolicy, dns: Arc<D>, ) -> Result<Arc<Self>, BootstrapError>
Loads or obtains a certificate for zone and *.zone, from
data_dir/tls/zones/<zone>, and returns a manager ready to serve and
renew it.
One manager covers exactly one zone. A deployment configured with
several needs one of these each — crate::fleet::CertificateFleet
is what builds and holds them.
Installs ring as the process’s default rustls crypto provider if
none is installed yet; if one is already installed (for instance by
another part of the process that also uses rustls) this is a no-op
rather than an error – a second install attempt is expected, not
exceptional.
Sourcepub async fn bootstrap_with_account(
data_dir: &Path,
zone: &str,
environment: Environment,
contact: &[&str],
policy: RenewalPolicy,
dns: Arc<D>,
account: Account,
) -> Result<Arc<Self>, BootstrapError>
pub async fn bootstrap_with_account( data_dir: &Path, zone: &str, environment: Environment, contact: &[&str], policy: RenewalPolicy, dns: Arc<D>, account: Account, ) -> Result<Arc<Self>, BootstrapError>
Assembles a manager from an [Account] built elsewhere, skipping
CertificateManager::bootstrap’s own credential-loading and its hardcoded
ReqwestAcmeClient against environment.directory_url().
This is the seam a test drives against an in-process fake ACME
directory: CertificateManager::bootstrap has no way to reach anything but a
real Let’s Encrypt endpoint, so nothing downstream of it could run
without one. Production code that already holds an [Account] – for
instance one restored through a different credential path than
crate::storage::CertStore – can use this directly too.
Sourceasync fn finish_bootstrap(
store: CertStore,
zone: &str,
environment: Environment,
contact: &[&str],
policy: RenewalPolicy,
dns: Arc<D>,
account: Account,
) -> Result<Arc<Self>, BootstrapError>
async fn finish_bootstrap( store: CertStore, zone: &str, environment: Environment, contact: &[&str], policy: RenewalPolicy, dns: Arc<D>, account: Account, ) -> Result<Arc<Self>, BootstrapError>
Everything both bootstrap paths share once an [Account] is in hand:
publish the zone’s CAA record, load or issue the certificate, and
assemble the manager.
Sourcepub fn resolver(&self) -> Arc<SwappableCert>
pub fn resolver(&self) -> Arc<SwappableCert>
The live certificate resolver. Build the process’s one
rustls::ServerConfig from this once, at startup; renewal swaps the
certificate this resolver hands back, not the config or the listener.
Sourcepub async fn alert_level(&self) -> AlertLevel
pub async fn alert_level(&self) -> AlertLevel
How urgently the current renewal state should be surfaced, right now.
Sourcepub async fn run_renewal_loop(self: Arc<Self>)
pub async fn run_renewal_loop(self: Arc<Self>)
Runs forever, checking on CHECK_INTERVAL whether renewal is due
and attempting it when it is.
A failed attempt never touches Self::resolver: the certificate
already being served keeps being served, and the failure is only
recorded in the tracker that Self::alert_level reads. Intended to
be spawned once and left running for the life of the process.
Sourcepub async fn maybe_renew(&self)
pub async fn maybe_renew(&self)
Checks whether renewal is due and, if so, attempts it once. Split out
from Self::run_renewal_loop so a test can call it directly on a
clock it controls, without waiting on CHECK_INTERVAL.