Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
743b8f0d25 | ||
|
398cd4162e | ||
|
27b5b0c02d |
5
.gitignore
vendored
5
.gitignore
vendored
@ -21,3 +21,8 @@
|
|||||||
# Go workspace file
|
# Go workspace file
|
||||||
go.work
|
go.work
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Added by cargo
|
||||||
|
|
||||||
|
/target
|
||||||
|
1923
Cargo.lock
generated
Normal file
1923
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
29
Cargo.toml
Normal file
29
Cargo.toml
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
[package]
|
||||||
|
name = "shoebill"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "server"
|
||||||
|
path = "src/server.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "client"
|
||||||
|
path = "src/cli/main.rs"
|
||||||
|
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
tonic = "0.10"
|
||||||
|
prost = "0.12"
|
||||||
|
tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] }
|
||||||
|
clap = { version = "4.4.7", features = ["derive"] }
|
||||||
|
serde_yaml = "0.9.27"
|
||||||
|
serde = "1.0.190"
|
||||||
|
prost-serde = "0.3.0"
|
||||||
|
kube = "0.87.1"
|
||||||
|
k8s-openapi = { version = "0.20.0", features = ["latest"] }
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
tonic-build = "0.10"
|
||||||
|
serde = "1.0.190"
|
||||||
|
|
9
build.rs
Normal file
9
build.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
tonic_build::configure()
|
||||||
|
.type_attribute(
|
||||||
|
".",
|
||||||
|
"#[derive(serde::Deserialize, serde::Serialize)]",
|
||||||
|
)
|
||||||
|
.compile(&["proto/shoebill.proto"], &["proto"])?;
|
||||||
|
Ok(())
|
||||||
|
}
|
13
example/vaultwarden/bundle.yaml
Normal file
13
example/vaultwarden/bundle.yaml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
metadata:
|
||||||
|
name: vaultwarden
|
||||||
|
version: 1.0.0
|
||||||
|
maintainers:
|
||||||
|
- name: allanger
|
||||||
|
email: allanger@badhouseplants.net
|
||||||
|
website: https://badhouseplants.net
|
||||||
|
spec:
|
||||||
|
type: package
|
||||||
|
image:
|
||||||
|
repository: registry.hub.docker.com/vaultwarden/server
|
||||||
|
tag: 1.29.2
|
4
example/vaultwarden/bundle/workload.yaml
Normal file
4
example/vaultwarden/bundle/workload.yaml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
kind: Deployment
|
||||||
|
replicas: 1
|
||||||
|
containers:
|
||||||
|
- image:
|
54
proto/shoebill.proto
Normal file
54
proto/shoebill.proto
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
package shoebill;
|
||||||
|
|
||||||
|
service Repo {
|
||||||
|
rpc Download (Bundle) returns (Bundle);
|
||||||
|
}
|
||||||
|
|
||||||
|
message Bundle {
|
||||||
|
BundleDefinition Definition = 1;
|
||||||
|
BundleType Type = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message BundleDefinition {
|
||||||
|
Metadata Metadata = 1;
|
||||||
|
Spec Spec = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Metadata {
|
||||||
|
string Name = 1;
|
||||||
|
string Version = 2;
|
||||||
|
repeated Maintainer Maintainers = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Spec {
|
||||||
|
string Type = 1;
|
||||||
|
Image Image = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Image {
|
||||||
|
string Repository = 1;
|
||||||
|
string Tag = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum BundleType {
|
||||||
|
TYPE_UNSPECIFIED = 0;
|
||||||
|
TYPE_PACKAGE = 1;
|
||||||
|
TYPE_LIBRARY = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Maintainer {
|
||||||
|
string Name = 1;
|
||||||
|
string Email = 2;
|
||||||
|
string Website = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
message Workload {
|
||||||
|
string Kind = 1;
|
||||||
|
int32 Replicas = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Container {
|
||||||
|
|
||||||
|
}
|
123
src/cli/main.rs
Normal file
123
src/cli/main.rs
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
use std::{error::Error, fs::OpenOptions, str::FromStr, collections::BTreeMap};
|
||||||
|
use clap::{Args, Parser, Subcommand};
|
||||||
|
use k8s_openapi::api::apps::v1::Deployment;
|
||||||
|
use kube::{Client, Api};
|
||||||
|
use shoebill::{BundleDefinition, BundleType, Bundle};
|
||||||
|
|
||||||
|
pub mod shoebill {
|
||||||
|
tonic::include_proto!("shoebill");
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for BundleType {
|
||||||
|
|
||||||
|
type Err = ();
|
||||||
|
|
||||||
|
fn from_str(input: &str) -> Result<BundleType, Self::Err> {
|
||||||
|
match input {
|
||||||
|
"package" => Ok(BundleType::TypePackage),
|
||||||
|
"library" => Ok(BundleType::TypeLibrary),
|
||||||
|
_ => Err(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Parser)]
|
||||||
|
#[command(author, version, about, long_about = None)]
|
||||||
|
#[command(propagate_version = true)]
|
||||||
|
struct Cli {
|
||||||
|
#[command(subcommand)]
|
||||||
|
command: Commands,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Subcommand)]
|
||||||
|
enum Commands {
|
||||||
|
/// Adds files to myapp
|
||||||
|
Install(InstallArgs),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Args)]
|
||||||
|
struct InstallArgs {
|
||||||
|
#[arg(short, long)]
|
||||||
|
path: String,
|
||||||
|
#[arg(short, long)]
|
||||||
|
namespace: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn define_bundle(path: String) -> Result<BundleDefinition, Box<dyn Error>> {
|
||||||
|
let config_res: std::result::Result<BundleDefinition, _>;
|
||||||
|
let f = OpenOptions::new().write(false).read(true).open(path);
|
||||||
|
let f = match f {
|
||||||
|
Ok(file) => file,
|
||||||
|
Err(err) => {
|
||||||
|
return Err(err.into());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
config_res = serde_yaml::from_reader(f);
|
||||||
|
match config_res {
|
||||||
|
Ok(config) => Ok(config),
|
||||||
|
Err(err) => Err(err.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
// First iteration ------------------------------------------------
|
||||||
|
// Install without repository, just a path to a file
|
||||||
|
// ----------------------------------------------------------------
|
||||||
|
// Derive from yaml file
|
||||||
|
let cli = Cli::parse();
|
||||||
|
|
||||||
|
// You can check for the existence of subcommands, and if found use their
|
||||||
|
// matches just as you would the top level cmd
|
||||||
|
|
||||||
|
let definition: BundleDefinition;
|
||||||
|
let mut namespace: String;
|
||||||
|
match &cli.command {
|
||||||
|
Commands::Install(args) => {
|
||||||
|
namespace = args.namespace.clone();
|
||||||
|
match define_bundle(args.path.clone()) {
|
||||||
|
Ok(def) => definition = def,
|
||||||
|
Err(err) => panic!("{}", err),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let r#type = BundleType::from_str(definition.clone().spec.unwrap().r#type.as_str()).unwrap();
|
||||||
|
let bundle = Bundle{definition: Some(definition.clone()), r#type: r#type.into()};
|
||||||
|
let client = Client::try_default().await?;
|
||||||
|
|
||||||
|
let deployment = Deployment {
|
||||||
|
metadata: kube::core::ObjectMeta {
|
||||||
|
annotations: Some(BTreeMap::from([
|
||||||
|
("Mercury".to_string(), "check".to_string()),
|
||||||
|
])),
|
||||||
|
labels: Some(BTreeMap::from([
|
||||||
|
("Mercury".to_string(), "check".to_string()),
|
||||||
|
])),
|
||||||
|
name: Some(bundle.clone().definition.unwrap().metadata.unwrap().name.to_string()),
|
||||||
|
namespace: Some(namespace),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
println!("{:?}", bundle);
|
||||||
|
println!("{:?}", deployment);
|
||||||
|
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
// let mut client = RepoClient::connect("http://[::1]:50051").await?;
|
||||||
|
//
|
||||||
|
// let request = tonic::Request::new(Bundle {
|
||||||
|
// name: "Tonic".into(),
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// let response = client.download(request).await?;
|
||||||
|
//
|
||||||
|
// println!("RESPONSE={:?}", response);
|
||||||
|
//
|
||||||
|
// Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cli init
|
34
src/server.rs
Normal file
34
src/server.rs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
use tonic::{transport::Server, Request, Response, Status};
|
||||||
|
|
||||||
|
use self::shoebill::repo_server::{Repo, RepoServer};
|
||||||
|
use self::shoebill::Bundle;
|
||||||
|
|
||||||
|
pub mod shoebill {
|
||||||
|
tonic::include_proto!("shoebill"); // The string specified here must match the proto package name
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct MyGreeter {}
|
||||||
|
|
||||||
|
#[tonic::async_trait]
|
||||||
|
impl Repo for MyGreeter {
|
||||||
|
async fn download(
|
||||||
|
&self,
|
||||||
|
req: Request<Bundle>,
|
||||||
|
) -> Result<Response<Bundle>, Status> {
|
||||||
|
Ok(Response::new(Bundle::default()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let addr = "[::1]:50051".parse()?;
|
||||||
|
let greeter = MyGreeter::default();
|
||||||
|
|
||||||
|
Server::builder()
|
||||||
|
.add_service(RepoServer::new(greeter))
|
||||||
|
.serve(addr)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user