-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathplan.rs
More file actions
93 lines (77 loc) · 2.69 KB
/
plan.rs
File metadata and controls
93 lines (77 loc) · 2.69 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
//! `OpenTofu` infrastructure planning step
//!
//! This module provides the `PlanInfrastructureStep` which handles `OpenTofu`
//! planning by executing `tofu plan`. This step creates an execution plan
//! showing what changes will be made to the infrastructure.
//!
//! ## Key Features
//!
//! - Infrastructure change planning and preview
//! - Resource dependency analysis and ordering
//! - Plan validation and error detection
//! - Integration with `OpenTofuClient` for command execution
//!
//! ## Planning Process
//!
//! The step executes `tofu plan` which:
//! - Analyzes current state vs desired configuration
//! - Determines what resources need to be created, modified, or destroyed
//! - Validates configuration and dependencies
//! - Provides a preview of changes before application
//!
//! This step is crucial for validating infrastructure changes before applying them.
use std::sync::Arc;
use tracing::{info, instrument};
use crate::adapters::tofu::client::OpenTofuClient;
use crate::shared::command::CommandError;
/// Simple step that plans `OpenTofu` configuration by executing `tofu plan`
pub struct PlanInfrastructureStep {
opentofu_client: Arc<OpenTofuClient>,
}
impl PlanInfrastructureStep {
#[must_use]
pub fn new(opentofu_client: Arc<OpenTofuClient>) -> Self {
Self { opentofu_client }
}
/// Execute the `OpenTofu` plan step
///
/// # Errors
///
/// Returns an error if:
/// * The `OpenTofu` plan fails
/// * The working directory does not exist or is not accessible
/// * The `OpenTofu` command execution fails
#[instrument(
name = "plan_infrastructure",
skip_all,
fields(step_type = "infrastructure", operation = "plan")
)]
pub fn execute(&self) -> Result<(), CommandError> {
info!(
step = "plan_infrastructure",
"Planning OpenTofu infrastructure"
);
// Execute tofu plan command with variables file
let output = self.opentofu_client.plan(&["-var-file=variables.tfvars"])?;
info!(
step = "plan_infrastructure",
status = "success",
"OpenTofu infrastructure planned successfully"
);
// Log output for debugging if needed
tracing::debug!(output = %output, "OpenTofu plan output");
Ok(())
}
}
#[cfg(test)]
mod tests {
use std::sync::Arc;
use crate::adapters::tofu::client::OpenTofuClient;
use super::*;
#[test]
fn it_should_create_plan_infrastructure_step() {
let opentofu_client = Arc::new(OpenTofuClient::new("/tmp"));
let _step = PlanInfrastructureStep::new(opentofu_client);
// If we reach this point, the step was created successfully
}
}