diff --git a/Makefile b/Makefile index 68e2e4709..8ad5a7737 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,8 @@ IMPORT := github.com/owncloud/$(NAME) BIN := bin DIST := dist HUGO := hugo +PROTO_VERSION := v0 +PROTO_SRC := pkg/proto/$(PROTO_VERSION)/*.proto ifeq ($(OS), Windows_NT) EXECUTABLE := $(NAME).exe @@ -155,41 +157,6 @@ docs: docs-copy docs-build watch: go run github.com/cespare/reflex -c reflex.conf -# $(GOPATH)/bin/protoc-gen-go: -# GO111MODULE=off go get -v github.com/golang/protobuf/protoc-gen-go - -# $(GOPATH)/bin/protoc-gen-micro: -# GO111MODULE=off go get -v github.com/micro/protoc-gen-micro - -# $(GOPATH)/bin/protoc-gen-microweb: -# GO111MODULE=off go get -v github.com/webhippie/protoc-gen-microweb - -# $(GOPATH)/bin/protoc-gen-swagger: -# GO111MODULE=off go get -v github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger - -# pkg/proto/v0/example.pb.go: pkg/proto/v0/example.proto -# protoc \ -# -I=third_party/ \ -# -I=pkg/proto/v0/ \ -# --go_out=logtostderr=true:pkg/proto/v0 example.proto - -# pkg/proto/v0/example.pb.micro.go: pkg/proto/v0/example.proto -# protoc \ -# -I=third_party/ \ -# -I=pkg/proto/v0/ \ -# --micro_out=logtostderr=true:pkg/proto/v0 example.proto - -# pkg/proto/v0/example.pb.web.go: pkg/proto/v0/example.proto -# protoc \ -# -I=third_party/ \ -# -I=pkg/proto/v0/ \ -# --microweb_out=logtostderr=true:pkg/proto/v0 example.proto - -# pkg/proto/v0/example.swagger.json: pkg/proto/v0/example.proto -# protoc \ -# -I=third_party/ \ -# -I=pkg/proto/v0/ \ -# --swagger_out=logtostderr=true:pkg/proto/v0 example.proto - -# .PHONY: protobuf -# protobuf: $(GOPATH)/bin/protoc-gen-go $(GOPATH)/bin/protoc-gen-micro $(GOPATH)/bin/protoc-gen-microweb $(GOPATH)/bin/protoc-gen-swagger pkg/proto/v0/example.pb.go pkg/proto/v0/example.pb.micro.go pkg/proto/v0/example.pb.web.go pkg/proto/v0/example.swagger.json +.PHONY: protoc-micro +protoc-micro: + protoc --go_out=. --micro_out=. $(PROTO_SRC) diff --git a/go.mod b/go.mod index 720fc0c76..49ad8d46d 100644 --- a/go.mod +++ b/go.mod @@ -8,11 +8,13 @@ require ( contrib.go.opencensus.io/exporter/zipkin v0.1.1 github.com/UnnoTed/fileb0x v1.1.4 github.com/go-chi/chi v4.1.0+incompatible + github.com/golang/protobuf v1.3.2 github.com/micro/cli/v2 v2.1.1 + github.com/micro/go-micro/v2 v2.0.0 github.com/oklog/run v1.0.0 github.com/openzipkin/zipkin-go v0.2.2 github.com/owncloud/ocis-pkg/v2 v2.0.1 - github.com/restic/calens v0.1.0 + github.com/restic/calens v0.2.0 github.com/spf13/viper v1.5.0 go.opencensus.io v0.22.2 ) diff --git a/go.sum b/go.sum index f2f9ee70b..ee4c3742e 100644 --- a/go.sum +++ b/go.sum @@ -35,6 +35,9 @@ github.com/Azure/go-autorest/tracing v0.1.0/go.mod h1:ROEEAFwXycQw7Sn3DXNtEedEvd github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver/v3 v3.0.2/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/Masterminds/sprig/v3 v3.0.1/go.mod h1:Cp7HwZjmqKrC+Y7XqSJOU2yRvAJRGLiohfgz5ZJj8+4= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= @@ -203,6 +206,8 @@ github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= @@ -252,8 +257,10 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T github.com/haya14busa/goverage v0.0.0-20180129164344-eec3514a20b5 h1:FdBGmSkD2QpQzRWup//SGObvWf2nq89zj9+ta9OvI3A= github.com/haya14busa/goverage v0.0.0-20180129164344-eec3514a20b5/go.mod h1:0YZ2wQSuwviXXXGUiK6zXzskyBLAbLXhamxzcFHSLoM= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df/go.mod h1:QMZY7/J/KSQEhKWFeDesPjMj+wCHReeknARU3wqlyN4= github.com/ijc/Gotty v0.0.0-20170406111628-a8b993ba6abd/go.mod h1:3LVOLeyx9XVvwPgrt2be44XgSqndprz1G18rSk8KD84= +github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= @@ -341,6 +348,7 @@ github.com/micro/go-micro v1.18.0 h1:gP70EZVHpJuUIT0YWth192JmlIci+qMOEByHm83XE9E github.com/micro/go-micro v1.18.0/go.mod h1:klwUJL1gkdY1MHFyz+fFJXn52dKcty4hoe95Mp571AA= github.com/micro/go-micro/v2 v2.0.0 h1:bMx549RwJ9Yuiui8cDVlfYhVNP8I8KBJTMyLthEXpRw= github.com/micro/go-micro/v2 v2.0.0/go.mod h1:v7QP5UhKRt37ixjJe8DouWmg0/eE6dltr5h0idJ9BpE= +github.com/micro/go-plugins/wrapper/trace/opencensus/v2 v2.0.1 h1:7IkXfl94MdLZQwk0lNmu9Cg5WP42Zak9EtQMeN4SvVs= github.com/micro/go-plugins/wrapper/trace/opencensus/v2 v2.0.1/go.mod h1:QrkcwcDtIs2hIJpIEhozekyf6Rfz5C36kFI8+zzCpX0= github.com/micro/mdns v0.3.0 h1:bYycYe+98AXR3s8Nq5qvt6C573uFTDPIYzJemWON0QE= github.com/micro/mdns v0.3.0/go.mod h1:KJ0dW7KmicXU2BV++qkLlmHYcVv7/hHnbtguSWt9Aoc= @@ -351,6 +359,7 @@ github.com/miekg/dns v1.1.22 h1:Jm64b3bO9kP43ddLjL2EY3Io6bmy1qGb9Xxz6TqS6rc= github.com/miekg/dns v1.1.22/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.27 h1:aEH/kqUzUxGJ/UHcEKdJY+ugH6WEzsEBBSPa8zuy1aM= github.com/miekg/dns v1.1.27/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-vnc v0.0.0-20150629162542-723ed9867aed/go.mod h1:3rdaFaCv4AyBgu5ALFM0+tSuHrBh6v692nyQe3ikrq0= github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= @@ -360,6 +369,7 @@ github.com/mitchellh/hashstructure v1.0.0 h1:ZkRJX1CyOoTkar7p/mLS5TZU4nJ1Rn/F8u9 github.com/mitchellh/hashstructure v1.0.0/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -465,6 +475,7 @@ github.com/rainycape/memcache v0.0.0-20150622160815-1031fa0ce2f2/go.mod h1:7tZKc github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/restic/calens v0.1.0 h1:RHGokdZ72dICyIz1EjEsfZwUhvNZz/zy2SawxJktdWA= github.com/restic/calens v0.1.0/go.mod h1:u67f5msOjCTDYNzOf/NoAUSdmXP03YXPCwIQLYADy5M= +github.com/restic/calens v0.2.0/go.mod h1:UXwyAKS4wsgUZGEc7NrzzygJbLsQZIo3wl+62Q1wvmU= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= diff --git a/pkg/command/server.go b/pkg/command/server.go index 04212df3e..62d136a51 100644 --- a/pkg/command/server.go +++ b/pkg/command/server.go @@ -2,6 +2,7 @@ package command import ( "context" + "github.com/owncloud/ocis-settings/pkg/server/grpc" "os" "os/signal" "strings" @@ -16,9 +17,7 @@ import ( zipkinhttp "github.com/openzipkin/zipkin-go/reporter/http" "github.com/owncloud/ocis-settings/pkg/config" "github.com/owncloud/ocis-settings/pkg/flagset" - "github.com/owncloud/ocis-settings/pkg/metrics" "github.com/owncloud/ocis-settings/pkg/server/debug" - "github.com/owncloud/ocis-settings/pkg/server/http" "go.opencensus.io/stats/view" "go.opencensus.io/trace" ) @@ -129,31 +128,20 @@ func Server(cfg *config.Config) *cli.Command { var ( gr = run.Group{} ctx, cancel = context.WithCancel(context.Background()) - metrics = metrics.New() ) defer cancel() { - server, err := http.Server( - http.Logger(logger), - http.Namespace(httpNamespace), - http.Context(ctx), - http.Config(cfg), - http.Metrics(metrics), - http.Flags(flagset.RootWithConfig(config.New())), - http.Flags(flagset.ServerWithConfig(config.New())), + server := grpc.Server( + grpc.Name("ocis-settings"), + grpc.Address(":9190"), + grpc.Logger(logger), + grpc.Context(ctx), + grpc.Config(cfg), + grpc.Namespace(httpNamespace), ) - if err != nil { - logger.Error(). - Err(err). - Str("server", "http"). - Msg("Failed to initialize server") - - return err - } - gr.Add(func() error { return server.Run() }, func(_ error) { diff --git a/pkg/config/config.go b/pkg/config/config.go index c92c9820c..0cde28425 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -31,9 +31,15 @@ type Tracing struct { Service string } +// Storage defines the available storage configuration. +type Storage struct { + RootMountPath string +} + // Config combines all available configuration parts. type Config struct { File string + Storage Storage Log Log Debug Debug HTTP HTTP diff --git a/pkg/flagset/flagset.go b/pkg/flagset/flagset.go index 2d43398f7..a480dc8d9 100644 --- a/pkg/flagset/flagset.go +++ b/pkg/flagset/flagset.go @@ -134,5 +134,12 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag { EnvVars: []string{"SETTINGS_HTTP_ROOT"}, Destination: &cfg.HTTP.Root, }, + &cli.StringFlag{ + Name: "settings-root-mount-path", + Value: "/", + Usage: "Mount path for the storage", + EnvVars: []string{"SETTINGS_ROOT_MOUNT_PATH"}, + Destination: &cfg.Storage.RootMountPath, + }, } } diff --git a/pkg/proto/v0/settings.pb.go b/pkg/proto/v0/settings.pb.go new file mode 100644 index 000000000..903812cee --- /dev/null +++ b/pkg/proto/v0/settings.pb.go @@ -0,0 +1,475 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: pkg/proto/v0/settings.proto + +package proto + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +// requests and responses +type CreateSettingsBundleRequest struct { + SettingsBundle *SettingsBundle `protobuf:"bytes,1,opt,name=settingsBundle,proto3" json:"settingsBundle,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CreateSettingsBundleRequest) Reset() { *m = CreateSettingsBundleRequest{} } +func (m *CreateSettingsBundleRequest) String() string { return proto.CompactTextString(m) } +func (*CreateSettingsBundleRequest) ProtoMessage() {} +func (*CreateSettingsBundleRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_199e73d7d5fd837b, []int{0} +} + +func (m *CreateSettingsBundleRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CreateSettingsBundleRequest.Unmarshal(m, b) +} +func (m *CreateSettingsBundleRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CreateSettingsBundleRequest.Marshal(b, m, deterministic) +} +func (m *CreateSettingsBundleRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_CreateSettingsBundleRequest.Merge(m, src) +} +func (m *CreateSettingsBundleRequest) XXX_Size() int { + return xxx_messageInfo_CreateSettingsBundleRequest.Size(m) +} +func (m *CreateSettingsBundleRequest) XXX_DiscardUnknown() { + xxx_messageInfo_CreateSettingsBundleRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_CreateSettingsBundleRequest proto.InternalMessageInfo + +func (m *CreateSettingsBundleRequest) GetSettingsBundle() *SettingsBundle { + if m != nil { + return m.SettingsBundle + } + return nil +} + +type CreateSettingsBundleResponse struct { + SettingsBundle *SettingsBundle `protobuf:"bytes,1,opt,name=settingsBundle,proto3" json:"settingsBundle,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CreateSettingsBundleResponse) Reset() { *m = CreateSettingsBundleResponse{} } +func (m *CreateSettingsBundleResponse) String() string { return proto.CompactTextString(m) } +func (*CreateSettingsBundleResponse) ProtoMessage() {} +func (*CreateSettingsBundleResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_199e73d7d5fd837b, []int{1} +} + +func (m *CreateSettingsBundleResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CreateSettingsBundleResponse.Unmarshal(m, b) +} +func (m *CreateSettingsBundleResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CreateSettingsBundleResponse.Marshal(b, m, deterministic) +} +func (m *CreateSettingsBundleResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_CreateSettingsBundleResponse.Merge(m, src) +} +func (m *CreateSettingsBundleResponse) XXX_Size() int { + return xxx_messageInfo_CreateSettingsBundleResponse.Size(m) +} +func (m *CreateSettingsBundleResponse) XXX_DiscardUnknown() { + xxx_messageInfo_CreateSettingsBundleResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_CreateSettingsBundleResponse proto.InternalMessageInfo + +func (m *CreateSettingsBundleResponse) GetSettingsBundle() *SettingsBundle { + if m != nil { + return m.SettingsBundle + } + return nil +} + +type GetSettingsBundleRequest struct { + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Extension string `protobuf:"bytes,2,opt,name=extension,proto3" json:"extension,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetSettingsBundleRequest) Reset() { *m = GetSettingsBundleRequest{} } +func (m *GetSettingsBundleRequest) String() string { return proto.CompactTextString(m) } +func (*GetSettingsBundleRequest) ProtoMessage() {} +func (*GetSettingsBundleRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_199e73d7d5fd837b, []int{2} +} + +func (m *GetSettingsBundleRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetSettingsBundleRequest.Unmarshal(m, b) +} +func (m *GetSettingsBundleRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetSettingsBundleRequest.Marshal(b, m, deterministic) +} +func (m *GetSettingsBundleRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetSettingsBundleRequest.Merge(m, src) +} +func (m *GetSettingsBundleRequest) XXX_Size() int { + return xxx_messageInfo_GetSettingsBundleRequest.Size(m) +} +func (m *GetSettingsBundleRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetSettingsBundleRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetSettingsBundleRequest proto.InternalMessageInfo + +func (m *GetSettingsBundleRequest) GetKey() string { + if m != nil { + return m.Key + } + return "" +} + +func (m *GetSettingsBundleRequest) GetExtension() string { + if m != nil { + return m.Extension + } + return "" +} + +type GetSettingsBundleResponse struct { + SettingsBundle *SettingsBundle `protobuf:"bytes,1,opt,name=settingsBundle,proto3" json:"settingsBundle,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetSettingsBundleResponse) Reset() { *m = GetSettingsBundleResponse{} } +func (m *GetSettingsBundleResponse) String() string { return proto.CompactTextString(m) } +func (*GetSettingsBundleResponse) ProtoMessage() {} +func (*GetSettingsBundleResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_199e73d7d5fd837b, []int{3} +} + +func (m *GetSettingsBundleResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetSettingsBundleResponse.Unmarshal(m, b) +} +func (m *GetSettingsBundleResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetSettingsBundleResponse.Marshal(b, m, deterministic) +} +func (m *GetSettingsBundleResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetSettingsBundleResponse.Merge(m, src) +} +func (m *GetSettingsBundleResponse) XXX_Size() int { + return xxx_messageInfo_GetSettingsBundleResponse.Size(m) +} +func (m *GetSettingsBundleResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetSettingsBundleResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetSettingsBundleResponse proto.InternalMessageInfo + +func (m *GetSettingsBundleResponse) GetSettingsBundle() *SettingsBundle { + if m != nil { + return m.SettingsBundle + } + return nil +} + +type ListSettingsBundlesRequest struct { + Extension string `protobuf:"bytes,1,opt,name=extension,proto3" json:"extension,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ListSettingsBundlesRequest) Reset() { *m = ListSettingsBundlesRequest{} } +func (m *ListSettingsBundlesRequest) String() string { return proto.CompactTextString(m) } +func (*ListSettingsBundlesRequest) ProtoMessage() {} +func (*ListSettingsBundlesRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_199e73d7d5fd837b, []int{4} +} + +func (m *ListSettingsBundlesRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ListSettingsBundlesRequest.Unmarshal(m, b) +} +func (m *ListSettingsBundlesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ListSettingsBundlesRequest.Marshal(b, m, deterministic) +} +func (m *ListSettingsBundlesRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ListSettingsBundlesRequest.Merge(m, src) +} +func (m *ListSettingsBundlesRequest) XXX_Size() int { + return xxx_messageInfo_ListSettingsBundlesRequest.Size(m) +} +func (m *ListSettingsBundlesRequest) XXX_DiscardUnknown() { + xxx_messageInfo_ListSettingsBundlesRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_ListSettingsBundlesRequest proto.InternalMessageInfo + +func (m *ListSettingsBundlesRequest) GetExtension() string { + if m != nil { + return m.Extension + } + return "" +} + +type ListSettingsBundlesResponse struct { + SettingsBundles []*SettingsBundle `protobuf:"bytes,1,rep,name=settingsBundles,proto3" json:"settingsBundles,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ListSettingsBundlesResponse) Reset() { *m = ListSettingsBundlesResponse{} } +func (m *ListSettingsBundlesResponse) String() string { return proto.CompactTextString(m) } +func (*ListSettingsBundlesResponse) ProtoMessage() {} +func (*ListSettingsBundlesResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_199e73d7d5fd837b, []int{5} +} + +func (m *ListSettingsBundlesResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ListSettingsBundlesResponse.Unmarshal(m, b) +} +func (m *ListSettingsBundlesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ListSettingsBundlesResponse.Marshal(b, m, deterministic) +} +func (m *ListSettingsBundlesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ListSettingsBundlesResponse.Merge(m, src) +} +func (m *ListSettingsBundlesResponse) XXX_Size() int { + return xxx_messageInfo_ListSettingsBundlesResponse.Size(m) +} +func (m *ListSettingsBundlesResponse) XXX_DiscardUnknown() { + xxx_messageInfo_ListSettingsBundlesResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_ListSettingsBundlesResponse proto.InternalMessageInfo + +func (m *ListSettingsBundlesResponse) GetSettingsBundles() []*SettingsBundle { + if m != nil { + return m.SettingsBundles + } + return nil +} + +// payloads +type SettingsBundle struct { + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + DisplayName string `protobuf:"bytes,2,opt,name=displayName,proto3" json:"displayName,omitempty"` + Extension string `protobuf:"bytes,3,opt,name=extension,proto3" json:"extension,omitempty"` + Settings []*Setting `protobuf:"bytes,4,rep,name=settings,proto3" json:"settings,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SettingsBundle) Reset() { *m = SettingsBundle{} } +func (m *SettingsBundle) String() string { return proto.CompactTextString(m) } +func (*SettingsBundle) ProtoMessage() {} +func (*SettingsBundle) Descriptor() ([]byte, []int) { + return fileDescriptor_199e73d7d5fd837b, []int{6} +} + +func (m *SettingsBundle) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SettingsBundle.Unmarshal(m, b) +} +func (m *SettingsBundle) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SettingsBundle.Marshal(b, m, deterministic) +} +func (m *SettingsBundle) XXX_Merge(src proto.Message) { + xxx_messageInfo_SettingsBundle.Merge(m, src) +} +func (m *SettingsBundle) XXX_Size() int { + return xxx_messageInfo_SettingsBundle.Size(m) +} +func (m *SettingsBundle) XXX_DiscardUnknown() { + xxx_messageInfo_SettingsBundle.DiscardUnknown(m) +} + +var xxx_messageInfo_SettingsBundle proto.InternalMessageInfo + +func (m *SettingsBundle) GetKey() string { + if m != nil { + return m.Key + } + return "" +} + +func (m *SettingsBundle) GetDisplayName() string { + if m != nil { + return m.DisplayName + } + return "" +} + +func (m *SettingsBundle) GetExtension() string { + if m != nil { + return m.Extension + } + return "" +} + +func (m *SettingsBundle) GetSettings() []*Setting { + if m != nil { + return m.Settings + } + return nil +} + +type Setting struct { + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + DisplayName string `protobuf:"bytes,2,opt,name=displayName,proto3" json:"displayName,omitempty"` + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + Values []*SettingsValue `protobuf:"bytes,4,rep,name=values,proto3" json:"values,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Setting) Reset() { *m = Setting{} } +func (m *Setting) String() string { return proto.CompactTextString(m) } +func (*Setting) ProtoMessage() {} +func (*Setting) Descriptor() ([]byte, []int) { + return fileDescriptor_199e73d7d5fd837b, []int{7} +} + +func (m *Setting) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Setting.Unmarshal(m, b) +} +func (m *Setting) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Setting.Marshal(b, m, deterministic) +} +func (m *Setting) XXX_Merge(src proto.Message) { + xxx_messageInfo_Setting.Merge(m, src) +} +func (m *Setting) XXX_Size() int { + return xxx_messageInfo_Setting.Size(m) +} +func (m *Setting) XXX_DiscardUnknown() { + xxx_messageInfo_Setting.DiscardUnknown(m) +} + +var xxx_messageInfo_Setting proto.InternalMessageInfo + +func (m *Setting) GetKey() string { + if m != nil { + return m.Key + } + return "" +} + +func (m *Setting) GetDisplayName() string { + if m != nil { + return m.DisplayName + } + return "" +} + +func (m *Setting) GetDescription() string { + if m != nil { + return m.Description + } + return "" +} + +func (m *Setting) GetValues() []*SettingsValue { + if m != nil { + return m.Values + } + return nil +} + +type SettingsValue struct { + Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SettingsValue) Reset() { *m = SettingsValue{} } +func (m *SettingsValue) String() string { return proto.CompactTextString(m) } +func (*SettingsValue) ProtoMessage() {} +func (*SettingsValue) Descriptor() ([]byte, []int) { + return fileDescriptor_199e73d7d5fd837b, []int{8} +} + +func (m *SettingsValue) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SettingsValue.Unmarshal(m, b) +} +func (m *SettingsValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SettingsValue.Marshal(b, m, deterministic) +} +func (m *SettingsValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_SettingsValue.Merge(m, src) +} +func (m *SettingsValue) XXX_Size() int { + return xxx_messageInfo_SettingsValue.Size(m) +} +func (m *SettingsValue) XXX_DiscardUnknown() { + xxx_messageInfo_SettingsValue.DiscardUnknown(m) +} + +var xxx_messageInfo_SettingsValue proto.InternalMessageInfo + +func (m *SettingsValue) GetType() string { + if m != nil { + return m.Type + } + return "" +} + +func init() { + proto.RegisterType((*CreateSettingsBundleRequest)(nil), "proto.CreateSettingsBundleRequest") + proto.RegisterType((*CreateSettingsBundleResponse)(nil), "proto.CreateSettingsBundleResponse") + proto.RegisterType((*GetSettingsBundleRequest)(nil), "proto.GetSettingsBundleRequest") + proto.RegisterType((*GetSettingsBundleResponse)(nil), "proto.GetSettingsBundleResponse") + proto.RegisterType((*ListSettingsBundlesRequest)(nil), "proto.ListSettingsBundlesRequest") + proto.RegisterType((*ListSettingsBundlesResponse)(nil), "proto.ListSettingsBundlesResponse") + proto.RegisterType((*SettingsBundle)(nil), "proto.SettingsBundle") + proto.RegisterType((*Setting)(nil), "proto.Setting") + proto.RegisterType((*SettingsValue)(nil), "proto.SettingsValue") +} + +func init() { + proto.RegisterFile("pkg/proto/v0/settings.proto", fileDescriptor_199e73d7d5fd837b) +} + +var fileDescriptor_199e73d7d5fd837b = []byte{ + // 392 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x94, 0x41, 0x4f, 0xea, 0x40, + 0x10, 0xc7, 0x53, 0xe0, 0xc1, 0x63, 0x08, 0xbc, 0xf7, 0xf6, 0x61, 0x52, 0x0b, 0x89, 0x75, 0xb9, + 0x18, 0x63, 0xc0, 0xe0, 0xcd, 0xc4, 0x98, 0xe0, 0xc1, 0xc4, 0x18, 0x0f, 0x25, 0xe1, 0x40, 0x50, + 0x53, 0x61, 0x42, 0x1a, 0xb0, 0xad, 0xdd, 0x85, 0xc8, 0x87, 0xd0, 0x8f, 0xe1, 0xe7, 0x34, 0xb4, + 0x8b, 0xb0, 0xeb, 0x96, 0x83, 0x7a, 0xda, 0xcd, 0xcc, 0x7f, 0xfe, 0xfb, 0xdb, 0xe9, 0x6c, 0xa1, + 0x16, 0x4e, 0xc6, 0xad, 0x30, 0x0a, 0x78, 0xd0, 0x9a, 0x1f, 0xb7, 0x18, 0x72, 0xee, 0xf9, 0x63, + 0xd6, 0x8c, 0x23, 0xe4, 0x57, 0xbc, 0xd0, 0x01, 0xd4, 0x2e, 0x22, 0x74, 0x39, 0x76, 0x45, 0xba, + 0x33, 0xf3, 0x47, 0x53, 0x74, 0xf0, 0x69, 0x86, 0x8c, 0x93, 0x33, 0xa8, 0x30, 0x29, 0x61, 0x1a, + 0xb6, 0x71, 0x50, 0x6a, 0xef, 0x24, 0x2e, 0x4d, 0xa5, 0x4a, 0x11, 0xd3, 0x5b, 0xa8, 0xeb, 0xdd, + 0x59, 0x18, 0xf8, 0x0c, 0xbf, 0x6b, 0x7f, 0x05, 0xe6, 0x25, 0x72, 0x3d, 0xf9, 0x5f, 0xc8, 0x4e, + 0x70, 0x11, 0xfb, 0x15, 0x9d, 0xe5, 0x96, 0xd4, 0xa1, 0x88, 0xcf, 0x1c, 0x7d, 0xe6, 0x05, 0xbe, + 0x99, 0x89, 0xe3, 0xeb, 0x00, 0xed, 0xc3, 0xae, 0xc6, 0xeb, 0x67, 0x38, 0x4f, 0xc1, 0xba, 0xf6, + 0x98, 0x62, 0xce, 0x56, 0xa4, 0x12, 0x97, 0xa1, 0x72, 0xdd, 0x41, 0x4d, 0x5b, 0x2b, 0xc8, 0xce, + 0xe1, 0x8f, 0x7c, 0x18, 0x33, 0x0d, 0x3b, 0x9b, 0x8e, 0xa6, 0xaa, 0xe9, 0xab, 0x01, 0x15, 0x59, + 0xa3, 0x69, 0x9d, 0x0d, 0xa5, 0x91, 0xc7, 0xc2, 0xa9, 0xbb, 0xb8, 0x71, 0x1f, 0x51, 0x34, 0x6f, + 0x33, 0x24, 0x5f, 0x22, 0xab, 0x5c, 0x82, 0x1c, 0xc2, 0xef, 0xd5, 0xb9, 0x66, 0x2e, 0xc6, 0xab, + 0xc8, 0x78, 0xce, 0x47, 0x9e, 0xbe, 0x18, 0x50, 0x10, 0xd1, 0x2f, 0x91, 0x2c, 0x15, 0xc8, 0x86, + 0x91, 0x17, 0xf2, 0x35, 0xcb, 0x66, 0x88, 0x1c, 0x41, 0x7e, 0xee, 0x4e, 0x67, 0xb8, 0x62, 0xa9, + 0x2a, 0xad, 0xea, 0x2d, 0x93, 0x8e, 0xd0, 0xd0, 0x06, 0x94, 0xa5, 0x04, 0x21, 0x90, 0xe3, 0x8b, + 0x10, 0x05, 0x55, 0xbc, 0x6f, 0xbf, 0x65, 0xa0, 0x9c, 0x74, 0xaf, 0x8b, 0xd1, 0xdc, 0x1b, 0x22, + 0xb9, 0x87, 0xaa, 0x6e, 0xf4, 0x09, 0x15, 0x87, 0x6d, 0x79, 0x75, 0x56, 0x63, 0xab, 0x46, 0x7c, + 0xf9, 0x1e, 0xfc, 0xfb, 0x34, 0xb0, 0x64, 0x4f, 0x54, 0xa6, 0x3d, 0x0b, 0xcb, 0x4e, 0x17, 0x08, + 0xdf, 0x01, 0xfc, 0xd7, 0x0c, 0x1c, 0xd9, 0x17, 0x85, 0xe9, 0x83, 0x6c, 0xd1, 0x6d, 0x92, 0xc4, + 0xbd, 0x53, 0xe8, 0x27, 0x3f, 0x9e, 0x87, 0x7c, 0xbc, 0x9c, 0xbc, 0x07, 0x00, 0x00, 0xff, 0xff, + 0x1d, 0x4a, 0xf8, 0xc6, 0xa5, 0x04, 0x00, 0x00, +} diff --git a/pkg/proto/v0/settings.pb.micro.go b/pkg/proto/v0/settings.pb.micro.go new file mode 100644 index 000000000..492c62922 --- /dev/null +++ b/pkg/proto/v0/settings.pb.micro.go @@ -0,0 +1,119 @@ +// Code generated by protoc-gen-micro. DO NOT EDIT. +// source: pkg/proto/v0/settings.proto + +package proto + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + math "math" +) + +import ( + context "context" + client "github.com/micro/go-micro/v2/client" + server "github.com/micro/go-micro/v2/server" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ client.Option +var _ server.Option + +// Client API for BundleService service + +type BundleService interface { + CreateSettingsBundle(ctx context.Context, in *CreateSettingsBundleRequest, opts ...client.CallOption) (*CreateSettingsBundleResponse, error) + GetSettingsBundle(ctx context.Context, in *GetSettingsBundleRequest, opts ...client.CallOption) (*GetSettingsBundleResponse, error) + ListSettingsBundles(ctx context.Context, in *ListSettingsBundlesRequest, opts ...client.CallOption) (*ListSettingsBundlesResponse, error) +} + +type bundleService struct { + c client.Client + name string +} + +func NewBundleService(name string, c client.Client) BundleService { + return &bundleService{ + c: c, + name: name, + } +} + +func (c *bundleService) CreateSettingsBundle(ctx context.Context, in *CreateSettingsBundleRequest, opts ...client.CallOption) (*CreateSettingsBundleResponse, error) { + req := c.c.NewRequest(c.name, "BundleService.CreateSettingsBundle", in) + out := new(CreateSettingsBundleResponse) + err := c.c.Call(ctx, req, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bundleService) GetSettingsBundle(ctx context.Context, in *GetSettingsBundleRequest, opts ...client.CallOption) (*GetSettingsBundleResponse, error) { + req := c.c.NewRequest(c.name, "BundleService.GetSettingsBundle", in) + out := new(GetSettingsBundleResponse) + err := c.c.Call(ctx, req, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bundleService) ListSettingsBundles(ctx context.Context, in *ListSettingsBundlesRequest, opts ...client.CallOption) (*ListSettingsBundlesResponse, error) { + req := c.c.NewRequest(c.name, "BundleService.ListSettingsBundles", in) + out := new(ListSettingsBundlesResponse) + err := c.c.Call(ctx, req, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// Server API for BundleService service + +type BundleServiceHandler interface { + CreateSettingsBundle(context.Context, *CreateSettingsBundleRequest, *CreateSettingsBundleResponse) error + GetSettingsBundle(context.Context, *GetSettingsBundleRequest, *GetSettingsBundleResponse) error + ListSettingsBundles(context.Context, *ListSettingsBundlesRequest, *ListSettingsBundlesResponse) error +} + +func RegisterBundleServiceHandler(s server.Server, hdlr BundleServiceHandler, opts ...server.HandlerOption) error { + type bundleService interface { + CreateSettingsBundle(ctx context.Context, in *CreateSettingsBundleRequest, out *CreateSettingsBundleResponse) error + GetSettingsBundle(ctx context.Context, in *GetSettingsBundleRequest, out *GetSettingsBundleResponse) error + ListSettingsBundles(ctx context.Context, in *ListSettingsBundlesRequest, out *ListSettingsBundlesResponse) error + } + type BundleService struct { + bundleService + } + h := &bundleServiceHandler{hdlr} + return s.Handle(s.NewHandler(&BundleService{h}, opts...)) +} + +type bundleServiceHandler struct { + BundleServiceHandler +} + +func (h *bundleServiceHandler) CreateSettingsBundle(ctx context.Context, in *CreateSettingsBundleRequest, out *CreateSettingsBundleResponse) error { + return h.BundleServiceHandler.CreateSettingsBundle(ctx, in, out) +} + +func (h *bundleServiceHandler) GetSettingsBundle(ctx context.Context, in *GetSettingsBundleRequest, out *GetSettingsBundleResponse) error { + return h.BundleServiceHandler.GetSettingsBundle(ctx, in, out) +} + +func (h *bundleServiceHandler) ListSettingsBundles(ctx context.Context, in *ListSettingsBundlesRequest, out *ListSettingsBundlesResponse) error { + return h.BundleServiceHandler.ListSettingsBundles(ctx, in, out) +} diff --git a/pkg/proto/v0/settings.proto b/pkg/proto/v0/settings.proto new file mode 100644 index 000000000..4c5bdcd8e --- /dev/null +++ b/pkg/proto/v0/settings.proto @@ -0,0 +1,55 @@ +syntax = "proto3"; + +package proto; +option go_package = "proto"; + +service BundleService { + rpc CreateSettingsBundle(CreateSettingsBundleRequest) returns (CreateSettingsBundleResponse); + rpc GetSettingsBundle(GetSettingsBundleRequest) returns (GetSettingsBundleResponse); + rpc ListSettingsBundles(ListSettingsBundlesRequest) returns (ListSettingsBundlesResponse); +} + +// requests and responses +message CreateSettingsBundleRequest { + SettingsBundle settingsBundle = 1; +} + +message CreateSettingsBundleResponse { + SettingsBundle settingsBundle = 1; +} + +message GetSettingsBundleRequest { + string extension = 1; + string key = 2; +} + +message GetSettingsBundleResponse { + SettingsBundle settingsBundle = 1; +} + +message ListSettingsBundlesRequest { + string extension = 1;// can be limited to all settings bundles of an extension +} + +message ListSettingsBundlesResponse { + repeated SettingsBundle settingsBundles = 1; +} + +// payloads +message SettingsBundle { + string extension = 1; + string key = 2; + string displayName = 3; + repeated Setting settings = 4; +} + +message Setting { + string key = 1; + string displayName = 2; + string description = 3; + repeated SettingsValue values = 4; +} + +message SettingsValue { + string type = 1; +} diff --git a/pkg/server/grpc/option.go b/pkg/server/grpc/option.go new file mode 100644 index 000000000..f47fed7df --- /dev/null +++ b/pkg/server/grpc/option.go @@ -0,0 +1,74 @@ +package grpc + +import ( + "context" + + "github.com/owncloud/ocis-settings/pkg/config" + "github.com/owncloud/ocis-pkg/v2/log" +) + +// Option defines a single option function. +type Option func(o *Options) + +// Options defines the available options for this package. +type Options struct { + Name string + Address string + Logger log.Logger + Context context.Context + Config *config.Config + Namespace string +} + +// newOptions initializes the available default options. +func newOptions(opts ...Option) Options { + opt := Options{} + + for _, o := range opts { + o(&opt) + } + + return opt +} + +// Logger provides a function to set the logger option. +func Logger(val log.Logger) Option { + return func(o *Options) { + o.Logger = val + } +} + +// Name provides a name for the service. +func Name(val string) Option { + return func(o *Options) { + o.Name = val + } +} + +// Address provides an address for the service. +func Address(val string) Option { + return func(o *Options) { + o.Address = val + } +} + +// Context provides a function to set the context option. +func Context(val context.Context) Option { + return func(o *Options) { + o.Context = val + } +} + +// Config provides a function to set the config option. +func Config(val *config.Config) Option { + return func(o *Options) { + o.Config = val + } +} + +// Namespace provides a function to set the namespace option. +func Namespace(val string) Option { + return func(o *Options) { + o.Namespace = val + } +} diff --git a/pkg/server/grpc/server.go b/pkg/server/grpc/server.go new file mode 100644 index 000000000..69ea95f3e --- /dev/null +++ b/pkg/server/grpc/server.go @@ -0,0 +1,28 @@ +package grpc + +import ( + "github.com/owncloud/ocis-settings/pkg/proto/v0" + svc "github.com/owncloud/ocis-settings/pkg/service/v0" + "github.com/owncloud/ocis-pkg/v2/service/grpc" +) + +// NewService initializes a new go-micro service ready to run +func Server(opts ...Option) grpc.Service { + options := newOptions(opts...) + + service := grpc.NewService( + grpc.Name(options.Name), + grpc.Context(options.Context), + grpc.Address(options.Address), + grpc.Namespace(options.Namespace), + grpc.Logger(options.Logger), + ) + + hdlr := svc.NewService(options.Config) + if err := proto.RegisterBundleServiceHandler(service.Server(), hdlr); err != nil { + options.Logger.Fatal().Err(err).Msg("could not register service handler") + } + + service.Init() + return service +} diff --git a/pkg/service/v0/instrument.go b/pkg/service/v0/instrument.go index 8cfd88452..10bbf0a22 100644 --- a/pkg/service/v0/instrument.go +++ b/pkg/service/v0/instrument.go @@ -1,30 +1,15 @@ package svc import ( - "net/http" - "github.com/owncloud/ocis-settings/pkg/metrics" ) // NewInstrument returns a service that instruments metrics. func NewInstrument(next Service, metrics *metrics.Metrics) Service { - return instrument{ - next: next, - metrics: metrics, - } + return Service{} } type instrument struct { next Service metrics *metrics.Metrics } - -// ServeHTTP implements the Service interface. -func (i instrument) ServeHTTP(w http.ResponseWriter, r *http.Request) { - i.next.ServeHTTP(w, r) -} - -// Dummy implements the Service interface. -func (i instrument) Dummy(w http.ResponseWriter, r *http.Request) { - i.next.Dummy(w, r) -} diff --git a/pkg/service/v0/logging.go b/pkg/service/v0/logging.go index e0b10f8c2..42c9b9722 100644 --- a/pkg/service/v0/logging.go +++ b/pkg/service/v0/logging.go @@ -1,30 +1,15 @@ package svc import ( - "net/http" - "github.com/owncloud/ocis-pkg/v2/log" ) // NewLogging returns a service that logs messages. func NewLogging(next Service, logger log.Logger) Service { - return logging{ - next: next, - logger: logger, - } + return Service{} } type logging struct { next Service logger log.Logger } - -// ServeHTTP implements the Service interface. -func (l logging) ServeHTTP(w http.ResponseWriter, r *http.Request) { - l.next.ServeHTTP(w, r) -} - -// Dummy implements the Service interface. -func (l logging) Dummy(w http.ResponseWriter, r *http.Request) { - l.next.Dummy(w, r) -} diff --git a/pkg/service/v0/service.go b/pkg/service/v0/service.go index 118d9a7f5..a0839adfb 100644 --- a/pkg/service/v0/service.go +++ b/pkg/service/v0/service.go @@ -1,52 +1,58 @@ package svc import ( - "net/http" + "context" + "github.com/owncloud/ocis-settings/pkg/settings" + store "github.com/owncloud/ocis-settings/pkg/store/filesystem" - "github.com/go-chi/chi" + "github.com/owncloud/ocis-settings/pkg/proto/v0" "github.com/owncloud/ocis-settings/pkg/config" ) -// Service defines the extension handlers. -type Service interface { - ServeHTTP(http.ResponseWriter, *http.Request) - Dummy(http.ResponseWriter, *http.Request) +type Service struct { + config *config.Config + manager settings.Manager } // NewService returns a service implementation for Service. -func NewService(opts ...Option) Service { - options := newOptions(opts...) - - m := chi.NewMux() - m.Use(options.Middleware...) - - svc := Settings{ - config: options.Config, - mux: m, +func NewService(cfg *config.Config) Service { + return Service{ + config:cfg, + manager:store.New(cfg), } - - m.Route(options.Config.HTTP.Root, func(r chi.Router) { - r.Get("/", svc.Dummy) - }) - - return svc } -// Settings defines implements the business logic for Service. -type Settings struct { - config *config.Config - mux *chi.Mux +func (g Service) CreateSettingsBundle(c context.Context, req *proto.CreateSettingsBundleRequest, res *proto.CreateSettingsBundleResponse) error { + r, err := g.manager.Write(req.SettingsBundle) + if err != nil { + return err + } + res.SettingsBundle = r + return nil } -// ServeHTTP implements the Service interface. -func (g Settings) ServeHTTP(w http.ResponseWriter, r *http.Request) { - g.mux.ServeHTTP(w, r) +func (g Service) GetSettingsBundle(c context.Context, req *proto.GetSettingsBundleRequest, res *proto.GetSettingsBundleResponse) error { + r, err := g.manager.Read(req.Extension, req.Key) + if err != nil { + return err + } + res.SettingsBundle = r + return nil } -// Dummy implements the Service interface. -func (g Settings) Dummy(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "text/plain") - w.WriteHeader(http.StatusOK) - - w.Write([]byte("Hello ocis-settings!")) +func (g Service) ListSettingsBundles(c context.Context, req *proto.ListSettingsBundlesRequest, res *proto.ListSettingsBundlesResponse) error { + r, err := listSettingsBundles(g, req.Extension) + if err != nil { + return err + } + res.SettingsBundles = r + return nil +} + +func listSettingsBundles(g Service, extension string) ([]*proto.SettingsBundle, error) { + if len(extension) == 0 { + return g.manager.List() + } else { + return g.manager.ListByExtension(extension) + } } diff --git a/pkg/service/v0/tracing.go b/pkg/service/v0/tracing.go index 48da0b320..434296fd3 100644 --- a/pkg/service/v0/tracing.go +++ b/pkg/service/v0/tracing.go @@ -1,26 +1,10 @@ package svc -import ( - "net/http" -) - // NewTracing returns a service that instruments traces. func NewTracing(next Service) Service { - return tracing{ - next: next, - } + return Service{} } type tracing struct { next Service } - -// ServeHTTP implements the Service interface. -func (t tracing) ServeHTTP(w http.ResponseWriter, r *http.Request) { - t.next.ServeHTTP(w, r) -} - -// Dummy implements the Service interface. -func (t tracing) Dummy(w http.ResponseWriter, r *http.Request) { - t.next.Dummy(w, r) -} diff --git a/pkg/settings/settings.go b/pkg/settings/settings.go new file mode 100644 index 000000000..1b3e7af0f --- /dev/null +++ b/pkg/settings/settings.go @@ -0,0 +1,22 @@ +package settings + +import ( + "github.com/owncloud/ocis-settings/pkg/config" + "github.com/owncloud/ocis-settings/pkg/proto/v0" +) + +var ( + // Registry uses the strategy pattern as a registry + Registry = map[string]RegisterFunc{} +) + +// RegisterFunc stores store constructors +type RegisterFunc func(*config.Config) Manager + +// Manager +type Manager interface { + Read(extension string, key string) (*proto.SettingsBundle, error) + Write(bundle *proto.SettingsBundle) (*proto.SettingsBundle, error) + List() ([]*proto.SettingsBundle, error) + ListByExtension(extension string) ([]*proto.SettingsBundle, error) +} diff --git a/pkg/store/filesystem/store.go b/pkg/store/filesystem/store.go new file mode 100644 index 000000000..882cde14c --- /dev/null +++ b/pkg/store/filesystem/store.go @@ -0,0 +1,145 @@ +// Package store implements the go-micro store interface +package store + +import ( + "encoding/json" + "fmt" + olog "github.com/owncloud/ocis-pkg/v2/log" + "github.com/owncloud/ocis-settings/pkg/config" + "github.com/owncloud/ocis-settings/pkg/proto/v0" + "github.com/owncloud/ocis-settings/pkg/settings" + "io/ioutil" + "os" + "path" + "strings" +) + +var ( + // StoreName is the default name for the settings store + StoreName = "ocis-settings-store" + managerName = "filesystem" + emptyKeyError = "key cannot be empty" +) + +// Store interacts with the filesystem to manage settings information +type Store struct { + mountPath string + Logger olog.Logger +} + +// New creates a new store +func New(cfg *config.Config) settings.Manager { + s := Store{} + + dest := path.Join(cfg.Storage.RootMountPath, StoreName) + if _, err := os.Stat(dest); err != nil { + s.Logger.Info().Msgf("creating container on %v", dest) + err := os.MkdirAll(dest, 0700) + if err != nil { + s.Logger.Err(err).Msgf("providing container on %v", dest) + } + } + + s.mountPath = dest + return &s +} + +// List returns all the bundles in the mountPath folder +func (s Store) List() ([]*proto.SettingsBundle, error) { + records := []*proto.SettingsBundle{} + bundles, err := ioutil.ReadDir(s.mountPath) + if err != nil { + s.Logger.Err(err).Msgf("error reading %v", s.mountPath) + return nil, err + } + + s.Logger.Info().Msg("listing bundles") + for _, v := range bundles { + records = append(records, parseFileName(v.Name())) + } + + return records, nil +} + +// ListByExtension returns all bundles in the mountPath folder belonging to the given extension +func (s Store) ListByExtension(extension string) ([]*proto.SettingsBundle, error) { + records := []*proto.SettingsBundle{} + bundles, err := ioutil.ReadDir(s.mountPath) + if err != nil { + s.Logger.Err(err).Msgf("error reading %v", s.mountPath) + return nil, err + } + + s.Logger.Info().Msgf("listing bundles by extension %v", extension) + for _, v := range bundles { + record := parseFileName(v.Name()) + if record.Extension == extension { + records = append(records, record) + } + } + + return records, nil +} + +// Read tries to find a bundle by the given extension and key within the mountPath +func (s Store) Read(extension string, key string) (*proto.SettingsBundle, error) { + fileName := buildFileNameFromData(extension, key) + contents, err := ioutil.ReadFile(path.Join(s.mountPath, fileName)) + if err != nil { + s.Logger.Err(err).Msgf("error reading contents for extension %v and key %v: file not found", extension, key) + return nil, err + } + + record := proto.SettingsBundle{} + if err = json.Unmarshal(contents, &record); err != nil { + s.Logger.Err(err).Msg("error unmarshalling record") + return nil, err + } + + return &record, nil +} + +// Write writes the given record into a file within the mountPath +func (s Store) Write(rec *proto.SettingsBundle) (*proto.SettingsBundle, error) { + if len(rec.Key) < 1 { + s.Logger.Error().Msg("key cannot be empty") + return nil, fmt.Errorf(emptyKeyError) + } + + contents, err := json.Marshal(rec) + if err != nil { + s.Logger.Err(err).Msg("record could not be marshalled") + return nil, err + } + + recordPath := path.Join(s.mountPath, buildFileNameFromBundle(rec)) + if err := ioutil.WriteFile(recordPath, contents, 0644); err != nil { + return nil, err + } + + s.Logger.Info().Msgf("%v bytes written to %v", len(contents), recordPath) + return rec, nil +} + +// Builds a unique file name from the given bundle +func buildFileNameFromBundle(bundle *proto.SettingsBundle) string { + return buildFileNameFromData(bundle.Extension, bundle.Key) +} + +// Builds a unique file name from the given params +func buildFileNameFromData(extension string, key string) string { + return extension + "__" + key + ".json" +} + +// Extracts extension and key from the given fileName and builds a (minimalistic) bundle from it +func parseFileName(fileName string) *proto.SettingsBundle { + parts := strings.Split(strings.Replace(fileName, ".json", "", 1), "__") + return &proto.SettingsBundle{ + Key: parts[1], + Extension: parts[0], + } +} + +func init() { + settings.Registry[managerName] = New +} diff --git a/pkg/store/registry.go b/pkg/store/registry.go new file mode 100644 index 000000000..03fa3840a --- /dev/null +++ b/pkg/store/registry.go @@ -0,0 +1,6 @@ +package store + +import ( + // init filesystem store + _ "github.com/owncloud/ocis-settings/pkg/store/filesystem" +)