Skip to content

Commit c9aec77

Browse files
committed
feat: Add uninstall demo/stack feature
1 parent a78def7 commit c9aec77

File tree

12 files changed

+784
-68
lines changed

12 files changed

+784
-68
lines changed

Cargo.lock

Lines changed: 33 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,10 @@ clap = { version = "4.5", features = ["derive", "env"] }
2828
clap_complete = "4.5"
2929
clap_complete_nushell = "4.5"
3030
comfy-table = { version = "7.1", features = ["custom_styling"] }
31+
dialoguer = "0.12.0"
3132
directories = "5.0"
3233
dotenvy = "0.15"
34+
either = "1.15.0"
3335
futures = "0.3"
3436
indexmap = { version = "2.2", features = ["serde"] }
3537
indicatif = "0.18"

rust/stackable-cockpit/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ helm-sys = { path = "../helm-sys" }
1717

1818
bcrypt.workspace = true
1919
clap.workspace = true
20+
either.workspace = true
2021
indexmap.workspace = true
2122
k8s-openapi.workspace = true
2223
kube.workspace = true

rust/stackable-cockpit/src/platform/demo/params.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ use stackable_operator::kvp::Labels;
33
use crate::platform::operator::ChartSourceType;
44

55
pub struct DemoInstallParameters {
6+
pub demo_name: String,
7+
68
pub operator_namespace: String,
79
pub demo_namespace: String,
810

@@ -14,3 +16,13 @@ pub struct DemoInstallParameters {
1416
pub labels: Labels,
1517
pub chart_source: ChartSourceType,
1618
}
19+
20+
pub struct DemoUninstallParameters {
21+
pub demo_name: String,
22+
23+
pub operator_namespace: String,
24+
pub demo_namespace: String,
25+
26+
pub skip_operators: bool,
27+
pub skip_crds: bool
28+
}

rust/stackable-cockpit/src/platform/demo/spec.rs

Lines changed: 122 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use kube::api::{ApiResource, GroupVersionKind};
12
use serde::{Deserialize, Serialize};
23
use snafu::{OptionExt, ResultExt, Snafu};
34
use tracing::{Span, debug, info, instrument, warn};
@@ -9,13 +10,13 @@ use crate::{
910
common::manifest::ManifestSpec,
1011
platform::{
1112
cluster::{ResourceRequests, ResourceRequestsError},
12-
demo::DemoInstallParameters,
13+
demo::{DemoInstallParameters, DemoUninstallParameters},
1314
manifests::{self, InstallManifestsExt},
1415
release::ReleaseList,
15-
stack::{self, StackInstallParameters, StackList},
16+
stack::{self, StackInstallParameters, StackList, StackSpec},
1617
},
1718
utils::{
18-
k8s::Client,
19+
k8s::{self, Client},
1920
params::{
2021
IntoParameters, IntoParametersError, Parameter, RawParameter, RawParameterParseError,
2122
},
@@ -47,8 +48,18 @@ pub enum Error {
4748
#[snafu(display("failed to install stack"))]
4849
InstallStack { source: stack::Error },
4950

51+
/// This error indicates that the release failed to uninstall.
52+
#[snafu(display("failed to uninstall release"))]
53+
UninstallRelease { source: stack::Error },
54+
5055
#[snafu(display("failed to install stack manifests"))]
5156
InstallManifests { source: manifests::Error },
57+
58+
#[snafu(display("failed to uninstall Helm manifests"))]
59+
UninstallHelmManifests { source: manifests::Error },
60+
61+
#[snafu(display("failed to delete object"))]
62+
DeleteObject { source: k8s::Error },
5263
}
5364

5465
impl InstallManifestsExt for DemoSpec {}
@@ -159,7 +170,6 @@ impl DemoSpec {
159170
labels: install_parameters.stack_labels.clone(),
160171
skip_release: install_parameters.skip_release,
161172
stack_name: self.stack.clone(),
162-
demo_name: None,
163173
chart_source: install_parameters.chart_source.clone(),
164174
};
165175

@@ -178,32 +188,133 @@ impl DemoSpec {
178188
.await
179189
}
180190

191+
#[instrument(skip_all, fields(
192+
demo_name = %uninstall_parameters.demo_name,
193+
demo_namespace = %uninstall_parameters.demo_namespace,
194+
stack_name = %self.stack,
195+
))]
196+
pub async fn uninstall(
197+
&self,
198+
release_list: ReleaseList,
199+
uninstall_parameters: DemoUninstallParameters,
200+
client: &Client,
201+
transfer_client: &xfer::Client,
202+
stack: StackSpec,
203+
) -> Result<(), Error> {
204+
// Uninstall Helm Charts
205+
let parameters = &mut Vec::new()
206+
.into_params(self.parameters.clone())
207+
.context(ParseParametersSnafu)?;
208+
209+
// We add the DEMO parameter, so that demos can use that to render e.g. the demo label
210+
parameters.insert("DEMO".to_owned(), uninstall_parameters.demo_name.clone());
211+
212+
Self::uninstall_helm_manifests(
213+
&self.manifests,
214+
parameters,
215+
&uninstall_parameters.demo_namespace.to_owned(),
216+
transfer_client,
217+
)
218+
.await
219+
.context(UninstallHelmManifestsSnafu)?;
220+
221+
let stack_parameters = &mut Vec::new()
222+
.into_params(stack.parameters.clone())
223+
.context(ParseParametersSnafu)?;
224+
225+
// We add the STACK parameter, so that stacks can use that to render e.g. the stack label
226+
stack_parameters.insert("STACK".to_owned(), self.stack.clone());
227+
228+
Self::uninstall_helm_manifests(
229+
&stack.manifests,
230+
stack_parameters,
231+
&uninstall_parameters.demo_namespace.to_owned(),
232+
transfer_client,
233+
)
234+
.await
235+
.context(UninstallHelmManifestsSnafu)?;
236+
237+
// Delete demo namespace
238+
client
239+
.delete_object(
240+
&uninstall_parameters.demo_namespace,
241+
&ApiResource::from_gvk(&GroupVersionKind {
242+
group: "".to_owned(),
243+
version: "v1".to_owned(),
244+
kind: "Namespace".to_owned(),
245+
}),
246+
None,
247+
)
248+
.await
249+
.context(DeleteObjectSnafu)?;
250+
251+
// Delete remaining objects not namespace scoped
252+
client
253+
.delete_all_objects_with_label("stackable.tech/demo", &uninstall_parameters.demo_name, None)
254+
.await
255+
.context(DeleteObjectSnafu)?;
256+
257+
// Delete operators and the operator namespace
258+
if !uninstall_parameters.skip_operators {
259+
stack
260+
.uninstall_release(release_list, &uninstall_parameters.operator_namespace)
261+
.await
262+
.context(UninstallReleaseSnafu)?;
263+
264+
client
265+
.delete_object(
266+
&uninstall_parameters.operator_namespace,
267+
&ApiResource::from_gvk(&GroupVersionKind {
268+
group: "".to_owned(),
269+
version: "v1".to_owned(),
270+
kind: "Namespace".to_owned(),
271+
}),
272+
None,
273+
)
274+
.await
275+
.context(DeleteObjectSnafu)?;
276+
}
277+
278+
// Delete CRDs
279+
if !uninstall_parameters.skip_crds {
280+
client
281+
.delete_crds_with_group_suffix("stackable.tech")
282+
.await
283+
.context(DeleteObjectSnafu)?;
284+
}
285+
286+
Ok(())
287+
}
288+
181289
#[instrument(skip_all, fields(
182290
stack_name = %self.stack,
183-
operator_namespace = %install_params.operator_namespace,
184-
demo_namespace = %install_params.demo_namespace,
291+
operator_namespace = %install_parameters.operator_namespace,
292+
demo_namespace = %install_parameters.demo_namespace,
185293
indicatif.pb_show = true
186294
))]
187295
async fn prepare_manifests(
188296
&self,
189-
install_params: DemoInstallParameters,
297+
install_parameters: DemoInstallParameters,
190298
client: &Client,
191299
transfer_client: &xfer::Client,
192300
) -> Result<(), Error> {
193301
info!("Installing demo manifests");
194302
Span::current().pb_set_message("Installing manifests");
195303

196-
let params = install_params
304+
let mut parameters = install_parameters
197305
.parameters
198306
.to_owned()
199307
.into_params(&self.parameters)
200308
.context(ParseParametersSnafu)?;
201309

310+
// We add the DEMO parameter, so that demos can use that to render e.g. the demo label
311+
parameters.insert("DEMO".to_owned(), install_parameters.demo_name);
312+
202313
Self::install_manifests(
203314
&self.manifests,
204-
&params,
205-
&install_params.demo_namespace,
206-
install_params.labels,
315+
&parameters,
316+
&install_parameters.demo_namespace,
317+
install_parameters.labels,
207318
client,
208319
transfer_client,
209320
)

0 commit comments

Comments
 (0)