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.

761 lines
23 KiB

  1. use crate::command_runner::{SetuidCommandRunner, StdCommandRunner};
  2. use crate::resources::{
  3. AcmeAccountKey, AcmeChallengesDir, AcmeChallengesNginxSnippet, AcmeRootCert, AcmeUser, Cert,
  4. CertChain, Cron, Csr, DefaultServer, Dir, File, GitCheckout, Key, KeyAndCertBundle,
  5. LoadedDirectory, MariaDbDatabase, MariaDbUser, NpmInstall, Owner, PhpFpmPool, Resource,
  6. ServeCustom, ServePhp, ServeRedir, ServeService, ServeStatic, StoredDirectory,
  7. SystemdSocketService, User, UserForDomain, WordpressPlugin, WordpressTranslation,
  8. };
  9. use crate::static_files::LETS_ENCRYPT_X3_CROSS_SIGNED;
  10. use crate::storage::SimpleStorage;
  11. use crate::symbols::acme::Cert as CertSymbol;
  12. use crate::symbols::concat::Concat as ConcatSymbol;
  13. use crate::symbols::cron::Cron as CronSymbol;
  14. use crate::symbols::dir::Dir as DirSymbol;
  15. use crate::symbols::file::File as FileSymbol;
  16. use crate::symbols::git::Checkout as GitCheckoutSymbol;
  17. use crate::symbols::mariadb::{
  18. Database as MariaDbDatabaseSymbol, Dump as MariaDbDumpSymbol, User as MariaDbUserSymbol,
  19. };
  20. use crate::symbols::npm::Install as NpmInstallSymbol;
  21. use crate::symbols::owner::Owner as OwnerSymbol;
  22. use crate::symbols::saved_directory::{SavedDirectory as SavedDirectorySymbol, StorageDirection};
  23. use crate::symbols::systemd::{
  24. ReloadService as ReloadServiceSymbol, UserService as UserServiceSymbol,
  25. UserSession as SystemdUserSessionSymbol,
  26. };
  27. use crate::symbols::tls::Csr as CsrSymbol;
  28. use crate::symbols::tls::Key as KeySymbol;
  29. use crate::symbols::user::User as UserSymbol;
  30. use crate::symbols::wordpress::{
  31. Plugin as WordpressPluginSymbol, Translation as WordpressTranslationSymbol,
  32. };
  33. use crate::templates::nginx;
  34. use crate::templates::php::fpm_pool_config as php_fpm_pool_config;
  35. use crate::templates::systemd::{
  36. nodejs_service as systemd_nodejs_service, socket_service as systemd_socket_service,
  37. };
  38. use crate::to_artifact::ToArtifact;
  39. use std::fmt::Display;
  40. use std::path::{Path, PathBuf};
  41. pub trait SymbolBuilder<R> {
  42. type Prerequisites: ToArtifact;
  43. fn prerequisites(resource: &R) -> Self::Prerequisites;
  44. type Symbol;
  45. fn create(
  46. resource: &R,
  47. target: &R::Artifact,
  48. inputs: <Self::Prerequisites as ToArtifact>::Artifact,
  49. ) -> Self::Symbol
  50. where
  51. R: Resource;
  52. }
  53. pub struct DefaultBuilder;
  54. impl<D> SymbolBuilder<Key<D>> for DefaultBuilder {
  55. type Prerequisites = ();
  56. fn prerequisites(_resource: &Key<D>) -> Self::Prerequisites {}
  57. type Symbol = KeySymbol<StdCommandRunner, PathBuf>;
  58. fn create(
  59. _resource: &Key<D>,
  60. target: &<Key<D> as Resource>::Artifact,
  61. (): <Self::Prerequisites as ToArtifact>::Artifact,
  62. ) -> Self::Symbol {
  63. KeySymbol::new(StdCommandRunner, target.clone().into())
  64. }
  65. }
  66. impl<D: Clone> SymbolBuilder<Csr<D>> for DefaultBuilder {
  67. type Prerequisites = Key<D>;
  68. fn prerequisites(resource: &Csr<D>) -> Self::Prerequisites {
  69. Key(resource.0.clone())
  70. }
  71. type Symbol = CsrSymbol<StdCommandRunner, D, PathBuf, PathBuf>;
  72. fn create(
  73. resource: &Csr<D>,
  74. target: &<Csr<D> as Resource>::Artifact,
  75. key: <Self::Prerequisites as ToArtifact>::Artifact,
  76. ) -> Self::Symbol {
  77. CsrSymbol::new(
  78. StdCommandRunner,
  79. resource.0.clone(),
  80. key.into(),
  81. target.clone().into(),
  82. )
  83. }
  84. }
  85. impl<D: Clone> SymbolBuilder<Cert<D>> for DefaultBuilder {
  86. type Prerequisites = (
  87. Csr<D>,
  88. AcmeRootCert,
  89. AcmeAccountKey,
  90. AcmeChallengesDir,
  91. AcmeUser,
  92. DefaultServer,
  93. );
  94. fn prerequisites(resource: &Cert<D>) -> Self::Prerequisites {
  95. (
  96. Csr(resource.0.clone()),
  97. AcmeRootCert,
  98. AcmeAccountKey,
  99. AcmeChallengesDir,
  100. AcmeUser,
  101. DefaultServer,
  102. )
  103. }
  104. type Symbol = CertSymbol<
  105. SetuidCommandRunner<'static, String, StdCommandRunner>,
  106. SetuidCommandRunner<'static, String, StdCommandRunner>,
  107. D,
  108. PathBuf,
  109. >;
  110. fn create(
  111. resource: &Cert<D>,
  112. target: &<Cert<D> as Resource>::Artifact,
  113. (csr, root_cert, account_key, challenges_dir, user_name, _): <Self::Prerequisites as ToArtifact>::Artifact,
  114. ) -> Self::Symbol {
  115. CertSymbol::new(
  116. resource.0.clone(),
  117. SetuidCommandRunner::new(user_name.0, &StdCommandRunner),
  118. root_cert.into(),
  119. account_key.into(),
  120. challenges_dir.into(),
  121. csr.into(),
  122. target.clone().into(),
  123. )
  124. }
  125. }
  126. impl<D: Clone> SymbolBuilder<CertChain<D>> for DefaultBuilder {
  127. type Prerequisites = (Cert<D>, AcmeRootCert);
  128. fn prerequisites(resource: &CertChain<D>) -> Self::Prerequisites {
  129. (Cert(resource.0.clone()), AcmeRootCert)
  130. }
  131. type Symbol = ConcatSymbol<[PathBuf; 2], PathBuf, PathBuf>;
  132. fn create(
  133. _resource: &CertChain<D>,
  134. target: &<CertChain<D> as Resource>::Artifact,
  135. (cert, root_cert): <Self::Prerequisites as ToArtifact>::Artifact,
  136. ) -> Self::Symbol {
  137. ConcatSymbol::new([cert.into(), root_cert.into()], target.clone().into())
  138. }
  139. }
  140. impl<D: Clone> SymbolBuilder<KeyAndCertBundle<D>> for DefaultBuilder {
  141. type Prerequisites = (CertChain<D>, Key<D>);
  142. fn prerequisites(resource: &KeyAndCertBundle<D>) -> Self::Prerequisites {
  143. (CertChain(resource.0.clone()), Key(resource.0.clone()))
  144. }
  145. type Symbol = ConcatSymbol<[PathBuf; 2], PathBuf, PathBuf>;
  146. fn create(
  147. _resource: &KeyAndCertBundle<D>,
  148. target: &<KeyAndCertBundle<D> as Resource>::Artifact,
  149. (cert_chain, key): <Self::Prerequisites as ToArtifact>::Artifact,
  150. ) -> Self::Symbol {
  151. ConcatSymbol::new([key.into(), cert_chain.into()], target.clone().into())
  152. }
  153. }
  154. impl<P: AsRef<Path> + Clone> SymbolBuilder<File<P>> for DefaultBuilder {
  155. type Prerequisites = ();
  156. fn prerequisites(_resource: &File<P>) -> Self::Prerequisites {}
  157. type Symbol = FileSymbol<P, String>;
  158. fn create(
  159. resource: &File<P>,
  160. _target: &<File<P> as Resource>::Artifact,
  161. (): <Self::Prerequisites as ToArtifact>::Artifact,
  162. ) -> Self::Symbol {
  163. FileSymbol::new(resource.0.clone(), resource.1.clone())
  164. }
  165. }
  166. impl<'a, P: AsRef<Path> + Clone> SymbolBuilder<GitCheckout<'a, P>> for DefaultBuilder {
  167. type Prerequisites = ();
  168. fn prerequisites(_resource: &GitCheckout<'a, P>) -> Self::Prerequisites {}
  169. type Symbol = GitCheckoutSymbol<StdCommandRunner, StdCommandRunner, P, &'a str, &'a str>;
  170. fn create(
  171. resource: &GitCheckout<'a, P>,
  172. _target: &<GitCheckout<'a, P> as Resource>::Artifact,
  173. (): <Self::Prerequisites as ToArtifact>::Artifact,
  174. ) -> Self::Symbol {
  175. GitCheckoutSymbol::new(resource.0.clone(), resource.1, resource.2, StdCommandRunner)
  176. }
  177. }
  178. impl SymbolBuilder<DefaultServer> for DefaultBuilder {
  179. type Prerequisites = AcmeChallengesNginxSnippet;
  180. fn prerequisites(_resource: &DefaultServer) -> Self::Prerequisites {
  181. AcmeChallengesNginxSnippet
  182. }
  183. type Symbol = (
  184. FileSymbol<PathBuf, String>,
  185. ReloadServiceSymbol<StdCommandRunner, StdCommandRunner, &'static str>,
  186. );
  187. fn create(
  188. _resource: &DefaultServer,
  189. target: &<DefaultServer as Resource>::Artifact,
  190. challenges_snippet_path: <Self::Prerequisites as ToArtifact>::Artifact,
  191. ) -> Self::Symbol {
  192. (
  193. FileSymbol::new(
  194. target.clone().into(),
  195. nginx::default_server(challenges_snippet_path),
  196. ),
  197. ReloadServiceSymbol::new(StdCommandRunner, "nginx"),
  198. )
  199. }
  200. }
  201. impl<D: AsRef<str> + Clone + Display> SymbolBuilder<ServeCustom<D>> for DefaultBuilder {
  202. type Prerequisites = (CertChain<D>, Key<D>, AcmeChallengesNginxSnippet);
  203. fn prerequisites(resource: &ServeCustom<D>) -> Self::Prerequisites {
  204. (
  205. CertChain(resource.0.clone()),
  206. Key(resource.0.clone()),
  207. AcmeChallengesNginxSnippet,
  208. )
  209. }
  210. type Symbol = (
  211. FileSymbol<PathBuf, String>,
  212. ReloadServiceSymbol<StdCommandRunner, StdCommandRunner, &'static str>,
  213. );
  214. fn create(
  215. resource: &ServeCustom<D>,
  216. target: &<ServeCustom<D> as Resource>::Artifact,
  217. (cert, key, challenges_snippet_path): <Self::Prerequisites as ToArtifact>::Artifact,
  218. ) -> Self::Symbol {
  219. (
  220. FileSymbol::new(
  221. target.clone().into(),
  222. nginx::server_config(&resource.0, cert, key, &resource.1, challenges_snippet_path),
  223. ),
  224. ReloadServiceSymbol::new(StdCommandRunner, "nginx"),
  225. )
  226. }
  227. }
  228. impl<D: Clone + Display, P: AsRef<Path>> SymbolBuilder<ServePhp<D, P>> for DefaultBuilder {
  229. type Prerequisites = (
  230. PhpFpmPool<D>,
  231. CertChain<D>,
  232. Key<D>,
  233. AcmeChallengesNginxSnippet,
  234. );
  235. fn prerequisites(resource: &ServePhp<D, P>) -> Self::Prerequisites {
  236. (
  237. PhpFpmPool(resource.0.clone(), 10),
  238. CertChain(resource.0.clone()),
  239. Key(resource.0.clone()),
  240. AcmeChallengesNginxSnippet,
  241. )
  242. }
  243. type Symbol = (
  244. FileSymbol<PathBuf, String>,
  245. ReloadServiceSymbol<StdCommandRunner, StdCommandRunner, &'static str>,
  246. );
  247. fn create(
  248. resource: &ServePhp<D, P>,
  249. target: &<ServePhp<D, P> as Resource>::Artifact,
  250. (pool, cert, key, challenges_snippet_path): <Self::Prerequisites as ToArtifact>::Artifact,
  251. ) -> Self::Symbol {
  252. (
  253. FileSymbol::new(
  254. target.clone().into(),
  255. nginx::server_config(
  256. &resource.0,
  257. cert,
  258. key,
  259. nginx::php_snippet(resource.2, &pool.0, &resource.1) + &resource.3,
  260. challenges_snippet_path,
  261. ),
  262. ),
  263. ReloadServiceSymbol::new(StdCommandRunner, "nginx"),
  264. )
  265. }
  266. }
  267. impl<D: Clone + Display, P: Clone + AsRef<Path>> SymbolBuilder<ServeService<D, P>>
  268. for DefaultBuilder
  269. {
  270. type Prerequisites = (
  271. SystemdSocketService<D, P>,
  272. CertChain<D>,
  273. Key<D>,
  274. AcmeChallengesNginxSnippet,
  275. );
  276. fn prerequisites(resource: &ServeService<D, P>) -> Self::Prerequisites {
  277. (
  278. SystemdSocketService(
  279. resource.0.clone(),
  280. resource.1,
  281. resource.2.clone(),
  282. resource.4.clone(),
  283. resource.5,
  284. ),
  285. CertChain(resource.0.clone()),
  286. Key(resource.0.clone()),
  287. AcmeChallengesNginxSnippet,
  288. )
  289. }
  290. type Symbol = (
  291. FileSymbol<PathBuf, String>,
  292. ReloadServiceSymbol<StdCommandRunner, StdCommandRunner, &'static str>,
  293. );
  294. fn create(
  295. resource: &ServeService<D, P>,
  296. target: &<ServeService<D, P> as Resource>::Artifact,
  297. (socket, cert, key, challenges_snippet_path): <Self::Prerequisites as ToArtifact>::Artifact,
  298. ) -> Self::Symbol {
  299. (
  300. FileSymbol::new(
  301. target.clone().into(),
  302. nginx::server_config(
  303. &resource.0,
  304. cert,
  305. key,
  306. nginx::proxy_snippet(&socket.0, &resource.3),
  307. challenges_snippet_path,
  308. ),
  309. ),
  310. ReloadServiceSymbol::new(StdCommandRunner, "nginx"),
  311. )
  312. }
  313. }
  314. impl<D: AsRef<str> + Clone + Display> SymbolBuilder<ServeRedir<D>> for DefaultBuilder {
  315. type Prerequisites = (CertChain<D>, Key<D>, AcmeChallengesNginxSnippet);
  316. fn prerequisites(resource: &ServeRedir<D>) -> Self::Prerequisites {
  317. (
  318. CertChain(resource.0.clone()),
  319. Key(resource.0.clone()),
  320. AcmeChallengesNginxSnippet,
  321. )
  322. }
  323. type Symbol = (
  324. FileSymbol<PathBuf, String>,
  325. ReloadServiceSymbol<StdCommandRunner, StdCommandRunner, &'static str>,
  326. );
  327. fn create(
  328. resource: &ServeRedir<D>,
  329. target: &<ServeRedir<D> as Resource>::Artifact,
  330. (cert, key, challenges_snippet_path): <Self::Prerequisites as ToArtifact>::Artifact,
  331. ) -> Self::Symbol {
  332. (
  333. FileSymbol::new(
  334. target.clone().into(),
  335. nginx::server_config(
  336. &resource.0,
  337. cert,
  338. key,
  339. nginx::redir_snippet(resource.1.as_ref()),
  340. challenges_snippet_path,
  341. ),
  342. ),
  343. ReloadServiceSymbol::new(StdCommandRunner, "nginx"),
  344. )
  345. }
  346. }
  347. impl<D: AsRef<str> + Clone + Display, P: AsRef<Path>> SymbolBuilder<ServeStatic<D, P>>
  348. for DefaultBuilder
  349. {
  350. type Prerequisites = (CertChain<D>, Key<D>, AcmeChallengesNginxSnippet);
  351. fn prerequisites(resource: &ServeStatic<D, P>) -> Self::Prerequisites {
  352. (
  353. CertChain(resource.0.clone()),
  354. Key(resource.0.clone()),
  355. AcmeChallengesNginxSnippet,
  356. )
  357. }
  358. type Symbol = (
  359. FileSymbol<PathBuf, String>,
  360. ReloadServiceSymbol<StdCommandRunner, StdCommandRunner, &'static str>,
  361. );
  362. fn create(
  363. resource: &ServeStatic<D, P>,
  364. target: &<ServeStatic<D, P> as Resource>::Artifact,
  365. (cert, key, challenges_snippet_path): <Self::Prerequisites as ToArtifact>::Artifact,
  366. ) -> Self::Symbol {
  367. (
  368. FileSymbol::new(
  369. target.clone().into(),
  370. nginx::server_config(
  371. &resource.0,
  372. cert,
  373. key,
  374. nginx::static_snippet(resource.1.as_ref()),
  375. challenges_snippet_path,
  376. ),
  377. ),
  378. ReloadServiceSymbol::new(StdCommandRunner, "nginx"),
  379. )
  380. }
  381. }
  382. impl<D: Clone> SymbolBuilder<PhpFpmPool<D>> for DefaultBuilder {
  383. type Prerequisites = ();
  384. fn prerequisites(_resource: &PhpFpmPool<D>) -> Self::Prerequisites {}
  385. type Symbol = (
  386. FileSymbol<PathBuf, String>,
  387. ReloadServiceSymbol<StdCommandRunner, StdCommandRunner, String>,
  388. );
  389. fn create(
  390. resource: &PhpFpmPool<D>,
  391. (socket_path, conf_path, user_name, service_name): &<PhpFpmPool<D> as Resource>::Artifact,
  392. (): <Self::Prerequisites as ToArtifact>::Artifact,
  393. ) -> Self::Symbol {
  394. (
  395. FileSymbol::new(
  396. conf_path.clone().into(),
  397. php_fpm_pool_config(&user_name.0, &socket_path, resource.1),
  398. ),
  399. ReloadServiceSymbol::new(StdCommandRunner, service_name.0.clone()),
  400. )
  401. }
  402. }
  403. impl<D, P: AsRef<Path>> SymbolBuilder<SystemdSocketService<D, P>> for DefaultBuilder {
  404. type Prerequisites = ();
  405. fn prerequisites(_resource: &SystemdSocketService<D, P>) -> Self::Prerequisites {}
  406. type Symbol = (
  407. FileSymbol<PathBuf, String>,
  408. SystemdUserSessionSymbol<'static, String, StdCommandRunner>,
  409. UserServiceSymbol<'static, PathBuf, String, StdCommandRunner>,
  410. );
  411. fn create(
  412. resource: &SystemdSocketService<D, P>,
  413. (socket_path, conf_path, user_name): &<SystemdSocketService<D, P> as Resource>::Artifact,
  414. (): <Self::Prerequisites as ToArtifact>::Artifact,
  415. ) -> Self::Symbol {
  416. (
  417. FileSymbol::new(
  418. conf_path.clone().into(),
  419. if resource.4 {
  420. systemd_nodejs_service(&resource.2, socket_path, &resource.3)
  421. } else {
  422. systemd_socket_service(
  423. socket_path,
  424. resource.2.as_ref().to_str().unwrap(),
  425. &resource.3,
  426. "",
  427. )
  428. },
  429. ),
  430. SystemdUserSessionSymbol::new(user_name.0.clone(), &StdCommandRunner),
  431. UserServiceSymbol::new(
  432. socket_path.clone().into(),
  433. user_name.0.clone(),
  434. resource.1,
  435. &StdCommandRunner,
  436. ),
  437. )
  438. }
  439. }
  440. impl<P: Clone> SymbolBuilder<Dir<P>> for DefaultBuilder {
  441. type Prerequisites = ();
  442. fn prerequisites(_resource: &Dir<P>) -> Self::Prerequisites {}
  443. type Symbol = DirSymbol<P>;
  444. fn create(
  445. resource: &Dir<P>,
  446. _target: &<Dir<P> as Resource>::Artifact,
  447. (): <Self::Prerequisites as ToArtifact>::Artifact,
  448. ) -> Self::Symbol {
  449. DirSymbol::new(resource.0.clone())
  450. }
  451. }
  452. impl<P: Clone + AsRef<Path>> SymbolBuilder<NpmInstall<P>> for DefaultBuilder {
  453. type Prerequisites = ();
  454. fn prerequisites(_resource: &NpmInstall<P>) -> Self::Prerequisites {}
  455. type Symbol = NpmInstallSymbol<'static, P, StdCommandRunner>;
  456. fn create(
  457. resource: &NpmInstall<P>,
  458. _target: &<NpmInstall<P> as Resource>::Artifact,
  459. (): <Self::Prerequisites as ToArtifact>::Artifact,
  460. ) -> Self::Symbol {
  461. NpmInstallSymbol::new(resource.0.clone(), &StdCommandRunner)
  462. }
  463. }
  464. impl<P: Clone + AsRef<Path>> SymbolBuilder<StoredDirectory<P>> for DefaultBuilder {
  465. type Prerequisites = ();
  466. fn prerequisites(_resource: &StoredDirectory<P>) -> Self::Prerequisites {}
  467. type Symbol = SavedDirectorySymbol<StdCommandRunner, StdCommandRunner, P, SimpleStorage>;
  468. fn create(
  469. resource: &StoredDirectory<P>,
  470. target: &<StoredDirectory<P> as Resource>::Artifact,
  471. (): <Self::Prerequisites as ToArtifact>::Artifact,
  472. ) -> Self::Symbol {
  473. SavedDirectorySymbol::new(
  474. resource.1.clone(),
  475. SimpleStorage::new(target.clone().into()),
  476. StorageDirection::Store,
  477. StdCommandRunner,
  478. )
  479. }
  480. }
  481. impl<P: Clone + AsRef<Path>> SymbolBuilder<LoadedDirectory<P>> for DefaultBuilder {
  482. type Prerequisites = ();
  483. fn prerequisites(_resource: &LoadedDirectory<P>) -> Self::Prerequisites {}
  484. type Symbol = SavedDirectorySymbol<StdCommandRunner, StdCommandRunner, P, SimpleStorage>;
  485. fn create(
  486. resource: &LoadedDirectory<P>,
  487. target: &<LoadedDirectory<P> as Resource>::Artifact,
  488. (): <Self::Prerequisites as ToArtifact>::Artifact,
  489. ) -> Self::Symbol {
  490. SavedDirectorySymbol::new(
  491. resource.1.clone(),
  492. SimpleStorage::new(target.clone().into()),
  493. StorageDirection::Load,
  494. StdCommandRunner,
  495. )
  496. }
  497. }
  498. impl<D: Clone> SymbolBuilder<UserForDomain<D>> for DefaultBuilder {
  499. type Prerequisites = ();
  500. fn prerequisites(_resource: &UserForDomain<D>) -> Self::Prerequisites {}
  501. type Symbol = UserSymbol<String, StdCommandRunner>;
  502. fn create(
  503. _resource: &UserForDomain<D>,
  504. (user_name, _home_path): &<UserForDomain<D> as Resource>::Artifact,
  505. (): <Self::Prerequisites as ToArtifact>::Artifact,
  506. ) -> Self::Symbol {
  507. UserSymbol::new(user_name.0.clone(), StdCommandRunner)
  508. }
  509. }
  510. impl SymbolBuilder<User> for DefaultBuilder {
  511. type Prerequisites = ();
  512. fn prerequisites(_resource: &User) -> Self::Prerequisites {}
  513. type Symbol = UserSymbol<String, StdCommandRunner>;
  514. fn create(
  515. resource: &User,
  516. (): &<User as Resource>::Artifact,
  517. (): <Self::Prerequisites as ToArtifact>::Artifact,
  518. ) -> Self::Symbol {
  519. UserSymbol::new(resource.0.clone(), StdCommandRunner)
  520. }
  521. }
  522. impl<P: AsRef<Path> + Clone> SymbolBuilder<Owner<P>> for DefaultBuilder {
  523. type Prerequisites = ();
  524. fn prerequisites(_resource: &Owner<P>) -> Self::Prerequisites {}
  525. type Symbol = OwnerSymbol<StdCommandRunner, StdCommandRunner, P, String>;
  526. fn create(
  527. resource: &Owner<P>,
  528. (): &<Owner<P> as Resource>::Artifact,
  529. (): <Self::Prerequisites as ToArtifact>::Artifact,
  530. ) -> Self::Symbol {
  531. OwnerSymbol::new(resource.1.clone(), resource.0.clone(), StdCommandRunner)
  532. }
  533. }
  534. impl SymbolBuilder<AcmeUser> for DefaultBuilder {
  535. type Prerequisites = ();
  536. fn prerequisites(_resource: &AcmeUser) -> Self::Prerequisites {}
  537. type Symbol = UserSymbol<String, StdCommandRunner>;
  538. fn create(
  539. _resource: &AcmeUser,
  540. user_name: &<AcmeUser as Resource>::Artifact,
  541. (): <Self::Prerequisites as ToArtifact>::Artifact,
  542. ) -> Self::Symbol {
  543. UserSymbol::new(user_name.0.clone(), StdCommandRunner)
  544. }
  545. }
  546. impl SymbolBuilder<AcmeChallengesDir> for DefaultBuilder {
  547. type Prerequisites = AcmeUser;
  548. fn prerequisites(_resource: &AcmeChallengesDir) -> Self::Prerequisites {
  549. AcmeUser
  550. }
  551. type Symbol = (
  552. DirSymbol<PathBuf>,
  553. OwnerSymbol<StdCommandRunner, StdCommandRunner, PathBuf, String>,
  554. );
  555. fn create(
  556. _resource: &AcmeChallengesDir,
  557. target: &<AcmeChallengesDir as Resource>::Artifact,
  558. user_name: <Self::Prerequisites as ToArtifact>::Artifact,
  559. ) -> Self::Symbol {
  560. (
  561. DirSymbol::new(target.clone().into()),
  562. OwnerSymbol::new(target.clone().into(), user_name.0, StdCommandRunner),
  563. )
  564. }
  565. }
  566. impl SymbolBuilder<AcmeChallengesNginxSnippet> for DefaultBuilder {
  567. type Prerequisites = AcmeChallengesDir;
  568. fn prerequisites(_resource: &AcmeChallengesNginxSnippet) -> Self::Prerequisites {
  569. AcmeChallengesDir
  570. }
  571. type Symbol = FileSymbol<PathBuf, String>;
  572. fn create(
  573. _resource: &AcmeChallengesNginxSnippet,
  574. target: &<AcmeChallengesNginxSnippet as Resource>::Artifact,
  575. challenges_dir: <Self::Prerequisites as ToArtifact>::Artifact,
  576. ) -> Self::Symbol {
  577. FileSymbol::new(
  578. target.clone().into(),
  579. nginx::acme_challenges_snippet(challenges_dir),
  580. )
  581. }
  582. }
  583. impl SymbolBuilder<AcmeAccountKey> for DefaultBuilder {
  584. type Prerequisites = AcmeUser;
  585. fn prerequisites(_resource: &AcmeAccountKey) -> Self::Prerequisites {
  586. AcmeUser
  587. }
  588. type Symbol = (
  589. KeySymbol<StdCommandRunner, PathBuf>,
  590. OwnerSymbol<StdCommandRunner, StdCommandRunner, PathBuf, String>,
  591. );
  592. fn create(
  593. _resource: &AcmeAccountKey,
  594. target: &<AcmeAccountKey as Resource>::Artifact,
  595. user_name: <Self::Prerequisites as ToArtifact>::Artifact,
  596. ) -> Self::Symbol {
  597. (
  598. KeySymbol::new(StdCommandRunner, target.clone().into()),
  599. OwnerSymbol::new(target.clone().into(), user_name.0, StdCommandRunner),
  600. )
  601. }
  602. }
  603. impl SymbolBuilder<AcmeRootCert> for DefaultBuilder {
  604. type Prerequisites = ();
  605. fn prerequisites(_resource: &AcmeRootCert) -> Self::Prerequisites {}
  606. type Symbol = FileSymbol<PathBuf, &'static str>;
  607. fn create(
  608. _resource: &AcmeRootCert,
  609. target: &<AcmeRootCert as Resource>::Artifact,
  610. (): <Self::Prerequisites as ToArtifact>::Artifact,
  611. ) -> Self::Symbol {
  612. FileSymbol::new(target.clone().into(), LETS_ENCRYPT_X3_CROSS_SIGNED)
  613. }
  614. }
  615. impl<D> SymbolBuilder<MariaDbUser<D>> for DefaultBuilder {
  616. type Prerequisites = ();
  617. fn prerequisites(_resource: &MariaDbUser<D>) -> Self::Prerequisites {}
  618. type Symbol = MariaDbUserSymbol<'static, String, StdCommandRunner>;
  619. fn create(
  620. _resource: &MariaDbUser<D>,
  621. user_name: &<MariaDbUser<D> as Resource>::Artifact,
  622. _: <Self::Prerequisites as ToArtifact>::Artifact,
  623. ) -> Self::Symbol {
  624. MariaDbUserSymbol::new(user_name.0.clone(), &StdCommandRunner)
  625. }
  626. }
  627. impl<D: Clone> SymbolBuilder<MariaDbDatabase<D>> for DefaultBuilder {
  628. type Prerequisites = MariaDbUser<D>;
  629. fn prerequisites(resource: &MariaDbDatabase<D>) -> Self::Prerequisites {
  630. MariaDbUser(resource.0.clone())
  631. }
  632. type Symbol = (
  633. MariaDbDatabaseSymbol<'static, String, SimpleStorage, StdCommandRunner>,
  634. MariaDbDumpSymbol<'static, String, StdCommandRunner, SimpleStorage>,
  635. );
  636. fn create(
  637. _resource: &MariaDbDatabase<D>,
  638. (db_name, _, data_path): &<MariaDbDatabase<D> as Resource>::Artifact,
  639. _: <Self::Prerequisites as ToArtifact>::Artifact,
  640. ) -> Self::Symbol {
  641. let db_dump = SimpleStorage::new(data_path.clone().into());
  642. (
  643. MariaDbDatabaseSymbol::new(db_name.0.clone(), db_dump.clone(), &StdCommandRunner),
  644. MariaDbDumpSymbol::new(db_name.0.clone(), db_dump, &StdCommandRunner),
  645. )
  646. }
  647. }
  648. impl<P: Clone + AsRef<Path>> SymbolBuilder<WordpressPlugin<P>> for DefaultBuilder {
  649. type Prerequisites = Dir<PathBuf>;
  650. fn prerequisites(resource: &WordpressPlugin<P>) -> Self::Prerequisites {
  651. Dir(resource.0.as_ref().join("wp-content/plugins"))
  652. }
  653. type Symbol = WordpressPluginSymbol<'static, P, &'static str, StdCommandRunner>;
  654. fn create(
  655. resource: &WordpressPlugin<P>,
  656. (): &<WordpressPlugin<P> as Resource>::Artifact,
  657. _: <Self::Prerequisites as ToArtifact>::Artifact,
  658. ) -> Self::Symbol {
  659. WordpressPluginSymbol::new(resource.0.clone(), resource.1, &StdCommandRunner)
  660. }
  661. }
  662. impl<P: Clone + AsRef<Path>> SymbolBuilder<WordpressTranslation<P>> for DefaultBuilder {
  663. type Prerequisites = Dir<PathBuf>;
  664. fn prerequisites(resource: &WordpressTranslation<P>) -> Self::Prerequisites {
  665. Dir(resource.0.as_ref().join("wp-content/languages"))
  666. }
  667. type Symbol = WordpressTranslationSymbol<'static, &'static str, PathBuf, StdCommandRunner>;
  668. fn create(
  669. resource: &WordpressTranslation<P>,
  670. (): &<WordpressTranslation<P> as Resource>::Artifact,
  671. _: <Self::Prerequisites as ToArtifact>::Artifact,
  672. ) -> Self::Symbol {
  673. WordpressTranslationSymbol::new(
  674. resource.0.as_ref().join("wp-content/languages"),
  675. resource.1,
  676. resource.2,
  677. &StdCommandRunner,
  678. )
  679. }
  680. }
  681. impl<D: Clone> SymbolBuilder<Cron<D>> for DefaultBuilder {
  682. type Prerequisites = UserForDomain<D>;
  683. fn prerequisites(resource: &Cron<D>) -> Self::Prerequisites {
  684. UserForDomain(resource.0.clone())
  685. }
  686. type Symbol = CronSymbol<'static, String, String, StdCommandRunner>;
  687. fn create(
  688. resource: &Cron<D>,
  689. (): &<Cron<D> as Resource>::Artifact,
  690. user_name: <Self::Prerequisites as ToArtifact>::Artifact,
  691. ) -> Self::Symbol {
  692. CronSymbol::new((user_name.0).0, resource.1.clone(), &StdCommandRunner)
  693. }
  694. }