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.

117 lines
4.4 KiB

6 years ago
7 years ago
6 years ago
7 years ago
7 years ago
6 years ago
7 years ago
6 years ago
7 years ago
7 years ago
6 years ago
6 years ago
7 years ago
  1. use std::ops::Deref;
  2. use std::path::Path;
  3. use command_runner::{CommandRunner, SetuidCommandRunner};
  4. use storage::SimpleStorage;
  5. use symbols::{Action, Symbol, SymbolRunner};
  6. use symbols::acme::{AcmeCert, AcmeCertChain};
  7. use symbols::file::File;
  8. use symbols::git::checkout::GitCheckout;
  9. use symbols::hook::Hook;
  10. use symbols::list::ListAction;
  11. use symbols::nginx::server::NginxServer;
  12. use symbols::owner::Owner;
  13. use symbols::stored_directory::{StoredDirectory, StorageDirection};
  14. use symbols::systemd::reload::ReloadService;
  15. use symbols::tls::SelfSignedTlsCert;
  16. pub struct SymbolFactory<'a, C: 'a + CommandRunner, R: 'a + SymbolRunner>{
  17. command_runner: &'a C,
  18. acme_command_runner: SetuidCommandRunner<'a, C>,
  19. symbol_runner: &'a R
  20. }
  21. impl<'b, C: 'b + CommandRunner, R: 'b + SymbolRunner> SymbolFactory<'b, C, R> {
  22. pub fn new(command_runner: &'b C, symbol_runner: &'b R) -> Self {
  23. let acme_user = "acme"; // FIXME: CONFIG
  24. let acme_command_runner = SetuidCommandRunner::new(acme_user, command_runner);
  25. SymbolFactory { command_runner: command_runner, acme_command_runner: acme_command_runner, symbol_runner: symbol_runner }
  26. }
  27. pub fn get_nginx_acme_server<'a, 'c: 'a, S: 'a + Symbol>(&'c self, host: &'static str, nginx_server_symbol: S) -> Box<Action + 'a> {
  28. Box::new(ListAction::new(vec![
  29. Box::new(SelfSignedTlsCert::new(
  30. host.into(),
  31. self.command_runner
  32. )).into_action(self.symbol_runner),
  33. Box::new(Hook::new(
  34. nginx_server_symbol,
  35. ReloadService::new("nginx", self.command_runner)
  36. )).into_action(self.symbol_runner),
  37. Box::new(AcmeCert::new(
  38. host.into(),
  39. &self.acme_command_runner
  40. )).into_action(self.symbol_runner),
  41. Box::new(Hook::new(
  42. AcmeCertChain::new(
  43. host.into(),
  44. &self.acme_command_runner
  45. ),
  46. ReloadService::new("nginx", self.command_runner)
  47. )).into_action(self.symbol_runner)
  48. ]))
  49. }
  50. pub fn get_nginx_acme_challenge_config<'a>(&'a self) -> Box<Action + 'a> {
  51. Box::new(File::new(
  52. "/etc/nginx/snippets/acme-challenge.conf", "location ^~ /.well-known/acme-challenge/ {
  53. alias /home/acme/challenges/;
  54. try_files $uri =404;
  55. }"
  56. )).into_action(self.symbol_runner)
  57. }
  58. pub fn get_php_fpm_pool_socket_path<'a>(&'a self, user_name: &'static str) -> String {
  59. format!("/run/php/{}.sock", user_name)
  60. }
  61. pub fn get_php_fpm_pool<'a>(&'a self, user_name: &'static str) -> Box<Action + 'a> {
  62. let socket = self.get_php_fpm_pool_socket_path(user_name);
  63. Box::new(Hook::new(
  64. File::new(
  65. format!("/etc/php/7.0/fpm/pool.d/{}.conf", user_name),
  66. format!(
  67. "[{0}]
  68. user = {0}
  69. group = www-data
  70. listen = {1}
  71. listen.owner = www-data
  72. pm = ondemand
  73. pm.max_children = 10"
  74. , user_name, socket)),
  75. ReloadService::new("php7.0-fpm", self.command_runner)
  76. )).into_action(self.symbol_runner)
  77. }
  78. pub fn get_nginx_php_server<'a>(&'a self, host_name: &'static str, user_name: &'static str, root_dir: &'static str) -> NginxServer<'a, C, String> {
  79. let socket = self.get_php_fpm_pool_socket_path(user_name);
  80. NginxServer::new_php(
  81. host_name,
  82. socket.into(),
  83. root_dir,
  84. self.command_runner
  85. )
  86. }
  87. pub fn get_stored_directory<'a, T: Into<String>>(&'a self, storage_name: &'static str, target: T) -> (Box<Action + 'a>, Box<Action + 'a>) {
  88. let data = SimpleStorage::new("/root/data".to_string(), storage_name.to_string());
  89. let string_target = target.into();
  90. (
  91. Box::new(StoredDirectory::new(string_target.clone().into(), data.clone(), StorageDirection::Save, self.command_runner)).into_action(self.symbol_runner),
  92. Box::new(StoredDirectory::new(string_target.into(), data.clone(), StorageDirection::Load, self.command_runner)).into_action(self.symbol_runner)
  93. )
  94. }
  95. pub fn get_git_checkout<'a, T: 'a + AsRef<str>>(&'a self, target: T, source: &'a str, branch: &'a str) -> Box<Action + 'a> {
  96. Box::new(GitCheckout::new(target, source, branch, self.command_runner)).into_action(self.symbol_runner)
  97. }
  98. pub fn get_owner<'a, F: 'a + AsRef<str>>(&'a self, file: F, user: &'a str) -> Box<Action + 'a> {
  99. Box::new(Owner::new(file, user.into(), self.command_runner)).into_action(self.symbol_runner)
  100. }
  101. pub fn get_file<'a, F: 'a + Deref<Target=str>, P: 'a + AsRef<Path>>(&'a self, path: P, content: F) -> Box<Action + 'a> {
  102. Box::new(File::new(path, content)).into_action(self.symbol_runner)
  103. }
  104. }