Compare commits

...

3 Commits

Author SHA1 Message Date
a-Sansara
520345cc06 add missing license 2020-10-12 17:31:00 +02:00
a-Sansara
cdfa16a96b add printscreen 2020-10-12 16:03:29 +02:00
a-Sansara
60f0d9e016 refact + add colorized 2020-10-12 01:34:25 +02:00
10 changed files with 206 additions and 80 deletions

View File

@ -1,9 +1,9 @@
[package] [package]
name = "ykre" name = "ykre"
version = "0.1.0" version = "0.2.0"
authors = ["a-Sansara <dev]at[pluie]dot[org>"] authors = ["a-Sansara <dev]at[pluie]dot[org>"]
edition = "2018" edition = "2018"
description = "Ykre is Yaml Kubernetes Resource Extractor" description = "Ykre stand for Yaml Kubernetes Resource Extractor"
license = "MIT" license = "MIT"
readme = "README.md" readme = "README.md"
keywords = ["cli", "yaml", "kubernetes", "kustomize"] keywords = ["cli", "yaml", "kubernetes", "kustomize"]
@ -13,3 +13,4 @@ categories = ["command-line-utilities"]
[dependencies] [dependencies]
yaml-rust = "0.4" yaml-rust = "0.4"
colored = "2"

25
LICENSE-MIT Normal file
View File

@ -0,0 +1,25 @@
Copyright (c) 2020 pluie.org
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@ -3,15 +3,17 @@
**Ykre** is a small cli program written in rust wich purpose is to extract from a list **Ykre** is a small cli program written in rust wich purpose is to extract from a list
of yaml documents, documents matching a specified condition. **Ykre** goal is to find of yaml documents, documents matching a specified condition. **Ykre** goal is to find
specific Kubernetes Resource from the kustomize output. specific Kubernetes Resource from the kustomize output.
**Ykre** stands for **Y**aml **K**ubernetes **R**esources **E**ctractor. **Ykre** stands for **Y**aml **K**ubernetes **R**esources **E**xtractor.
![ykre](https://www.pluie.org/img/ykre.png)
## Install ## Install
from a debian package : from a debian package :
```  ``` 
wget -q https://github.com/pluie-org/ykre/raw/master/dist/ykre_0.1.0_amd64.deb wget -q https://github.com/pluie-org/ykre/raw/master/dist/ykre_0.2.0_amd64.deb
sudo apt install ./ykre_0.1.0_amd64.deb sudo apt install ./ykre_0.2.0_amd64.deb
``` ```
via Cargo via Cargo
@ -25,7 +27,7 @@ wget -q -O - https://github.com/pluie-org/ykre/raw/master/install.sh | sh
ykre SEARCH [DEF] ykre SEARCH [DEF]
``` ```
## examples ## Examples
display content of the kubernetes resource 'myResourceName' display content of the kubernetes resource 'myResourceName'
``` ```

Binary file not shown.

BIN
dist/ykre_0.2.0_amd64.deb vendored Normal file

Binary file not shown.

View File

@ -1,29 +1,8 @@
extern crate yaml_rust; extern crate yaml_rust;
extern crate colored;
pub mod ykre; pub mod ykre;
use std::io; fn main() -> std::io::Result<()> {
use std::panic; ykre::run()
const PANIC_BYPASS_FILE : &str = "src/ykre/pipin.rs";
const PANIC_BYPASS_LINE : u32 = 9;
fn main() -> io::Result<()> {
panic::set_hook(Box::new(|_info| {
let mut bypass :bool = false;
if let Some(location) = &_info.location() {
bypass = location.file() == PANIC_BYPASS_FILE && location.line() == PANIC_BYPASS_LINE;
}
if !bypass {
//~ println!("{:?}", &_info);
if let Some(s) = &_info.payload().downcast_ref::<&str>() {
if s.len() > 1 {
println!("{}", s);
}
}
}
}));
ykre::run();
Ok(())
} }

View File

@ -1,56 +1,52 @@
mod yaml; mod yaml;
mod pipin; mod pipin;
mod app; mod app;
mod echo;
mod color;
pub use self::yaml::YamlDocument; pub use self::yaml::YamlDocument;
pub use self::pipin::{spawn_stdin, sleep}; pub use self::pipin::*;
pub use self::app::{run}; pub use self::echo::*;
pub use self::color::*;
pub use self::app::run;
const YKRE_LIMIT_ATTEMPT : u64 = 900; const BG : Rgb = Rgb { r: 30, g: 85, b:125 };
const YKRE_SLEEP_START : u64 = 50; const CSEP : Rgb = Rgb { r: 30, g: 85, b:125 };
const YKRE_SLEEP_DATA : u64 = 1; const CTITLE : Rgb = Rgb { r:255, g:220, b:190 };
const YKRE_SLEEP_NODATA : u64 = 1; const CTITLESEP : Rgb = Rgb { r:255, g:175, b: 35 };
const YKRE_DEFAULT_DEF : &str = "metadata.name"; const CKEY1 : Rgb = Rgb { r: 23, g:141, b: 84 };
const YKRE_ERROR_NOTFOUND : &str = r" const CVAL1 : Rgb = Rgb { r:149, g:197, b:157 };
:: Ykre :: const CKEY2 : Rgb = Rgb { r:237, g:214, b:140 };
const CVAL2 : Rgb = Rgb { r:238, g:194, b: 55 };
error : no match found for specified pattern const CTEXT : Rgb = Rgb { r:190, g:162, b:216 };
"; const CPROG : Rgb = Rgb { r:255, g:255, b:255 };
const YKRE_ERROR_INVALID : &str = r" const COPTSEP : Rgb = Rgb { r:255, g:151, b: 75 };
:: Ykre :: //~ const COPT : Rgb = Rgb { r: 23, g:141, b: 84 };
const CARG : Rgb = Rgb { r: 90, g:205, b:255 };
error : invalid parameter. type ykre for usage const CUSAGE : Rgb = Rgb { r:238, g:194, b: 55 };
"; const CSTR : Rgb = Rgb { r: 66, g:135, b: 99 };
const YKRE_ERROR_NOPIPE : &str = r" const CCOM : Rgb = Rgb { r:105, g:103, b:149 };
:: Ykre :: const CERR : Rgb = Rgb { r:175, g: 37, b: 21 };
const CERRMSG : Rgb = Rgb { r:210, g: 99, b: 86 };
error : you must send data using pipe
";
const YKRE_HELP : &str = r"
-----------------------------------------------------------------------------------
:: Ykre :: v0.1 license : MIT - author : a-Sansara
-----------------------------------------------------------------------------------
const WIDTH : usize = 82;
const PANIC_BYPASS_LINE : u32 = 9;
const PANIC_BYPASS_FILE : &str = "src/ykre/pipin.rs";
const YKRE_AUTHOR : &str = "a-Sansara";
const YKRE_VERSION : &str = "0.2";
const YKRE_LICENSE : &str = "MIT";
const YKRE_NAME : &str = "Ykre";
const YKRE_DEFAULT_DEF : &str = "metadata.name";
const YKRE_LIMIT_ATTEMPT : u64 = 1500;
const YKRE_SLEEP_START : u64 = 50;
const YKRE_SLEEP_DATA : u64 = 1;
const YKRE_SLEEP_NODATA : u64 = 1;
const YKRE_ERROR_NOTFOUND : &str = "no match found for specified pattern";
const YKRE_ERROR_INVALID : &str = "invalid parameter. Type ykre for help";
const YKRE_ERROR_NOPIPE : &str = "you must send data using pipe. Type ykre for help";
const YKRE_DESCRIPTION : &str = r"
Ykre is a small program written in `rust` wich purpose is to extract from a list Ykre is a small program written in `rust` wich purpose is to extract from a list
of yaml documents, documents matching a specified condition. Ykre goal is to find of yaml documents, documents matching a specified condition. Ykre goal is to find
specific Kubernetes Resource from the kustomize output. specific Kubernetes Resource from the kustomize output.
Ykre stands for Yaml Kubernetes Resources Ectractor. Ykre stands for Yaml Kubernetes Resources Extractor.
Usage :
ykre SEARCH [DEF]
you MUST use pipe with ykre command
SEARCH - value of kubernetes resource name
DEF - the yaml node to look for
(default : 'metadata.name', dot is the separator for embed nodes)
ex :
# display content of the kubernetes resource 'myResourceName'
cat kubresources.yaml | ykre 'myResourceName'
# write content of the kubernetes resource 'pv-dump' into a file
kustomize build ./config/volumes/local | ykre 'pv-dump' > ./tmp.yaml
# retriew kubernetes pv resources matching 2Gi disk capacity
kustomize build ./config/volumes/dev | ykre 2Gi spec.capacity.storage
"; ";

View File

@ -1,5 +1,6 @@
use std::panic; use std::panic;
use std::env; use std::env;
use std::io;
use std::sync::mpsc::TryRecvError; use std::sync::mpsc::TryRecvError;
use crate::ykre::*; use crate::ykre::*;
@ -43,11 +44,15 @@ pub fn get_data(buf :&mut String, limit :u32) -> bool {
return has_data return has_data
} }
pub fn run() { pub fn run() -> io::Result<()> {
set_panic();
let args: Vec<String> = env::args().collect(); let args: Vec<String> = env::args().collect();
if args.len() == 1 { if args.len() == 1 {
println!("{}", YKRE_HELP); title(YKRE_NAME, YKRE_VERSION, YKRE_LICENSE, YKRE_AUTHOR);
return description(YKRE_DESCRIPTION);
usage();
example();
return Ok(());
} }
else if args.len() > 1 && args.len() <= 3 { else if args.len() > 1 && args.len() <= 3 {
@ -59,9 +64,32 @@ pub fn run() {
}; };
let limit : u32 = env::var("YKRE_LIMIT_ATTEMPT").unwrap_or(format!("{}", YKRE_LIMIT_ATTEMPT).to_owned()).parse::<u32>().unwrap(); let limit : u32 = env::var("YKRE_LIMIT_ATTEMPT").unwrap_or(format!("{}", YKRE_LIMIT_ATTEMPT).to_owned()).parse::<u32>().unwrap();
if get_data(&mut buf, limit) { if get_data(&mut buf, limit) {
return find(search, def, buf); find(search, def, buf);
return Ok(());
} }
panic!(YKRE_ERROR_NOPIPE) panic!(YKRE_ERROR_NOPIPE)
} }
panic!(YKRE_ERROR_INVALID) panic!(YKRE_ERROR_INVALID)
} }
pub fn set_panic() {
panic::set_hook(Box::new(|_info| {
let mut bypass :bool = false;
if let Some(location) = &_info.location() {
bypass = location.file() == PANIC_BYPASS_FILE && location.line() == PANIC_BYPASS_LINE;
}
if !bypass {
//~ println!("{:?}", &_info);
if let Some(s) = &_info.payload().downcast_ref::<&str>() {
if s.len() > 1 {
title(YKRE_NAME, YKRE_VERSION, YKRE_LICENSE, YKRE_AUTHOR);
perror(s);
if *s != &YKRE_ERROR_NOTFOUND {
usage();
println!("");
}
}
}
}
}));
}

19
src/ykre/color.rs Normal file
View File

@ -0,0 +1,19 @@
use colored::*;
pub struct Rgb {
pub r: u8,
pub g: u8,
pub b: u8,
}
impl Rgb {
pub fn new(r: u8, g: u8, b: u8) -> Self {
Self { r, g, b }
}
pub fn fg(self, label: &str) -> ColoredString {
label.truecolor(self.r, self.g, self.b)
}
pub fn bg(self, label: &str) -> ColoredString {
label.on_truecolor(self.r, self.g, self.b)
}
}

76
src/ykre/echo.rs Normal file
View File

@ -0,0 +1,76 @@
use crate::ykre::*;
use colored::*;
use std::borrow::Cow;
pub fn title(label :&str, version :&str, license: &str, author :&str) {
let space = 42+version.len()+label.len()+license.len()+author.len();
let sep = format!("{}", CSEP.fg(&"".repeat(WIDTH+1)));
let titlesep = CTITLESEP.fg(" :: ");
let ptitle = BG.bg(&format!("{}{}{}", titlesep, CTITLE.fg(label), titlesep)).bold();
println!("{}" , sep);
print! (" {} " , ptitle);
print! ("{}" , keyval("version", version, CKEY1, CVAL1).bold());
print! ("{}" , " ".repeat(WIDTH-space));
print! ("{} " , keyval("license", license, CKEY1, CVAL1).bold());
println!("{}" , keyval("author", author, CKEY2, CVAL2).bold());
println!("{}" , sep);
}
pub fn keyval (key :&str, val :&str, ck : Rgb, cv : Rgb) -> Cow<'static, str> {
format!("{} {}", ck.fg(&format!("{} :", key)), cv.fg(val)).into()
}
pub fn description(description :&str) {
println!(" {}", CTEXT.fg(description));
}
pub fn usage() {
let space_arg : usize = 11;
let arg1 : &str = "SEARCH";
let arg2 : &str = "DEF";
println!(" {} :", CUSAGE.fg("Usage").bold());
println!("");
println!(" {}", format!("{} {} {}{}{}",
CPROG.fg(&YKRE_NAME.to_lowercase()),
CARG.fg(&arg1),
COPTSEP.fg("["),
CARG.fg(&arg2),
COPTSEP.fg("]")
).bold());
println!("");
println!(" {}", CTEXT.fg("you MUST use pipe with ykre command"));
println!("");
print! ("{}{} : ", " ".repeat(space_arg-arg1.len()), CARG.fg(arg1).bold());
println!("{}" , CTEXT.fg("value of matching yaml node (kubernetes resource name)"));
println!("");
print! ("{}{} : ", " ".repeat(space_arg-arg2.len()), CARG.fg(arg2).bold());
println!("{}" , CTEXT.fg("the yaml node to look for"));
println!("{}{}" , " ".repeat(space_arg+3), CTEXT.fg("(default : 'metadata.name', dot is the separator for embed nodes)"));
}
pub fn example() {
println!("");
println!(" {} :" , CUSAGE.fg("Examples").bold());
println!("");
println!(" {}", CCOM.fg("# display content of the kubernetes resource 'myResourceName'"));
print! (" {}", format!("{} {} {}", CPROG.fg("cat"), CARG.fg("'./kubresources.yaml'"), COPTSEP.fg("|")).bold());
println!(" {}" , format!("{} {}" , CPROG.fg("ykre"), CARG.fg("'myResourceName'")).bold());
println!("");
println!(" {}", CCOM.fg("# write content of the kubernetes resource 'pv-dump' into a file"));
print! (" {}", format!("{} {} {} {}", CPROG.fg("kustomize"), CARG.fg("build"), CARG.fg("'./config/volumes/local'"), COPTSEP.fg("|")).bold());
println!(" {}" , format!("{} {} {} {}", CPROG.fg("ykre"), CARG.fg("'pv-dump'"), COPTSEP.fg(">"), CSTR.fg("./tmp.yaml")).bold());
println!("");
println!(" {}", CCOM.fg("# retriew kubernetes pv resources matching 2Gi disk capacity"));
print! (" {}", format!("{} {} {} {}", CPROG.fg("kustomize"), CARG.fg("build"), CARG.fg("'./config/volumes/dev'"), COPTSEP.fg("|")).bold());
println!(" {}" , format!("{} {} {}" , CPROG.fg("ykre"), CARG.fg("'2Gi'"), CARG.fg("'spec.capacity.storage'")).bold());
println!("");
}
pub fn perror(msg: &str) {
println!("");
println!(" {} : {}", format!("{}", CERR.fg("error")).bold(), CERRMSG.fg(msg));
println!("");
}