You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
330 lines
8.4 KiB
330 lines
8.4 KiB
use crate::artifacts::{
|
|
DatabaseName as DatabaseNameArtifact, Path as PathArtifact, ServiceName as ServiceNameArtifact,
|
|
UserName as UserNameArtifact,
|
|
};
|
|
use crate::templates::php::FpmPoolConfig;
|
|
use std::hash::Hash;
|
|
use std::path::PathBuf;
|
|
|
|
pub trait Resource {
|
|
type Artifact;
|
|
}
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
|
pub struct Key<D>(pub D);
|
|
impl<D> Resource for Key<D> {
|
|
type Artifact = PathArtifact;
|
|
}
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
|
pub struct Csr<D>(pub D);
|
|
impl<D> Resource for Csr<D> {
|
|
type Artifact = PathArtifact;
|
|
}
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
|
pub struct Cert<D>(pub D);
|
|
impl<D> Resource for Cert<D> {
|
|
type Artifact = PathArtifact;
|
|
}
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
|
pub struct CertChain<D>(pub D);
|
|
impl<D> Resource for CertChain<D> {
|
|
type Artifact = PathArtifact;
|
|
}
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
|
pub struct KeyAndCertBundle<D>(pub D);
|
|
impl<D> Resource for KeyAndCertBundle<D> {
|
|
type Artifact = PathArtifact;
|
|
}
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
|
pub struct File<P>(pub P, pub String);
|
|
impl<'a, P> Resource for File<P> {
|
|
type Artifact = ();
|
|
}
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
|
pub struct GitCheckout<'a, P>(pub P, pub &'a str, pub &'a str);
|
|
impl<'a, P> Resource for GitCheckout<'a, P> {
|
|
type Artifact = ();
|
|
}
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
|
pub struct Dir<P>(pub P);
|
|
impl<P> Resource for Dir<P> {
|
|
type Artifact = ();
|
|
}
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
|
pub struct UserForDomain<D>(pub D);
|
|
impl<D> Resource for UserForDomain<D> {
|
|
type Artifact = (UserNameArtifact, PathArtifact);
|
|
}
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
|
pub struct AcmeAccountKey;
|
|
impl Resource for AcmeAccountKey {
|
|
type Artifact = PathArtifact;
|
|
}
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
|
pub struct AcmeUser;
|
|
impl Resource for AcmeUser {
|
|
type Artifact = UserNameArtifact;
|
|
}
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
|
pub struct AcmeRootCert;
|
|
impl Resource for AcmeRootCert {
|
|
type Artifact = PathArtifact;
|
|
}
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
|
pub struct AcmeChallengesDir;
|
|
impl Resource for AcmeChallengesDir {
|
|
type Artifact = PathArtifact;
|
|
}
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
|
pub struct AcmeChallengesNginxSnippet;
|
|
impl Resource for AcmeChallengesNginxSnippet {
|
|
type Artifact = PathArtifact;
|
|
}
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
|
pub struct StoredDirectory<P>(pub &'static str, pub P);
|
|
impl<P> Resource for StoredDirectory<P> {
|
|
type Artifact = PathArtifact;
|
|
}
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
|
pub struct LoadedDirectory<P>(pub &'static str, pub P);
|
|
impl<P> Resource for LoadedDirectory<P> {
|
|
type Artifact = PathArtifact;
|
|
}
|
|
|
|
pub fn get_saved_directory<P: Clone>(
|
|
storage_name: &'static str,
|
|
target: P,
|
|
) -> (StoredDirectory<P>, LoadedDirectory<P>) {
|
|
(
|
|
StoredDirectory(storage_name, target.clone()),
|
|
LoadedDirectory(storage_name, target),
|
|
)
|
|
}
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
|
pub struct User(pub String);
|
|
impl Resource for User {
|
|
type Artifact = ();
|
|
}
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
|
pub struct SystemdSocketService<D, P>(pub D, pub &'static str, pub P, pub P, pub bool);
|
|
impl<D, P> Resource for SystemdSocketService<D, P> {
|
|
type Artifact = (PathArtifact, PathArtifact, UserNameArtifact);
|
|
}
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
|
pub struct NpmInstall<P>(pub P);
|
|
impl<P> Resource for NpmInstall<P> {
|
|
type Artifact = ();
|
|
}
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
|
pub struct Owner<P>(pub String, pub P);
|
|
impl<P> Resource for Owner<P> {
|
|
type Artifact = ();
|
|
}
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
|
pub struct ServeCustom<D>(pub D, pub String);
|
|
impl<D> Resource for ServeCustom<D> {
|
|
type Artifact = PathArtifact;
|
|
}
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
|
pub struct ServePhp<D, P, C>(pub D, pub P, pub &'static str, pub String, pub C);
|
|
impl<D, P, C> Resource for ServePhp<D, P, C> {
|
|
type Artifact = PathArtifact;
|
|
}
|
|
|
|
// Domain, service name, exec, static, dir
|
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
|
pub struct ServeService<D, P>(pub D, pub &'static str, pub P, pub P, pub P, pub bool);
|
|
impl<D, P> Resource for ServeService<D, P> {
|
|
type Artifact = PathArtifact;
|
|
}
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
|
pub struct ServeRedir<D>(pub D, pub D);
|
|
impl<D> Resource for ServeRedir<D> {
|
|
type Artifact = PathArtifact;
|
|
}
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
|
pub struct ServeStatic<D, P>(pub D, pub P);
|
|
impl<D, P> Resource for ServeStatic<D, P> {
|
|
type Artifact = PathArtifact;
|
|
}
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
|
pub struct DefaultServer;
|
|
impl Resource for DefaultServer {
|
|
type Artifact = PathArtifact;
|
|
}
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
|
pub struct PhpFpmPool<D>(pub D, pub FpmPoolConfig);
|
|
impl<D> Resource for PhpFpmPool<D> {
|
|
type Artifact = (
|
|
PathArtifact,
|
|
PathArtifact,
|
|
UserNameArtifact,
|
|
ServiceNameArtifact,
|
|
);
|
|
}
|
|
|
|
// A single domain could possibly need multiple databases
|
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
|
pub struct MariaDbDatabase<D>(pub D);
|
|
impl<D> Resource for MariaDbDatabase<D> {
|
|
type Artifact = (DatabaseNameArtifact, UserNameArtifact, PathArtifact);
|
|
}
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
|
pub struct MariaDbUser<D>(pub D);
|
|
impl<D> Resource for MariaDbUser<D> {
|
|
type Artifact = UserNameArtifact;
|
|
}
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
|
pub struct PostgresqlDatabase<D>(pub D);
|
|
impl<D> Resource for PostgresqlDatabase<D> {
|
|
type Artifact = (DatabaseNameArtifact, PathArtifact);
|
|
}
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
|
pub struct WordpressPlugin<P>(pub P, pub &'static str);
|
|
impl<P> Resource for WordpressPlugin<P> {
|
|
type Artifact = ();
|
|
}
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
|
pub struct WordpressTranslation<P>(pub P, pub &'static str, pub &'static str);
|
|
impl<P> Resource for WordpressTranslation<P> {
|
|
type Artifact = ();
|
|
}
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
|
pub struct Cron<D>(pub D, pub String);
|
|
impl<D> Resource for Cron<D> {
|
|
type Artifact = ();
|
|
}
|
|
|
|
use std::rc::{Rc, Weak};
|
|
|
|
pub trait FromResource<R> {
|
|
fn from_resource(from: R) -> (Self, Weak<R>)
|
|
where
|
|
Self: Sized;
|
|
}
|
|
|
|
pub trait FromArtifact<R: Resource> {
|
|
fn from_artifact(from: R::Artifact) -> Self
|
|
where
|
|
Self: Sized;
|
|
fn into_artifact(self) -> R::Artifact
|
|
where
|
|
Self: Sized;
|
|
}
|
|
|
|
macro_rules! default_resources {
|
|
( $($name:ident: $type:ty,)* ) => {
|
|
#[derive(Debug, PartialEq, Eq, Hash)]
|
|
pub enum DefaultResources<'a, D> {
|
|
$( $name(Rc<$type>) ),*
|
|
}
|
|
|
|
$(impl<'a, D> FromResource<$type> for DefaultResources<'a, D> {
|
|
fn from_resource(from: $type) -> (Self, Weak<$type>) {
|
|
let inner = Rc::new(from);
|
|
(Self::$name(Rc::clone(&inner)), Rc::downgrade(&inner))
|
|
}
|
|
})*
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub enum DefaultArtifacts<'a, D> {
|
|
$( $name(<$type as Resource>::Artifact) ),*
|
|
}
|
|
|
|
$(impl<'a, D> FromArtifact<$type> for DefaultArtifacts<'a, D> {
|
|
fn from_artifact(from: <$type as Resource>::Artifact) -> Self {
|
|
Self::$name(from)
|
|
}
|
|
|
|
fn into_artifact(self) -> <$type as Resource>::Artifact {
|
|
match self {
|
|
Self::$name(inner) => inner,
|
|
_ => panic!()
|
|
}
|
|
}
|
|
})*
|
|
}
|
|
}
|
|
|
|
// Only one enum entry per resource type, otherwise the equality checks fail
|
|
default_resources!(
|
|
AcmeAccountKey: AcmeAccountKey,
|
|
AcmeChallengesDir: AcmeChallengesDir,
|
|
AcmeChallengesNginxSnippet: AcmeChallengesNginxSnippet,
|
|
AcmeRootCert: AcmeRootCert,
|
|
AcmeUser: AcmeUser,
|
|
Cert: Cert<D>,
|
|
CertChain: CertChain<D>,
|
|
Cron: Cron<D>,
|
|
Csr: Csr<D>,
|
|
DefaultServer: DefaultServer,
|
|
Dir: Dir<PathBuf>,
|
|
File: File<PathBuf>,
|
|
GitCheckout: GitCheckout<'a, PathBuf>,
|
|
Key: Key<D>,
|
|
KeyAndCertBundle: KeyAndCertBundle<D>,
|
|
LoadedDirectory: LoadedDirectory<PathBuf>,
|
|
MariaDbDatabase: MariaDbDatabase<D>,
|
|
MariaDbUser: MariaDbUser<D>,
|
|
PostgresqlDatabase: PostgresqlDatabase<D>,
|
|
SystemdSocketService: SystemdSocketService<D, PathBuf>,
|
|
NpmInstall: NpmInstall<PathBuf>,
|
|
Owner: Owner<PathBuf>,
|
|
PhpFpmPool: PhpFpmPool<D>,
|
|
ServeCustom: ServeCustom<D>,
|
|
ServeService: ServeService<D, PathBuf>,
|
|
ServePhp: ServePhp<D, PathBuf, FpmPoolConfig>,
|
|
ServeRedir: ServeRedir<D>,
|
|
ServeStatic: ServeStatic<D, PathBuf>,
|
|
StoredDirectory: StoredDirectory<PathBuf>,
|
|
User: User,
|
|
UserForDomain: UserForDomain<D>,
|
|
WordpressPlugin: WordpressPlugin<PathBuf>,
|
|
WordpressTranslation: WordpressTranslation<PathBuf>,
|
|
);
|
|
|
|
pub fn serve_php<D, P: Into<PathBuf>, C: Into<FpmPoolConfig>>(
|
|
domain: D,
|
|
path: P,
|
|
root_filename: &'static str,
|
|
nginx_config: impl Into<String>,
|
|
pool_config: C,
|
|
) -> ServePhp<D, PathBuf, FpmPoolConfig> {
|
|
ServePhp(
|
|
domain,
|
|
path.into(),
|
|
root_filename,
|
|
nginx_config.into(),
|
|
pool_config.into(),
|
|
)
|
|
}
|