Skip to main content

kratactl/cli/zone/
destroy.rs

1use anyhow::Result;
2use clap::Parser;
3use krata::{
4    events::EventStream,
5    v1::control::{
6        control_service_client::ControlServiceClient, watch_events_reply::Event, DestroyZoneRequest,
7    },
8};
9
10use crate::cli::resolve_zone;
11use krata::v1::common::ZoneState;
12use log::error;
13use tonic::{transport::Channel, Request};
14
15#[derive(Parser)]
16#[command(about = "Destroy a zone")]
17pub struct ZoneDestroyCommand {
18    #[arg(
19        short = 'W',
20        long,
21        help = "Wait for the destruction of the zone to complete"
22    )]
23    wait: bool,
24    #[arg(help = "Zone to destroy, either the name or the uuid")]
25    zone: String,
26}
27
28impl ZoneDestroyCommand {
29    pub async fn run(
30        self,
31        mut client: ControlServiceClient<Channel>,
32        events: EventStream,
33    ) -> Result<()> {
34        let zone_id: String = resolve_zone(&mut client, &self.zone).await?;
35        let _ = client
36            .destroy_zone(Request::new(DestroyZoneRequest {
37                zone_id: zone_id.clone(),
38            }))
39            .await?
40            .into_inner();
41        if self.wait {
42            wait_zone_destroyed(&zone_id, events).await?;
43        }
44        Ok(())
45    }
46}
47
48async fn wait_zone_destroyed(id: &str, events: EventStream) -> Result<()> {
49    let mut stream = events.subscribe();
50    while let Ok(event) = stream.recv().await {
51        let Event::ZoneChanged(changed) = event;
52        let Some(zone) = changed.zone else {
53            continue;
54        };
55
56        if zone.id != id {
57            continue;
58        }
59
60        let Some(status) = zone.status else {
61            continue;
62        };
63
64        if let Some(ref error) = status.error_status {
65            if status.state() == ZoneState::Failed {
66                error!("destroy failed: {}", error.message);
67                std::process::exit(1);
68            } else {
69                error!("zone error: {}", error.message);
70            }
71        }
72
73        if status.state() == ZoneState::Destroyed {
74            std::process::exit(0);
75        }
76    }
77    Ok(())
78}