Compare commits
3 Commits
another-id
...
try-rust
Author | SHA1 | Date | |
---|---|---|---|
743b8f0d25 | |||
398cd4162e | |||
27b5b0c02d |
5
.gitignore
vendored
5
.gitignore
vendored
@ -21,3 +21,8 @@
|
||||
# Go workspace file
|
||||
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"
|
||||
|
@ -1,3 +1,3 @@
|
||||
# giops
|
||||
|
||||
A templater for the gitops setup
|
||||
A templater for the gitops setup
|
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(())
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
metadata:
|
||||
name: db-operator
|
||||
version: 1.0.0
|
||||
|
||||
image:
|
||||
tag: 1.15.3
|
||||
repository: db-operator
|
@ -1,7 +0,0 @@
|
||||
workload:
|
||||
kind: Deployment
|
||||
replicas: 1
|
||||
containers:
|
||||
- name: controller
|
||||
image: {{ .Image }}
|
||||
imagePullPolicy: Always
|
@ -1,8 +1,13 @@
|
||||
---
|
||||
metadata:
|
||||
name: vaultwarden
|
||||
version: 1.0.0
|
||||
|
||||
spec:
|
||||
image:
|
||||
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:
|
16
go.mod
16
go.mod
@ -1,16 +0,0 @@
|
||||
module git.badhouseplants.net/allanger/shoebill
|
||||
|
||||
go 1.21.3
|
||||
|
||||
require (
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/stretchr/testify v1.8.4
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
20
go.sum
20
go.sum
@ -1,20 +0,0 @@
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
@ -1,3 +0,0 @@
|
||||
package bundler
|
||||
|
||||
func Build()
|
@ -1,13 +0,0 @@
|
||||
package controller
|
||||
|
||||
type Client struct {}
|
||||
|
||||
func (cli *Client) Install () error {
|
||||
// Generate the package from templates
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cli *Client) Tempalte() error {
|
||||
return nil
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
package templater
|
||||
|
||||
// Datasource for template rendering
|
||||
type TemplateDS struct {
|
||||
}
|
||||
|
||||
func (tds *TemplateDS) Render() {
|
||||
|
||||
}
|
@ -1 +0,0 @@
|
||||
package templater_test
|
@ -1,50 +0,0 @@
|
||||
// It's called bundle to avoid a conflict with the GO package
|
||||
package bundle
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"git.badhouseplants.net/allanger/shoebill/pkg/types/metadata"
|
||||
"git.badhouseplants.net/allanger/shoebill/pkg/types/workload"
|
||||
"github.com/sirupsen/logrus"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
type Bundle struct {
|
||||
// A bundle's metadata
|
||||
Metadata *metadata.Metadata `yaml:"metadata"`
|
||||
BundlePath string `yaml:"-"`
|
||||
Workload *workload.Workload `yaml:"-"`
|
||||
}
|
||||
|
||||
type Image struct {
|
||||
Repository string
|
||||
Tag string
|
||||
}
|
||||
|
||||
// Init a new bundle struct from the file
|
||||
func ReadFromFile(filePath string) (*Bundle, error) {
|
||||
var bundle Bundle
|
||||
logrus.Infof("readig the bundle file: %s", filePath)
|
||||
bundleFile, err := os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := yaml.Unmarshal(bundleFile, &bundle); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bundle.BundlePath = filepath.Dir(filePath)
|
||||
return &bundle, nil
|
||||
}
|
||||
|
||||
func (bundle *Bundle) Bootstrap() (err error) {
|
||||
// TODO: It's ugly as hell
|
||||
workloadFilePath := fmt.Sprintf("%s/bundle/workload.yaml", bundle.BundlePath)
|
||||
bundle.Workload, err = workload.ReadFromFile(workloadFilePath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return nil
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
package bundle_test
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"git.badhouseplants.net/allanger/shoebill/pkg/types/bundle"
|
||||
"git.badhouseplants.net/allanger/shoebill/utils/helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// Test that the file can be read
|
||||
func TestUnitReadValidFile(t *testing.T) {
|
||||
f := helpers.CreateFile(t)
|
||||
defer os.Remove(f.Name())
|
||||
|
||||
const validFile = `---
|
||||
metadata:
|
||||
name: db-operator
|
||||
version: 1.0.0
|
||||
maintainer:
|
||||
name: allanger
|
||||
email: allanger@badhouseplants.net
|
||||
website: https://badhouseplants.net
|
||||
`
|
||||
helpers.FillFile(t, f, validFile)
|
||||
|
||||
bundle, err := bundle.ReadFromFile(f.Name())
|
||||
|
||||
// Check that there is no unexpected error
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Check the bundle metadata
|
||||
assert.Equal(t, "1.0.0", bundle.Metadata.Version)
|
||||
assert.Equal(t, "db-operator", bundle.Metadata.Name)
|
||||
|
||||
assert.Equal(t, "allanger", bundle.Metadata.Maintainer.Name)
|
||||
assert.Equal(t, "allanger@badhouseplants.net", bundle.Metadata.Maintainer.Email)
|
||||
assert.Equal(t, "https://badhouseplants.net", bundle.Metadata.Maintainer.Website)
|
||||
}
|
||||
|
||||
func TestIntegrationBootstrap(t *testing.T) {
|
||||
bundlePath := "../../../test/test-bundle/bundle.yaml"
|
||||
bundle, err := bundle.ReadFromFile(bundlePath)
|
||||
|
||||
// Check that there is no unexpected error
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Check the bundle file in the test folder to get the actual data
|
||||
assert.Equal(t, "0.0.1", bundle.Metadata.Version)
|
||||
assert.Equal(t, "test-bundle", bundle.Metadata.Name)
|
||||
|
||||
assert.Equal(t, "allanger", bundle.Metadata.Maintainer.Name)
|
||||
assert.Equal(t, "allanger@badhouseplants.net", bundle.Metadata.Maintainer.Email)
|
||||
assert.Equal(t, "https://badhouseplants.net", bundle.Metadata.Maintainer.Website)
|
||||
|
||||
err = bundle.Bootstrap()
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, "Deployment", bundle.Workload.Kind)
|
||||
assert.Equal(t, 1, bundle.Workload.Replicas)
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
package image
|
||||
|
||||
type Image struct {
|
||||
Repository string
|
||||
Tag string
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
package metadata
|
||||
|
||||
type Metadata struct {
|
||||
Name string `yaml:"name"` // -- A name of the bundle
|
||||
Version string `yaml:"version"` // -- The bundle's version
|
||||
Maintainer Maintainer `yaml:"maintainer"` // -- A main maintainer of the package
|
||||
}
|
||||
|
||||
type Maintainer struct {
|
||||
Name string `yaml:"name"` // -- Maintainer's name
|
||||
Email string `yaml:"email"` // -- Maintainer's email
|
||||
Website string `yaml:"website"` // -- Maintainer's website
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
package workload
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
type Workload struct {
|
||||
Kind string
|
||||
Replicas int
|
||||
}
|
||||
|
||||
func ReadFromFile(bundlePath string) (*Workload, error) {
|
||||
var workload Workload
|
||||
logrus.Infof("readig the workload file: %s", bundlePath)
|
||||
bundleFile, err := os.ReadFile(bundlePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := yaml.Unmarshal(bundleFile, &workload); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &workload, nil
|
||||
}
|
||||
|
||||
func (wd *Workload) ValidateKind() error {
|
||||
if wd.Kind == "Deployment" || wd.Kind == "StatefulSet" || wd.Kind == "DaemonSet" {
|
||||
return nil
|
||||
}
|
||||
err := fmt.Errorf("kind is not valid, expect Deployment|StatefulSet|DaemonSet, got %s", wd.Kind)
|
||||
return err
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
package workload_test
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"git.badhouseplants.net/allanger/shoebill/pkg/types/workload"
|
||||
"git.badhouseplants.net/allanger/shoebill/utils/helpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestUnitReadValidFile(t *testing.T) {
|
||||
f := helpers.CreateFile(t)
|
||||
defer os.Remove(f.Name())
|
||||
|
||||
const validFile = `---
|
||||
kind: Deployment
|
||||
replicas: 1
|
||||
containers:
|
||||
- name: controller
|
||||
image: {{ .Image }}
|
||||
imagePullPolicy: Always
|
||||
`
|
||||
helpers.FillFile(t, f, validFile)
|
||||
|
||||
workload, err := workload.ReadFromFile(f.Name())
|
||||
|
||||
// Check that there is no unexpected error
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Check the bundle metadata
|
||||
assert.Equal(t, "Deployment", workload.Kind)
|
||||
assert.Equal(t, 1, workload.Replicas)
|
||||
|
||||
}
|
||||
|
||||
func TestUnitKindValidatorDeployment(t *testing.T) {
|
||||
wd := &workload.Workload{
|
||||
Kind: "Deployment",
|
||||
}
|
||||
err := wd.ValidateKind()
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestUnitKindValidatorStatefulSet(t *testing.T) {
|
||||
wd := &workload.Workload{
|
||||
Kind: "StatefulSet",
|
||||
}
|
||||
err := wd.ValidateKind()
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestUnitKindValidatorDeamonSet(t *testing.T) {
|
||||
wd := &workload.Workload{
|
||||
Kind: "DaemonSet",
|
||||
}
|
||||
err := wd.ValidateKind()
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestUnitKindValidatorInvalid(t *testing.T) {
|
||||
wd := &workload.Workload{
|
||||
Kind: "Invalid",
|
||||
}
|
||||
err := wd.ValidateKind()
|
||||
assert.ErrorContains(t, err, "got Invalid")
|
||||
}
|
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(())
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
metadata:
|
||||
name: test-bundle
|
||||
version: 0.0.1
|
||||
maintainer:
|
||||
name: allanger
|
||||
email: allanger@badhouseplants.net
|
||||
website: https://badhouseplants.net
|
||||
|
||||
spec:
|
||||
image:
|
||||
repository: registry.hub.docker.com/vaultwarden/server
|
||||
tag: 1.29.2
|
@ -1,6 +0,0 @@
|
||||
kind: Deployment
|
||||
replicas: 1
|
||||
containers:
|
||||
- name: controller
|
||||
image: {{ .Image }}
|
||||
imagePullPolicy: Always
|
@ -1,22 +0,0 @@
|
||||
package helpers
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func CreateFile(t *testing.T) *os.File {
|
||||
f, err := os.CreateTemp("", "sample")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
t.Logf("file is created: %s", f.Name())
|
||||
return f
|
||||
}
|
||||
|
||||
func FillFile(t *testing.T, f *os.File, content string) {
|
||||
_, err := f.WriteString(content)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user