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.

106 lines
3.7 KiB

  1. use regex::Regex;
  2. use command_runner::CommandRunner;
  3. use loggers::StdErrLogger;
  4. use repository::SymbolRepository;
  5. use resources::Resource;
  6. use schema::{NonRepeatingSymbolRunner, ReportingSymbolRunner, RequirementsResolvingSymbolRunner};
  7. use symbols::{Symbol, SymbolRunner};
  8. use symbols::dir::Dir;
  9. use symbols::list::List;
  10. use symbols::owner::Owner;
  11. use symbols::systemd::user_session::SystemdUserSession;
  12. use symbols::tls::{TlsCsr, TlsKey};
  13. use symbols::user::{User, UserAdder};
  14. use symbols::user::SystemUserAdder;
  15. pub struct Factory {
  16. }
  17. impl Factory {
  18. pub fn new() -> Self {
  19. Self {}
  20. }
  21. pub fn get_repo<'a, CR: CommandRunner>(&self, command_runner: &'a CR) -> DefaultSymbolRepository<'a, SystemUserAdder<'a, CR>, CR> {
  22. DefaultSymbolRepository::new(command_runner)
  23. }
  24. pub fn get_symbol_runner<'a, RUNNER: SymbolRunner, REPO: SymbolRepository<'a>>(&self, symbol_runner: &'a RUNNER, repo: &'a REPO) -> Box<'a + SymbolRunner> {
  25. let runner1 = ReportingSymbolRunner::new(symbol_runner, StdErrLogger);
  26. let runner2 = NonRepeatingSymbolRunner::new(runner1);
  27. Box::new(RequirementsResolvingSymbolRunner::new(runner2, repo))
  28. }
  29. }
  30. pub struct DefaultSymbolRepository<'a, A: 'a + UserAdder, C: 'a + CommandRunner> {
  31. user_adder: A,
  32. command_runner: &'a C,
  33. home: Regex,
  34. home_config: Regex,
  35. csr: Regex,
  36. private_key: Regex,
  37. systemd_linger: Regex
  38. }
  39. impl<'a, C: 'a + CommandRunner> DefaultSymbolRepository<'a, SystemUserAdder<'a, C>, C> {
  40. pub fn new(command_runner: &'a C) -> Self {
  41. Self {
  42. command_runner: command_runner,
  43. user_adder: SystemUserAdder::new(command_runner),
  44. home: Regex::new("^/home/([^/]+)$").unwrap(),
  45. home_config: Regex::new("^/home/([^/]+)/.config(?:/|$)").unwrap(),
  46. csr: Regex::new("^/etc/ssl/local_certs/([^/]+).csr$").unwrap(),
  47. private_key: Regex::new("^/etc/ssl/private/([^/]+).key$").unwrap(),
  48. systemd_linger: Regex::new("^/var/lib/systemd/linger/([^/]+)$").unwrap()
  49. }
  50. }
  51. }
  52. impl<'a, C: CommandRunner> SymbolRepository<'a> for DefaultSymbolRepository<'a, SystemUserAdder<'a, C>, C> {
  53. fn get_symbol(&'a self, resource: &Resource) -> Option<Box<Symbol + 'a>> {
  54. match resource.get_type() {
  55. "user" => Some(Box::new(User::new(
  56. resource.get_value().to_string().into(),
  57. self.command_runner,
  58. &self.user_adder
  59. ))),
  60. "dir" => {
  61. let value = resource.get_value();
  62. Some(
  63. if let Some(matches) = self.home_config.captures(value) {
  64. Box::new(List::new(vec![
  65. Box::new(Dir::new(value.to_string())),
  66. Box::new(Owner::new(value.to_string(), matches[1].to_string().into(), self.command_runner))
  67. ])) as Box<Symbol>
  68. } else if let Some(matches) = self.home.captures(value) {
  69. Box::new(
  70. User::new(matches[1].to_string().into(), self.command_runner, &self.user_adder)
  71. ) as Box<Symbol>
  72. } else { Box::new(Dir::new(value.to_string())) as Box<Symbol> }
  73. )
  74. },
  75. "file" => {
  76. let value = resource.get_value();
  77. if let Some(matches) = self.csr.captures(value) {
  78. Some(Box::new(TlsCsr::new(
  79. matches[1].to_string().into(),
  80. self.command_runner
  81. )) as Box<Symbol>)
  82. } else if let Some(matches) = self.private_key.captures(value) {
  83. Some(Box::new(TlsKey::new(
  84. matches[1].to_string().into(),
  85. self.command_runner
  86. )) as Box<Symbol>)
  87. } else if let Some(matches) = self.systemd_linger.captures(value) {
  88. Some(Box::new(SystemdUserSession::new(
  89. matches[1].to_string().into(),
  90. self.command_runner
  91. )) as Box<Symbol>)
  92. } else { None }
  93. },
  94. _ => None
  95. }
  96. }
  97. }