-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathcontainer.rs
More file actions
120 lines (101 loc) · 4.57 KB
/
container.rs
File metadata and controls
120 lines (101 loc) · 4.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//! Dependency injection container for deployment services
//!
//! This module provides the `Services` struct that acts as a dependency injection container,
//! holding all the service clients and template renderers needed for deployment operations.
//! It centralizes service construction and makes them easily accessible throughout the application.
//!
//! ## Services Included
//!
//! - **Command clients**: `OpenTofu`, LXD, Ansible clients for external tool interaction
//! - **Template services**: Template manager and specialized renderers for different tools
//! - **Configuration**: Centralized configuration management
use std::sync::Arc;
use std::time::Duration;
use crate::adapters::ansible::AnsibleClient;
use crate::adapters::lxd::LxdClient;
use crate::adapters::ssh::SshCredentials;
use crate::adapters::tofu::OpenTofuClient;
use crate::config::Config;
use crate::domain::template::TemplateManager;
use crate::domain::{InstanceName, ProfileName};
use crate::infrastructure::external_tools::ansible::AnsibleTemplateRenderer;
use crate::infrastructure::external_tools::ansible::ANSIBLE_SUBFOLDER;
use crate::infrastructure::external_tools::tofu::TofuTemplateRenderer;
use crate::infrastructure::external_tools::tofu::OPENTOFU_SUBFOLDER;
use crate::infrastructure::persistence::repository_factory::RepositoryFactory;
use crate::shared::Clock;
/// Default lock timeout for repository operations
///
/// This timeout controls how long repository operations will wait to acquire
/// file locks before giving up. This prevents operations from hanging indefinitely
/// if another process has locked the state file.
///
/// TODO: Make this configurable via Config in the future
const REPOSITORY_LOCK_TIMEOUT_SECS: u64 = 30;
/// Service clients and renderers for performing actions
pub struct Services {
// Command wrappers
pub opentofu_client: Arc<OpenTofuClient>,
pub lxd_client: Arc<LxdClient>,
pub ansible_client: Arc<AnsibleClient>,
// Template related services
pub template_manager: Arc<TemplateManager>,
pub tofu_template_renderer: Arc<TofuTemplateRenderer>,
pub ansible_template_renderer: Arc<AnsibleTemplateRenderer>,
// Infrastructure services
/// Clock service for testable time management
pub clock: Arc<dyn Clock>,
// Persistence layer
/// Factory for creating environment-specific repositories
pub repository_factory: RepositoryFactory,
}
impl Services {
/// Create a new services container using the provided configuration
#[must_use]
pub fn new(
config: &Config,
ssh_credentials: SshCredentials,
instance_name: InstanceName,
profile_name: ProfileName,
) -> Self {
// Create template manager
let template_manager = TemplateManager::new(config.templates_dir.clone());
let template_manager = Arc::new(template_manager);
// Create OpenTofu client pointing to build/opentofu_subfolder directory
let opentofu_client = OpenTofuClient::new(config.build_dir.join(OPENTOFU_SUBFOLDER));
// Create LXD client for instance management
let lxd_client = LxdClient::new();
// Create Ansible client pointing to build/ansible_subfolder directory
let ansible_client = AnsibleClient::new(config.build_dir.join(ANSIBLE_SUBFOLDER));
// Create provision template renderer
let tofu_template_renderer = TofuTemplateRenderer::new(
template_manager.clone(),
config.build_dir.clone(),
ssh_credentials,
instance_name,
profile_name,
);
// Create configuration template renderer
let ansible_template_renderer =
AnsibleTemplateRenderer::new(config.build_dir.clone(), template_manager.clone());
// Create repository factory
let repository_factory =
RepositoryFactory::new(Duration::from_secs(REPOSITORY_LOCK_TIMEOUT_SECS));
// Create clock service (production implementation uses system time)
let clock: Arc<dyn Clock> = Arc::new(crate::shared::SystemClock);
Self {
// Command wrappers
opentofu_client: Arc::new(opentofu_client),
lxd_client: Arc::new(lxd_client),
ansible_client: Arc::new(ansible_client),
// Template related services
template_manager: template_manager.clone(),
tofu_template_renderer: Arc::new(tofu_template_renderer),
ansible_template_renderer: Arc::new(ansible_template_renderer),
// Infrastructure services
clock,
// Persistence layer
repository_factory,
}
}
}