Skip to main content

pulumi_automation/
stack.rs

1use std::collections::HashMap;
2
3use serde::{Deserialize, Serialize};
4use strum::Display;
5use tokio::sync::mpsc::Sender;
6
7use crate::event::EngineEvent;
8
9#[derive(Debug, Default, Clone, Deserialize, Serialize)]
10#[serde(rename_all = "camelCase")]
11pub struct ResourceState {
12    pub inputs: Option<serde_json::Value>,
13    pub outputs: Option<serde_json::Value>,
14    pub urn: String,
15    #[serde(rename = "type")]
16    pub resource_type: ResourceType,
17    pub id: Option<String>,
18    pub provider: Option<String>,
19    pub parent: Option<String>,
20    pub source_position: Option<String>,
21    pub modified: Option<String>,
22    pub custom: Option<bool>,
23    pub external: Option<bool>,
24    pub created: Option<String>,
25    pub dependencies: Option<Vec<String>>,
26    pub additional_secret_outputs: Option<Vec<String>>,
27    pub property_dependencies: Option<HashMap<String, Vec<String>>>,
28
29    #[serde(flatten)]
30    pub extra_values: Option<serde_json::Value>,
31}
32
33impl ResourceState {
34    pub fn name(&self) -> String {
35        self.urn
36            .split("::")
37            .last()
38            .map(|s| s.to_string())
39            .unwrap_or_else(|| self.urn.clone())
40    }
41}
42
43#[derive(Default, Display, Debug, Clone, Deserialize, Serialize, Eq, PartialEq, Hash)]
44pub enum ResourceType {
45    #[default]
46    Unknown,
47    #[serde(rename = "pulumi:pulumi:Stack")]
48    #[strum(serialize = "pulumi:pulumi:Stack")]
49    Stack,
50    #[serde(untagged)]
51    #[strum(serialize = "{0}")]
52    Other(String),
53}
54
55#[derive(Default, strum::Display, Debug, Clone, Deserialize, Serialize, Eq, PartialEq, Hash)]
56#[serde(rename_all = "kebab-case")]
57pub enum Operation {
58    #[default]
59    Unknown,
60    Same,
61    Read,
62    Create,
63    Update,
64    Delete,
65    Replace,
66    Refresh,
67    Import,
68    CreateReplacement,
69    DeleteReplaced,
70    ReadReplacement,
71    Discard,
72    DiscardReplaced,
73    RemovePendingReplace,
74    ImportReplacement,
75}
76
77#[derive(Default, Debug, Clone, Deserialize, Serialize)]
78#[serde(rename_all = "camelCase")]
79pub struct StackChangeStep {
80    pub op: Operation,
81    pub urn: String,
82    pub provider: Option<String>,
83    pub new_state: Option<ResourceState>,
84    pub old_state: Option<ResourceState>,
85    #[serde(flatten)]
86    pub extra_values: Option<serde_json::Value>,
87}
88
89#[derive(Default, Debug, Clone, Deserialize, Serialize)]
90#[serde(rename_all = "camelCase")]
91pub struct StackChangeSummary {
92    pub steps: Vec<StackChangeStep>,
93    pub change_summary: Option<HashMap<Operation, usize>>,
94    pub duration: i64,
95    #[serde(flatten)]
96    pub extra_values: Option<serde_json::Value>,
97}
98
99#[derive(Debug, Clone)]
100pub struct PulumiProcessListener {
101    pub preview_tx: Option<Sender<StackChangeSummary>>,
102    pub event_tx: Sender<EngineEvent>,
103}
104
105#[derive(Debug, Clone, Default)]
106pub struct StackRefreshOptions {
107    pub skip_preview: Option<bool>,
108    pub target: Option<Vec<String>>,
109    pub target_dependents: Option<bool>,
110    pub exclude: Option<Vec<String>>,
111    pub exclude_dependents: Option<bool>,
112    pub show_secrets: Option<bool>,
113    pub continue_on_error: Option<bool>,
114}
115
116#[derive(Debug, Clone, Default)]
117pub struct StackDestroyOptions {
118    pub skip_preview: Option<bool>,
119    pub refresh: Option<bool>,
120    pub target: Option<Vec<String>>,
121    pub target_dependents: Option<bool>,
122    pub exclude: Option<Vec<String>>,
123    pub exclude_dependents: Option<bool>,
124    pub show_secrets: Option<bool>,
125    pub continue_on_error: Option<bool>,
126    pub exclude_protected: Option<bool>,
127}
128
129#[derive(Debug, Clone, Default)]
130pub struct StackUpOptions {
131    pub skip_preview: Option<bool>,
132    pub preview: Option<bool>,
133    pub refresh: Option<bool>,
134    pub replace: Option<Vec<String>>,
135    pub diff: Option<bool>,
136    pub target: Option<Vec<String>>,
137    pub target_dependents: Option<bool>,
138    pub exclude: Option<Vec<String>>,
139    pub exclude_dependents: Option<bool>,
140    pub show_secrets: Option<bool>,
141    pub continue_on_error: Option<bool>,
142    pub expect_no_changes: Option<bool>,
143    pub show_reads: Option<bool>,
144    pub show_replacement_steps: Option<bool>,
145}
146
147#[derive(Debug, Clone, Default)]
148pub struct StackPreviewOptions {
149    pub refresh: Option<bool>,
150    pub replace: Option<Vec<String>>,
151    pub diff: Option<bool>,
152    pub target: Option<Vec<String>>,
153    pub target_dependents: Option<bool>,
154    pub exclude: Option<Vec<String>>,
155    pub exclude_dependents: Option<bool>,
156    pub show_secrets: Option<bool>,
157    pub continue_on_error: Option<bool>,
158    pub expect_no_changes: Option<bool>,
159    pub show_reads: Option<bool>,
160    pub show_replacement_steps: Option<bool>,
161}
162
163#[async_trait::async_trait]
164pub trait Stack: Sized {
165    fn preview(&self, options: StackPreviewOptions) -> super::Result<StackChangeSummary>;
166    async fn preview_async(
167        &self,
168        options: StackPreviewOptions,
169        listener: PulumiProcessListener,
170    ) -> super::Result<()>;
171    async fn up(
172        &self,
173        options: StackUpOptions,
174        listener: PulumiProcessListener,
175    ) -> super::Result<()>;
176    async fn refresh(
177        &self,
178        options: StackRefreshOptions,
179        listener: PulumiProcessListener,
180    ) -> super::Result<()>;
181    async fn destroy(
182        &self,
183        options: StackDestroyOptions,
184        listener: PulumiProcessListener,
185    ) -> super::Result<()>;
186}