From 9fa77a27ba739d9bf8e2be344a10003159605c08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Mon, 15 Mar 2021 15:17:29 +0000 Subject: [PATCH] fix graph and graph-explorer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jörn Friedrich Dreyer --- accounts/pkg/command/root.go | 6 +- graph-explorer/cmd/graph-explorer/main.go | 3 +- graph-explorer/pkg/command/root.go | 118 ++++++++++++++-------- graph-explorer/pkg/command/server.go | 75 +++++--------- graph-explorer/pkg/config/config.go | 13 ++- graph-explorer/pkg/flagset/flagset.go | 32 +++--- graph-explorer/pkg/metrics/metrics.go | 21 ++-- graph/cmd/graph/main.go | 3 +- graph/pkg/command/root.go | 34 ++++++- graph/pkg/command/server.go | 77 +++++--------- graph/pkg/config/config.go | 12 +++ graph/pkg/flagset/flagset.go | 6 +- graph/pkg/metrics/metrics.go | 21 ++-- graph/pkg/service/v0/groups.go | 8 +- graph/pkg/service/v0/users.go | 11 +- ocis/pkg/runtime/service/service.go | 4 + proxy/pkg/proxy/proxy.go | 8 ++ web/pkg/flagset/flagset.go | 2 +- 18 files changed, 254 insertions(+), 200 deletions(-) diff --git a/accounts/pkg/command/root.go b/accounts/pkg/command/root.go index 0dc270fc9..731cf3774 100644 --- a/accounts/pkg/command/root.go +++ b/accounts/pkg/command/root.go @@ -5,15 +5,13 @@ import ( "os" "strings" - "github.com/owncloud/ocis/ocis-pkg/sync" - - "github.com/owncloud/ocis/accounts/pkg/flagset" - "github.com/micro/cli/v2" "github.com/owncloud/ocis/accounts/pkg/config" + "github.com/owncloud/ocis/accounts/pkg/flagset" "github.com/owncloud/ocis/accounts/pkg/version" ociscfg "github.com/owncloud/ocis/ocis-pkg/config" "github.com/owncloud/ocis/ocis-pkg/log" + "github.com/owncloud/ocis/ocis-pkg/sync" "github.com/spf13/viper" "github.com/thejerf/suture/v4" ) diff --git a/graph-explorer/cmd/graph-explorer/main.go b/graph-explorer/cmd/graph-explorer/main.go index f5a83bcd6..f0d3cdcac 100644 --- a/graph-explorer/cmd/graph-explorer/main.go +++ b/graph-explorer/cmd/graph-explorer/main.go @@ -4,10 +4,11 @@ import ( "os" "github.com/owncloud/ocis/graph-explorer/pkg/command" + "github.com/owncloud/ocis/graph-explorer/pkg/config" ) func main() { - if err := command.Execute(); err != nil { + if err := command.Execute(config.New()); err != nil { os.Exit(1) } } diff --git a/graph-explorer/pkg/command/root.go b/graph-explorer/pkg/command/root.go index 9ff72d7fa..8252b158f 100644 --- a/graph-explorer/pkg/command/root.go +++ b/graph-explorer/pkg/command/root.go @@ -1,6 +1,7 @@ package command import ( + "context" "os" "strings" @@ -8,14 +9,15 @@ import ( "github.com/owncloud/ocis/graph-explorer/pkg/config" "github.com/owncloud/ocis/graph-explorer/pkg/flagset" "github.com/owncloud/ocis/graph-explorer/pkg/version" + ociscfg "github.com/owncloud/ocis/ocis-pkg/config" "github.com/owncloud/ocis/ocis-pkg/log" + "github.com/owncloud/ocis/ocis-pkg/sync" "github.com/spf13/viper" + "github.com/thejerf/suture/v4" ) // Execute is the entry point for the graph-explorer command. -func Execute() error { - cfg := config.New() - +func Execute(cfg *config.Config) error { app := &cli.App{ Name: "graph-explorer", Version: version.String, @@ -32,45 +34,8 @@ func Execute() error { Flags: flagset.RootWithConfig(cfg), Before: func(c *cli.Context) error { - logger := NewLogger(cfg) - - viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) - viper.SetEnvPrefix("GRAPH_EXPLORER") - viper.AutomaticEnv() - - if c.IsSet("config-file") { - viper.SetConfigFile(c.String("config-file")) - } else { - viper.SetConfigName("graph-explorer") - - viper.AddConfigPath("/etc/ocis") - viper.AddConfigPath("$HOME/.ocis") - viper.AddConfigPath("./config") - } - - if err := viper.ReadInConfig(); err != nil { - switch err.(type) { - case viper.ConfigFileNotFoundError: - logger.Info(). - Msg("Continue without config") - case viper.UnsupportedConfigError: - logger.Fatal(). - Err(err). - Msg("Unsupported config type") - default: - logger.Fatal(). - Err(err). - Msg("Failed to read config") - } - } - - if err := viper.Unmarshal(&cfg); err != nil { - logger.Fatal(). - Err(err). - Msg("Failed to parse config") - } - - return nil + cfg.Server.Version = version.String + return ParseConfig(c, cfg) }, Commands: []*cli.Command{ @@ -101,3 +66,72 @@ func NewLogger(cfg *config.Config) log.Logger { log.Color(cfg.Log.Color), ) } + +// ParseConfig loads accounts configuration from Viper known paths. +func ParseConfig(c *cli.Context, cfg *config.Config) error { + sync.ParsingViperConfig.Lock() + defer sync.ParsingViperConfig.Unlock() + logger := NewLogger(cfg) + + viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) + viper.SetEnvPrefix("GRAPH_EXPLORER") + viper.AutomaticEnv() + + if c.IsSet("config-file") { + viper.SetConfigFile(c.String("config-file")) + } else { + viper.SetConfigName("graph-explorer") + + viper.AddConfigPath("/etc/ocis") + viper.AddConfigPath("$HOME/.ocis") + viper.AddConfigPath("./config") + } + + if err := viper.ReadInConfig(); err != nil { + switch err.(type) { + case viper.ConfigFileNotFoundError: + logger.Info(). + Msg("Continue without config") + case viper.UnsupportedConfigError: + logger.Fatal(). + Err(err). + Msg("Unsupported config type") + default: + logger.Fatal(). + Err(err). + Msg("Failed to read config") + } + } + + if err := viper.Unmarshal(&cfg); err != nil { + logger.Fatal(). + Err(err). + Msg("Failed to parse config") + } + + return nil +} + +// SutureService allows for the graph-explorer command to be embedded and supervised by a suture supervisor tree. +type SutureService struct { + cfg *config.Config +} + +// NewSutureService creates a new graph-explorer.SutureService +func NewSutureService(cfg *ociscfg.Config) suture.Service { + if cfg.Mode == 0 { + cfg.GraphExplorer.Supervised = true + } + return SutureService{ + cfg: cfg.GraphExplorer, + } +} + +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/graph-explorer/pkg/command/server.go b/graph-explorer/pkg/command/server.go index 986c88a12..4a2735786 100644 --- a/graph-explorer/pkg/command/server.go +++ b/graph-explorer/pkg/command/server.go @@ -2,8 +2,6 @@ package command import ( "context" - "os" - "os/signal" "strings" "time" @@ -19,6 +17,7 @@ import ( "github.com/owncloud/ocis/graph-explorer/pkg/metrics" "github.com/owncloud/ocis/graph-explorer/pkg/server/debug" "github.com/owncloud/ocis/graph-explorer/pkg/server/http" + "github.com/owncloud/ocis/ocis-pkg/sync" "go.opencensus.io/stats/view" "go.opencensus.io/trace" ) @@ -29,11 +28,18 @@ func Server(cfg *config.Config) *cli.Command { Name: "server", Usage: "Start integrated server", Flags: flagset.ServerWithConfig(cfg), - Before: func(c *cli.Context) error { + Before: func(ctx *cli.Context) error { + logger := NewLogger(cfg) if cfg.HTTP.Root != "/" { cfg.HTTP.Root = strings.TrimSuffix(cfg.HTTP.Root, "/") } + // When running on single binary mode the before hook from the root command won't get called. We manually + // call this before hook from ocis command, so the configuration can be loaded. + if !cfg.Supervised { + return ParseConfig(ctx, cfg) + } + logger.Debug().Str("service", "graph-explorer").Msg("ignoring config file parsing when running supervised") return nil }, Action: func(c *cli.Context) error { @@ -125,29 +131,30 @@ func Server(cfg *config.Config) *cli.Command { var ( gr = run.Group{} - ctx, cancel = context.WithCancel(context.Background()) - metrics = metrics.New() + ctx, cancel = func() (context.Context, context.CancelFunc) { + if cfg.Context == nil { + return context.WithCancel(context.Background()) + } + return context.WithCancel(cfg.Context) + }() + mtrcs = metrics.New() ) defer cancel() + mtrcs.BuildInfo.WithLabelValues(cfg.Server.Version).Set(1) + { server, err := http.Server( http.Logger(logger), http.Context(ctx), http.Namespace(cfg.HTTP.Namespace), http.Config(cfg), - http.Metrics(metrics), - http.Flags(flagset.RootWithConfig(cfg)), - http.Flags(flagset.ServerWithConfig(cfg)), + http.Metrics(mtrcs), ) if err != nil { - logger.Info(). - Err(err). - Str("transport", "http"). - Msg("Failed to initialize server") - + logger.Info().Err(err).Str("transport", "http").Msg("Failed to initialize server") return err } @@ -177,48 +184,18 @@ func Server(cfg *config.Config) *cli.Command { ) if err != nil { - logger.Info(). - Err(err). - Str("transport", "debug"). - Msg("Failed to initialize server") - + logger.Info().Err(err).Str("transport", "debug").Msg("Failed to initialize server") return err } - gr.Add(func() error { - return server.ListenAndServe() - }, func(_ error) { - ctx, timeout := context.WithTimeout(ctx, 5*time.Second) - - defer timeout() - defer cancel() - - if err := server.Shutdown(ctx); err != nil { - logger.Info(). - Err(err). - Str("transport", "debug"). - Msg("Failed to shutdown server") - } else { - logger.Info(). - Str("transport", "debug"). - Msg("Shutting down server") - } + gr.Add(server.ListenAndServe, func(_ error) { + _ = server.Shutdown(ctx) + cancel() }) } - { - stop := make(chan os.Signal, 1) - - gr.Add(func() error { - signal.Notify(stop, os.Interrupt) - - <-stop - - return nil - }, func(err error) { - //close(stop) - cancel() - }) + if !cfg.Supervised { + sync.Trap(&gr, cancel) } return gr.Run() diff --git a/graph-explorer/pkg/config/config.go b/graph-explorer/pkg/config/config.go index 8c9ba7347..9a7c2288e 100644 --- a/graph-explorer/pkg/config/config.go +++ b/graph-explorer/pkg/config/config.go @@ -1,5 +1,7 @@ package config +import "context" + // Log defines the available logging configuration. type Log struct { Level string @@ -22,6 +24,12 @@ type HTTP struct { Namespace string } +// Server configures a server. +type Server struct { + Version string + Name string +} + // Tracing defines the available tracing configuration. type Tracing struct { Enabled bool @@ -44,9 +52,12 @@ type Config struct { Log Log Debug Debug HTTP HTTP + Server Server Tracing Tracing GraphExplorer GraphExplorer - Supervised bool + + Context context.Context + Supervised bool } // New initializes a new configuration with or without defaults. diff --git a/graph-explorer/pkg/flagset/flagset.go b/graph-explorer/pkg/flagset/flagset.go index f8edfec2b..df69a637d 100644 --- a/graph-explorer/pkg/flagset/flagset.go +++ b/graph-explorer/pkg/flagset/flagset.go @@ -3,6 +3,7 @@ package flagset import ( "github.com/micro/cli/v2" "github.com/owncloud/ocis/graph-explorer/pkg/config" + "github.com/owncloud/ocis/ocis-pkg/flags" ) // RootWithConfig applies cfg to the root flagset @@ -10,20 +11,17 @@ func RootWithConfig(cfg *config.Config) []cli.Flag { return []cli.Flag{ &cli.StringFlag{ Name: "log-level", - Value: "info", Usage: "Set logging level", EnvVars: []string{"GRAPH_EXPLORER_LOG_LEVEL"}, Destination: &cfg.Log.Level, }, &cli.BoolFlag{ - Value: true, Name: "log-pretty", Usage: "Enable pretty logging", EnvVars: []string{"GRAPH_EXPLORER_LOG_PRETTY"}, Destination: &cfg.Log.Pretty, }, &cli.BoolFlag{ - Value: true, Name: "log-color", Usage: "Enable colored logging", EnvVars: []string{"GRAPH_EXPLORER_LOG_COLOR"}, @@ -37,7 +35,7 @@ func HealthWithConfig(cfg *config.Config) []cli.Flag { return []cli.Flag{ &cli.StringFlag{ Name: "debug-addr", - Value: "0.0.0.0:9136", + Value: flags.OverrideDefaultString(cfg.Debug.Addr, "0.0.0.0:9136"), Usage: "Address to debug endpoint", EnvVars: []string{"GRAPH_EXPLORER_DEBUG_ADDR"}, Destination: &cfg.Debug.Addr, @@ -56,42 +54,42 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag { }, &cli.StringFlag{ Name: "tracing-type", - Value: "jaeger", + Value: flags.OverrideDefaultString(cfg.Tracing.Type, "jaeger"), Usage: "Tracing backend type", EnvVars: []string{"GRAPH_EXPLORER_TRACING_TYPE"}, Destination: &cfg.Tracing.Type, }, &cli.StringFlag{ Name: "tracing-endpoint", - Value: "", + Value: flags.OverrideDefaultString(cfg.Tracing.Endpoint, ""), Usage: "Endpoint for the agent", EnvVars: []string{"GRAPH_EXPLORER_TRACING_ENDPOINT"}, Destination: &cfg.Tracing.Endpoint, }, &cli.StringFlag{ Name: "tracing-collector", - Value: "", + Value: flags.OverrideDefaultString(cfg.Tracing.Collector, ""), Usage: "Endpoint for the collector", EnvVars: []string{"GRAPH_EXPLORER_TRACING_COLLECTOR"}, Destination: &cfg.Tracing.Collector, }, &cli.StringFlag{ Name: "tracing-service", - Value: "graph-explorer", + Value: flags.OverrideDefaultString(cfg.Tracing.Service, "graph-explorer"), Usage: "Service name for tracing", EnvVars: []string{"GRAPH_EXPLORER_TRACING_SERVICE"}, Destination: &cfg.Tracing.Service, }, &cli.StringFlag{ Name: "debug-addr", - Value: "0.0.0.0:9136", + Value: flags.OverrideDefaultString(cfg.Debug.Addr, "0.0.0.0:9136"), Usage: "Address to bind debug server", EnvVars: []string{"GRAPH_EXPLORER_DEBUG_ADDR"}, Destination: &cfg.Debug.Addr, }, &cli.StringFlag{ Name: "debug-token", - Value: "", + Value: flags.OverrideDefaultString(cfg.Debug.Token, ""), Usage: "Token to grant metrics access", EnvVars: []string{"GRAPH_EXPLORER_DEBUG_TOKEN"}, Destination: &cfg.Debug.Token, @@ -110,42 +108,42 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag { }, &cli.StringFlag{ Name: "http-addr", - Value: "0.0.0.0:9135", + Value: flags.OverrideDefaultString(cfg.HTTP.Addr, "0.0.0.0:9135"), Usage: "Address to bind http server", EnvVars: []string{"GRAPH_EXPLORER_HTTP_ADDR"}, Destination: &cfg.HTTP.Addr, }, &cli.StringFlag{ Name: "http-root", - Value: "/", + Value: flags.OverrideDefaultString(cfg.HTTP.Root, "/graph-explorer"), Usage: "Root path of http server", EnvVars: []string{"GRAPH_EXPLORER_HTTP_ROOT"}, Destination: &cfg.HTTP.Root, }, &cli.StringFlag{ Name: "http-namespace", - Value: "com.owncloud.web", + Value: flags.OverrideDefaultString(cfg.HTTP.Namespace, "com.owncloud.web"), Usage: "Set the base namespace for the http namespace", EnvVars: []string{"GRAPH_EXPLORER_NAMESPACE"}, Destination: &cfg.HTTP.Namespace, }, &cli.StringFlag{ Name: "issuer", - Value: "https://localhost:9130", + Value: flags.OverrideDefaultString(cfg.GraphExplorer.Issuer, "https://localhost:9200"), Usage: "Set the OpenID Connect Provider", - EnvVars: []string{"GRAPH_EXPLORER_ISSUER"}, + EnvVars: []string{"GRAPH_EXPLORER_ISSUER", "OCIS_URL"}, Destination: &cfg.GraphExplorer.Issuer, }, &cli.StringFlag{ Name: "client-id", - Value: "ocis-explorer.js", + Value: flags.OverrideDefaultString(cfg.GraphExplorer.ClientID, "ocis-explorer.js"), Usage: "Set the OpenID Client ID to send to the issuer", EnvVars: []string{"GRAPH_EXPLORER_CLIENT_ID"}, Destination: &cfg.GraphExplorer.ClientID, }, &cli.StringFlag{ Name: "graph-url", - Value: "http://localhost:9120", + Value: flags.OverrideDefaultString(cfg.GraphExplorer.GraphURL, "https://localhost:9200/graph"), Usage: "Set the url to the graph api service", EnvVars: []string{"GRAPH_EXPLORER_GRAPH_URL"}, Destination: &cfg.GraphExplorer.GraphURL, diff --git a/graph-explorer/pkg/metrics/metrics.go b/graph-explorer/pkg/metrics/metrics.go index 42989bd5a..be28d582e 100644 --- a/graph-explorer/pkg/metrics/metrics.go +++ b/graph-explorer/pkg/metrics/metrics.go @@ -1,5 +1,7 @@ package metrics +import "github.com/prometheus/client_golang/prometheus" + var ( // Namespace defines the namespace for the defines metrics. Namespace = "ocis" @@ -11,22 +13,21 @@ var ( // Metrics defines the available metrics of this service. type Metrics struct { // Counter *prometheus.CounterVec + BuildInfo *prometheus.GaugeVec } // New initializes the available metrics. func New() *Metrics { m := &Metrics{ - // Counter: prometheus.NewCounterVec(prometheus.CounterOpts{ - // Namespace: Namespace, - // Subsystem: Subsystem, - // Name: "greet_total", - // Help: "How many greeting requests processed", - // }, []string{}), + BuildInfo: prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Namespace: Namespace, + Subsystem: Subsystem, + Name: "build_info", + Help: "Build information", + }, []string{"version"}), } - // prometheus.Register( - // m.Counter, - // ) - + _ = prometheus.Register(m.BuildInfo) + // TODO: implement metrics return m } diff --git a/graph/cmd/graph/main.go b/graph/cmd/graph/main.go index bc98213e3..c43db0993 100644 --- a/graph/cmd/graph/main.go +++ b/graph/cmd/graph/main.go @@ -4,10 +4,11 @@ import ( "os" "github.com/owncloud/ocis/graph/pkg/command" + "github.com/owncloud/ocis/graph/pkg/config" ) func main() { - if err := command.Execute(); err != nil { + if err := command.Execute(config.New()); err != nil { os.Exit(1) } } diff --git a/graph/pkg/command/root.go b/graph/pkg/command/root.go index a179de92d..aae6a9055 100644 --- a/graph/pkg/command/root.go +++ b/graph/pkg/command/root.go @@ -1,25 +1,26 @@ package command import ( + "context" "os" "strings" "github.com/owncloud/ocis/ocis-pkg/sync" + "github.com/thejerf/suture/v4" "github.com/micro/cli/v2" "github.com/owncloud/ocis/graph/pkg/config" "github.com/owncloud/ocis/graph/pkg/flagset" "github.com/owncloud/ocis/graph/pkg/version" + ociscfg "github.com/owncloud/ocis/ocis-pkg/config" "github.com/owncloud/ocis/ocis-pkg/log" "github.com/spf13/viper" ) // Execute is the entry point for the ocis-graph command. -func Execute() error { - cfg := config.New() - +func Execute(cfg *config.Config) error { app := &cli.App{ - Name: "graph", + Name: "ocis-graph", Version: version.String, Usage: "Serve Graph API for oCIS", Compiled: version.Compiled(), @@ -34,6 +35,7 @@ func Execute() error { Flags: flagset.RootWithConfig(cfg), Before: func(c *cli.Context) error { + cfg.Server.Version = version.String return ParseConfig(c, cfg) }, @@ -110,3 +112,27 @@ func ParseConfig(c *cli.Context, cfg *config.Config) error { return nil } + +// SutureService allows for the graph command to be embedded and supervised by a suture supervisor tree. +type SutureService struct { + cfg *config.Config +} + +// NewSutureService creates a new graph.SutureService +func NewSutureService(cfg *ociscfg.Config) suture.Service { + if cfg.Mode == 0 { + cfg.Graph.Supervised = true + } + return SutureService{ + cfg: cfg.Graph, + } +} + +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/graph/pkg/command/server.go b/graph/pkg/command/server.go index a17a86a58..bb184c8e1 100644 --- a/graph/pkg/command/server.go +++ b/graph/pkg/command/server.go @@ -2,8 +2,6 @@ package command import ( "context" - "os" - "os/signal" "strings" "time" @@ -19,6 +17,7 @@ import ( "github.com/owncloud/ocis/graph/pkg/metrics" "github.com/owncloud/ocis/graph/pkg/server/debug" "github.com/owncloud/ocis/graph/pkg/server/http" + "github.com/owncloud/ocis/ocis-pkg/sync" "go.opencensus.io/stats/view" "go.opencensus.io/trace" ) @@ -29,12 +28,19 @@ func Server(cfg *config.Config) *cli.Command { Name: "server", Usage: "Start integrated server", Flags: flagset.ServerWithConfig(cfg), - Before: func(c *cli.Context) error { + Before: func(ctx *cli.Context) error { + logger := NewLogger(cfg) if cfg.HTTP.Root != "/" { cfg.HTTP.Root = strings.TrimSuffix(cfg.HTTP.Root, "/") } - return ParseConfig(c, cfg) + // When running on single binary mode the before hook from the root command won't get called. We manually + // call this before hook from ocis command, so the configuration can be loaded. + if !cfg.Supervised { + return ParseConfig(ctx, cfg) + } + logger.Debug().Str("service", "graph").Msg("ignoring config file parsing when running supervised") + return nil }, Action: func(c *cli.Context) error { logger := NewLogger(cfg) @@ -125,28 +131,29 @@ func Server(cfg *config.Config) *cli.Command { var ( gr = run.Group{} - ctx, cancel = context.WithCancel(context.Background()) - metrics = metrics.New() + ctx, cancel = func() (context.Context, context.CancelFunc) { + if cfg.Context == nil { + return context.WithCancel(context.Background()) + } + return context.WithCancel(cfg.Context) + }() + mtrcs = metrics.New() ) defer cancel() + mtrcs.BuildInfo.WithLabelValues(cfg.Server.Version).Set(1) + { server, err := http.Server( http.Logger(logger), http.Context(ctx), http.Config(cfg), - http.Metrics(metrics), - http.Flags(flagset.RootWithConfig(cfg)), - http.Flags(flagset.ServerWithConfig(cfg)), + http.Metrics(mtrcs), ) if err != nil { - logger.Info(). - Err(err). - Str("transport", "http"). - Msg("Failed to initialize server") - + logger.Info().Err(err).Str("transport", "http").Msg("Failed to initialize server") return err } @@ -169,48 +176,18 @@ func Server(cfg *config.Config) *cli.Command { ) if err != nil { - logger.Info(). - Err(err). - Str("transport", "debug"). - Msg("Failed to initialize server") - + logger.Info().Err(err).Str("transport", "debug").Msg("Failed to initialize server") return err } - gr.Add(func() error { - return server.ListenAndServe() - }, func(_ error) { - ctx, timeout := context.WithTimeout(ctx, 5*time.Second) - - defer timeout() - defer cancel() - - if err := server.Shutdown(ctx); err != nil { - logger.Info(). - Err(err). - Str("transport", "debug"). - Msg("Failed to shutdown server") - } else { - logger.Info(). - Str("transport", "debug"). - Msg("Shutting down server") - } + gr.Add(server.ListenAndServe, func(_ error) { + _ = server.Shutdown(ctx) + cancel() }) } - { - stop := make(chan os.Signal, 1) - - gr.Add(func() error { - signal.Notify(stop, os.Interrupt) - - <-stop - - return nil - }, func(err error) { - //close(stop) - cancel() - }) + if !cfg.Supervised { + sync.Trap(&gr, cancel) } return gr.Run() diff --git a/graph/pkg/config/config.go b/graph/pkg/config/config.go index abfc50915..580652a89 100644 --- a/graph/pkg/config/config.go +++ b/graph/pkg/config/config.go @@ -1,5 +1,7 @@ package config +import "context" + // Log defines the available logging configuration. type Log struct { Level string @@ -22,6 +24,12 @@ type HTTP struct { Root string } +// Server configures a server. +type Server struct { + Version string + Name string +} + // Tracing defines the available tracing configuration. type Tracing struct { Enabled bool @@ -60,10 +68,14 @@ type Config struct { Log Log Debug Debug HTTP HTTP + Server Server Tracing Tracing Ldap Ldap OpenIDConnect OpenIDConnect Reva Reva + + Context context.Context + Supervised bool } // New initializes a new configuration with or without defaults. diff --git a/graph/pkg/flagset/flagset.go b/graph/pkg/flagset/flagset.go index deb3f37af..0f161e975 100644 --- a/graph/pkg/flagset/flagset.go +++ b/graph/pkg/flagset/flagset.go @@ -122,7 +122,7 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag { }, &cli.StringFlag{ Name: "http-root", - Value: flags.OverrideDefaultString(cfg.HTTP.Root, "/"), + Value: flags.OverrideDefaultString(cfg.HTTP.Root, "/graph"), Usage: "Root path of http server", EnvVars: []string{"GRAPH_HTTP_ROOT"}, Destination: &cfg.HTTP.Root, @@ -178,9 +178,9 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag { }, &cli.StringFlag{ Name: "oidc-endpoint", - Value: flags.OverrideDefaultString(cfg.OpenIDConnect.Endpoint, "https://localhost:9130"), + Value: flags.OverrideDefaultString(cfg.OpenIDConnect.Endpoint, "https://localhost:9200"), Usage: "OpenIDConnect endpoint", - EnvVars: []string{"GRAPH_OIDC_ENDPOINT"}, + EnvVars: []string{"GRAPH_OIDC_ENDPOINT", "OCIS_URL"}, Destination: &cfg.OpenIDConnect.Endpoint, }, &cli.BoolFlag{ diff --git a/graph/pkg/metrics/metrics.go b/graph/pkg/metrics/metrics.go index 2f192d0ff..00108406f 100644 --- a/graph/pkg/metrics/metrics.go +++ b/graph/pkg/metrics/metrics.go @@ -1,5 +1,7 @@ package metrics +import "github.com/prometheus/client_golang/prometheus" + var ( // Namespace defines the namespace for the defines metrics. Namespace = "ocis" @@ -11,22 +13,21 @@ var ( // Metrics defines the available metrics of this service. type Metrics struct { // Counter *prometheus.CounterVec + BuildInfo *prometheus.GaugeVec } // New initializes the available metrics. func New() *Metrics { m := &Metrics{ - // Counter: prometheus.NewCounterVec(prometheus.CounterOpts{ - // Namespace: Namespace, - // Subsystem: Subsystem, - // Name: "greet_total", - // Help: "How many greeting requests processed", - // }, []string{}), + BuildInfo: prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Namespace: Namespace, + Subsystem: Subsystem, + Name: "build_info", + Help: "Build information", + }, []string{"version"}), } - // prometheus.Register( - // m.Counter, - // ) - + _ = prometheus.Register(m.BuildInfo) + // TODO: implement metrics return m } diff --git a/graph/pkg/service/v0/groups.go b/graph/pkg/service/v0/groups.go index a00cb5b75..c98619c21 100644 --- a/graph/pkg/service/v0/groups.go +++ b/graph/pkg/service/v0/groups.go @@ -23,7 +23,8 @@ func (g Graph) GroupCtx(next http.Handler) http.Handler { errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest) return } - filter := fmt.Sprintf("(entryuuid=%s)", groupID) + // TODO make filter configurable + filter := fmt.Sprintf("(&(objectClass=posixGroup)(ownCloudUUID=%s))", groupID) group, err := g.ldapGetSingleEntry(g.config.Ldap.BaseDNGroups, filter) if err != nil { g.logger.Info().Err(err).Msgf("Failed to read group %s", groupID) @@ -45,10 +46,11 @@ func (g Graph) GetGroups(w http.ResponseWriter, r *http.Request) { return } - result, err := g.ldapSearch(con, "(objectclass=*)", g.config.Ldap.BaseDNGroups) + // TODO make filter configurable + result, err := g.ldapSearch(con, "(objectClass=posixGroup)", g.config.Ldap.BaseDNGroups) if err != nil { - g.logger.Error().Err(err).Msg("Failed search ldap with filter: '(objectclass=*)'") + g.logger.Error().Err(err).Msg("Failed search ldap with filter: '(objectClass=posixGroup)'") errorcode.ServiceNotAvailable.Render(w, r, http.StatusInternalServerError) return } diff --git a/graph/pkg/service/v0/users.go b/graph/pkg/service/v0/users.go index 8e6fc81bb..ba20972b2 100644 --- a/graph/pkg/service/v0/users.go +++ b/graph/pkg/service/v0/users.go @@ -27,7 +27,8 @@ func (g Graph) UserCtx(next http.Handler) http.Handler { errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest) return } - filter := fmt.Sprintf("(entryuuid=%s)", userID) + // TODO make filter configurable + filter := fmt.Sprintf("(&(objectClass=posixAccount)(ownCloudUUID=%s))", userID) user, err = g.ldapGetSingleEntry(g.config.Ldap.BaseDNUsers, filter) if err != nil { g.logger.Info().Err(err).Msgf("Failed to read user %s", userID) @@ -45,7 +46,8 @@ func (g Graph) GetMe(w http.ResponseWriter, r *http.Request) { claims := oidc.FromContext(r.Context()) g.logger.Info().Interface("Claims", claims).Msg("Claims in /me") - filter := fmt.Sprintf("(uid=%s)", claims.PreferredUsername) + // TODO make filter configurable + filter := fmt.Sprintf("(&(objectClass=posixAccount)(cn=%s))", claims.PreferredUsername) user, err := g.ldapGetSingleEntry(g.config.Ldap.BaseDNUsers, filter) if err != nil { g.logger.Info().Err(err).Msgf("Failed to read user %s", claims.PreferredUsername) @@ -68,10 +70,11 @@ func (g Graph) GetUsers(w http.ResponseWriter, r *http.Request) { return } - result, err := g.ldapSearch(con, "(objectclass=*)", g.config.Ldap.BaseDNUsers) + // TODO make filter configurable + result, err := g.ldapSearch(con, "(objectClass=posixAccount)", g.config.Ldap.BaseDNUsers) if err != nil { - g.logger.Error().Err(err).Msg("Failed search ldap with filter: '(objectclass=*)'") + g.logger.Error().Err(err).Msg("Failed search ldap with filter: '(objectClass=posixAccount)'") errorcode.ServiceNotAvailable.Render(w, r, http.StatusInternalServerError) return } diff --git a/ocis/pkg/runtime/service/service.go b/ocis/pkg/runtime/service/service.go index a1d089b3a..93e8417e1 100644 --- a/ocis/pkg/runtime/service/service.go +++ b/ocis/pkg/runtime/service/service.go @@ -19,6 +19,8 @@ import ( "github.com/olekukonko/tablewriter" accounts "github.com/owncloud/ocis/accounts/pkg/command" glauth "github.com/owncloud/ocis/glauth/pkg/command" + graph "github.com/owncloud/ocis/graph/pkg/command" + graphExplorer "github.com/owncloud/ocis/graph-explorer/pkg/command" idp "github.com/owncloud/ocis/idp/pkg/command" ociscfg "github.com/owncloud/ocis/ocis-pkg/config" "github.com/owncloud/ocis/ocis-pkg/log" @@ -82,6 +84,8 @@ func NewService(options ...Option) (*Service, error) { s.ServicesRegistry["settings"] = settings.NewSutureService s.ServicesRegistry["storage-metadata"] = storage.NewStorageMetadata s.ServicesRegistry["glauth"] = glauth.NewSutureService + s.ServicesRegistry["graph"] = graph.NewSutureService + s.ServicesRegistry["graph-explorer"] = graphExplorer.NewSutureService s.ServicesRegistry["idp"] = idp.NewSutureService s.ServicesRegistry["ocs"] = ocs.NewSutureService s.ServicesRegistry["onlyoffice"] = onlyoffice.NewSutureService diff --git a/proxy/pkg/proxy/proxy.go b/proxy/pkg/proxy/proxy.go index 8e588418c..3f4d92bda 100644 --- a/proxy/pkg/proxy/proxy.go +++ b/proxy/pkg/proxy/proxy.go @@ -322,6 +322,14 @@ func defaultPolicies() []config.Policy { Endpoint: "/data", Backend: "http://localhost:9140", }, + { + Endpoint: "/graph/", + Backend: "http://localhost:9120", + }, + { + Endpoint: "/graph-explorer/", + Backend: "http://localhost:9135", + }, // if we were using the go micro api gateway we could look up the endpoint in the registry dynamically { Endpoint: "/api/v0/accounts", diff --git a/web/pkg/flagset/flagset.go b/web/pkg/flagset/flagset.go index 1c52d3734..982377bf5 100644 --- a/web/pkg/flagset/flagset.go +++ b/web/pkg/flagset/flagset.go @@ -35,7 +35,7 @@ func HealthWithConfig(cfg *config.Config) []cli.Flag { return []cli.Flag{ &cli.StringFlag{ Name: "debug-addr", - Value: "0.0.0.0:9104", + Value: flags.OverrideDefaultString(cfg.Debug.Addr, "0.0.0.0:9104"), Usage: "Address to debug endpoint", EnvVars: []string{"WEB_DEBUG_ADDR"}, Destination: &cfg.Debug.Addr,