Skip to content

Commit

Permalink
Merge branch 'shinusuresh-feat/cluster-role-bindings'
Browse files Browse the repository at this point in the history
  • Loading branch information
deepu105 committed Aug 31, 2022
2 parents b19f144 + 10f308f commit 00646b7
Show file tree
Hide file tree
Showing 8 changed files with 236 additions and 33 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## Unreleased - 2022-XX-YY

- Add support for RoleBindings (https://github.com/kdash-rs/kdash/pull/245)
- Add support for ClusterRoleBindings (https://github.com/kdash-rs/kdash/pull/249)

## [0.3.4] - 2022-08-18

Expand Down
22 changes: 18 additions & 4 deletions src/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ use self::{
pods::{KubeContainer, KubePod},
replicasets::KubeReplicaSet,
replication_controllers::KubeReplicationController,
roles::{KubeClusterRoles, KubeRoleBindings, KubeRoles},
roles::{KubeClusterRoleBinding, KubeClusterRoles, KubeRoleBindings, KubeRoles},
secrets::KubeSecret,
statefulsets::KubeStatefulSet,
storageclass::KubeStorageClass,
Expand Down Expand Up @@ -77,6 +77,7 @@ pub enum ActiveBlock {
Roles,
RoleBindings,
ClusterRoles,
ClusterRoleBinding,
More,
}

Expand Down Expand Up @@ -134,7 +135,8 @@ pub struct Data {
pub storage_classes: StatefulTable<KubeStorageClass>,
pub roles: StatefulTable<KubeRoles>,
pub role_bindings: StatefulTable<KubeRoleBindings>,
pub clusterroles: StatefulTable<KubeClusterRoles>,
pub cluster_roles: StatefulTable<KubeClusterRoles>,
pub cluster_role_binding: StatefulTable<KubeClusterRoleBinding>,
}

/// selected data items
Expand Down Expand Up @@ -210,7 +212,8 @@ impl Default for Data {
storage_classes: StatefulTable::new(),
roles: StatefulTable::new(),
role_bindings: StatefulTable::new(),
clusterroles: StatefulTable::new(),
cluster_roles: StatefulTable::new(),
cluster_role_binding: StatefulTable::new(),
}
}
}
Expand Down Expand Up @@ -338,7 +341,10 @@ impl Default for App {
("Roles".into(), ActiveBlock::Roles),
("Role Bindings".into(), ActiveBlock::RoleBindings),
("Cluster Roles".into(), ActiveBlock::ClusterRoles),
// ("Cluster Role Bindings".into(), ActiveBlock::RplCtrl),
(
"Cluster Role Bindings".into(),
ActiveBlock::ClusterRoleBinding,
),
// ("Service Accounts".into(), ActiveBlock::RplCtrl),
// ("Ingresses".into(), ActiveBlock::RplCtrl),
// ("Network Policies".into(), ActiveBlock::RplCtrl),
Expand Down Expand Up @@ -535,6 +541,7 @@ impl App {
self.dispatch(IoEvent::GetRoles).await;
self.dispatch(IoEvent::GetRoleBindings).await;
self.dispatch(IoEvent::GetClusterRoles).await;
self.dispatch(IoEvent::GetClusterRoleBinding).await;
self.dispatch(IoEvent::GetMetrics).await;
}

Expand Down Expand Up @@ -585,6 +592,9 @@ impl App {
ActiveBlock::ClusterRoles => {
self.dispatch(IoEvent::GetClusterRoles).await;
}
ActiveBlock::ClusterRoleBinding => {
self.dispatch(IoEvent::GetClusterRoleBinding).await;
}
ActiveBlock::Logs => {
if !self.is_streaming {
// do not tail to avoid duplicates
Expand Down Expand Up @@ -745,6 +755,10 @@ mod tests {
assert_eq!(sync_io_rx.recv().await.unwrap(), IoEvent::GetRoles);
assert_eq!(sync_io_rx.recv().await.unwrap(), IoEvent::GetRoleBindings);
assert_eq!(sync_io_rx.recv().await.unwrap(), IoEvent::GetClusterRoles);
assert_eq!(
sync_io_rx.recv().await.unwrap(),
IoEvent::GetClusterRoleBinding
);
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
101 changes: 79 additions & 22 deletions src/app/roles.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use k8s_openapi::{
api::rbac::v1::{ClusterRole, Role, RoleBinding},
api::rbac::v1::{ClusterRole, ClusterRoleBinding, Role, RoleBinding},
chrono::Utc,
};

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

#[derive(Clone, Debug, PartialEq)]
pub struct KubeRoleBindings {
pub namespace: String,
pub name: String,
pub role: String,
pub age: String,
k8s_obj: RoleBinding,
}

#[derive(Clone, Debug, PartialEq)]
pub struct KubeClusterRoles {
pub name: String,
Expand All @@ -21,12 +30,11 @@ pub struct KubeClusterRoles {
}

#[derive(Clone, Debug, PartialEq)]
pub struct KubeRoleBindings {
pub namespace: String,
pub struct KubeClusterRoleBinding {
pub name: String,
pub role: String,
pub age: String,
k8s_obj: RoleBinding,
k8s_obj: ClusterRoleBinding,
}

impl KubeResource<Role> for KubeRoles {
Expand All @@ -45,11 +53,14 @@ impl KubeResource<Role> for KubeRoles {
}

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

Expand All @@ -59,13 +70,16 @@ impl KubeResource<ClusterRole> for KubeClusterRoles {
}

impl KubeResource<RoleBinding> for KubeRoleBindings {
fn from_api(rolebinding: &RoleBinding) -> Self {
fn from_api(role_binding: &RoleBinding) -> Self {
KubeRoleBindings {
namespace: rolebinding.metadata.namespace.clone().unwrap_or_default(),
name: rolebinding.metadata.name.clone().unwrap_or_default(),
role: rolebinding.role_ref.name.clone(),
age: utils::to_age(rolebinding.metadata.creation_timestamp.as_ref(), Utc::now()),
k8s_obj: rolebinding.to_owned(),
namespace: role_binding.metadata.namespace.clone().unwrap_or_default(),
name: role_binding.metadata.name.clone().unwrap_or_default(),
role: role_binding.role_ref.name.clone(),
age: utils::to_age(
role_binding.metadata.creation_timestamp.as_ref(),
Utc::now(),
),
k8s_obj: role_binding.to_owned(),
}
}

Expand All @@ -74,12 +88,38 @@ impl KubeResource<RoleBinding> for KubeRoleBindings {
}
}

impl KubeResource<ClusterRoleBinding> for KubeClusterRoleBinding {
fn from_api(cluster_role_binding: &ClusterRoleBinding) -> Self {
KubeClusterRoleBinding {
name: cluster_role_binding
.metadata
.name
.clone()
.unwrap_or_default(),
role: format!(
"{}/{}",
cluster_role_binding.role_ref.kind.clone(),
cluster_role_binding.role_ref.name.clone()
),
age: utils::to_age(
cluster_role_binding.metadata.creation_timestamp.as_ref(),
Utc::now(),
),
k8s_obj: cluster_role_binding.to_owned(),
}
}

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

#[cfg(test)]
mod tests {
use k8s_openapi::chrono::Utc;

use crate::app::{
roles::{KubeClusterRoles, KubeRoleBindings, KubeRoles},
roles::{KubeClusterRoleBinding, KubeClusterRoles, KubeRoleBindings, KubeRoles},
test_utils::{convert_resource_from_file, get_time},
utils,
};
Expand All @@ -101,13 +141,13 @@ mod tests {
}

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

assert_eq!(clusterroles.len(), 1);
assert_eq!(cluster_roles.len(), 1);
assert_eq!(
clusterroles[0],
cluster_roles[0],
KubeClusterRoles {
name: "admin".into(),
age: utils::to_age(Some(&get_time("2021-12-14T11:04:22Z")), Utc::now()),
Expand All @@ -118,12 +158,12 @@ mod tests {

#[test]
fn test_role_binding_from_rbac_api() {
let (rolebindings, rolebindings_list): (Vec<KubeRoleBindings>, Vec<_>) =
let (role_bindings, rolebindings_list): (Vec<KubeRoleBindings>, Vec<_>) =
convert_resource_from_file("role_bindings");

assert_eq!(rolebindings.len(), 1);
assert_eq!(role_bindings.len(), 1);
assert_eq!(
rolebindings[0],
role_bindings[0],
KubeRoleBindings {
namespace: "default".to_string(),
name: "kiali".into(),
Expand All @@ -133,4 +173,21 @@ mod tests {
}
)
}

#[test]
fn test_cluster_role_bindings_from_rbac_api() {
let (cluster_role_binding, cluster_role_bindings_list): (Vec<KubeClusterRoleBinding>, Vec<_>) =
convert_resource_from_file("clusterrole_binding");

assert_eq!(cluster_role_binding.len(), 2);
assert_eq!(
cluster_role_binding[0],
KubeClusterRoleBinding {
name: "admin-user".into(),
role: "ClusterRole/cluster-admin".into(),
age: utils::to_age(Some(&get_time("2022-03-02T16:50:53Z")), Utc::now()),
k8s_obj: cluster_role_bindings_list[0].clone(),
}
)
}
}
20 changes: 18 additions & 2 deletions src/handlers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ async fn handle_route_events(key: Key, app: &mut App) {
}
}
ActiveBlock::ClusterRoles => {
if let Some(res) = handle_block_action(key, &mut app.data.clusterroles) {
if let Some(res) = handle_block_action(key, &mut app.data.cluster_roles) {
let _ok = handle_describe_decode_or_yaml_action(
key,
app,
Expand All @@ -505,6 +505,21 @@ async fn handle_route_events(key: Key, app: &mut App) {
.await;
}
}
ActiveBlock::ClusterRoleBinding => {
if let Some(res) = handle_block_action(key, &mut app.data.cluster_role_binding) {
let _ok = handle_describe_decode_or_yaml_action(
key,
app,
&res,
IoCmdEvent::GetDescribe {
kind: "clusterrolebinding".to_owned(),
value: res.name.to_owned(),
ns: None,
},
)
.await;
}
}
ActiveBlock::Contexts | ActiveBlock::Utilization | ActiveBlock::Help => { /* Do nothing */ }
}
}
Expand Down Expand Up @@ -570,7 +585,8 @@ async fn handle_block_scroll(app: &mut App, up: bool, is_mouse: bool, page: bool
ActiveBlock::StorageClasses => app.data.storage_classes.handle_scroll(up, page),
ActiveBlock::Roles => app.data.roles.handle_scroll(up, page),
ActiveBlock::RoleBindings => app.data.role_bindings.handle_scroll(up, page),
ActiveBlock::ClusterRoles => app.data.clusterroles.handle_scroll(up, page),
ActiveBlock::ClusterRoles => app.data.cluster_roles.handle_scroll(up, page),
ActiveBlock::ClusterRoleBinding => app.data.cluster_role_binding.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
13 changes: 11 additions & 2 deletions src/network/kube_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use crate::app::{
pods::KubePod,
replicasets::KubeReplicaSet,
replication_controllers::KubeReplicationController,
roles::{KubeClusterRoles, KubeRoleBindings, KubeRoles},
roles::{KubeClusterRoleBinding, KubeClusterRoles, KubeRoleBindings, KubeRoles},
secrets::KubeSecret,
statefulsets::KubeStatefulSet,
storageclass::KubeStorageClass,
Expand Down Expand Up @@ -333,7 +333,16 @@ impl<'a> Network<'a> {
.await;

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

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

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

/// calls the kubernetes API to list the given resource for either selected namespace or all namespaces
Expand Down
4 changes: 4 additions & 0 deletions src/network/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ pub enum IoEvent {
GetRoles,
GetRoleBindings,
GetClusterRoles,
GetClusterRoleBinding,
GetMetrics,
RefreshClient,
}
Expand Down Expand Up @@ -170,6 +171,9 @@ impl<'a> Network<'a> {
IoEvent::GetClusterRoles => {
self.get_cluster_roles().await;
}
IoEvent::GetClusterRoleBinding => {
self.get_cluster_role_binding().await;
}
};

let mut app = self.app.lock().await;
Expand Down
Loading

0 comments on commit 00646b7

Please sign in to comment.