From 889a42c964bfd42b60052e8fe5b8b3d042af6e9d Mon Sep 17 00:00:00 2001 From: kobergj Date: Fri, 11 Feb 2022 17:14:48 +0100 Subject: [PATCH] [full-ci] Events (#3146) * initial events draft Signed-off-by: jkoberg * start nats server with ocis Signed-off-by: jkoberg * use feature reva and add config Signed-off-by: jkoberg * remove unneeded files Signed-off-by: jkoberg * edge reva and fix pipeline Signed-off-by: jkoberg * configure nats server via ocis Signed-off-by: jkoberg * update expected failures Signed-off-by: jkoberg * add nats to parallel deployment Signed-off-by: jkoberg * more expected failures Signed-off-by: jkoberg * use NATS instead of cp SETTINGS Signed-off-by: jkoberg * remove more configuration options Signed-off-by: jkoberg --- .drone.star | 2 +- .../oc10_ocis_parallel/docker-compose.yml | 2 +- go.mod | 2 +- nats/cmd/nats/main.go | 14 ++++ nats/pkg/command/health.go | 18 +++++ nats/pkg/command/root.go | 64 +++++++++++++++ nats/pkg/command/server.go | 79 +++++++++++++++++++ nats/pkg/command/version.go | 19 +++++ nats/pkg/config/config.go | 27 +++++++ nats/pkg/config/debug.go | 9 +++ nats/pkg/config/defaultconfig.go | 16 ++++ nats/pkg/config/log.go | 9 +++ nats/pkg/config/parser/parse.go | 40 ++++++++++ nats/pkg/config/service.go | 6 ++ nats/pkg/logging/logging.go | 17 ++++ ocis-pkg/config/config.go | 2 + ocis-pkg/config/defaultconfig.go | 2 + ocis/pkg/command/natsserver.go | 26 ++++++ ocis/pkg/runtime/service/service.go | 2 + storage/pkg/command/sharing.go | 8 ++ 20 files changed, 361 insertions(+), 3 deletions(-) create mode 100644 nats/cmd/nats/main.go create mode 100644 nats/pkg/command/health.go create mode 100644 nats/pkg/command/root.go create mode 100644 nats/pkg/command/server.go create mode 100644 nats/pkg/command/version.go create mode 100644 nats/pkg/config/config.go create mode 100644 nats/pkg/config/debug.go create mode 100644 nats/pkg/config/defaultconfig.go create mode 100644 nats/pkg/config/log.go create mode 100644 nats/pkg/config/parser/parse.go create mode 100644 nats/pkg/config/service.go create mode 100644 nats/pkg/logging/logging.go create mode 100644 ocis/pkg/command/natsserver.go diff --git a/.drone.star b/.drone.star index d11d09d0b1..17242bf6a3 100644 --- a/.drone.star +++ b/.drone.star @@ -1491,7 +1491,7 @@ def ocisServer(storage, accounts_hash_difficulty = 4, volumes = [], depends_on = "OCIS_STORAGE_READ_ONLY": "false", # General oCIS config # OCIS_RUN_EXTENSIONS specifies to start all extensions except glauth, idp and accounts. These are replaced by external services - "OCIS_RUN_EXTENSIONS": "settings,storage-metadata,graph,graph-explorer,ocs,store,thumbnails,web,webdav,storage-frontend,storage-gateway,storage-userprovider,storage-groupprovider,storage-authbasic,storage-authbearer,storage-authmachine,storage-users,storage-shares,storage-public-link,storage-appprovider,storage-sharing,proxy", + "OCIS_RUN_EXTENSIONS": "settings,storage-metadata,graph,graph-explorer,ocs,store,thumbnails,web,webdav,storage-frontend,storage-gateway,storage-userprovider,storage-groupprovider,storage-authbasic,storage-authbearer,storage-authmachine,storage-users,storage-shares,storage-public-link,storage-appprovider,storage-sharing,proxy,nats", "OCIS_LOG_LEVEL": "error", "OCIS_URL": OCIS_URL, "PROXY_TLS": "true", diff --git a/deployments/examples/oc10_ocis_parallel/docker-compose.yml b/deployments/examples/oc10_ocis_parallel/docker-compose.yml index 4e9062ce51..7bbc28b24a 100644 --- a/deployments/examples/oc10_ocis_parallel/docker-compose.yml +++ b/deployments/examples/oc10_ocis_parallel/docker-compose.yml @@ -112,7 +112,7 @@ services: OCIS_STORAGE_READ_ONLY: "false" # TODO: conflict with OWNCLOUDSQL -> https://github.com/owncloud/ocis/issues/2303 # General oCIS config # OCIS_RUN_EXTENSIONS specifies to start all extensions except glauth, idp and accounts. These are replaced by external services - OCIS_RUN_EXTENSIONS: settings,storage-metadata,graph,graph-explorer,ocs,store,thumbnails,web,webdav,storage-frontend,storage-gateway,storage-userprovider,storage-groupprovider,storage-authbasic,storage-authbearer,storage-authmachine,storage-users,storage-shares,storage-public-link,storage-appprovider,storage-sharing,proxy + OCIS_RUN_EXTENSIONS: settings,storage-metadata,graph,graph-explorer,ocs,store,thumbnails,web,webdav,storage-frontend,storage-gateway,storage-userprovider,storage-groupprovider,storage-authbasic,storage-authbearer,storage-authmachine,storage-users,storage-shares,storage-public-link,storage-appprovider,storage-sharing,proxy,nats OCIS_LOG_LEVEL: ${OCIS_LOG_LEVEL:-error} # make oCIS less verbose OCIS_URL: https://${CLOUD_DOMAIN:-cloud.owncloud.test} PROXY_TLS: "false" # do not use SSL between Traefik and oCIS diff --git a/go.mod b/go.mod index 6bc6b75638..5d4bc97e30 100644 --- a/go.mod +++ b/go.mod @@ -44,6 +44,7 @@ require ( github.com/mennanov/fieldmask-utils v0.5.0 github.com/mitchellh/mapstructure v1.4.3 github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 + github.com/nats-io/nats-streaming-server v0.24.1 github.com/nmcclain/asn1-ber v0.0.0-20170104154839-2661553a0484 github.com/nmcclain/ldap v0.0.0-20210720162743-7f8d1e44eeba github.com/oklog/run v1.1.0 @@ -200,7 +201,6 @@ require ( github.com/mschoch/smat v0.2.0 // indirect github.com/nats-io/jwt/v2 v2.2.1-0.20220113022732-58e87895b296 // indirect github.com/nats-io/nats-server/v2 v2.7.2 // indirect - github.com/nats-io/nats-streaming-server v0.24.1 // indirect github.com/nats-io/nats.go v1.13.1-0.20220121202836-972a071d373d // indirect github.com/nats-io/nkeys v0.3.0 // indirect github.com/nats-io/nuid v1.0.1 // indirect diff --git a/nats/cmd/nats/main.go b/nats/cmd/nats/main.go new file mode 100644 index 0000000000..2c6cdac1e7 --- /dev/null +++ b/nats/cmd/nats/main.go @@ -0,0 +1,14 @@ +package main + +import ( + "os" + + "github.com/owncloud/ocis/nats/pkg/command" + "github.com/owncloud/ocis/nats/pkg/config" +) + +func main() { + if err := command.Execute(config.DefaultConfig()); err != nil { + os.Exit(1) + } +} diff --git a/nats/pkg/command/health.go b/nats/pkg/command/health.go new file mode 100644 index 0000000000..e81307406f --- /dev/null +++ b/nats/pkg/command/health.go @@ -0,0 +1,18 @@ +package command + +import ( + "github.com/owncloud/ocis/nats/pkg/config" + "github.com/urfave/cli/v2" +) + +// Health is the entrypoint for the health command. +func Health(cfg *config.Config) *cli.Command { + return &cli.Command{ + Name: "health", + Usage: "Check health status", + Action: func(c *cli.Context) error { + // Not implemented + return nil + }, + } +} diff --git a/nats/pkg/command/root.go b/nats/pkg/command/root.go new file mode 100644 index 0000000000..d21919a555 --- /dev/null +++ b/nats/pkg/command/root.go @@ -0,0 +1,64 @@ +package command + +import ( + "context" + "os" + + "github.com/owncloud/ocis/nats/pkg/config" + "github.com/owncloud/ocis/ocis-pkg/clihelper" + ociscfg "github.com/owncloud/ocis/ocis-pkg/config" + "github.com/thejerf/suture/v4" + "github.com/urfave/cli/v2" +) + +// GetCommands provides all commands for this service +func GetCommands(cfg *config.Config) cli.Commands { + return []*cli.Command{ + // start this service + Server(cfg), + + // interaction with this service + + // infos about this service + Health(cfg), + Version(cfg), + } +} + +// Execute is the entry point for the nats command. +func Execute(cfg *config.Config) error { + app := clihelper.DefaultApp(&cli.App{ + Name: "nats", + Usage: "starts nats server", + Commands: GetCommands(cfg), + }) + + cli.HelpFlag = &cli.BoolFlag{ + Name: "help,h", + Usage: "Show the help", + } + + return app.Run(os.Args) +} + +// SutureService allows for the nats command to be embedded and supervised by a suture supervisor tree. +type SutureService struct { + cfg *config.Config +} + +// NewSutureService creates a new nats.SutureService +func NewSutureService(cfg *ociscfg.Config) suture.Service { + cfg.Settings.Commons = cfg.Commons + return SutureService{ + cfg: cfg.Nats, + } +} + +func (s SutureService) Serve(ctx context.Context) error { + s.cfg.Context = ctx + if err := Execute(s.cfg); err != nil { + return err + } + + return nil +} diff --git a/nats/pkg/command/server.go b/nats/pkg/command/server.go new file mode 100644 index 0000000000..6ce9aae4e3 --- /dev/null +++ b/nats/pkg/command/server.go @@ -0,0 +1,79 @@ +package command + +import ( + "fmt" + + "github.com/cs3org/reva/pkg/events/server" + "github.com/owncloud/ocis/nats/pkg/config" + "github.com/owncloud/ocis/nats/pkg/config/parser" + "github.com/owncloud/ocis/nats/pkg/logging" + "github.com/owncloud/ocis/ocis-pkg/log" + "github.com/urfave/cli/v2" + + // TODO: .Logger Option on events/server would make this import redundant + stanServer "github.com/nats-io/nats-streaming-server/server" +) + +// Server is the entrypoint for the server command. +func Server(cfg *config.Config) *cli.Command { + return &cli.Command{ + Name: "server", + Usage: fmt.Sprintf("start %s extension without runtime (unsupervised mode)", cfg.Service.Name), + Category: "server", + Before: func(c *cli.Context) error { + return parser.ParseConfig(cfg) + }, + Action: func(c *cli.Context) error { + logger := logging.Configure(cfg.Service.Name, cfg.Log) + err := server.RunNatsServer(server.Host(cfg.Nats.Host), server.Port(cfg.Nats.Port), server.StanOpts(func(o *stanServer.Options) { + o.CustomLogger = &logWrapper{logger} + })) + if err != nil { + return err + } + for { + } + }, + } +} + +// we need to wrap our logger so we can pass it to the nats server +type logWrapper struct { + logger log.Logger +} + +// Noticef logs a notice statement +func (l *logWrapper) Noticef(format string, v ...interface{}) { + msg := fmt.Sprintf(format, v...) + l.logger.Info().Msg(msg) +} + +// Warnf logs a warning statement +func (l *logWrapper) Warnf(format string, v ...interface{}) { + msg := fmt.Sprintf(format, v...) + l.logger.Warn().Msg(msg) +} + +// Fatalf logs a fatal statement +func (l *logWrapper) Fatalf(format string, v ...interface{}) { + msg := fmt.Sprintf(format, v...) + l.logger.Fatal().Msg(msg) +} + +// Errorf logs an error statement +func (l *logWrapper) Errorf(format string, v ...interface{}) { + msg := fmt.Sprintf(format, v...) + l.logger.Error().Msg(msg) +} + +// Debugf logs a debug statement +func (l *logWrapper) Debugf(format string, v ...interface{}) { + msg := fmt.Sprintf(format, v...) + l.logger.Debug().Msg(msg) +} + +// Tracef logs a trace statement +func (l *logWrapper) Tracef(format string, v ...interface{}) { + msg := fmt.Sprintf(format, v...) + l.logger.Trace().Msg(msg) +} diff --git a/nats/pkg/command/version.go b/nats/pkg/command/version.go new file mode 100644 index 0000000000..0d29013b7f --- /dev/null +++ b/nats/pkg/command/version.go @@ -0,0 +1,19 @@ +package command + +import ( + "github.com/owncloud/ocis/nats/pkg/config" + "github.com/urfave/cli/v2" +) + +// Version prints the service versions of all running instances. +func Version(cfg *config.Config) *cli.Command { + return &cli.Command{ + Name: "version", + Usage: "print the version of this binary and the running extension instances", + Category: "info", + Action: func(c *cli.Context) error { + // not implemented + return nil + }, + } +} diff --git a/nats/pkg/config/config.go b/nats/pkg/config/config.go new file mode 100644 index 0000000000..f9f2aef6c7 --- /dev/null +++ b/nats/pkg/config/config.go @@ -0,0 +1,27 @@ +package config + +import ( + "context" + + "github.com/owncloud/ocis/ocis-pkg/shared" +) + +// Config combines all available configuration parts. +type Config struct { + *shared.Commons + + Service Service + + Log *Log `ocisConfig:"log"` + Debug Debug `ocisConfig:"debug"` + + Nats Nats `ociConfig:"nats"` + + Context context.Context +} + +// Nats is the nats config +type Nats struct { + Host string + Port int +} diff --git a/nats/pkg/config/debug.go b/nats/pkg/config/debug.go new file mode 100644 index 0000000000..4795db4413 --- /dev/null +++ b/nats/pkg/config/debug.go @@ -0,0 +1,9 @@ +package config + +// Debug defines the available debug configuration. +type Debug struct { + Addr string `ocisConfig:"addr" env:"NATS_DEBUG_ADDR"` + Token string `ocisConfig:"token" env:"NATS_DEBUG_TOKEN"` + Pprof bool `ocisConfig:"pprof" env:"NATS_DEBUG_PPROF"` + Zpages bool `ocisConfig:"zpages" env:"NATS_DEBUG_ZPAGES"` +} diff --git a/nats/pkg/config/defaultconfig.go b/nats/pkg/config/defaultconfig.go new file mode 100644 index 0000000000..e67a584d5f --- /dev/null +++ b/nats/pkg/config/defaultconfig.go @@ -0,0 +1,16 @@ +package config + +// NOTE: Most of this configuration is not needed to keep it as simple as possible +// TODO: Clean up unneeded configuration + +func DefaultConfig() *Config { + return &Config{ + Service: Service{ + Name: "nats", + }, + Nats: Nats{ + Host: "127.0.0.1", + Port: 4222, + }, + } +} diff --git a/nats/pkg/config/log.go b/nats/pkg/config/log.go new file mode 100644 index 0000000000..42d77c8372 --- /dev/null +++ b/nats/pkg/config/log.go @@ -0,0 +1,9 @@ +package config + +// Log defines the available log configuration. +type Log struct { + Level string `mapstructure:"level" env:"OCIS_LOG_LEVEL;NATS_LOG_LEVEL"` + Pretty bool `mapstructure:"pretty" env:"OCIS_LOG_PRETTY;NATS_LOG_PRETTY"` + Color bool `mapstructure:"color" env:"OCIS_LOG_COLOR;NATS_LOG_COLOR"` + File string `mapstructure:"file" env:"OCIS_LOG_FILE;NATS_LOG_FILE"` +} diff --git a/nats/pkg/config/parser/parse.go b/nats/pkg/config/parser/parse.go new file mode 100644 index 0000000000..04e4e2b0a0 --- /dev/null +++ b/nats/pkg/config/parser/parse.go @@ -0,0 +1,40 @@ +package parser + +import ( + "errors" + + "github.com/owncloud/ocis/nats/pkg/config" + ociscfg "github.com/owncloud/ocis/ocis-pkg/config" + + "github.com/owncloud/ocis/ocis-pkg/config/envdecode" +) + +// ParseConfig loads accounts configuration from known paths. +func ParseConfig(cfg *config.Config) error { + _, err := ociscfg.BindSourcesToStructs(cfg.Service.Name, cfg) + if err != nil { + return err + } + + // provide with defaults for shared logging, since we need a valid destination address for BindEnv. + if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil { + cfg.Log = &config.Log{ + Level: cfg.Commons.Log.Level, + Pretty: cfg.Commons.Log.Pretty, + Color: cfg.Commons.Log.Color, + File: cfg.Commons.Log.File, + } + } else if cfg.Log == nil { + cfg.Log = &config.Log{} + } + + // load all env variables relevant to the config in the current context. + if err := envdecode.Decode(cfg); err != nil { + // no environment variable set for this config is an expected "error" + if !errors.Is(err, envdecode.ErrNoTargetFieldsAreSet) { + return err + } + } + + return nil +} diff --git a/nats/pkg/config/service.go b/nats/pkg/config/service.go new file mode 100644 index 0000000000..f98aa3d27e --- /dev/null +++ b/nats/pkg/config/service.go @@ -0,0 +1,6 @@ +package config + +// Service defines the available service configuration. +type Service struct { + Name string +} diff --git a/nats/pkg/logging/logging.go b/nats/pkg/logging/logging.go new file mode 100644 index 0000000000..b60d2c9f94 --- /dev/null +++ b/nats/pkg/logging/logging.go @@ -0,0 +1,17 @@ +package logging + +import ( + "github.com/owncloud/ocis/nats/pkg/config" + "github.com/owncloud/ocis/ocis-pkg/log" +) + +// LoggerFromConfig initializes a service-specific logger instance. +func Configure(name string, cfg *config.Log) log.Logger { + return log.NewLogger( + log.Name(name), + log.Level(cfg.Level), + log.Pretty(cfg.Pretty), + log.Color(cfg.Color), + log.File(cfg.File), + ) +} diff --git a/ocis-pkg/config/config.go b/ocis-pkg/config/config.go index 1f3e3c0d2c..76aaeb35f6 100644 --- a/ocis-pkg/config/config.go +++ b/ocis-pkg/config/config.go @@ -8,6 +8,7 @@ import ( graphExplorer "github.com/owncloud/ocis/graph-explorer/pkg/config" graph "github.com/owncloud/ocis/graph/pkg/config" idp "github.com/owncloud/ocis/idp/pkg/config" + nats "github.com/owncloud/ocis/nats/pkg/config" ocs "github.com/owncloud/ocis/ocs/pkg/config" proxy "github.com/owncloud/ocis/proxy/pkg/config" settings "github.com/owncloud/ocis/settings/pkg/config" @@ -60,6 +61,7 @@ type Config struct { Graph *graph.Config `ocisConfig:"graph"` GraphExplorer *graphExplorer.Config `ocisConfig:"graph_explorer"` IDP *idp.Config `ocisConfig:"idp"` + Nats *nats.Config `ocisConfig:"nats"` OCS *ocs.Config `ocisConfig:"ocs"` Web *web.Config `ocisConfig:"web"` Proxy *proxy.Config `ocisConfig:"proxy"` diff --git a/ocis-pkg/config/defaultconfig.go b/ocis-pkg/config/defaultconfig.go index 21cf14ba05..53853cbfaf 100644 --- a/ocis-pkg/config/defaultconfig.go +++ b/ocis-pkg/config/defaultconfig.go @@ -6,6 +6,7 @@ import ( graphExplorer "github.com/owncloud/ocis/graph-explorer/pkg/config" graph "github.com/owncloud/ocis/graph/pkg/config" idp "github.com/owncloud/ocis/idp/pkg/config" + nats "github.com/owncloud/ocis/nats/pkg/config" ocs "github.com/owncloud/ocis/ocs/pkg/config" proxy "github.com/owncloud/ocis/proxy/pkg/config" settings "github.com/owncloud/ocis/settings/pkg/config" @@ -29,6 +30,7 @@ func DefaultConfig() *Config { GLAuth: glauth.DefaultConfig(), Graph: graph.DefaultConfig(), IDP: idp.DefaultConfig(), + Nats: nats.DefaultConfig(), Proxy: proxy.DefaultConfig(), GraphExplorer: graphExplorer.DefaultConfig(), OCS: ocs.DefaultConfig(), diff --git a/ocis/pkg/command/natsserver.go b/ocis/pkg/command/natsserver.go new file mode 100644 index 0000000000..165f61f0a2 --- /dev/null +++ b/ocis/pkg/command/natsserver.go @@ -0,0 +1,26 @@ +package command + +import ( + "github.com/owncloud/ocis/nats/pkg/command" + "github.com/owncloud/ocis/ocis-pkg/config" + "github.com/owncloud/ocis/ocis-pkg/config/parser" + "github.com/owncloud/ocis/ocis/pkg/register" + "github.com/urfave/cli/v2" +) + +// NatsServerCommand is the entrypoint for the nats server command. +func NatsServerCommand(cfg *config.Config) *cli.Command { + return &cli.Command{ + Name: "nats-server", + Usage: "start nats server", + Category: "extensions", + Before: func(ctx *cli.Context) error { + return parser.ParseConfig(cfg) + }, + Subcommands: command.GetCommands(cfg.Nats), + } +} + +func init() { + register.AddCommand(NatsServerCommand) +} diff --git a/ocis/pkg/runtime/service/service.go b/ocis/pkg/runtime/service/service.go index fa7c68586b..d160305ee0 100644 --- a/ocis/pkg/runtime/service/service.go +++ b/ocis/pkg/runtime/service/service.go @@ -23,6 +23,7 @@ import ( graphExplorer "github.com/owncloud/ocis/graph-explorer/pkg/command" graph "github.com/owncloud/ocis/graph/pkg/command" idp "github.com/owncloud/ocis/idp/pkg/command" + nats "github.com/owncloud/ocis/nats/pkg/command" "github.com/owncloud/ocis/ocis-pkg/config" ociscfg "github.com/owncloud/ocis/ocis-pkg/config" "github.com/owncloud/ocis/ocis-pkg/log" @@ -91,6 +92,7 @@ func NewService(options ...Option) (*Service, error) { } s.ServicesRegistry["settings"] = settings.NewSutureService + s.ServicesRegistry["nats"] = nats.NewSutureService s.ServicesRegistry["storage-metadata"] = storage.NewStorageMetadata s.ServicesRegistry["glauth"] = glauth.NewSutureService s.ServicesRegistry["graph"] = graph.NewSutureService diff --git a/storage/pkg/command/sharing.go b/storage/pkg/command/sharing.go index 52735f32b3..ce21db21fe 100644 --- a/storage/pkg/command/sharing.go +++ b/storage/pkg/command/sharing.go @@ -175,6 +175,14 @@ func sharingConfigFromStruct(c *cli.Context, cfg *config.Config) map[string]inte }, }, }, + "interceptors": map[string]interface{}{ + "eventsmiddleware": map[string]interface{}{ + "group": "sharing", + "type": "nats", + "address": "127.0.0.1:4222", + "clusterID": "test-cluster", + }, + }, }, } return rcfg