[feat] add get_erpositories / get_repository_tags method
This commit is contained in:
commit
b2e98a53b9
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/target
|
1
.rustfmt.toml
Normal file
1
.rustfmt.toml
Normal file
@ -0,0 +1 @@
|
||||
tab_spaces = 2
|
1581
Cargo.lock
generated
Normal file
1581
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
16
Cargo.toml
Normal file
16
Cargo.toml
Normal file
@ -0,0 +1,16 @@
|
||||
[package]
|
||||
name = "registry-cleaner"
|
||||
version = "0.1.0"
|
||||
authors = ["Jay <jay@trj.tw>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
args = "2.2.0"
|
||||
getopts = "0.2.21"
|
||||
reqwest = {version = "0.10.8", features =["json", "rustls-tls", "trust-dns", "blocking"]}
|
||||
serde = {version = "1.0.117", features = ["derive"] }
|
||||
serde_json = "1.0.59"
|
||||
tokio = { version = "0.2", features = ["full"] }
|
||||
url = "2.1.1"
|
1
src/api/mod.rs
Normal file
1
src/api/mod.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod registry;
|
51
src/api/registry.rs
Normal file
51
src/api/registry.rs
Normal file
@ -0,0 +1,51 @@
|
||||
use reqwest;
|
||||
use serde::Deserialize;
|
||||
use url::Url;
|
||||
|
||||
pub struct Registry<'a> {
|
||||
pub url: &'a str,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct RepositoryList {
|
||||
pub repositories: Vec<String>,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct RepositoryTags {
|
||||
name: String,
|
||||
tags: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
impl<'a> Registry<'a> {
|
||||
pub async fn get_repositories(&self) -> Result<RepositoryList, Box<dyn std::error::Error>> {
|
||||
let registry_url = Url::parse(self.url).unwrap();
|
||||
let api_url = registry_url.join("/v2/_catalog").unwrap();
|
||||
|
||||
let resp = reqwest::get(api_url)
|
||||
.await?
|
||||
.json::<RepositoryList>()
|
||||
.await?;
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
pub async fn get_repository_tags(
|
||||
&self,
|
||||
repo: &str,
|
||||
) -> Result<RepositoryTags, Box<dyn std::error::Error>> {
|
||||
let registry_url = Url::parse(self.url).unwrap();
|
||||
let api_url = registry_url
|
||||
.join(format!("/v2/{}/tags/list", repo).as_str())
|
||||
.unwrap();
|
||||
|
||||
let resp = reqwest::get(api_url).await?;
|
||||
|
||||
println!("{:?}", resp.headers());
|
||||
|
||||
let data = resp.json::<RepositoryTags>().await?;
|
||||
Ok(data)
|
||||
}
|
||||
}
|
108
src/main.rs
Normal file
108
src/main.rs
Normal file
@ -0,0 +1,108 @@
|
||||
#[allow(dead_code)]
|
||||
extern crate args;
|
||||
extern crate getopts;
|
||||
use args::{Args, ArgsError};
|
||||
// use args::validations::{Order,OrderValidation};
|
||||
use getopts::Occur;
|
||||
use tokio::runtime::Runtime;
|
||||
mod api;
|
||||
|
||||
#[allow(unused)]
|
||||
struct Opts {
|
||||
registry: String,
|
||||
image: String,
|
||||
exclude: Vec<String>,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut rt = Runtime::new().unwrap();
|
||||
|
||||
let input_args = std::env::args().collect::<Vec<String>>();
|
||||
let _parsed = parse(&input_args).unwrap();
|
||||
|
||||
rt.block_on(async {
|
||||
let registry = api::registry::Registry {
|
||||
url: _parsed.registry.as_str(),
|
||||
};
|
||||
let res = registry.get_repositories().await.unwrap();
|
||||
if res.repositories.len() == 0 {
|
||||
return;
|
||||
}
|
||||
println!("response :::: {:?}", res);
|
||||
|
||||
let mut proc_images: Vec<String> = Vec::new();
|
||||
|
||||
if _parsed.image.len() > 0 {
|
||||
proc_images.push(_parsed.image);
|
||||
} else {
|
||||
proc_images = res.repositories.to_owned();
|
||||
}
|
||||
|
||||
println!("proc images ::: {:?}", proc_images);
|
||||
|
||||
for img in proc_images.into_iter() {
|
||||
let _repo_tags = registry.get_repository_tags(img.as_str()).await.unwrap();
|
||||
|
||||
println!("{:?}", _repo_tags);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn parse(input: &Vec<String>) -> Result<Opts, ArgsError> {
|
||||
let mut arg = Args::new("Registry Cleaner", "clean registry images");
|
||||
|
||||
arg.flag("h", "help", "print usage");
|
||||
arg.option(
|
||||
"i",
|
||||
"image",
|
||||
"image name empty is all",
|
||||
"IMAGE",
|
||||
Occur::Optional,
|
||||
Some(String::from("")),
|
||||
);
|
||||
arg.option(
|
||||
"e",
|
||||
"exclude",
|
||||
"exclude tag no delete",
|
||||
"EXCLUDE",
|
||||
Occur::Optional,
|
||||
None,
|
||||
);
|
||||
arg.option(
|
||||
"r",
|
||||
"registry",
|
||||
"registry url",
|
||||
"REGISTRY",
|
||||
Occur::Optional,
|
||||
None,
|
||||
);
|
||||
|
||||
arg.parse(input).unwrap();
|
||||
|
||||
let help: bool = arg.value_of("help").unwrap();
|
||||
if help {
|
||||
let str = arg.full_usage();
|
||||
eprintln!("{}", str);
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
let exclude: Vec<String> = match arg.values_of("exclude") {
|
||||
Ok(strs) => strs,
|
||||
Err(_) => vec![],
|
||||
};
|
||||
|
||||
let image: String = match arg.value_of("image") {
|
||||
Ok(v) => v,
|
||||
Err(_) => String::from(""),
|
||||
};
|
||||
|
||||
let url: String = arg.value_of("registry").unwrap();
|
||||
|
||||
let opts = Opts {
|
||||
image: image.clone(),
|
||||
exclude: exclude.clone(),
|
||||
registry: url,
|
||||
};
|
||||
|
||||
Ok(opts)
|
||||
}
|
Loading…
Reference in New Issue
Block a user