Browse Source

Allow the config file to include other files

pull/5/head
Rodolphe Breard 6 years ago
parent
commit
7eed211434
  1. 1
      CHANGELOG.md
  2. 64
      acmed/src/config.rs
  3. 11
      man/en/acmed.toml.5

1
CHANGELOG.md

@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added ### Added
- ACMEd now displays a warning when the server indicates an error in an order or an authorization. - ACMEd now displays a warning when the server indicates an error in an order or an authorization.
- A configuration file can now include several other files.
## [0.4.0] - 2019-05-08 ## [0.4.0] - 2019-05-08

64
acmed/src/config.rs

@ -6,19 +6,32 @@ use serde::Deserialize;
use std::fmt; use std::fmt;
use std::fs::{self, File}; use std::fs::{self, File};
use std::io::prelude::*; use std::io::prelude::*;
use std::path::Path;
use std::path::{Path, PathBuf};
macro_rules! set_cfg_attr {
($to: expr, $from: expr) => {
if let Some(v) = $from {
$to = Some(v);
};
};
}
#[derive(Deserialize)] #[derive(Deserialize)]
#[serde(deny_unknown_fields)] #[serde(deny_unknown_fields)]
pub struct Config { pub struct Config {
pub global: Option<GlobalOptions>, pub global: Option<GlobalOptions>,
#[serde(default)]
pub endpoint: Vec<Endpoint>, pub endpoint: Vec<Endpoint>,
#[serde(default)] #[serde(default)]
pub hook: Vec<Hook>, pub hook: Vec<Hook>,
#[serde(default)] #[serde(default)]
pub group: Vec<Group>, pub group: Vec<Group>,
#[serde(default)]
pub account: Vec<Account>, pub account: Vec<Account>,
#[serde(default)]
pub certificate: Vec<Certificate>, pub certificate: Vec<Certificate>,
#[serde(default)]
pub include: Vec<String>,
} }
impl Config { impl Config {
@ -110,7 +123,7 @@ impl Config {
} }
} }
#[derive(Deserialize)]
#[derive(Clone, Deserialize)]
#[serde(deny_unknown_fields)] #[serde(deny_unknown_fields)]
pub struct GlobalOptions { pub struct GlobalOptions {
pub accounts_directory: Option<String>, pub accounts_directory: Option<String>,
@ -307,12 +320,51 @@ fn init_directories(config: &Config) -> Result<(), Error> {
Ok(()) Ok(())
} }
pub fn from_file(file: &str) -> Result<Config, Error> {
info!("Loading configuration file: {}", file);
let mut file = File::open(file)?;
fn get_cnf_path(from: &PathBuf, file: &str) -> PathBuf {
let mut path = from.clone();
path.pop();
path.push(file);
path
}
fn read_cnf(path: &PathBuf) -> Result<Config, Error> {
info!("Loading configuration file: {}", path.display());
let mut file = File::open(path)?;
let mut contents = String::new(); let mut contents = String::new();
file.read_to_string(&mut contents)?; file.read_to_string(&mut contents)?;
let config: Config = toml::from_str(&contents)?;
let mut config: Config = toml::from_str(&contents)?;
for cnf_name in config.include.iter() {
let cnf_path = get_cnf_path(path, cnf_name);
let mut add_cnf = read_cnf(&cnf_path)?;
config.endpoint.append(&mut add_cnf.endpoint);
config.hook.append(&mut add_cnf.hook);
config.group.append(&mut add_cnf.group);
config.account.append(&mut add_cnf.account);
config.certificate.append(&mut add_cnf.certificate);
if config.global.is_none() {
config.global = add_cnf.global;
} else if let Some(new_glob) = add_cnf.global {
let mut tmp_glob = config.global.clone().unwrap();
set_cfg_attr!(tmp_glob.accounts_directory, new_glob.accounts_directory);
set_cfg_attr!(
tmp_glob.certificates_directory,
new_glob.certificates_directory
);
set_cfg_attr!(tmp_glob.cert_file_mode, new_glob.cert_file_mode);
set_cfg_attr!(tmp_glob.cert_file_user, new_glob.cert_file_user);
set_cfg_attr!(tmp_glob.cert_file_group, new_glob.cert_file_group);
set_cfg_attr!(tmp_glob.pk_file_mode, new_glob.pk_file_mode);
set_cfg_attr!(tmp_glob.pk_file_user, new_glob.pk_file_user);
set_cfg_attr!(tmp_glob.pk_file_group, new_glob.pk_file_group);
config.global = Some(tmp_glob);
}
}
Ok(config)
}
pub fn from_file(file_name: &str) -> Result<Config, Error> {
let path = PathBuf::from(file_name);
let config = read_cnf(&path)?;
init_directories(&config)?; init_directories(&config)?;
Ok(config) Ok(config)
} }

11
man/en/acmed.toml.5

@ -18,6 +18,17 @@ It is written in the
.Em TOML .Em TOML
format. The allowed elements are described below. format. The allowed elements are described below.
.Bl -tag .Bl -tag
.It Ic include
Array containing the path to configuration file to include. The path can be either relative or absolute. If relative, it is relative to the configuration file which included it.
.Pp
In case or overlapping global option definition, the one of the last included file will be used. For example, if a file
.Em A
includes files
.Em B
and
.Em C
and all three defines the same global option, the final value will be the one defined in file
.Em C .
.It Ic global .It Ic global
Table containing the global configuration options. Table containing the global configuration options.
.Bl -tag .Bl -tag

Loading…
Cancel
Save