Skip to content

Commit

Permalink
Merge b145232 into ab559ee
Browse files Browse the repository at this point in the history
  • Loading branch information
shinusuresh committed Aug 7, 2022
2 parents ab559ee + b145232 commit 7cce962
Show file tree
Hide file tree
Showing 8 changed files with 489 additions and 6 deletions.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -220,4 +220,4 @@ MIT
- [Asha Somayajula](https://github.com/somayaj)
- [Tobias de Bruijn](https://github.com/TheDutchMC)
- [Omid Rad](https://github.com/omid)
- [shinu-ynap](https://github.com/shinu-ynap)
- [Shinu Suresh](https://github.com/shinusuresh)
12 changes: 10 additions & 2 deletions src/app/mod.rs
Expand Up @@ -40,7 +40,7 @@ use self::{
pods::{KubeContainer, KubePod},
replicasets::KubeReplicaSet,
replication_controllers::KubeReplicationController,
roles::KubeRoles,
roles::{KubeClusterRoles, KubeRoles},
secrets::KubeSecret,
statefulsets::KubeStatefulSet,
storageclass::KubeStorageClass,
Expand Down Expand Up @@ -75,6 +75,7 @@ pub enum ActiveBlock {
RplCtrl,
StorageClasses,
Roles,
ClusterRoles,
More,
}

Expand Down Expand Up @@ -131,6 +132,7 @@ pub struct Data {
pub rpl_ctrls: StatefulTable<KubeReplicationController>,
pub storage_classes: StatefulTable<KubeStorageClass>,
pub roles: StatefulTable<KubeRoles>,
pub clusterroles: StatefulTable<KubeClusterRoles>,
}

/// selected data items
Expand Down Expand Up @@ -205,6 +207,7 @@ impl Default for Data {
rpl_ctrls: StatefulTable::new(),
storage_classes: StatefulTable::new(),
roles: StatefulTable::new(),
clusterroles: StatefulTable::new(),
}
}
}
Expand Down Expand Up @@ -331,7 +334,7 @@ impl Default for App {
("Storage Classes".into(), ActiveBlock::StorageClasses),
("Roles".into(), ActiveBlock::Roles),
// ("Role Bindings".into(), ActiveBlock::RplCtrl),
// ("Cluster Roles".into(), ActiveBlock::RplCtrl),
("Cluster Roles".into(), ActiveBlock::ClusterRoles),
// ("Cluster Role Bindings".into(), ActiveBlock::RplCtrl),
// ("Service Accounts".into(), ActiveBlock::RplCtrl),
// ("Ingresses".into(), ActiveBlock::RplCtrl),
Expand Down Expand Up @@ -527,6 +530,7 @@ impl App {
self.dispatch(IoEvent::GetReplicationControllers).await;
self.dispatch(IoEvent::GetStorageClasses).await;
self.dispatch(IoEvent::GetRoles).await;
self.dispatch(IoEvent::GetClusterRoles).await;
self.dispatch(IoEvent::GetMetrics).await;
}

Expand Down Expand Up @@ -571,6 +575,9 @@ impl App {
ActiveBlock::Roles => {
self.dispatch(IoEvent::GetRoles).await;
}
ActiveBlock::ClusterRoles => {
self.dispatch(IoEvent::GetClusterRoles).await;
}
ActiveBlock::Logs => {
if !self.is_streaming {
// do not tail to avoid duplicates
Expand Down Expand Up @@ -729,6 +736,7 @@ mod tests {
);
assert_eq!(sync_io_rx.recv().await.unwrap(), IoEvent::GetStorageClasses);
assert_eq!(sync_io_rx.recv().await.unwrap(), IoEvent::GetRoles);
assert_eq!(sync_io_rx.recv().await.unwrap(), IoEvent::GetClusterRoles);
assert_eq!(sync_io_rx.recv().await.unwrap(), IoEvent::GetMetrics);
assert_eq!(sync_io_rx.recv().await.unwrap(), IoEvent::GetNamespaces);
assert_eq!(sync_io_rx.recv().await.unwrap(), IoEvent::GetNodes);
Expand Down
41 changes: 39 additions & 2 deletions src/app/roles.rs
@@ -1,4 +1,4 @@
use k8s_openapi::{api::rbac::v1::Role, chrono::Utc};
use k8s_openapi::{api::rbac::v1::ClusterRole, api::rbac::v1::Role, chrono::Utc};

use super::{models::KubeResource, utils};

Expand All @@ -10,6 +10,13 @@ pub struct KubeRoles {
k8s_obj: Role,
}

#[derive(Clone, Debug, PartialEq)]
pub struct KubeClusterRoles {
pub name: String,
pub age: String,
k8s_obj: ClusterRole,
}

impl KubeResource<Role> for KubeRoles {
fn from_api(role: &Role) -> Self {
KubeRoles {
Expand All @@ -25,9 +32,23 @@ impl KubeResource<Role> for KubeRoles {
}
}

impl KubeResource<ClusterRole> for KubeClusterRoles {
fn from_api(clusterrole: &ClusterRole) -> Self {
KubeClusterRoles {
name: clusterrole.metadata.name.clone().unwrap_or_default(),
age: utils::to_age(clusterrole.metadata.creation_timestamp.as_ref(), Utc::now()),
k8s_obj: clusterrole.to_owned(),
}
}

fn get_k8s_obj(&self) -> &ClusterRole {
&self.k8s_obj
}
}

#[cfg(test)]
mod tests {
use crate::app::roles::KubeRoles;
use crate::app::roles::{KubeClusterRoles, KubeRoles};
use crate::app::test_utils::{convert_resource_from_file, get_time};
use crate::app::utils;
use k8s_openapi::chrono::Utc;
Expand All @@ -47,4 +68,20 @@ mod tests {
}
)
}

#[test]
fn test_cluster_roles_binding_from_rbac_api() {
let (clusterroles, cluster_roles_list): (Vec<KubeClusterRoles>, Vec<_>) =
convert_resource_from_file("clusterroles");

assert_eq!(clusterroles.len(), 1);
assert_eq!(
clusterroles[0],
KubeClusterRoles {
name: "admin".into(),
age: utils::to_age(Some(&get_time("2021-12-14T11:04:22Z")), Utc::now()),
k8s_obj: cluster_roles_list[0].clone(),
}
)
}
}
16 changes: 16 additions & 0 deletions src/handlers/mod.rs
Expand Up @@ -446,6 +446,21 @@ async fn handle_route_events(key: Key, app: &mut App) {
.await;
}
}
ActiveBlock::ClusterRoles => {
if let Some(res) = handle_block_action(key, &mut app.data.clusterroles) {
let _ok = handle_describe_or_yaml_action(
key,
app,
&res,
IoCmdEvent::GetDescribe {
kind: "clusterroles".to_owned(),
value: res.name.to_owned(),
ns: None,
},
)
.await;
}
}
ActiveBlock::Contexts | ActiveBlock::Utilization | ActiveBlock::Help => { /* Do nothing */ }
}
}
Expand Down Expand Up @@ -509,6 +524,7 @@ async fn handle_block_scroll(app: &mut App, up: bool, is_mouse: bool, page: bool
ActiveBlock::RplCtrl => app.data.rpl_ctrls.handle_scroll(up, page),
ActiveBlock::StorageClasses => app.data.storage_classes.handle_scroll(up, page),
ActiveBlock::Roles => app.data.roles.handle_scroll(up, page),
ActiveBlock::ClusterRoles => app.data.clusterroles.handle_scroll(up, page),
ActiveBlock::Contexts => app.data.contexts.handle_scroll(up, page),
ActiveBlock::Utilization => app.data.metrics.handle_scroll(up, page),
ActiveBlock::Help => app.help_docs.handle_scroll(up, page),
Expand Down
11 changes: 10 additions & 1 deletion src/network/kube_api.rs
Expand Up @@ -28,7 +28,7 @@ use crate::app::{
pods::KubePod,
replicasets::KubeReplicaSet,
replication_controllers::KubeReplicationController,
roles::KubeRoles,
roles::{KubeClusterRoles, KubeRoles},
secrets::KubeSecret,
statefulsets::KubeStatefulSet,
storageclass::KubeStorageClass,
Expand Down Expand Up @@ -318,6 +318,15 @@ impl<'a> Network<'a> {
app.data.roles.set_items(items);
}

pub async fn get_cluster_roles(&self) {
let items: Vec<KubeClusterRoles> = self
.get_namespaced_resources(|it| KubeClusterRoles::from_api(it))
.await;

let mut app = self.app.lock().await;
app.data.clusterroles.set_items(items);
}

/// calls the kubernetes API to list the given resource for either selected namespace or all namespaces
async fn get_namespaced_resources<K: ApiResource, T, F>(&self, map_fn: F) -> Vec<T>
where
Expand Down
4 changes: 4 additions & 0 deletions src/network/mod.rs
Expand Up @@ -29,6 +29,7 @@ pub enum IoEvent {
GetReplicationControllers,
GetStorageClasses,
GetRoles,
GetClusterRoles,
GetMetrics,
RefreshClient,
}
Expand Down Expand Up @@ -162,6 +163,9 @@ impl<'a> Network<'a> {
IoEvent::GetRoles => {
self.get_roles().await;
}
IoEvent::GetClusterRoles => {
self.get_cluster_roles().await;
}
};

let mut app = self.app.lock().await;
Expand Down
51 changes: 51 additions & 0 deletions src/ui/resource_tabs.rs
Expand Up @@ -34,6 +34,7 @@ static SECRETS_TITLE: &str = "Secrets";
static RPL_CTRL_TITLE: &str = "ReplicationControllers";
static STORAGE_CLASSES_LABEL: &str = "StorageClasses";
static ROLES_TITLE: &str = "Roles";
static CLUSTER_ROLES_TITLE: &str = "ClusterRoles";
static DESCRIBE_ACTIVE: &str = "-> Describe ";
static YAML_ACTIVE: &str = "-> YAML ";

Expand Down Expand Up @@ -84,6 +85,7 @@ fn draw_more<B: Backend>(block: ActiveBlock, f: &mut Frame<'_, B>, app: &mut App
ActiveBlock::RplCtrl => draw_replication_controllers_tab(block, f, app, area),
ActiveBlock::StorageClasses => draw_storage_classes_tab(block, f, app, area),
ActiveBlock::Roles => draw_roles_tab(block, f, app, area),
ActiveBlock::ClusterRoles => draw_cluster_roles_tab(block, f, app, area),
ActiveBlock::Describe | ActiveBlock::Yaml => {
let mut prev_route = app.get_prev_route();
if prev_route.active_block == block {
Expand All @@ -95,6 +97,7 @@ fn draw_more<B: Backend>(block: ActiveBlock, f: &mut Frame<'_, B>, app: &mut App
ActiveBlock::RplCtrl => draw_replication_controllers_tab(block, f, app, area),
ActiveBlock::StorageClasses => draw_storage_classes_tab(block, f, app, area),
ActiveBlock::Roles => draw_roles_tab(block, f, app, area),
ActiveBlock::ClusterRoles => draw_cluster_roles_tab(block, f, app, area),
_ => { /* do nothing */ }
}
}
Expand Down Expand Up @@ -1057,6 +1060,54 @@ fn draw_roles_block<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, area: Rect)
);
}

fn draw_cluster_roles_tab<B: Backend>(
block: ActiveBlock,
f: &mut Frame<'_, B>,
app: &mut App,
area: Rect,
) {
draw_resource_tab!(
CLUSTER_ROLES_TITLE,
block,
f,
app,
area,
draw_cluster_roles_tab,
draw_cluster_roles_block,
app.data.clusterroles
);
}

fn draw_cluster_roles_block<B: Backend>(f: &mut Frame<'_, B>, app: &mut App, area: Rect) {
let title = get_resource_title(
app,
CLUSTER_ROLES_TITLE,
"",
app.data.clusterroles.items.len(),
);

draw_resource_block(
f,
area,
ResourceTableProps {
title,
inline_help: DESCRIBE_YAML_AND_ESC_HINT.into(),
resource: &mut app.data.clusterroles,
table_headers: vec!["Name", "Age"],
column_widths: vec![Constraint::Percentage(50), Constraint::Percentage(50)],
},
|c| {
Row::new(vec![
Cell::from(c.name.to_owned()),
Cell::from(c.age.to_owned()),
])
.style(style_primary(app.light_theme))
},
app.light_theme,
app.is_loading,
);
}

/// common for all resources
fn draw_describe_block<B: Backend>(
f: &mut Frame<'_, B>,
Expand Down

0 comments on commit 7cce962

Please sign in to comment.