torrust_tracker_deployer_lib/application/steps/rendering/
caddy_templates.rs1use std::path::PathBuf;
28use std::sync::Arc;
29
30use tracing::{info, instrument};
31
32use crate::application::services::rendering::CaddyTemplateRenderingService;
33use crate::application::services::rendering::CaddyTemplateRenderingServiceError;
34use crate::domain::environment::Environment;
35use crate::shared::clock::Clock;
36
37pub struct RenderCaddyTemplatesStep<S> {
47 environment: Arc<Environment<S>>,
48 templates_dir: PathBuf,
49 build_dir: PathBuf,
50 clock: Arc<dyn Clock>,
51}
52
53impl<S> RenderCaddyTemplatesStep<S> {
54 #[must_use]
63 pub fn new(
64 environment: Arc<Environment<S>>,
65 templates_dir: PathBuf,
66 build_dir: PathBuf,
67 clock: Arc<dyn Clock>,
68 ) -> Self {
69 Self {
70 environment,
71 templates_dir,
72 build_dir,
73 clock,
74 }
75 }
76
77 #[instrument(
95 name = "render_caddy_templates",
96 skip_all,
97 fields(
98 step_type = "rendering",
99 template_type = "caddy",
100 build_dir = %self.build_dir.display()
101 )
102 )]
103 pub fn execute(&self) -> Result<Option<PathBuf>, CaddyTemplateRenderingServiceError> {
104 if self.environment.context().user_inputs.https().is_none() {
106 info!(
107 step = "render_caddy_templates",
108 status = "skipped",
109 reason = "https_not_configured",
110 "Skipping Caddy template rendering - HTTPS not configured"
111 );
112 return Ok(None);
113 }
114
115 info!(
116 step = "render_caddy_templates",
117 templates_dir = %self.templates_dir.display(),
118 build_dir = %self.build_dir.display(),
119 "Rendering Caddy configuration templates"
120 );
121
122 let service = CaddyTemplateRenderingService::from_paths(
123 self.templates_dir.clone(),
124 self.build_dir.clone(),
125 self.clock.clone(),
126 );
127
128 let user_inputs = &self.environment.context().user_inputs;
129 let Some(caddy_build_dir) = service.render(user_inputs)? else {
130 info!(
131 step = "render_caddy_templates",
132 status = "skipped",
133 reason = "no_tls_services",
134 "Skipping Caddy template rendering - no services have TLS configured"
135 );
136 return Ok(None);
137 };
138
139 info!(
140 step = "render_caddy_templates",
141 caddy_build_dir = %caddy_build_dir.display(),
142 status = "success",
143 "Caddy templates rendered successfully"
144 );
145
146 Ok(Some(caddy_build_dir))
147 }
148}
149
150#[cfg(test)]
151mod tests {
152 use tempfile::TempDir;
153
154 use super::*;
155 use crate::domain::environment::testing::EnvironmentTestBuilder;
156 use crate::shared::clock::SystemClock;
157
158 #[test]
159 fn it_should_create_render_caddy_templates_step() {
160 let templates_dir = TempDir::new().expect("Failed to create templates dir");
161 let build_dir = TempDir::new().expect("Failed to create build dir");
162
163 let (environment, _, _, _temp_dir) =
164 EnvironmentTestBuilder::new().build_with_custom_paths();
165 let environment = Arc::new(environment);
166
167 let clock = Arc::new(SystemClock);
168 let step = RenderCaddyTemplatesStep::new(
169 environment.clone(),
170 templates_dir.path().to_path_buf(),
171 build_dir.path().to_path_buf(),
172 clock,
173 );
174
175 assert_eq!(step.build_dir, build_dir.path());
176 assert_eq!(step.templates_dir, templates_dir.path());
177 }
178
179 #[test]
180 fn it_should_skip_rendering_when_https_not_configured() {
181 let templates_dir = TempDir::new().expect("Failed to create templates dir");
182 let build_dir = TempDir::new().expect("Failed to create build dir");
183
184 let (environment, _, _, _temp_dir) =
186 EnvironmentTestBuilder::new().build_with_custom_paths();
187 let environment = Arc::new(environment);
188
189 let clock = Arc::new(SystemClock);
190 let step = RenderCaddyTemplatesStep::new(
191 environment,
192 templates_dir.path().to_path_buf(),
193 build_dir.path().to_path_buf(),
194 clock,
195 );
196
197 let result = step.execute();
198 assert!(result.is_ok(), "Should succeed when HTTPS not configured");
199 assert!(
200 result.unwrap().is_none(),
201 "Should return None when HTTPS not configured"
202 );
203 }
204}