package main import ( "net/http" "forge.cadoles.com/wpetit/hydra-passwordless/internal/route" "github.com/getsentry/sentry-go" "github.com/go-chi/chi" "github.com/go-chi/chi/middleware" "gitlab.com/wpetit/goweb/middleware/container" "flag" "fmt" "log" "os" "forge.cadoles.com/wpetit/hydra-passwordless/internal/config" sentryhttp "github.com/getsentry/sentry-go/http" "github.com/pkg/errors" ) //nolint: gochecknoglobals var ( configFile = "" workdir = "" dumpConfig = false version = false ) // nolint: gochecknoglobals var ( GitRef = "unknown" ProjectVersion = "unknown" BuildDate = "unknown" ) //nolint: gochecknoinits func init() { flag.StringVar(&configFile, "config", configFile, "configuration file") flag.StringVar(&workdir, "workdir", workdir, "working directory") flag.BoolVar(&dumpConfig, "dump-config", dumpConfig, "dump configuration and exit") flag.BoolVar(&version, "version", version, "show version and exit") } func main() { flag.Parse() if version { fmt.Printf("%s (%s) - %s\n", ProjectVersion, GitRef, BuildDate) os.Exit(0) } // Switch to new working directory if defined if workdir != "" { if err := os.Chdir(workdir); err != nil { log.Fatalf("%+v", errors.Wrapf(err, "could not change working directory to '%s'", workdir)) } } // Load configuration file if defined, use default configuration otherwise var conf *config.Config var err error if configFile != "" { conf, err = config.NewFromFile(configFile) if err != nil { log.Fatalf("%+v", errors.Wrapf(err, "could not load config file '%s'", configFile)) } } else { if dumpConfig { conf = config.NewDumpDefault() } else { conf = config.NewDefault() } } // Dump configuration if asked if dumpConfig { if err := config.Dump(conf, os.Stdout); err != nil { log.Fatalf("%+v", errors.Wrap(err, "could not dump config")) } os.Exit(0) } if err := config.WithEnvironment(conf); err != nil { log.Fatalf("%+v", errors.Wrap(err, "could not override config with environment")) } useSentry := conf.Sentry.DSN != "" if useSentry { var sentryEnv string if conf.Sentry.Environment == "" { sentryEnv, _ = os.Hostname() } else { sentryEnv = conf.Sentry.Environment } err := sentry.Init(sentry.ClientOptions{ Dsn: conf.Sentry.DSN, Debug: conf.Debug, SampleRate: conf.Sentry.ServerSampleRate, Release: ProjectVersion + "-" + GitRef, Environment: sentryEnv, }) if err != nil { log.Fatalf("%+v", errors.Wrap(err, "could not initialize sentry")) } defer sentry.Flush(conf.Sentry.ServerFlushTimeout) } // Create service container ctn, err := getServiceContainer(conf) if err != nil { log.Fatalf("%+v", errors.Wrap(err, "could not create service container")) } r := chi.NewRouter() // Define base middlewares r.Use(middleware.Logger) r.Use(middleware.Recoverer) if useSentry { sentryMiddleware := sentryhttp.New(sentryhttp.Options{ Repanic: true, }) r.Use(sentryMiddleware.Handle) } // Expose service container on router r.Use(container.ServiceContainer(ctn)) // Define routes if err := route.Mount(r, conf); err != nil { log.Fatalf("%+v", errors.Wrap(err, "could not mount http routes")) } log.Printf("listening on '%s'", conf.HTTP.Address) if err := http.ListenAndServe(conf.HTTP.Address, r); err != nil { log.Fatalf("%+v", errors.Wrapf(err, "could not listen on '%s'", conf.HTTP.Address)) } }