diff --git a/keptn-gateway/cmd/api/main.go b/keptn-gateway/cmd/api/main.go index a475a6b10c..4f834a1d82 100644 --- a/keptn-gateway/cmd/api/main.go +++ b/keptn-gateway/cmd/api/main.go @@ -1,15 +1,10 @@ package main import ( - "fmt" "keptn.sh/keptn-gateway/internal/gateway" ) func main() { gw := gateway.NewGateway() - - err := gw.Server.ListenAndServe() - if err != nil { - panic(fmt.Sprintf("cannot start server: %s", err)) - } + gw.Serve() } diff --git a/keptn-gateway/internal/gateway/gateway.go b/keptn-gateway/internal/gateway/gateway.go index ae05fc3ace..1a076fce56 100644 --- a/keptn-gateway/internal/gateway/gateway.go +++ b/keptn-gateway/internal/gateway/gateway.go @@ -4,8 +4,10 @@ import ( "fmt" "net/http" "os" + "os/signal" "path/filepath" "strconv" + "syscall" "time" _ "github.com/joho/godotenv/autoload" @@ -19,7 +21,7 @@ type Gateway struct { port int logger *zap.Logger client *kubernetes.Clientset - Server *http.Server + server *http.Server } func NewGateway() *Gateway { @@ -28,12 +30,6 @@ func NewGateway() *Gateway { port = 8080 } - NewGateway := &Gateway{ - port: port, - logger: zap.Must(zap.NewDevelopment()), - } - defer NewGateway.logger.Sync() - // kubernetes clientset in cluster /* config, err := rest.InClusterConfig() @@ -50,19 +46,42 @@ func NewGateway() *Gateway { return nil } - NewGateway.client, err = kubernetes.NewForConfig(config) + client, err := kubernetes.NewForConfig(config) if err != nil { panic(err.Error()) } - // http server - NewGateway.Server = &http.Server{ - Addr: fmt.Sprintf(":%d", NewGateway.port), - Handler: NewGateway.RegisterRoutes(), - IdleTimeout: time.Minute, - ReadTimeout: 10 * time.Second, - WriteTimeout: 30 * time.Second, + NewGateway := &Gateway{ + port: port, + logger: zap.Must(zap.NewDevelopment()), + server: &http.Server{ + Addr: fmt.Sprintf(":%d", port), + Handler: RegisterRoutes(client), + IdleTimeout: time.Minute, + ReadTimeout: 10 * time.Second, + WriteTimeout: 30 * time.Second, + }, } + defer NewGateway.logger.Sync() return NewGateway } + +func (gw *Gateway) Serve() error { + go func() { + gw.logger.Info("server starting") + if err := gw.server.ListenAndServe(); err != http.ErrServerClosed { + panic(err) + } + }() + + c := make(chan os.Signal, 2) + signal.Notify(c, os.Interrupt, syscall.SIGTERM) + + <-c // block until signal received + + gw.logger.Info("shutting down") + gw.server.Shutdown(nil) + + return nil +} diff --git a/keptn-gateway/internal/gateway/routes.go b/keptn-gateway/internal/gateway/routes.go index f48badcbe8..4f0d1045c4 100644 --- a/keptn-gateway/internal/gateway/routes.go +++ b/keptn-gateway/internal/gateway/routes.go @@ -7,9 +7,21 @@ import ( "github.com/gin-contrib/cors" "github.com/gin-gonic/gin" + "go.uber.org/zap" + "k8s.io/client-go/kubernetes" ) -func (s *Gateway) RegisterRoutes() http.Handler { +type RouteConfig struct { + client *kubernetes.Clientset + logger *zap.Logger +} + +func RegisterRoutes(client *kubernetes.Clientset) http.Handler { + rc := RouteConfig{ + client: client, + logger: zap.Must(zap.NewDevelopment()), + } + r := gin.Default() r.Use(cors.New(cors.Config{ @@ -21,13 +33,13 @@ func (s *Gateway) RegisterRoutes() http.Handler { MaxAge: 12 * time.Hour, })) - r.GET("/namespace/:namespace/keptnapp/:keptnapp/resources", s.ResourcePanelHandler) - r.GET("/namespace/:namespace/keptnapp/:keptnapp/health", s.HealthHandler) + r.GET("/namespace/:namespace/keptnapp/:keptnapp/resources", rc.ResourcePanelHandler) + r.GET("/namespace/:namespace/keptnapp/:keptnapp/health", rc.HealthHandler) return r } -func (s *Gateway) ResourcePanelHandler(c *gin.Context) { +func (rc *RouteConfig) ResourcePanelHandler(c *gin.Context) { namespace := c.Param("namespace") keptnapp := c.Param("keptnapp") @@ -38,7 +50,7 @@ func (s *Gateway) ResourcePanelHandler(c *gin.Context) { c.JSON(http.StatusOK, resp) } -func (s *Gateway) HealthHandler(c *gin.Context) { +func (rc *RouteConfig) HealthHandler(c *gin.Context) { _ = c.Param("namespace") _ = c.Param("keptnapp")