package cmd import ( "github.com/spf13/cobra" "github.com/spf13/viper" "go.infratographer.com/x/echox" "go.infratographer.com/x/events" "go.infratographer.com/x/oauth2x" "go.infratographer.com/x/otelx" "go.infratographer.com/x/versionx" "go.infratographer.com/x/viperx" "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" "go.equinixmetal.net/infra9-metal-bridge/internal/config" "go.equinixmetal.net/infra9-metal-bridge/internal/metal" "go.equinixmetal.net/infra9-metal-bridge/internal/permissions" "go.equinixmetal.net/infra9-metal-bridge/internal/pubsub" "go.equinixmetal.net/infra9-metal-bridge/internal/service" ) var serveCmd = &cobra.Command{ Use: "serve", Short: "starts the metal bridge", Run: serve, } var defaultListen = ":8080" func init() { rootCmd.AddCommand(serveCmd) echox.MustViperFlags(viper.GetViper(), serveCmd.Flags(), defaultListen) events.MustViperFlagsForPublisher(viper.GetViper(), serveCmd.Flags(), appName) events.MustViperFlagsForSubscriber(viper.GetViper(), serveCmd.Flags()) serveCmd.PersistentFlags().StringSlice("events-topics", []string{}, "event topics to subscribe to") viperx.MustBindFlag(viper.GetViper(), "events.subscriber.topics", serveCmd.PersistentFlags().Lookup("events-topics")) oauth2x.MustViperFlags(viper.GetViper(), serveCmd.Flags()) permissions.MustViperFlags(viper.GetViper(), serveCmd.Flags()) metal.MustViperFlags(viper.GetViper(), serveCmd.Flags()) } func serve(cmd *cobra.Command, _ []string) { err := otelx.InitTracer(config.AppConfig.OTel, appName, logger) if err != nil { logger.Fatalw("error initializing tracing", "error", err) } publisher, err := events.NewPublisherWithLogger(config.AppConfig.Events.Publisher, logger) if err != nil { logger.Fatalw("unable to initialize event publisher", "error", err) } metal, err := metal.New( metal.WithLogger(logger.Desugar()), metal.WithConfig(config.AppConfig.EquinixMetal), ) if err != nil { logger.Fatalw("error initializing Metal client", "error", err) } permHTTPClient := permissions.DefaultHTTPClient if config.AppConfig.OIDC.Client.ID != "" { tokenSrc, err := oauth2x.NewClientCredentialsTokenSrc(cmd.Context(), config.AppConfig.OIDC.Client) if err != nil { logger.Fatalw("error initializing oauth2 client", "error", err) } permHTTPClient = oauth2x.NewClient(cmd.Context(), tokenSrc) permHTTPClient.Transport = otelhttp.NewTransport(permHTTPClient.Transport) } perms, err := permissions.NewClient("", permissions.WithLogger(logger), permissions.WithConfig(config.AppConfig.Permissions), permissions.WithHTTPClient(permHTTPClient), ) if err != nil { logger.Fatalw("error initializing Permissions client", "error", err) } service, err := service.New(publisher, metal, perms, service.WithLogger(logger), service.WithConfig(config.AppConfig.Service), service.WithRoles(config.AppConfig.Roles), ) if err != nil { logger.Fatalw("error initializing service", "error", err) } subscriber, err := pubsub.NewSubscriber(cmd.Context(), config.AppConfig.Events.Subscriber.SubscriberConfig, service, pubsub.WithLogger(logger), ) if err != nil { logger.Fatalw("unable to initialize event subscriber", "error", err) } for _, topic := range config.AppConfig.Events.Subscriber.Topics { if err := subscriber.Subscribe(topic); err != nil { logger.Fatalw("error subscribing to topic: "+topic, "topic", topic, "error", err) } } srv, err := echox.NewServer( logger.Desugar(), echox.ConfigFromViper(viper.GetViper()), versionx.BuildDetails(), ) if err != nil { logger.Fatalw("failed to initialize new server", "error", err) } defer subscriber.Close() logger.Info("Listening for events") go func() { if err := subscriber.Listen(); err != nil { logger.Fatalw("error listening for events", "error", err) } }() if err := srv.Run(); err != nil { logger.Fatalw("failed to run server", "error", err) } }