1use crate::instance_spec::{Registry, TemplateUploader};
2
3#[derive(Clone, Debug, clap::Parser)]
4pub struct App {
5 #[clap(subcommand)]
6 command: Command,
7}
8
9impl App {
10 pub async fn run(&self, config: &Config<'_>) {
11 self.command.run(config).await
12 }
13}
14
15pub struct Config<'a> {
16 pub cloudformation: &'a aws_sdk_cloudformation::client::Client,
17 pub registry: &'a Registry,
18 pub template_uploader: Option<&'a TemplateUploader<'a>>,
19}
20
21#[derive(Clone, Debug, Eq, PartialEq, clap::Parser)]
22pub enum Command {
23 Instance(Box<crate::cli::instance::App>),
24}
25
26impl Command {
27 pub async fn run(&self, config: &Config<'_>) {
28 match self {
29 Self::Instance(command) => command.run(config).await,
30 }
31 }
32}
33
34mod instance {
35 use crate::instance_spec::ReviewChangeSet;
36 use crate::types::*;
37
38 #[derive(Clone, Debug, Eq, PartialEq, clap::Parser)]
39 pub struct App {
40 #[clap(subcommand)]
41 command: Command,
42 }
43
44 impl App {
45 pub async fn run(&self, config: &super::Config<'_>) {
46 self.command.run(config).await
47 }
48 }
49
50 #[derive(Clone, Debug, Eq, PartialEq, clap::Parser)]
51 pub enum ChangeSetCommand {
52 Create {
53 #[arg(long)]
54 change_set_name: ChangeSetName,
55 #[arg(long = "parameter")]
56 parameters: Vec<Parameter>,
57 },
58 Delete {
59 #[arg(long)]
60 change_set_name: ChangeSetName,
61 },
62 Describe {
63 #[arg(long)]
64 change_set_name: ChangeSetName,
65 },
66 List,
67 }
68
69 #[derive(Clone, Debug, Eq, PartialEq, clap::Parser)]
70 pub enum Command {
71 ChangeSet {
72 #[arg(long = "stack-name")]
73 name: StackName,
74 #[clap(subcommand)]
75 command: ChangeSetCommand,
76 },
77 Delete {
79 #[arg(long = "stack-name")]
80 name: StackName,
81 },
82 List,
84 Update {
86 #[arg(long = "stack-name")]
87 name: StackName,
88 #[arg(long = "parameter")]
89 parameters: Vec<Parameter>,
90 #[arg(long, default_value = "interactive")]
91 review_change_set: ReviewChangeSet,
92 },
93 Sync {
96 #[arg(long = "stack-name")]
97 name: StackName,
98 #[arg(long = "parameter")]
99 parameters: Vec<Parameter>,
100 #[arg(long, default_value = "interactive")]
101 review_change_set: ReviewChangeSet,
102 },
103 Watch {
105 #[arg(long = "stack-name")]
106 name: StackName,
107 },
108 }
109
110 impl Command {
111 pub async fn run(&self, config: &super::Config<'_>) {
112 let fetch_context = |name| {
113 config
114 .registry
115 .find(name)
116 .expect("registered instance spec")
117 .context(config.cloudformation, config.template_uploader)
118 };
119
120 match self {
121 Self::ChangeSet {
122 name,
123 command:
124 ChangeSetCommand::Create {
125 change_set_name,
126 parameters,
127 },
128 } => {
129 let parameter_map = ParameterMap::parse(parameters).unwrap();
130 fetch_context(name)
131 .create_change_set(change_set_name, ¶meter_map)
132 .await;
133 }
134 Self::ChangeSet {
135 name,
136 command: ChangeSetCommand::Delete { change_set_name },
137 } => {
138 fetch_context(name).delete_change_set(change_set_name).await;
139 }
140 Self::ChangeSet {
141 name,
142 command: ChangeSetCommand::Describe { change_set_name },
143 } => {
144 fetch_context(name)
145 .describe_change_set(change_set_name)
146 .await;
147 }
148 Self::ChangeSet {
149 name,
150 command: ChangeSetCommand::List,
151 } => fetch_context(name).list_change_sets().await,
152 Self::Delete { name } => fetch_context(name).delete().await,
153 Self::List => config
154 .registry
155 .0
156 .iter()
157 .for_each(|instance_spec| println!("{}", instance_spec.stack_name.0)),
158 Self::Sync {
159 name,
160 parameters,
161 review_change_set,
162 } => {
163 let parameter_map = ParameterMap::parse(parameters).unwrap();
164
165 fetch_context(name)
166 .sync(review_change_set, ¶meter_map)
167 .await
168 }
169 Self::Update {
170 name,
171 parameters,
172 review_change_set,
173 } => {
174 let parameter_map = ParameterMap::parse(parameters).unwrap();
175
176 fetch_context(name)
177 .update(review_change_set, ¶meter_map)
178 .await
179 }
180 Self::Watch { name } => {
181 crate::instance_spec::InstanceSpec::watch(
182 config.cloudformation,
183 crate::stack::load_stack_id(config.cloudformation, name).await,
184 )
185 .await
186 }
187 }
188 }
189 }
190}