Skip to content

Commit

Permalink
Merge pull request #6 from maheshrayas/code-cleanup
Browse files Browse the repository at this point in the history
cleanup: use traits for method implementation
  • Loading branch information
maheshrayas authored Apr 20, 2022
2 parents 2cd4e39 + 009e6ee commit 43aae3c
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 100 deletions.
12 changes: 12 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ openssl = { version = "0.10", features = ["vendored"] }
csv="1.1.6"
jwalk = "0.6.0"
rayon ="1.5.1"
async-trait = "0.1.53"
157 changes: 88 additions & 69 deletions src/cluster.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::utils::{ClusterOP, JsonDetails, TableDetails};
use crate::utils::{ClusterOP, Finder, JsonDetails, TableDetails};
use anyhow::Result;
use kube::{
api::{Api, DynamicObject, ResourceExt},
Expand All @@ -7,85 +7,104 @@ use kube::{
Client,
};
use log::info;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::sync::Arc;
use tokio::task::spawn;
use async_trait::async_trait;

pub(crate) async fn get_cluster_resources(
version: &str,
val: Vec<Value>,
) -> Result<Vec<TableDetails>> {
let client = Client::try_default().await?;
let current_config = kube::config::Kubeconfig::read().unwrap();
info!(
"Connected to cluster {:?}",
current_config.current_context.unwrap()
);
info!("Target apiversions v{}", version);
let join_handle: ClusterOP = val
.into_iter()
.map(|resource| {
let arc_client = Arc::new(client.clone());
let client_clone = Arc::clone(&arc_client);
spawn(async move {
let mut temp_table: Vec<TableDetails> = vec![];
let kind = resource["kind"].as_str().unwrap().to_string();
let group = resource["group"].as_str().unwrap().to_string();
let version = resource["version"].as_str().unwrap().to_string();
let removed = resource["removed"].as_str().unwrap().to_string();
let gvk = GroupVersionKind::gvk(&group, &version, &kind);
let (ar, _) = pinned_kind(&(*client_clone).clone(), &gvk).await?;
let api: Api<DynamicObject> = Api::all_with((*client_clone).clone(), &ar);
let list = if let Ok(list) = api.list(&Default::default()).await {
list
} else {
return Ok(temp_table);
};
#[derive(Serialize, Deserialize, Default, Debug)]
pub(crate) struct Cluster {
version: String,
deprecated_api_result: Vec<Value>,
}

for item in list.items {
let name = item.name();
let ns = item.to_owned().metadata.namespace.unwrap_or_default();
if removed.eq("true") {
temp_table.push(TableDetails {
kind: ar.kind.to_string(),
namespace: ns,
name,
supported_api_version: "REMOVED".to_string(),
deprecated_api_version: "REMOVED".to_string(),
});
impl<'a> Cluster {
pub(crate) async fn new(version: String) -> anyhow::Result<Cluster> {
Ok(Cluster {
version: version.to_owned(),
deprecated_api_result: Self::get_deprecated_api(&version).await?,
})
}
}

#[async_trait]
impl Finder for Cluster {
async fn find_deprecated_api(&self) -> Result<Vec<TableDetails>> {
let client = Client::try_default().await?;
let current_config = kube::config::Kubeconfig::read().unwrap();
info!(
"Connected to cluster {:?}",
current_config.current_context.unwrap()
);
info!("Target apiversions v{}", &self.version);
let m = self.deprecated_api_result.to_owned();
let join_handle: ClusterOP = m
.into_iter()
.map(|resource| {
let arc_client = Arc::new(client.clone());
let client_clone = Arc::clone(&arc_client);
let resource = Arc::clone(&Arc::new(resource));
spawn(async move {
let mut temp_table: Vec<TableDetails> = vec![];
let kind = resource["kind"].as_str().unwrap().to_string();
let group = resource["group"].as_str().unwrap().to_string();
let version = resource["version"].as_str().unwrap().to_string();
let removed = resource["removed"].as_str().unwrap().to_string();
let gvk = GroupVersionKind::gvk(&group, &version, &kind);
let (ar, _) = pinned_kind(&(*client_clone).clone(), &gvk).await?;
let api: Api<DynamicObject> = Api::all_with((*client_clone).clone(), &ar);
let list = if let Ok(list) = api.list(&Default::default()).await {
list
} else {
let annotations = item.annotations();
let last_applied_apiversion = if let Some(last_applied) =
annotations.get("kubectl.kubernetes.io/last-applied-configuration")
{
let m: JsonDetails = serde_json::from_str(last_applied)?;
Some(m.api_version)
return Ok(temp_table);
};

for item in list.items {
let name = item.name();
let ns = item.to_owned().metadata.namespace.unwrap_or_default();
if removed.eq("true") {
temp_table.push(TableDetails {
kind: ar.kind.to_string(),
namespace: ns,
name,
supported_api_version: "REMOVED".to_string(),
deprecated_api_version: "REMOVED".to_string(),
});
} else {
None
};
let annotations = item.annotations();
let last_applied_apiversion = if let Some(last_applied) =
annotations.get("kubectl.kubernetes.io/last-applied-configuration")
{
let m: JsonDetails = serde_json::from_str(last_applied)?;
Some(m.api_version)
} else {
None
};

if let Some(ls_app_ver) = last_applied_apiversion {
let supported_version = format!("{}/{}", &group, &version);
if !ls_app_ver.eq(&supported_version) {
let t = TableDetails {
kind: ar.kind.to_string(),
namespace: ns,
name,
supported_api_version: supported_version,
deprecated_api_version: ls_app_ver,
};
temp_table.push(t);
if let Some(ls_app_ver) = last_applied_apiversion {
let supported_version = format!("{}/{}", &group, &version);
if !ls_app_ver.eq(&supported_version) {
let t = TableDetails {
kind: ar.kind.to_string(),
namespace: ns,
name,
supported_api_version: supported_version,
deprecated_api_version: ls_app_ver,
};
temp_table.push(t);
}
}
}
}
}
Ok(temp_table)
Ok(temp_table)
})
})
})
.collect();
let mut v: Vec<TableDetails> = vec![];
for task in join_handle {
v.append(&mut task.await?.unwrap());
.collect();
let mut v: Vec<TableDetails> = vec![];
for task in join_handle {
v.append(&mut task.await?.unwrap());
}
Ok(v)
}
Ok(v)
}
33 changes: 28 additions & 5 deletions src/file.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::utils::TableDetails;
use crate::utils::{TableDetails,Finder};
use jwalk::{Parallelism, WalkDir};
use rayon::iter::ParallelBridge;
use rayon::prelude::ParallelIterator;
Expand All @@ -7,10 +7,32 @@ use std::fs::File;
use std::io::Read;
use std::sync::mpsc::{channel, Sender};
use yaml_rust::YamlLoader;
use async_trait::async_trait;
use serde::{Deserialize, Serialize};

pub(crate) fn search_files(t: Vec<Value>, loc: String) -> Vec<TableDetails> {
#[derive(Serialize, Deserialize, Default, Debug)]
pub(crate) struct FileSystem {
version: String,
file_dir: String,
deprecated_apis: Vec<Value>,

}

impl<'a> FileSystem {
pub(crate) async fn new(file_dir: String, version: String) -> anyhow::Result<FileSystem> {
Ok(FileSystem {
file_dir,
version:version.to_owned(),
deprecated_apis: Self::get_deprecated_api(&version).await?,
})
}
}

#[async_trait]
impl<'a> Finder for FileSystem {
async fn find_deprecated_api(&self) -> anyhow::Result<Vec<TableDetails>> {
let (sender, receiver) = channel();
WalkDir::new(loc)
WalkDir::new(&self.file_dir)
.parallelism(Parallelism::RayonNewPool(0))
.into_iter()
.par_bridge()
Expand All @@ -30,7 +52,7 @@ pub(crate) fn search_files(t: Vec<Value>, loc: String) -> Vec<TableDetails> {
// TODO: use combinators
for doc in docs {
if let Some(mut api_version) = doc["apiVersion"].as_str() {
for z in t.iter() {
for z in self.deprecated_apis.iter() {
if z["kind"]
.as_str()
.unwrap()
Expand Down Expand Up @@ -102,5 +124,6 @@ pub(crate) fn search_files(t: Vec<Value>, loc: String) -> Vec<TableDetails> {
};
temp_table.push(t);
}
temp_table
Ok(temp_table)
}
}
29 changes: 14 additions & 15 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use comfy_table::Table;
use file::search_files;
use utils::{generate_csv_header, Deprecated, Output, Scrape};
use file::{FileSystem};
use utils::{generate_csv_header, Output, Scrape, Finder};
mod cluster;
mod file;
mod utils;
use crate::cluster::get_cluster_resources;
use crate::utils::{generate_table_header, init_logger, ClusterOP, VecTableDetails};
use crate::cluster::Cluster;
use crate::utils::{generate_table_header, init_logger};
use clap::Parser;
use log::info;

Expand Down Expand Up @@ -40,10 +40,10 @@ impl Sunset {
async fn main() -> anyhow::Result<()> {
let cli = Sunset::parse();
// You can check the value provided by positional arguments, or option arguments
let version = if let Some(version) = cli.target_version.as_deref() {
version
let version: String = if let Some(version) = &cli.target_version{
version.to_string()
} else {
"1.16"
"1.16".to_string()
};

match cli.debug {
Expand All @@ -55,15 +55,13 @@ async fn main() -> anyhow::Result<()> {

init_logger();

let val = Deprecated::get_apiversion(format!("v{}", version).as_str())
.await?
.as_array()
.unwrap()
.to_owned();


match cli.check_scrape_type() {
Scrape::Cluster => {
let x = utils::VecTableDetails(get_cluster_resources(version, val).await?);
let c = Cluster::new(version).await?;
println!("hello");
let x = utils::VecTableDetails(c.find_deprecated_api().await?);
match cli.output {
Output::Csv => {
let mut wtr = csv::Writer::from_path("./deprecated-list.csv")?;
Expand All @@ -87,7 +85,8 @@ async fn main() -> anyhow::Result<()> {
}
}
Scrape::Dir(loc) => {
let x: VecTableDetails = utils::VecTableDetails(search_files(val, loc));
let c = FileSystem::new(loc, version).await?;
let x = utils::VecTableDetails(c.find_deprecated_api().await?);
match cli.output {
Output::Csv => {
let mut wtr = csv::Writer::from_path("./deprecated-list.csv")?;
Expand All @@ -110,6 +109,6 @@ async fn main() -> anyhow::Result<()> {
}
}
}
}
};
Ok(())
}
27 changes: 16 additions & 11 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::{fs::File, io::Write};
use tokio::task::JoinHandle;
use async_trait::async_trait;

pub(crate) type ClusterOP = Vec<JoinHandle<Result<Vec<TableDetails>>>>;

Expand Down Expand Up @@ -82,17 +83,6 @@ pub(crate) struct Deprecated {
pub(crate) apis: serde_json::Value,
}

impl Deprecated {
pub(crate) async fn get_apiversion(version: &str) -> Result<Value> {
let url = format!(
"https://raw.githubusercontent.com/maheshrayas/k8s_deprecated_api/main/{}/data.json",
version
);
let x: Value = reqwest::get(url).await?.json().await?;
Ok(x)
}
}

pub(crate) fn init_logger() {
let env = Env::default()
.filter("RUST_LOG")
Expand Down Expand Up @@ -122,3 +112,18 @@ pub(crate) enum Scrape {
Cluster,
Dir(String),
}


#[async_trait]
pub(crate) trait Finder {
async fn find_deprecated_api(&self) -> Result<Vec<TableDetails>>;
async fn get_deprecated_api(version:&String) -> anyhow::Result<Vec<Value>> {

let url = format!(
"https://raw.githubusercontent.com/maheshrayas/k8s_deprecated_api/main/v{}/data.json",
version
);
let v: Value = reqwest::get(url).await?.json().await?;
Ok(v.as_array().unwrap().to_owned())
}
}

0 comments on commit 43aae3c

Please sign in to comment.