-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathapply.rs
More file actions
128 lines (105 loc) · 3.65 KB
/
apply.rs
File metadata and controls
128 lines (105 loc) · 3.65 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
//! `OpenTofu` infrastructure application step
//!
//! This module provides the `ApplyInfrastructureStep` which handles `OpenTofu`
//! application by executing `tofu apply`. This step applies the planned
//! infrastructure changes to provision or modify resources.
//!
//! ## Key Features
//!
//! - Infrastructure provisioning and resource creation
//! - Configurable auto-approval for automation scenarios
//! - Progress tracking and status reporting
//! - Integration with `OpenTofuClient` for command execution
//!
//! ## Application Process
//!
//! The step executes `tofu apply` which:
//! - Applies planned changes to create/modify/destroy resources
//! - Manages resource dependencies and ordering
//! - Updates infrastructure state with actual resource information
//! - Provides detailed progress and completion status
//!
//! This step is where actual infrastructure provisioning occurs.
use std::sync::Arc;
use tracing::{info, instrument};
use crate::adapters::tofu::client::OpenTofuClient;
use crate::shared::command::CommandError;
/// Simple step that applies `OpenTofu` configuration by executing `tofu apply`
pub struct ApplyInfrastructureStep {
opentofu_client: Arc<OpenTofuClient>,
auto_approve: bool,
}
impl ApplyInfrastructureStep {
#[must_use]
pub fn new(opentofu_client: Arc<OpenTofuClient>) -> Self {
Self {
opentofu_client,
auto_approve: true, // Default to auto-approve for automation
}
}
#[must_use]
pub fn with_auto_approve(mut self, auto_approve: bool) -> Self {
self.auto_approve = auto_approve;
self
}
/// Execute the `OpenTofu` apply step
///
/// # Errors
///
/// Returns an error if:
/// * The `OpenTofu` apply fails
/// * The working directory does not exist or is not accessible
/// * The `OpenTofu` command execution fails
#[instrument(
name = "apply_infrastructure",
skip_all,
fields(
step_type = "infrastructure",
operation = "apply",
auto_approve = %self.auto_approve
)
)]
pub fn execute(&self) -> Result<(), CommandError> {
info!(
step = "apply_infrastructure",
auto_approve = self.auto_approve,
"Applying OpenTofu infrastructure"
);
// Execute tofu apply command with variables file
let output = self
.opentofu_client
.apply(self.auto_approve, &["-var-file=variables.tfvars"])?;
info!(
step = "apply_infrastructure",
status = "success",
"OpenTofu infrastructure applied successfully"
);
// Log output for debugging if needed
tracing::debug!(output = %output, "OpenTofu apply output");
Ok(())
}
}
#[cfg(test)]
mod tests {
use std::sync::Arc;
use crate::adapters::tofu::client::OpenTofuClient;
use super::*;
#[test]
fn it_should_create_apply_infrastructure_step() {
let opentofu_client = Arc::new(OpenTofuClient::new("/tmp"));
let _step = ApplyInfrastructureStep::new(opentofu_client);
// If we reach this point, the step was created successfully
}
#[test]
fn it_should_create_step_with_custom_auto_approve() {
let opentofu_client = Arc::new(OpenTofuClient::new("/tmp"));
let step = ApplyInfrastructureStep::new(opentofu_client).with_auto_approve(false);
assert!(!step.auto_approve);
}
#[test]
fn it_should_default_to_auto_approve() {
let opentofu_client = Arc::new(OpenTofuClient::new("/tmp"));
let step = ApplyInfrastructureStep::new(opentofu_client);
assert!(step.auto_approve);
}
}