Skip to content

Commit d1dffc8

Browse files
authored
Delete namespace (#195)
Delete a namespace and all resources within it.
1 parent 784789f commit d1dffc8

File tree

11 files changed

+189
-12
lines changed

11 files changed

+189
-12
lines changed

.sqlx/query-176ad85b2b9a88831e77f8c12481814efb1b5985081ffb1c46e9d596b03246f9.json

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

src/delete.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ pub enum DeleteCommands {
2828
Service(DeleteResourceArgs),
2929
ClusterIssuer(DeleteResourceArgs),
3030
Cluster(DeleteClusterArgs),
31+
Namespace(DeleteNamespaceArgs),
32+
}
33+
34+
#[derive(Debug, Args)]
35+
pub struct DeleteNamespaceArgs {
36+
name: String,
37+
#[command(flatten)]
38+
config: ConfigFileArgs,
3139
}
3240

3341
#[derive(Debug, Args)]
@@ -81,6 +89,17 @@ impl<D: DeleteDeps> Delete<D> {
8189
.await?
8290
}
8391
DeleteCommands::Cluster(args) => self.delete_cluster(args).await?,
92+
DeleteCommands::Namespace(args) => {
93+
self.delete_resource(
94+
ResourceType::Namespace,
95+
DeleteResourceArgs {
96+
name: args.name.clone(),
97+
namespace: args.name,
98+
config: args.config,
99+
},
100+
)
101+
.await?
102+
}
84103
}
85104
Ok(())
86105
}

src/object_list_item.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ impl TryFrom<&SupportedResources> for ObjectListItem {
153153
SupportedResources::Secret(s) => &s.metadata,
154154
SupportedResources::Service(s) => &s.metadata,
155155
SupportedResources::ClusterIssuer(i) => &i.metadata,
156+
SupportedResources::Namespace(ns) => &ns.metadata,
156157
};
157158

158159
let name = get_skate_label_value(&meta.labels, &SkateLabels::Name).ok_or("no name")?;

src/scheduler.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,7 @@ impl DefaultScheduler {
855855
SupportedResources::Secret(secret) => Self::plan_secret(state, secret),
856856
SupportedResources::Service(service) => Self::plan_service(state, service),
857857
SupportedResources::ClusterIssuer(issuer) => Self::plan_cluster_issuer(state, issuer),
858+
SupportedResources::Namespace(_ns) => todo!(),
858859
}
859860
}
860861

src/scheduler/priority_sort.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use k8s_openapi::api::core::v1::Pod;
33

44
pub(crate) struct PrioritySort {}
55

6+
#[allow(unused)]
67
pub fn pod_priority(pod: &Pod) -> i32 {
78
pod.spec
89
.as_ref()

src/skatelet/apply.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ async fn apply_supported_resource<D: ApplyDeps>(
101101
let ctrl = ClusterIssuerController::new(deps.get_db(), ingress_ctrl);
102102
ctrl.apply(issuer).await?;
103103
}
104+
SupportedResources::Namespace(_) => {}
104105
}
105106
Ok(())
106107
}

src/skatelet/database/resource.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,24 @@ pub async fn list_resources_by_type(
142142
Ok(resources)
143143
}
144144

145+
pub async fn list_resources_by_namespace(
146+
db: impl SqliteExecutor<'_>,
147+
ns: &str,
148+
) -> super::Result<Vec<Resource>> {
149+
let resources = sqlx::query_as!(
150+
Resource,
151+
r#" SELECT id as "id!: String", name as "name!: String", namespace as "namespace!: String", resource_type, manifest as "manifest!: serde_json::Value", hash as "hash!: String", created_at as "created_at!: DateTime<Local>", updated_at as "updated_at!: DateTime<Local>", generation
152+
FROM resources
153+
WHERE namespace = $1
154+
"#,
155+
ns
156+
)
157+
.fetch_all(db)
158+
.await?;
159+
160+
Ok(resources)
161+
}
162+
145163
pub async fn list_resources(db: impl SqliteExecutor<'_>) -> super::Result<Vec<Resource>> {
146164
let resources = sqlx::query_as!(
147165
Resource,
@@ -191,6 +209,12 @@ pub enum ResourceType {
191209
ClusterIssuer,
192210
#[strum(serialize = "nodes", serialize = "node", to_string = "node")]
193211
Node,
212+
#[strum(
213+
serialize = "namespaces",
214+
serialize = "namespace",
215+
to_string = "namespace"
216+
)]
217+
Namespace,
194218
}
195219

196220
impl From<String> for ResourceType {

src/skatelet/delete.rs

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,12 @@ use crate::skatelet::apply::StdinCommand;
22
use crate::supported_resources::SupportedResources;
33
use crate::supported_resources::SupportedResources::{ClusterIssuer, CronJob, Ingress, Service};
44
use clap::{Args, Subcommand};
5+
use k8s_openapi::api::batch::v1::CronJob as K8sCronJob;
6+
use k8s_openapi::api::core::v1::{Namespace, Secret};
57
use std::collections::BTreeMap;
68
use std::io;
79
use std::io::Read;
810

9-
use k8s_openapi::api::batch::v1::CronJob as K8sCronJob;
10-
use k8s_openapi::api::core::v1::Secret;
11-
1211
use crate::controllers::clusterissuer::ClusterIssuerController;
1312
use crate::controllers::cronjob::CronjobController;
1413
use crate::controllers::daemonset::DaemonSetController;
@@ -21,6 +20,7 @@ use crate::deps::{With, WithDB};
2120
use crate::errors::SkateError;
2221
use crate::exec::ShellExec;
2322
use crate::skatelet::VAR_PATH;
23+
use crate::skatelet::database::resource::list_resources_by_namespace;
2424
use crate::spec;
2525
use crate::util::SkateLabels;
2626
use k8s_openapi::api::core::v1::Service as K8sService;
@@ -46,6 +46,7 @@ pub enum DeleteResourceCommands {
4646
Daemonset(DeleteResourceArgs),
4747
Service(DeleteResourceArgs),
4848
Clusterissuer(DeleteResourceArgs),
49+
Namespace(DeleteResourceArgs),
4950
}
5051

5152
#[derive(Debug, Args, Clone)]
@@ -101,6 +102,10 @@ impl<D: DeleteDeps> Deleter<D> {
101102
self.delete_cluster_issuer(args.clone(), resource_args.clone())
102103
.await
103104
}
105+
DeleteResourceCommands::Namespace(resource_args) => {
106+
self.delete_namespace(args.clone(), resource_args.clone())
107+
.await
108+
}
104109
}
105110
}
106111

@@ -243,6 +248,23 @@ impl<D: DeleteDeps> Deleter<D> {
243248
Ok(())
244249
}
245250

251+
async fn delete_namespace(
252+
&self,
253+
delete_args: DeleteArgs,
254+
resource_args: DeleteResourceArgs,
255+
) -> Result<(), SkateError> {
256+
self.manifest_delete(
257+
&SupportedResources::Namespace(Namespace {
258+
metadata: Self::deletion_metadata(resource_args),
259+
spec: None,
260+
status: None,
261+
}),
262+
delete_args.termination_grace_period,
263+
)
264+
.await?;
265+
Ok(())
266+
}
267+
246268
async fn manifest_delete(
247269
&self,
248270
object: &SupportedResources,
@@ -291,6 +313,25 @@ impl<D: DeleteDeps> Deleter<D> {
291313
let ctrl = ClusterIssuerController::new(self.deps.get_db(), ingress_controller);
292314
ctrl.delete(issuer).await?;
293315
}
316+
SupportedResources::Namespace(ns) => {
317+
// find all resources within the ns in the db
318+
// run manifest delete on all of those
319+
// report any errors
320+
let name = match &ns.metadata.name {
321+
Some(n) => n,
322+
None => return Err(SkateError::String("no metadata name".to_string())),
323+
};
324+
let resources =
325+
list_resources_by_namespace(&self.deps.get_db(), name.as_str()).await?;
326+
327+
for resource in resources {
328+
let str_manifest = serde_yaml::to_string(&resource.manifest)?;
329+
let object: serde_yaml::Value = serde_yaml::from_str(&str_manifest)?;
330+
let object = SupportedResources::try_from(&object)?;
331+
println!("deleting {} {}", resource.resource_type, resource.name);
332+
Box::pin(self.manifest_delete(&object, grace_period)).await?;
333+
}
334+
}
294335
}
295336
Ok(())
296337
}

src/state/state.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ impl ClusterState {
534534
&mut self,
535535
filter_node: Option<&str>,
536536
filter_types: &[ResourceType],
537-
) -> Vec<MutCatalogueItem> {
537+
) -> Vec<MutCatalogueItem<'_>> {
538538
self.nodes
539539
.iter_mut()
540540
.filter(|n| filter_node.is_none() || n.node_name == filter_node.unwrap())
@@ -559,7 +559,7 @@ impl ClusterState {
559559
filter_types: &[ResourceType],
560560
namespace: Option<&str>,
561561
name: Option<&str>,
562-
) -> Vec<CatalogueItem> {
562+
) -> Vec<CatalogueItem<'_, '_, '_, '_>> {
563563
let mut map: HashMap<String, CatalogueItem> = HashMap::new();
564564

565565
for node in &self.nodes {

src/supported_resources.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use anyhow::anyhow;
88
use k8s_openapi::Resource;
99
use k8s_openapi::api::apps::v1::{DaemonSet, Deployment};
1010
use k8s_openapi::api::batch::v1::CronJob;
11-
use k8s_openapi::api::core::v1::{Pod, PodTemplateSpec, Secret, Service};
11+
use k8s_openapi::api::core::v1::{Namespace, Pod, PodTemplateSpec, Secret, Service};
1212
use k8s_openapi::api::networking::v1::Ingress;
1313
use k8s_openapi::apimachinery::pkg::apis::meta::v1::ObjectMeta;
1414
use serde::{Deserialize, Serialize};
@@ -35,6 +35,8 @@ pub enum SupportedResources {
3535
Service(Service),
3636
#[strum(serialize = "ClusterIssuer")]
3737
ClusterIssuer(ClusterIssuer),
38+
#[strum(serialize = "Namespace")]
39+
Namespace(Namespace),
3840
}
3941

4042
impl Into<ResourceType> for &SupportedResources {
@@ -48,6 +50,7 @@ impl Into<ResourceType> for &SupportedResources {
4850
SupportedResources::Secret(_) => ResourceType::Secret,
4951
SupportedResources::Service(_) => ResourceType::Service,
5052
SupportedResources::ClusterIssuer(_) => ResourceType::ClusterIssuer,
53+
SupportedResources::Namespace(_) => ResourceType::Namespace,
5154
}
5255
}
5356
}
@@ -99,14 +102,14 @@ impl TryFrom<&Value> for SupportedResources {
99102
let clusterissuer: ClusterIssuer = serde::Deserialize::deserialize(value)?;
100103
Ok(SupportedResources::ClusterIssuer(clusterissuer))
101104
} else {
102-
Err(anyhow!(format!("version: {}, kind {}", api_version, kind))
103-
.context("unsupported resource type")
104-
.into())
105+
Err(anyhow!(format!(
106+
"unsupported resource: version {}, kind {}",
107+
api_version, kind
108+
))
109+
.into())
105110
}
106111
}
107-
_ => Err(anyhow!("missing 'kind' and 'apiVersion' fields")
108-
.context("unsupported resource type")
109-
.into()),
112+
_ => Err(anyhow!("resource missing 'kind' and 'apiVersion' fields").into()),
110113
}
111114
}
112115
}
@@ -122,6 +125,7 @@ impl SupportedResources {
122125
SupportedResources::Secret(s) => metadata_name(s),
123126
SupportedResources::Service(s) => metadata_name(s),
124127
SupportedResources::ClusterIssuer(c) => metadata_name(c),
128+
SupportedResources::Namespace(n) => metadata_name(n),
125129
}
126130
}
127131

@@ -243,6 +247,7 @@ impl SupportedResources {
243247
SupportedResources::Secret(_) => false,
244248
SupportedResources::Service(_) => false,
245249
SupportedResources::ClusterIssuer(_) => false,
250+
SupportedResources::Namespace(_) => false,
246251
}
247252
}
248253
fn fixup_pod_template(
@@ -501,6 +506,10 @@ impl SupportedResources {
501506
issuer.metadata = Self::fixup_metadata(issuer.metadata.clone(), None)?;
502507
resource
503508
}
509+
SupportedResources::Namespace(ref mut ns) => {
510+
ns.metadata = Self::fixup_metadata(ns.metadata.clone(), None)?;
511+
resource
512+
}
504513
};
505514
Ok(resource)
506515
}

0 commit comments

Comments
 (0)