A library for writing host-specific, single-binary configuration management and deployment tools
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.

305 lines
7.7 KiB

7 years ago
  1. use crate::artifacts::{
  2. DatabaseName as DatabaseNameArtifact, Path as PathArtifact, ServiceName as ServiceNameArtifact,
  3. UserName as UserNameArtifact,
  4. };
  5. use std::hash::Hash;
  6. use std::path::PathBuf;
  7. pub trait Resource {
  8. type Artifact;
  9. }
  10. #[derive(Debug, Hash, PartialEq, Eq)]
  11. pub struct Key<D>(pub D);
  12. impl<D> Resource for Key<D> {
  13. type Artifact = PathArtifact;
  14. }
  15. #[derive(Debug, Hash, PartialEq, Eq)]
  16. pub struct Csr<D>(pub D);
  17. impl<D> Resource for Csr<D> {
  18. type Artifact = PathArtifact;
  19. }
  20. #[derive(Debug, Hash, PartialEq, Eq)]
  21. pub struct Cert<D>(pub D);
  22. impl<D> Resource for Cert<D> {
  23. type Artifact = PathArtifact;
  24. }
  25. #[derive(Debug, Hash, PartialEq, Eq)]
  26. pub struct CertChain<D>(pub D);
  27. impl<D> Resource for CertChain<D> {
  28. type Artifact = PathArtifact;
  29. }
  30. #[derive(Debug, Hash, PartialEq, Eq)]
  31. pub struct KeyAndCertBundle<D>(pub D);
  32. impl<D> Resource for KeyAndCertBundle<D> {
  33. type Artifact = PathArtifact;
  34. }
  35. #[derive(Debug, Hash, PartialEq, Eq)]
  36. pub struct File<P>(pub P, pub String);
  37. impl<'a, P> Resource for File<P> {
  38. type Artifact = ();
  39. }
  40. #[derive(Debug, Hash, PartialEq, Eq)]
  41. pub struct GitCheckout<'a, P>(pub P, pub &'a str, pub &'a str);
  42. impl<'a, P> Resource for GitCheckout<'a, P> {
  43. type Artifact = ();
  44. }
  45. #[derive(Debug, Hash, PartialEq, Eq)]
  46. pub struct Dir<P>(pub P);
  47. impl<P> Resource for Dir<P> {
  48. type Artifact = ();
  49. }
  50. #[derive(Debug, Hash, PartialEq, Eq)]
  51. pub struct UserForDomain<D>(pub D);
  52. impl<D> Resource for UserForDomain<D> {
  53. type Artifact = (UserNameArtifact, PathArtifact);
  54. }
  55. #[derive(Debug, Hash, PartialEq, Eq)]
  56. pub struct AcmeAccountKey;
  57. impl Resource for AcmeAccountKey {
  58. type Artifact = PathArtifact;
  59. }
  60. #[derive(Debug, Hash, PartialEq, Eq)]
  61. pub struct AcmeUser;
  62. impl Resource for AcmeUser {
  63. type Artifact = UserNameArtifact;
  64. }
  65. #[derive(Debug, Hash, PartialEq, Eq)]
  66. pub struct AcmeRootCert;
  67. impl Resource for AcmeRootCert {
  68. type Artifact = PathArtifact;
  69. }
  70. #[derive(Debug, Hash, PartialEq, Eq)]
  71. pub struct AcmeChallengesDir;
  72. impl Resource for AcmeChallengesDir {
  73. type Artifact = PathArtifact;
  74. }
  75. #[derive(Debug, Hash, PartialEq, Eq)]
  76. pub struct AcmeChallengesNginxSnippet;
  77. impl Resource for AcmeChallengesNginxSnippet {
  78. type Artifact = PathArtifact;
  79. }
  80. #[derive(Debug, Hash, PartialEq, Eq)]
  81. pub struct StoredDirectory<P>(pub &'static str, pub P);
  82. impl<P> Resource for StoredDirectory<P> {
  83. type Artifact = PathArtifact;
  84. }
  85. #[derive(Debug, Hash, PartialEq, Eq)]
  86. pub struct LoadedDirectory<P>(pub &'static str, pub P);
  87. impl<P> Resource for LoadedDirectory<P> {
  88. type Artifact = PathArtifact;
  89. }
  90. pub fn get_saved_directory<P: Clone>(
  91. storage_name: &'static str,
  92. target: P,
  93. ) -> (StoredDirectory<P>, LoadedDirectory<P>) {
  94. (
  95. StoredDirectory(storage_name, target.clone()),
  96. LoadedDirectory(storage_name, target),
  97. )
  98. }
  99. #[derive(Debug, Hash, PartialEq, Eq)]
  100. pub struct User(pub String);
  101. impl Resource for User {
  102. type Artifact = ();
  103. }
  104. #[derive(Debug, Hash, PartialEq, Eq)]
  105. pub struct SystemdSocketService<D, P>(pub D, pub &'static str, pub P, pub P, pub bool);
  106. impl<D, P> Resource for SystemdSocketService<D, P> {
  107. type Artifact = (PathArtifact, PathArtifact, UserNameArtifact);
  108. }
  109. #[derive(Debug, Hash, PartialEq, Eq)]
  110. pub struct NpmInstall<P>(pub P);
  111. impl<P> Resource for NpmInstall<P> {
  112. type Artifact = ();
  113. }
  114. #[derive(Debug, Hash, PartialEq, Eq)]
  115. pub struct Owner<P>(pub String, pub P);
  116. impl<P> Resource for Owner<P> {
  117. type Artifact = ();
  118. }
  119. #[derive(Debug, Hash, PartialEq, Eq)]
  120. pub struct ServeCustom<D>(pub D, pub String);
  121. impl<D> Resource for ServeCustom<D> {
  122. type Artifact = PathArtifact;
  123. }
  124. #[derive(Debug, Hash, PartialEq, Eq)]
  125. pub struct ServePhp<D, P>(pub D, pub P, pub &'static str, pub String, pub usize);
  126. impl<D, P> Resource for ServePhp<D, P> {
  127. type Artifact = PathArtifact;
  128. }
  129. // Domain, service name, exec, static, dir
  130. #[derive(Debug, Hash, PartialEq, Eq)]
  131. pub struct ServeService<D, P>(pub D, pub &'static str, pub P, pub P, pub P, pub bool);
  132. impl<D, P> Resource for ServeService<D, P> {
  133. type Artifact = PathArtifact;
  134. }
  135. #[derive(Debug, Hash, PartialEq, Eq)]
  136. pub struct ServeRedir<D>(pub D, pub D);
  137. impl<D> Resource for ServeRedir<D> {
  138. type Artifact = PathArtifact;
  139. }
  140. #[derive(Debug, Hash, PartialEq, Eq)]
  141. pub struct ServeStatic<D, P>(pub D, pub P);
  142. impl<D, P> Resource for ServeStatic<D, P> {
  143. type Artifact = PathArtifact;
  144. }
  145. #[derive(Debug, Hash, PartialEq, Eq)]
  146. pub struct DefaultServer;
  147. impl Resource for DefaultServer {
  148. type Artifact = PathArtifact;
  149. }
  150. #[derive(Debug, Hash, PartialEq, Eq)]
  151. pub struct PhpFpmPool<D>(pub D, pub usize);
  152. impl<D> Resource for PhpFpmPool<D> {
  153. type Artifact = (
  154. PathArtifact,
  155. PathArtifact,
  156. UserNameArtifact,
  157. ServiceNameArtifact,
  158. );
  159. }
  160. // A single domain could possibly need multiple databases
  161. #[derive(Debug, Hash, PartialEq, Eq)]
  162. pub struct MariaDbDatabase<D>(pub D);
  163. impl<D> Resource for MariaDbDatabase<D> {
  164. type Artifact = (DatabaseNameArtifact, UserNameArtifact, PathArtifact);
  165. }
  166. #[derive(Debug, Hash, PartialEq, Eq)]
  167. pub struct MariaDbUser<D>(pub D);
  168. impl<D> Resource for MariaDbUser<D> {
  169. type Artifact = UserNameArtifact;
  170. }
  171. #[derive(Debug, Hash, PartialEq, Eq)]
  172. pub struct WordpressPlugin<P>(pub P, pub &'static str);
  173. impl<P> Resource for WordpressPlugin<P> {
  174. type Artifact = ();
  175. }
  176. #[derive(Debug, Hash, PartialEq, Eq)]
  177. pub struct WordpressTranslation<P>(pub P, pub &'static str, pub &'static str);
  178. impl<P> Resource for WordpressTranslation<P> {
  179. type Artifact = ();
  180. }
  181. #[derive(Debug, Hash, PartialEq, Eq)]
  182. pub struct Cron<D>(pub D, pub String);
  183. impl<D> Resource for Cron<D> {
  184. type Artifact = ();
  185. }
  186. use std::rc::{Rc, Weak};
  187. pub trait FromResource<R> {
  188. fn from_resource(from: R) -> (Self, Weak<R>)
  189. where
  190. Self: Sized;
  191. }
  192. pub trait FromArtifact<R: Resource> {
  193. fn from_artifact(from: R::Artifact) -> Self
  194. where
  195. Self: Sized;
  196. fn into_artifact(self) -> R::Artifact
  197. where
  198. Self: Sized;
  199. }
  200. macro_rules! default_resources {
  201. ( $($name:ident: $type:ty,)* ) => {
  202. #[derive(Debug, PartialEq, Eq, Hash)]
  203. pub enum DefaultResources<'a, D> {
  204. $( $name(Rc<$type>) ),*
  205. }
  206. $(impl<'a, D> FromResource<$type> for DefaultResources<'a, D> {
  207. fn from_resource(from: $type) -> (Self, Weak<$type>) {
  208. let inner = Rc::new(from);
  209. (Self::$name(Rc::clone(&inner)), Rc::downgrade(&inner))
  210. }
  211. })*
  212. #[derive(Clone, Debug)]
  213. pub enum DefaultArtifacts<'a, D> {
  214. $( $name(<$type as Resource>::Artifact) ),*
  215. }
  216. $(impl<'a, D> FromArtifact<$type> for DefaultArtifacts<'a, D> {
  217. fn from_artifact(from: <$type as Resource>::Artifact) -> Self {
  218. Self::$name(from)
  219. }
  220. fn into_artifact(self) -> <$type as Resource>::Artifact {
  221. match self {
  222. Self::$name(inner) => inner,
  223. _ => panic!()
  224. }
  225. }
  226. })*
  227. }
  228. }
  229. default_resources!(
  230. AcmeAccountKey: AcmeAccountKey,
  231. AcmeChallengesDir: AcmeChallengesDir,
  232. AcmeChallengesNginxSnippet: AcmeChallengesNginxSnippet,
  233. AcmeRootCert: AcmeRootCert,
  234. AcmeUser: AcmeUser,
  235. Cert: Cert<D>,
  236. CertChain: CertChain<D>,
  237. Cron: Cron<D>,
  238. Csr: Csr<D>,
  239. DefaultServer: DefaultServer,
  240. Dir: Dir<PathBuf>,
  241. File: File<PathBuf>,
  242. GitCheckout: GitCheckout<'a, PathBuf>,
  243. Key: Key<D>,
  244. KeyAndCertBundle: KeyAndCertBundle<D>,
  245. LoadedDirectory: LoadedDirectory<PathBuf>,
  246. MariaDbDatabase: MariaDbDatabase<D>,
  247. MariaDbUser: MariaDbUser<D>,
  248. SystemdSocketService: SystemdSocketService<D, PathBuf>,
  249. NpmInstall: NpmInstall<PathBuf>,
  250. Owner: Owner<PathBuf>,
  251. PhpFpmPool: PhpFpmPool<D>,
  252. ServeCustom: ServeCustom<D>,
  253. ServeService: ServeService<D, PathBuf>,
  254. ServePhp: ServePhp<D, PathBuf>,
  255. ServeRedir: ServeRedir<D>,
  256. ServeStatic: ServeStatic<D, PathBuf>,
  257. StoredDirectory: StoredDirectory<PathBuf>,
  258. User: User,
  259. UserForDomain: UserForDomain<D>,
  260. WordpressPlugin: WordpressPlugin<PathBuf>,
  261. WordpressTranslation: WordpressTranslation<PathBuf>,
  262. );