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.

107 lines
3.7 KiB

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