Compare commits

...

3 Commits

Author SHA1 Message Date
Nikolai Rodionov
743b8f0d25
Start generating a deployment 2023-11-07 03:28:13 +01:00
Nikolai Rodionov
398cd4162e
Start generating a deployment 2023-11-06 21:45:48 +01:00
Nikolai Rodionov
27b5b0c02d
Nothing really 2023-11-05 21:36:05 +01:00
9 changed files with 2194 additions and 0 deletions

5
.gitignore vendored
View File

@ -21,3 +21,8 @@
# Go workspace file # Go workspace file
go.work go.work
# Added by cargo
/target

1923
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

29
Cargo.toml Normal file
View 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
View 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(())
}

View 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

View File

@ -0,0 +1,4 @@
kind: Deployment
replicas: 1
containers:
- image:

54
proto/shoebill.proto Normal file
View 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
View 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
View 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(())
}