Bläddra i källkod

Initial commit

jamesread 5 år sedan
incheckning
b758e6ec7c
7 ändrade filer med 282 tillägg och 0 borttagningar
  1. 8 0
      Makefile
  2. 36 0
      OliveTin.proto
  3. 54 0
      cmd/OliveTin/main.go
  4. 21 0
      go.mod
  5. 45 0
      pkg/config/config.go
  6. 61 0
      pkg/grpcApi/grpcApi.go
  7. 57 0
      pkg/restApi/restapi.go

+ 8 - 0
Makefile

@@ -0,0 +1,8 @@
+default: 
+	go build -o OliveTin github.com/jamesread/OliveTin/cmd/OliveTin
+
+grpc:
+	protoc -I.:/usr/share/gocode/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis/ --go_out=plugins=grpc:gen/grpc/ OliveTin.proto 
+	protoc -I.:/usr/share/gocode/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis/ --grpc-gateway_out=gen/grpc --grpc-gateway_opt paths=source_relative --grpc-gateway_opt generate_unbound_methods=true OliveTin.proto
+
+.PHONY: grpc

+ 36 - 0
OliveTin.proto

@@ -0,0 +1,36 @@
+syntax = "proto3";
+
+import "google/api/annotations.proto";
+
+message ActionButton {
+	string title = 1;
+	string icon = 2;
+}
+
+message GetButtonsResponse {
+	string title = 1;
+	repeated ActionButton actions = 2;
+}
+
+message GetButtonsRequest {}
+
+message StartActionRequest {
+	string actionName = 1;
+}
+
+message StartActionResponse {}
+
+service OliveTinApi {
+	rpc GetButtons(GetButtonsRequest) returns (GetButtonsResponse) {
+		option (google.api.http) = {
+			get: "/GetButtons"
+		};
+	}
+
+	rpc StartAction(StartActionRequest) returns (StartActionResponse) {
+		option (google.api.http) = {
+			get: "/StartAction"
+		};
+	}
+
+}

+ 54 - 0
cmd/OliveTin/main.go

@@ -0,0 +1,54 @@
+package main
+
+import (
+	log "github.com/sirupsen/logrus"
+
+	restApi "github.com/jamesread/OliveTin/pkg/restApi"
+	grpcApi "github.com/jamesread/OliveTin/pkg/grpcApi"
+
+	config "github.com/jamesread/OliveTin/pkg/config"
+	"github.com/spf13/viper"
+	"os"
+)
+
+var (
+	cfg *config.Config;
+)
+
+func init() {
+	log.Info("OliveTin initializing");
+	log.SetLevel(log.DebugLevel) // Default to debug, to catch cfg issues
+
+	viper.AutomaticEnv();
+	viper.SetConfigType("yaml")
+	viper.AddConfigPath(".")
+	viper.AddConfigPath("/etc/olivetin/")
+
+	if err := viper.ReadInConfig(); err != nil {
+		log.Panicf("Config file error %s", err);
+	};
+
+	cfg = config.DefaultConfig();
+
+	if err := viper.UnmarshalExact(cfg); err != nil {
+		log.Errorf("Config unmarshal error %+v", err)
+		os.Exit(1);
+	}
+
+	log.SetLevel(cfg.GetLogLevel())
+
+	viper.WatchConfig();
+}
+
+func main() {
+	log.WithFields(log.Fields {
+		"listenPortRestActions": cfg.ListenPortRestActions,
+		"listenPortWebUi": cfg.ListenPortWebUi,
+	}).Info("OliveTin started");
+
+	log.Debugf("%+v", cfg)
+
+	go grpcApi.Start()
+
+	restApi.Start();
+}

+ 21 - 0
go.mod

@@ -0,0 +1,21 @@
+module github.com/jamesread/OliveTin
+
+go 1.15
+
+require (
+	github.com/golang/protobuf v1.5.2
+	github.com/grpc-ecosystem/grpc-gateway v1.16.0
+	github.com/grpc-ecosystem/grpc-gateway/v2 v2.3.0
+	github.com/sirupsen/logrus v1.8.1
+	github.com/spf13/pflag v1.0.5 // indirect
+	github.com/spf13/viper v1.7.1
+	github.com/stretchr/testify v1.7.0 // indirect
+	golang.org/x/net v0.0.0-20210119194325-5f4716e94777 // indirect
+	golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c // indirect
+	golang.org/x/text v0.3.5 // indirect
+	golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
+	google.golang.org/genproto v0.0.0-20210224155714-063164c882e6
+	google.golang.org/grpc v1.37.0
+	gopkg.in/yaml.v2 v2.3.0 // indirect
+	gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
+)

+ 45 - 0
pkg/config/config.go

@@ -0,0 +1,45 @@
+package config
+
+import (
+	log "github.com/sirupsen/logrus"
+	"strings"
+)
+
+type ActionButton struct {
+	Title string
+	Icon string
+	Css map[string]string `mapstructure:omitempty`
+}
+
+type Entity struct {
+	Title string
+	Icon string
+	ActionButtons []ActionButton `mapstructure:"actions"`
+	Css map[string]string
+}
+
+type Config struct {
+	ListenPortRestActions int
+	ListenPortWebUi int
+	LogLevel string
+	ActionButtons []ActionButton `mapstructure:"actions"`
+	Entities []Entity `mapstructure:omitempty`
+}
+
+func DefaultConfig() *Config {
+	config := Config{};
+	config.ListenPortRestActions = 1337;
+	config.ListenPortWebUi = 1339;
+	config.LogLevel = "INFO"
+
+	return &config
+}
+
+func (cfg *Config) GetLogLevel() (log.Level) {
+	switch (strings.ToUpper(cfg.LogLevel)) {
+	case "INFO": return log.InfoLevel;
+	case "WARN": return log.WarnLevel;
+	case "DEBUG": return log.DebugLevel;
+	default: return log.DebugLevel; 
+	}
+}

+ 61 - 0
pkg/grpcApi/grpcApi.go

@@ -0,0 +1,61 @@
+package grpcApi;
+
+import (
+	"google.golang.org/grpc"
+	pb "github.com/jamesread/OliveTin/gen/grpc"
+	"fmt"
+	"net"
+	log "github.com/sirupsen/logrus"
+	ctx "context"
+)
+
+type OliveTinApi struct {
+
+}
+
+func (api *OliveTinApi) StartAction(ctx ctx.Context, req *pb.StartActionRequest) (*pb.StartActionResponse, error) {
+	res := &pb.StartActionResponse{}
+
+	log.WithFields(log.Fields{
+		"actionName": req.ActionName,
+	}).Infof("StartAction")
+
+	return res, nil
+}
+
+func (api *OliveTinApi) GetButtons(ctx ctx.Context, req *pb.GetButtonsRequest) (*pb.GetButtonsResponse, error) {
+	res := &pb.GetButtonsResponse{};
+
+	btn1 := pb.ActionButton {
+		Title: "foo",
+		Icon: "&#x1F1E6",
+	};
+
+	btn2 := pb.ActionButton {
+		Title: "bar",
+		Icon: "&#x1F1E6",
+	};
+
+	res.Actions = append(res.Actions, &btn1);
+	res.Actions = append(res.Actions, &btn2);
+
+	return res, nil
+}
+
+func Start() {
+	port := 1337;
+	lis, err := net.Listen("tcp", fmt.Sprintf("0.0.0.0:%d", port));
+
+	if err != nil {
+		log.Fatalf("Failed to listen - %v", err);
+	}
+
+	grpcServer := grpc.NewServer();
+	pb.RegisterOliveTinApiServer(grpcServer, newServer());
+	grpcServer.Serve(lis)
+}
+
+func newServer() (*OliveTinApi) {
+	server := OliveTinApi {};
+	return &server;
+}

+ 57 - 0
pkg/restApi/restapi.go

@@ -0,0 +1,57 @@
+package restApi;
+
+import (
+	"google.golang.org/grpc"
+	"fmt"
+	log "github.com/sirupsen/logrus"
+	"context"
+	"github.com/grpc-ecosystem/grpc-gateway/runtime"
+	"net/http"
+	"strings"
+
+	gw "github.com/jamesread/OliveTin/gen/grpc"
+)
+
+
+func Start() (error) {
+	port := 1339;
+
+	ctx := context.Background()
+	ctx, cancel := context.WithCancel(ctx)
+	defer cancel()
+
+	//lis, err := net.Listen("tcp", fmt.Sprintf("0.0.0.0:%d", port));
+
+	mux := runtime.NewServeMux()
+	opts := []grpc.DialOption{grpc.WithInsecure()}
+
+	err := gw.RegisterOliveTinApiHandlerFromEndpoint(ctx, mux, "127.0.0.1:1337", opts)
+
+	if err != nil {
+		log.Fatalf("gw error %v", err)
+	}
+
+	return http.ListenAndServe(fmt.Sprintf(":%d", port), allowCors(mux))
+}
+
+func allowCors(h http.Handler) http.Handler {
+	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		if origin := r.Header.Get("Origin"); origin != "" {
+			w.Header().Set("Access-Control-Allow-Origin", origin)
+			if r.Method == "OPTIONS" && r.Header.Get("Access-Control-Request-Method") != "" {
+				preflightHandler(w, r)
+				return
+			}
+		}
+		h.ServeHTTP(w, r)
+	})
+}
+
+func preflightHandler(w http.ResponseWriter, r *http.Request) {
+	headers := []string{"Content-Type", "Accept"}
+	w.Header().Set("Access-Control-Allow-Headers", strings.Join(headers, ","))
+	methods := []string{"GET", "HEAD", "POST", "PUT", "DELETE"}
+	w.Header().Set("Access-Control-Allow-Methods", strings.Join(methods, ","))
+	log.Infof("preflight request for %s", r.URL.Path)
+	return
+}