Browse Source

Add key + cert chain bundles

master
Adrian Heine 4 years ago
parent
commit
fccd0bc685
  1. 16
      src/symbols/acme/mod.rs
  2. 79
      src/symbols/concat.rs
  3. 7
      src/symbols/factory.rs
  4. 1
      src/symbols/mod.rs

16
src/symbols/acme/mod.rs

@ -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

@ -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())
}
}

7
src/symbols/factory.rs

@ -63,6 +63,13 @@ impl<'b, C: 'b + CommandRunner, P: 'b + Policy> SymbolFactory<'b, C, P> {
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,

1
src/symbols/mod.rs

@ -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;

Loading…
Cancel
Save