-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathrun_create_command.rs
More file actions
185 lines (169 loc) · 6.26 KB
/
run_create_command.rs
File metadata and controls
185 lines (169 loc) · 6.26 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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
//! Environment creation task for E2E testing
//!
//! This module provides the E2E testing task for creating deployment environments
//! using the `CreateCommandHandler`. It orchestrates environment creation with proper
//! validation and repository persistence.
//!
//! ## Key Operations
//!
//! - Creates environments using the `CreateCommandHandler`
//! - Handles environment creation workflow for E2E tests
//! - Provides structured error handling and reporting
//!
//! ## Integration
//!
//! This is a generic task that works with the command handler pattern:
//! - Uses the `FileRepositoryFactory` to create repositories
//! - Creates `EnvironmentCreationConfig` from test parameters
//! - Integrates with the existing `CreateCommandHandler` workflow
use std::sync::Arc;
use thiserror::Error;
use tracing::info;
use crate::application::command_handlers::create::config::tracker::TrackerSection;
use crate::application::command_handlers::create::config::{
EnvironmentCreationConfig, EnvironmentSection, LxdProviderSection, ProviderSection,
SshCredentialsConfig,
};
use crate::application::command_handlers::create::{
CreateCommandHandler, CreateCommandHandlerError,
};
use crate::domain::environment::Created;
use crate::domain::Environment;
use crate::infrastructure::persistence::file_repository_factory::FileRepositoryFactory;
use crate::shared::Clock;
/// Create a new environment using the `CreateCommandHandler`
///
/// This function executes environment creation using the `CreateCommandHandler` for E2E tests.
/// It builds the configuration from parameters and creates the environment,
/// ensuring proper validation and persistence.
///
/// # Arguments
///
/// * `file_repository_factory` - Repository factory for creating environment repositories
/// * `clock` - Clock service for timestamp generation
/// * `working_dir` - Working directory for environment storage
/// * `environment_name` - Name of the environment to create
/// * `ssh_private_key_path` - Path to SSH private key file
/// * `ssh_public_key_path` - Path to SSH public key file
/// * `ssh_username` - SSH username for the environment
/// * `ssh_port` - SSH port number
///
/// # Returns
///
/// Returns the created `Environment<Created>` on success.
///
/// # Errors
///
/// Returns an error if:
/// - Configuration is invalid
/// - Environment already exists
/// - Repository operations fail
#[allow(clippy::too_many_arguments)]
pub fn run_create_command(
file_repository_factory: &FileRepositoryFactory,
clock: Arc<dyn Clock>,
working_dir: &std::path::Path,
environment_name: &str,
ssh_private_key_path: String,
ssh_public_key_path: String,
ssh_username: &str,
ssh_port: u16,
) -> Result<Environment<Created>, CreateTaskError> {
info!(
environment_name = environment_name,
"Creating environment via CreateCommandHandler"
);
// Create repository using FileRepositoryFactory with data directory
let data_dir = working_dir.join("data");
let repository = file_repository_factory.create(data_dir);
// Create the command handler
let create_command = CreateCommandHandler::new(repository, clock);
// Build the configuration with LXD provider
let config = EnvironmentCreationConfig::new(
EnvironmentSection {
name: environment_name.to_string(),
description: None,
instance_name: None, // Auto-generate from environment name
},
SshCredentialsConfig::new(
ssh_private_key_path,
ssh_public_key_path,
ssh_username.to_string(),
ssh_port,
),
ProviderSection::Lxd(LxdProviderSection {
profile_name: format!("lxd-{environment_name}"),
}),
TrackerSection::default(),
None,
None,
None, // HTTPS configuration
None, // Backup configuration
);
// Execute the command
let environment = create_command
.execute(config, working_dir)
.map_err(|source| CreateTaskError::CreationFailed { source })?;
info!(
environment_name = environment.name().as_str(),
instance_name = environment.instance_name().as_str(),
"Environment created successfully via CreateCommandHandler"
);
Ok(environment)
}
/// Errors that can occur during the create task
#[derive(Debug, Error)]
pub enum CreateTaskError {
/// Environment creation command execution failed
#[error(
"Failed to create environment: {source}
Tip: Check that the environment name is valid and doesn't already exist"
)]
CreationFailed {
#[source]
source: CreateCommandHandlerError,
},
}
impl CreateTaskError {
/// Get detailed troubleshooting guidance for this error
///
/// This method provides comprehensive troubleshooting steps that can be
/// displayed to users when they need more help resolving the error.
///
/// # Example
///
/// ```rust
/// # use torrust_tracker_deployer_lib::testing::e2e::tasks::run_create_command::CreateTaskError;
/// # use torrust_tracker_deployer_lib::application::command_handlers::create::CreateCommandHandlerError;
/// let error = CreateTaskError::CreationFailed {
/// source: CreateCommandHandlerError::EnvironmentAlreadyExists {
/// name: "test-env".to_string(),
/// },
/// };
/// println!("{}", error.help());
/// ```
#[must_use]
pub fn help(&self) -> &'static str {
match self {
Self::CreationFailed { .. } => {
"Environment Creation Failed - Detailed Troubleshooting:
1. Check environment name:
- Must be lowercase letters and numbers only
- Use dashes as word separators
- Cannot start or end with separators
- Cannot start with numbers
2. Verify environment doesn't already exist:
- Check the data directory for existing environment
- Use 'destroy' command to remove existing environment if needed
3. Check SSH key files:
- Verify SSH private key file exists and is readable
- Verify SSH public key file exists and is readable
- Ensure key file permissions are correct (600 for private key)
4. Check repository access:
- Ensure data directory is writable
- Verify no file locks are preventing write access
For more information, see the E2E testing documentation."
}
}
}
}