From 1fbb7c4e4b4dec53e2766425b0d84d10968e36b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodolphe=20Br=C3=A9ard?= Date: Tue, 24 Dec 2024 14:33:34 +0100 Subject: [PATCH] Use a table of table for the endpoints --- config/20_letsencrypt.toml | 6 ++---- man/en/acmed.toml.5 | 9 +++------ src/config.rs | 16 ++++++++++++++-- src/config/endpoint.rs | 16 ++++++---------- tests/config/override/00_initial.toml | 7 +++++++ tests/config/override/01_override.toml | 7 +++++++ 6 files changed, 39 insertions(+), 22 deletions(-) diff --git a/config/20_letsencrypt.toml b/config/20_letsencrypt.toml index 60700f4..18c5ac8 100644 --- a/config/20_letsencrypt.toml +++ b/config/20_letsencrypt.toml @@ -3,14 +3,12 @@ name = "Let's Encrypt rate-limit" number = 20 period = "1s" -[[endpoint]] -name = "Let's Encrypt v2 production" +[endpoint."letsencrypt-v2-production"] url = "https://acme-v02.api.letsencrypt.org/directory" rate_limits = ["Let's Encrypt rate-limit"] tos_agreed = false -[[endpoint]] -name = "Let's Encrypt v2 staging" +[endpoint."letsencrypt-v2-staging"] url = "https://acme-staging-v02.api.letsencrypt.org/directory" rate_limits = ["Let's Encrypt rate-limit"] tos_agreed = false diff --git a/man/en/acmed.toml.5 b/man/en/acmed.toml.5 index 4059480..8a0b569 100644 --- a/man/en/acmed.toml.5 +++ b/man/en/acmed.toml.5 @@ -237,7 +237,7 @@ Table where the certificate's subject attributes are specified. Possible keys, w .El .El .It Ic endpoint -Array of table where each element defines a Certificate Authority +Table of table where each element defines a Certificate Authority .Pq CA which may be used to request certificates. .Bl -tag @@ -247,8 +247,6 @@ Template used to build the file's name. For detailed documentation, see the directive located in the .Em certificate element. -.It Cm name Ar string -The name the endpoint is registered under. Must be unique. .It Cm rate_limits Ar array Array containing the names of the HTTPS rate limits to apply. .It Cm random_early_renew Ar string @@ -747,8 +745,7 @@ Default certificates and associated private keys directory. .Sh EXAMPLES The following example defines a typical endpoint, account and certificate for a domain, several subdomains and an IP address. .Bd -literal -offset indent -[[endpoint]] -name = "example name" +[endpoint."example-name"] url = "https://acme.example.org/directory" tos_agreed = true @@ -759,7 +756,7 @@ contacts = [ ] [[certificate]] -endpoint = "example name" +endpoint = "example-name" account = "my test account" identifiers = [ { dns = "exemple.net", challenge = "http-01"}, diff --git a/src/config.rs b/src/config.rs index e4457cf..10b903d 100644 --- a/src/config.rs +++ b/src/config.rs @@ -17,6 +17,7 @@ pub use rate_limit::*; use anyhow::{Context, Result}; use config::{Config, File}; use serde_derive::Deserialize; +use std::collections::HashMap; use std::path::{Path, PathBuf}; use walkdir::WalkDir; @@ -27,7 +28,7 @@ const ALLOWED_FILE_EXT: &[&str] = &["toml"]; pub struct AcmedConfig { pub(in crate::config) global: Option, #[serde(default)] - pub(in crate::config) endpoint: Vec, + pub(in crate::config) endpoint: HashMap, #[serde(default, rename = "rate-limit")] pub(in crate::config) rate_limit: Vec, #[serde(default)] @@ -146,7 +147,18 @@ mod tests { PathBuf::from("/tmp/example/cert/dir") ); assert!(cfg.rate_limit.is_empty()); - assert!(cfg.endpoint.is_empty()); + assert_eq!(cfg.endpoint.len(), 2); + println!("Debug: cfg.endpoint: {:?}", cfg.endpoint); + let ac1 = cfg.endpoint.get("test ac 1").unwrap(); + assert_eq!(ac1.url, "https://acme-v02.ac1.example.org/directory"); + assert_eq!(ac1.tos_agreed, true); + assert!(ac1.random_early_renew.is_none()); + assert!(ac1.root_certificates.is_empty()); + let ac2 = cfg.endpoint.get("test ac 2").unwrap(); + assert_eq!(ac2.url, "https://acme-v02.ac2.example.org/directory"); + assert_eq!(ac2.tos_agreed, false); + assert_eq!(ac2.random_early_renew, Some(Duration::from_secs(10))); + assert_eq!(ac2.root_certificates, vec![PathBuf::from("test.pem")]); assert!(cfg.hook.is_empty()); assert!(cfg.group.is_empty()); assert_eq!(cfg.account.len(), 1); diff --git a/src/config/endpoint.rs b/src/config/endpoint.rs index 7c822f0..55ef46e 100644 --- a/src/config/endpoint.rs +++ b/src/config/endpoint.rs @@ -6,7 +6,6 @@ use std::path::PathBuf; #[serde(deny_unknown_fields)] pub struct Endpoint { pub(in crate::config) file_name_format: Option, - pub(in crate::config) name: String, pub(in crate::config) random_early_renew: Option, #[serde(default)] pub(in crate::config) rate_limits: Vec, @@ -31,14 +30,10 @@ mod tests { #[test] fn minimal() { - let cfg = r#" -name = "test" -url = "https://acme-v02.api.example.com/directory" -"#; + let cfg = r#"url = "https://acme-v02.api.example.com/directory""#; let e: Endpoint = load_str(cfg).unwrap(); assert!(e.file_name_format.is_none()); - assert_eq!(e.name, "test"); assert!(e.random_early_renew.is_none()); assert!(e.rate_limits.is_empty()); assert!(e.renew_delay.is_none()); @@ -50,7 +45,6 @@ url = "https://acme-v02.api.example.com/directory" #[test] fn full() { let cfg = r#" -name = "test" url = "https://acme-v02.api.example.com/directory" file_name_format = "{{ key_type }} {{ file_type }} {{ name }}.{{ ext }}" random_early_renew = "1d" @@ -65,7 +59,6 @@ tos_agreed = true e.file_name_format, Some("{{ key_type }} {{ file_type }} {{ name }}.{{ ext }}".to_string()) ); - assert_eq!(e.name, "test"); assert_eq!(e.random_early_renew, Some(Duration::from_days(1))); assert_eq!(e.rate_limits, vec!["rl 1", "rl 2"]); assert_eq!(e.renew_delay, Some(Duration::from_days(21))); @@ -75,8 +68,11 @@ tos_agreed = true } #[test] - fn missing_name() { - let cfg = r#""#; + fn missing_url() { + let cfg = r#" +root_certificates = ["root_cert.pem"] +tos_agreed = true +"#; let res = load_str::(cfg); assert!(res.is_err()); diff --git a/tests/config/override/00_initial.toml b/tests/config/override/00_initial.toml index 5743deb..f6e130c 100644 --- a/tests/config/override/00_initial.toml +++ b/tests/config/override/00_initial.toml @@ -2,6 +2,13 @@ accounts_directory = "/tmp/example/account/dir" certificates_directory = "/tmp/example/cert/dir/" +[endpoint."test AC 1"] +url = "https://acme-v02.ac1.example.org/directory" +tos_agreed = false + +[endpoint."test AC 2"] +url = "https://acme-v02.ac2.example.org/directory" + [[account]] name = "example" contacts = [ diff --git a/tests/config/override/01_override.toml b/tests/config/override/01_override.toml index e5417fe..4f3aaf1 100644 --- a/tests/config/override/01_override.toml +++ b/tests/config/override/01_override.toml @@ -1 +1,8 @@ global.accounts_directory = "/tmp/other/account/dir" + +endpoint."test ac 2".random_early_renew = "10s" + +endpoint."test AC 1".tos_agreed = true + +[endpoint."test AC 2"] +root_certificates = ["test.pem"]