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.

767 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.0.clone())
  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.0,
  81. target.0.clone(),
  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.0,
  119. account_key.0,
  120. challenges_dir.0,
  121. csr.0,
  122. target.0.clone(),
  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.0, root_cert.0], target.0.clone())
  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.0, cert_chain.0], target.0.clone())
  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.0.clone(),
  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.0.clone(),
  222. nginx::server_config(
  223. &resource.0,
  224. cert.0,
  225. key.0,
  226. &resource.1,
  227. challenges_snippet_path,
  228. ),
  229. ),
  230. ReloadServiceSymbol::new(StdCommandRunner, "nginx"),
  231. )
  232. }
  233. }
  234. impl<D: Clone + Display, P: AsRef<Path>> SymbolBuilder<ServePhp<D, P>> for DefaultBuilder {
  235. type Prerequisites = (
  236. PhpFpmPool<D>,
  237. CertChain<D>,
  238. Key<D>,
  239. AcmeChallengesNginxSnippet,
  240. );
  241. fn prerequisites(resource: &ServePhp<D, P>) -> Self::Prerequisites {
  242. (
  243. PhpFpmPool(resource.0.clone(), 10),
  244. CertChain(resource.0.clone()),
  245. Key(resource.0.clone()),
  246. AcmeChallengesNginxSnippet,
  247. )
  248. }
  249. type Symbol = (
  250. FileSymbol<PathBuf, String>,
  251. ReloadServiceSymbol<StdCommandRunner, StdCommandRunner, &'static str>,
  252. );
  253. fn create(
  254. resource: &ServePhp<D, P>,
  255. target: &<ServePhp<D, P> as Resource>::Artifact,
  256. (pool, cert, key, challenges_snippet_path): <Self::Prerequisites as ToArtifact>::Artifact,
  257. ) -> Self::Symbol {
  258. (
  259. FileSymbol::new(
  260. target.0.clone(),
  261. nginx::server_config(
  262. &resource.0,
  263. cert.0,
  264. key.0,
  265. nginx::php_snippet(resource.2, &pool.0, &resource.1) + &resource.3,
  266. challenges_snippet_path,
  267. ),
  268. ),
  269. ReloadServiceSymbol::new(StdCommandRunner, "nginx"),
  270. )
  271. }
  272. }
  273. impl<D: Clone + Display, P: Clone + AsRef<Path>> SymbolBuilder<ServeService<D, P>>
  274. for DefaultBuilder
  275. {
  276. type Prerequisites = (
  277. SystemdSocketService<D, P>,
  278. CertChain<D>,
  279. Key<D>,
  280. AcmeChallengesNginxSnippet,
  281. );
  282. fn prerequisites(resource: &ServeService<D, P>) -> Self::Prerequisites {
  283. (
  284. SystemdSocketService(
  285. resource.0.clone(),
  286. resource.1,
  287. resource.2.clone(),
  288. resource.4.clone(),
  289. resource.5,
  290. ),
  291. CertChain(resource.0.clone()),
  292. Key(resource.0.clone()),
  293. AcmeChallengesNginxSnippet,
  294. )
  295. }
  296. type Symbol = (
  297. FileSymbol<PathBuf, String>,
  298. ReloadServiceSymbol<StdCommandRunner, StdCommandRunner, &'static str>,
  299. );
  300. fn create(
  301. resource: &ServeService<D, P>,
  302. target: &<ServeService<D, P> as Resource>::Artifact,
  303. (socket, cert, key, challenges_snippet_path): <Self::Prerequisites as ToArtifact>::Artifact,
  304. ) -> Self::Symbol {
  305. (
  306. FileSymbol::new(
  307. target.0.clone(),
  308. nginx::server_config(
  309. &resource.0,
  310. cert.0,
  311. key.0,
  312. nginx::proxy_snippet(&socket.0, &resource.3),
  313. challenges_snippet_path,
  314. ),
  315. ),
  316. ReloadServiceSymbol::new(StdCommandRunner, "nginx"),
  317. )
  318. }
  319. }
  320. impl<D: AsRef<str> + Clone + Display> SymbolBuilder<ServeRedir<D>> for DefaultBuilder {
  321. type Prerequisites = (CertChain<D>, Key<D>, AcmeChallengesNginxSnippet);
  322. fn prerequisites(resource: &ServeRedir<D>) -> Self::Prerequisites {
  323. (
  324. CertChain(resource.0.clone()),
  325. Key(resource.0.clone()),
  326. AcmeChallengesNginxSnippet,
  327. )
  328. }
  329. type Symbol = (
  330. FileSymbol<PathBuf, String>,
  331. ReloadServiceSymbol<StdCommandRunner, StdCommandRunner, &'static str>,
  332. );
  333. fn create(
  334. resource: &ServeRedir<D>,
  335. target: &<ServeRedir<D> as Resource>::Artifact,
  336. (cert, key, challenges_snippet_path): <Self::Prerequisites as ToArtifact>::Artifact,
  337. ) -> Self::Symbol {
  338. (
  339. FileSymbol::new(
  340. target.0.clone(),
  341. nginx::server_config(
  342. &resource.0,
  343. cert.0,
  344. key.0,
  345. nginx::redir_snippet(resource.1.as_ref()),
  346. challenges_snippet_path,
  347. ),
  348. ),
  349. ReloadServiceSymbol::new(StdCommandRunner, "nginx"),
  350. )
  351. }
  352. }
  353. impl<D: AsRef<str> + Clone + Display, P: AsRef<Path>> SymbolBuilder<ServeStatic<D, P>>
  354. for DefaultBuilder
  355. {
  356. type Prerequisites = (CertChain<D>, Key<D>, AcmeChallengesNginxSnippet);
  357. fn prerequisites(resource: &ServeStatic<D, P>) -> Self::Prerequisites {
  358. (
  359. CertChain(resource.0.clone()),
  360. Key(resource.0.clone()),
  361. AcmeChallengesNginxSnippet,
  362. )
  363. }
  364. type Symbol = (
  365. FileSymbol<PathBuf, String>,
  366. ReloadServiceSymbol<StdCommandRunner, StdCommandRunner, &'static str>,
  367. );
  368. fn create(
  369. resource: &ServeStatic<D, P>,
  370. target: &<ServeStatic<D, P> as Resource>::Artifact,
  371. (cert, key, challenges_snippet_path): <Self::Prerequisites as ToArtifact>::Artifact,
  372. ) -> Self::Symbol {
  373. (
  374. FileSymbol::new(
  375. target.0.clone(),
  376. nginx::server_config(
  377. &resource.0,
  378. cert.0,
  379. key.0,
  380. nginx::static_snippet(resource.1.as_ref()),
  381. challenges_snippet_path,
  382. ),
  383. ),
  384. ReloadServiceSymbol::new(StdCommandRunner, "nginx"),
  385. )
  386. }
  387. }
  388. impl<D: Clone> SymbolBuilder<PhpFpmPool<D>> for DefaultBuilder {
  389. type Prerequisites = ();
  390. fn prerequisites(_resource: &PhpFpmPool<D>) -> Self::Prerequisites {}
  391. type Symbol = (
  392. FileSymbol<PathBuf, String>,
  393. ReloadServiceSymbol<StdCommandRunner, StdCommandRunner, String>,
  394. );
  395. fn create(
  396. resource: &PhpFpmPool<D>,
  397. (socket_path, conf_path, user_name, service_name): &<PhpFpmPool<D> as Resource>::Artifact,
  398. (): <Self::Prerequisites as ToArtifact>::Artifact,
  399. ) -> Self::Symbol {
  400. (
  401. FileSymbol::new(
  402. conf_path.0.clone(),
  403. php_fpm_pool_config(&user_name.0, &socket_path.0, resource.1),
  404. ),
  405. ReloadServiceSymbol::new(StdCommandRunner, service_name.0.clone()),
  406. )
  407. }
  408. }
  409. impl<D, P: AsRef<Path>> SymbolBuilder<SystemdSocketService<D, P>> for DefaultBuilder {
  410. type Prerequisites = ();
  411. fn prerequisites(_resource: &SystemdSocketService<D, P>) -> Self::Prerequisites {}
  412. type Symbol = (
  413. FileSymbol<PathBuf, String>,
  414. SystemdUserSessionSymbol<'static, String, StdCommandRunner>,
  415. UserServiceSymbol<'static, PathBuf, String, StdCommandRunner>,
  416. );
  417. fn create(
  418. resource: &SystemdSocketService<D, P>,
  419. (socket_path, conf_path, user_name): &<SystemdSocketService<D, P> as Resource>::Artifact,
  420. (): <Self::Prerequisites as ToArtifact>::Artifact,
  421. ) -> Self::Symbol {
  422. (
  423. FileSymbol::new(
  424. conf_path.0.clone(),
  425. if resource.4 {
  426. systemd_nodejs_service(&resource.2, socket_path, &resource.3)
  427. } else {
  428. systemd_socket_service(
  429. socket_path,
  430. resource.2.as_ref().to_str().unwrap(),
  431. &resource.3,
  432. "",
  433. )
  434. },
  435. ),
  436. SystemdUserSessionSymbol::new(user_name.0.clone(), &StdCommandRunner),
  437. UserServiceSymbol::new(
  438. socket_path.0.clone(),
  439. user_name.0.clone(),
  440. resource.1,
  441. &StdCommandRunner,
  442. ),
  443. )
  444. }
  445. }
  446. impl<P: Clone> SymbolBuilder<Dir<P>> for DefaultBuilder {
  447. type Prerequisites = ();
  448. fn prerequisites(_resource: &Dir<P>) -> Self::Prerequisites {}
  449. type Symbol = DirSymbol<P>;
  450. fn create(
  451. resource: &Dir<P>,
  452. _target: &<Dir<P> as Resource>::Artifact,
  453. (): <Self::Prerequisites as ToArtifact>::Artifact,
  454. ) -> Self::Symbol {
  455. DirSymbol::new(resource.0.clone())
  456. }
  457. }
  458. impl<P: Clone + AsRef<Path>> SymbolBuilder<NpmInstall<P>> for DefaultBuilder {
  459. type Prerequisites = ();
  460. fn prerequisites(_resource: &NpmInstall<P>) -> Self::Prerequisites {}
  461. type Symbol = NpmInstallSymbol<'static, P, StdCommandRunner>;
  462. fn create(
  463. resource: &NpmInstall<P>,
  464. _target: &<NpmInstall<P> as Resource>::Artifact,
  465. (): <Self::Prerequisites as ToArtifact>::Artifact,
  466. ) -> Self::Symbol {
  467. NpmInstallSymbol::new(resource.0.clone(), &StdCommandRunner)
  468. }
  469. }
  470. impl<P: Clone + AsRef<Path>> SymbolBuilder<StoredDirectory<P>> for DefaultBuilder {
  471. type Prerequisites = ();
  472. fn prerequisites(_resource: &StoredDirectory<P>) -> Self::Prerequisites {}
  473. type Symbol = SavedDirectorySymbol<StdCommandRunner, StdCommandRunner, P, SimpleStorage>;
  474. fn create(
  475. resource: &StoredDirectory<P>,
  476. target: &<StoredDirectory<P> as Resource>::Artifact,
  477. (): <Self::Prerequisites as ToArtifact>::Artifact,
  478. ) -> Self::Symbol {
  479. SavedDirectorySymbol::new(
  480. resource.1.clone(),
  481. SimpleStorage::new(target.0.clone()),
  482. StorageDirection::Store,
  483. StdCommandRunner,
  484. )
  485. }
  486. }
  487. impl<P: Clone + AsRef<Path>> SymbolBuilder<LoadedDirectory<P>> for DefaultBuilder {
  488. type Prerequisites = ();
  489. fn prerequisites(_resource: &LoadedDirectory<P>) -> Self::Prerequisites {}
  490. type Symbol = SavedDirectorySymbol<StdCommandRunner, StdCommandRunner, P, SimpleStorage>;
  491. fn create(
  492. resource: &LoadedDirectory<P>,
  493. target: &<LoadedDirectory<P> as Resource>::Artifact,
  494. (): <Self::Prerequisites as ToArtifact>::Artifact,
  495. ) -> Self::Symbol {
  496. SavedDirectorySymbol::new(
  497. resource.1.clone(),
  498. SimpleStorage::new(target.0.clone()),
  499. StorageDirection::Load,
  500. StdCommandRunner,
  501. )
  502. }
  503. }
  504. impl<D: Clone> SymbolBuilder<UserForDomain<D>> for DefaultBuilder {
  505. type Prerequisites = ();
  506. fn prerequisites(_resource: &UserForDomain<D>) -> Self::Prerequisites {}
  507. type Symbol = UserSymbol<String, StdCommandRunner>;
  508. fn create(
  509. _resource: &UserForDomain<D>,
  510. (user_name, _home_path): &<UserForDomain<D> as Resource>::Artifact,
  511. (): <Self::Prerequisites as ToArtifact>::Artifact,
  512. ) -> Self::Symbol {
  513. UserSymbol::new(user_name.0.clone(), StdCommandRunner)
  514. }
  515. }
  516. impl SymbolBuilder<User> for DefaultBuilder {
  517. type Prerequisites = ();
  518. fn prerequisites(_resource: &User) -> Self::Prerequisites {}
  519. type Symbol = UserSymbol<String, StdCommandRunner>;
  520. fn create(
  521. resource: &User,
  522. (): &<User as Resource>::Artifact,
  523. (): <Self::Prerequisites as ToArtifact>::Artifact,
  524. ) -> Self::Symbol {
  525. UserSymbol::new(resource.0.clone(), StdCommandRunner)
  526. }
  527. }
  528. impl<P: AsRef<Path> + Clone> SymbolBuilder<Owner<P>> for DefaultBuilder {
  529. type Prerequisites = ();
  530. fn prerequisites(_resource: &Owner<P>) -> Self::Prerequisites {}
  531. type Symbol = OwnerSymbol<StdCommandRunner, StdCommandRunner, P, String>;
  532. fn create(
  533. resource: &Owner<P>,
  534. (): &<Owner<P> as Resource>::Artifact,
  535. (): <Self::Prerequisites as ToArtifact>::Artifact,
  536. ) -> Self::Symbol {
  537. OwnerSymbol::new(resource.1.clone(), resource.0.clone(), StdCommandRunner)
  538. }
  539. }
  540. impl SymbolBuilder<AcmeUser> for DefaultBuilder {
  541. type Prerequisites = ();
  542. fn prerequisites(_resource: &AcmeUser) -> Self::Prerequisites {}
  543. type Symbol = UserSymbol<String, StdCommandRunner>;
  544. fn create(
  545. _resource: &AcmeUser,
  546. user_name: &<AcmeUser as Resource>::Artifact,
  547. (): <Self::Prerequisites as ToArtifact>::Artifact,
  548. ) -> Self::Symbol {
  549. UserSymbol::new(user_name.0.clone(), StdCommandRunner)
  550. }
  551. }
  552. impl SymbolBuilder<AcmeChallengesDir> for DefaultBuilder {
  553. type Prerequisites = AcmeUser;
  554. fn prerequisites(_resource: &AcmeChallengesDir) -> Self::Prerequisites {
  555. AcmeUser
  556. }
  557. type Symbol = (
  558. DirSymbol<PathBuf>,
  559. OwnerSymbol<StdCommandRunner, StdCommandRunner, PathBuf, String>,
  560. );
  561. fn create(
  562. _resource: &AcmeChallengesDir,
  563. target: &<AcmeChallengesDir as Resource>::Artifact,
  564. user_name: <Self::Prerequisites as ToArtifact>::Artifact,
  565. ) -> Self::Symbol {
  566. (
  567. DirSymbol::new(target.0.clone()),
  568. OwnerSymbol::new(target.0.clone(), user_name.0, StdCommandRunner),
  569. )
  570. }
  571. }
  572. impl SymbolBuilder<AcmeChallengesNginxSnippet> for DefaultBuilder {
  573. type Prerequisites = AcmeChallengesDir;
  574. fn prerequisites(_resource: &AcmeChallengesNginxSnippet) -> Self::Prerequisites {
  575. AcmeChallengesDir
  576. }
  577. type Symbol = FileSymbol<PathBuf, String>;
  578. fn create(
  579. _resource: &AcmeChallengesNginxSnippet,
  580. target: &<AcmeChallengesNginxSnippet as Resource>::Artifact,
  581. challenges_dir: <Self::Prerequisites as ToArtifact>::Artifact,
  582. ) -> Self::Symbol {
  583. FileSymbol::new(
  584. target.0.clone(),
  585. nginx::acme_challenges_snippet(challenges_dir),
  586. )
  587. }
  588. }
  589. impl SymbolBuilder<AcmeAccountKey> for DefaultBuilder {
  590. type Prerequisites = AcmeUser;
  591. fn prerequisites(_resource: &AcmeAccountKey) -> Self::Prerequisites {
  592. AcmeUser
  593. }
  594. type Symbol = (
  595. KeySymbol<StdCommandRunner, PathBuf>,
  596. OwnerSymbol<StdCommandRunner, StdCommandRunner, PathBuf, String>,
  597. );
  598. fn create(
  599. _resource: &AcmeAccountKey,
  600. target: &<AcmeAccountKey as Resource>::Artifact,
  601. user_name: <Self::Prerequisites as ToArtifact>::Artifact,
  602. ) -> Self::Symbol {
  603. (
  604. KeySymbol::new(StdCommandRunner, target.0.clone()),
  605. OwnerSymbol::new(target.0.clone(), user_name.0, StdCommandRunner),
  606. )
  607. }
  608. }
  609. impl SymbolBuilder<AcmeRootCert> for DefaultBuilder {
  610. type Prerequisites = ();
  611. fn prerequisites(_resource: &AcmeRootCert) -> Self::Prerequisites {}
  612. type Symbol = FileSymbol<PathBuf, &'static str>;
  613. fn create(
  614. _resource: &AcmeRootCert,
  615. target: &<AcmeRootCert as Resource>::Artifact,
  616. (): <Self::Prerequisites as ToArtifact>::Artifact,
  617. ) -> Self::Symbol {
  618. FileSymbol::new(target.0.clone(), LETS_ENCRYPT_X3_CROSS_SIGNED)
  619. }
  620. }
  621. impl<D> SymbolBuilder<MariaDbUser<D>> for DefaultBuilder {
  622. type Prerequisites = ();
  623. fn prerequisites(_resource: &MariaDbUser<D>) -> Self::Prerequisites {}
  624. type Symbol = MariaDbUserSymbol<'static, String, StdCommandRunner>;
  625. fn create(
  626. _resource: &MariaDbUser<D>,
  627. user_name: &<MariaDbUser<D> as Resource>::Artifact,
  628. _: <Self::Prerequisites as ToArtifact>::Artifact,
  629. ) -> Self::Symbol {
  630. MariaDbUserSymbol::new(user_name.0.clone(), &StdCommandRunner)
  631. }
  632. }
  633. impl<D: Clone> SymbolBuilder<MariaDbDatabase<D>> for DefaultBuilder {
  634. type Prerequisites = MariaDbUser<D>;
  635. fn prerequisites(resource: &MariaDbDatabase<D>) -> Self::Prerequisites {
  636. MariaDbUser(resource.0.clone())
  637. }
  638. type Symbol = (
  639. MariaDbDatabaseSymbol<'static, String, SimpleStorage, StdCommandRunner>,
  640. MariaDbDumpSymbol<'static, String, StdCommandRunner, SimpleStorage>,
  641. );
  642. fn create(
  643. _resource: &MariaDbDatabase<D>,
  644. (db_name, _, data_path): &<MariaDbDatabase<D> as Resource>::Artifact,
  645. _: <Self::Prerequisites as ToArtifact>::Artifact,
  646. ) -> Self::Symbol {
  647. let db_dump = SimpleStorage::new(data_path.0.clone());
  648. (
  649. MariaDbDatabaseSymbol::new(db_name.0.clone(), db_dump.clone(), &StdCommandRunner),
  650. MariaDbDumpSymbol::new(db_name.0.clone(), db_dump, &StdCommandRunner),
  651. )
  652. }
  653. }
  654. impl<P: Clone + AsRef<Path>> SymbolBuilder<WordpressPlugin<P>> for DefaultBuilder {
  655. type Prerequisites = Dir<PathBuf>;
  656. fn prerequisites(resource: &WordpressPlugin<P>) -> Self::Prerequisites {
  657. Dir(resource.0.as_ref().join("wp-content/plugins"))
  658. }
  659. type Symbol = WordpressPluginSymbol<'static, P, &'static str, StdCommandRunner>;
  660. fn create(
  661. resource: &WordpressPlugin<P>,
  662. (): &<WordpressPlugin<P> as Resource>::Artifact,
  663. _: <Self::Prerequisites as ToArtifact>::Artifact,
  664. ) -> Self::Symbol {
  665. WordpressPluginSymbol::new(resource.0.clone(), resource.1, &StdCommandRunner)
  666. }
  667. }
  668. impl<P: Clone + AsRef<Path>> SymbolBuilder<WordpressTranslation<P>> for DefaultBuilder {
  669. type Prerequisites = Dir<PathBuf>;
  670. fn prerequisites(resource: &WordpressTranslation<P>) -> Self::Prerequisites {
  671. Dir(resource.0.as_ref().join("wp-content/languages"))
  672. }
  673. type Symbol = WordpressTranslationSymbol<'static, &'static str, PathBuf, StdCommandRunner>;
  674. fn create(
  675. resource: &WordpressTranslation<P>,
  676. (): &<WordpressTranslation<P> as Resource>::Artifact,
  677. _: <Self::Prerequisites as ToArtifact>::Artifact,
  678. ) -> Self::Symbol {
  679. WordpressTranslationSymbol::new(
  680. resource.0.as_ref().join("wp-content/languages"),
  681. resource.1,
  682. resource.2,
  683. &StdCommandRunner,
  684. )
  685. }
  686. }
  687. impl<D: Clone> SymbolBuilder<Cron<D>> for DefaultBuilder {
  688. type Prerequisites = UserForDomain<D>;
  689. fn prerequisites(resource: &Cron<D>) -> Self::Prerequisites {
  690. UserForDomain(resource.0.clone())
  691. }
  692. type Symbol = CronSymbol<'static, String, String, StdCommandRunner>;
  693. fn create(
  694. resource: &Cron<D>,
  695. (): &<Cron<D> as Resource>::Artifact,
  696. user_name: <Self::Prerequisites as ToArtifact>::Artifact,
  697. ) -> Self::Symbol {
  698. CronSymbol::new((user_name.0).0, resource.1.clone(), &StdCommandRunner)
  699. }
  700. }