Compare commits

..

5 commits

6 changed files with 116 additions and 6 deletions

View file

@ -3,6 +3,7 @@ use std::path::{Path, PathBuf};
use crate::command_runner::CommandRunner;
use crate::command_runner::SetuidCommandRunner;
use crate::symbols::concat::Concat;
use crate::symbols::dir::Dir;
use crate::symbols::file::File;
use crate::symbols::list::List;
@ -94,4 +95,19 @@ impl<'a, U: Clone + AsRef<str>, H: AsRef<Path>, C: AsRef<str>, R: CommandRunner>
AcmeCertChain::new(host, &self.acme_command_runner, root_cert_path),
))
}
pub fn get_key_and_cert_bundle<HOST: 'a + Clone + AsRef<str>>(
&'a self,
host: HOST,
) -> impl Symbol + 'a {
List::from((
self.get_cert(host.clone()),
Concat::new(
[
format!("/etc/ssl/private/{}.key", host.as_ref()),
format!("/etc/ssl/local_certs/{}.chained.crt", host.as_ref()),
],
format!("/etc/ssl/private/{}.with_key.crt", host.as_ref()),
),
))
}
}

79
src/symbols/concat.rs Normal file
View file

@ -0,0 +1,79 @@
use std::error::Error;
use std::fmt;
use std::fs::{metadata, File};
use std::io::copy;
use std::marker::PhantomData;
use std::path::Path;
use crate::resources::Resource;
use crate::symbols::{Action, OwnedSymbolAction, Symbol, SymbolAction, SymbolRunner};
pub struct Concat<S, D, I> {
target: D,
sources: S,
source_item: PhantomData<I>,
}
impl<S, D, I> Concat<S, D, I> {
pub fn new(sources: S, target: D) -> Self {
Self {
target,
sources,
source_item: PhantomData::default(),
}
}
}
impl<S: AsRef<[I]>, D: AsRef<Path>, I: AsRef<Path>> Symbol for Concat<S, D, I> {
fn target_reached(&self) -> Result<bool, Box<dyn Error>> {
let target = self.target.as_ref();
if !target.exists() {
return Ok(false);
}
let target_date = metadata(target)?.modified()?;
for source in self.sources.as_ref() {
if metadata(source)?.modified()? > target_date {
return Ok(false);
}
}
Ok(true)
}
fn execute(&self) -> Result<(), Box<dyn Error>> {
let mut file = File::create(self.target.as_ref())?;
for source in self.sources.as_ref() {
copy(&mut File::open(source)?, &mut file)?;
}
Ok(())
}
fn get_prerequisites(&self) -> Vec<Resource> {
let mut r: Vec<Resource> = self
.sources
.as_ref()
.iter()
.map(|s| Resource::new("file", s.as_ref().to_str().unwrap()))
.collect();
if let Some(parent) = self.target.as_ref().parent() {
r.push(Resource::new("dir", parent.to_str().unwrap()))
}
r
}
fn as_action<'a>(&'a self, runner: &'a dyn SymbolRunner) -> Box<dyn Action + 'a> {
Box::new(SymbolAction::new(runner, self))
}
fn into_action<'a>(self: Box<Self>, runner: &'a dyn SymbolRunner) -> Box<dyn Action + 'a>
where
Self: 'a,
{
Box::new(OwnedSymbolAction::new(runner, *self))
}
}
impl<S, D: AsRef<Path>, I> fmt::Display for Concat<S, D, I> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
write!(f, "Concat {}", self.target.as_ref().display())
}
}

View file

@ -59,9 +59,20 @@ impl<'b, C: 'b + CommandRunner, P: 'b + Policy> SymbolFactory<'b, C, P> {
}
}
pub fn get_nginx_acme_server<'a, 'c: 'a, S: 'a + Symbol>(
&'c self,
host: &'static str,
pub fn get_cert<'a, H: 'a + AsRef<str> + Clone>(&'a self, host: H) -> impl Symbol + 'a {
self.acme_factory.get_cert(host)
}
pub fn get_key_and_cert_bundle<'a, H: 'a + AsRef<str> + Clone>(
&'a self,
host: H,
) -> impl Symbol + 'a {
self.acme_factory.get_key_and_cert_bundle(host)
}
pub fn get_nginx_acme_server<'a, S: 'a + Symbol>(
&'a self,
host: &'a str,
nginx_server_symbol: S,
) -> impl Symbol + 'a {
List::from((
@ -71,7 +82,7 @@ impl<'b, C: 'b + CommandRunner, P: 'b + Policy> SymbolFactory<'b, C, P> {
ReloadService::new("nginx", self.command_runner),
),
Hook::new(
self.acme_factory.get_cert(host),
self.get_cert(host),
ReloadService::new("nginx", self.command_runner),
),
))
@ -154,9 +165,9 @@ env[PATH] = /usr/local/bin:/usr/bin:/bin
root_dir,
10,
"
location / {{
location / {
try_files $uri $uri/ /index.php?$args;
}}
}
",
)
}

View file

@ -48,6 +48,8 @@ impl Symbol for List<'_> {
for symbol in &self.symbols {
if let Some(provides) = symbol.provides() {
r.extend(provides.into_iter());
} else {
return None;
}
}
if r.is_empty() {

View file

@ -68,6 +68,7 @@ impl<'a, S: Symbol + 'a> Action for OwnedSymbolAction<'a, S> {
}
pub mod acme;
pub mod concat;
pub mod cron;
pub mod dir;
pub mod factory;

View file

@ -54,6 +54,7 @@ impl<C: CommandRunner> Symbol for TlsKey<'_, C> {
"-text".as_ref(),
],
)?;
// FIXME check bytes
Ok(stdout.ends_with("RSA key ok\n".as_bytes()))
}