Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 23 additions & 9 deletions Dockerfile.openapi
Original file line number Diff line number Diff line change
@@ -1,17 +1,27 @@
FROM openapitools/openapi-generator-cli:v7.16.0
# Multi-arch base image with Java for openapi-generator
FROM eclipse-temurin:17-jdk
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious about the error for arm64 , since I never had an error working on a Macbook M3 and also the image openapitools/openapi-generator-cli:v7.16.0 and is the one used in Sentinel....

was that one also giving you problems?

Either way, it doesn't hurt if this fixes errors, and we may transition to discard completely the Java based generator in favor of a faster go-based one (without containers)


# -o APT::Sandbox::User=root is a workaround for rootless podman setgroups error in Prow env
RUN apt-get -o APT::Sandbox::User=root update
RUN apt-get -o APT::Sandbox::User=root install -y make sudo git wget

# Install Go 1.24
RUN wget https://go.dev/dl/go1.24.0.linux-amd64.tar.gz && \
tar -C /usr/local -xzf go1.24.0.linux-amd64.tar.gz && \
rm go1.24.0.linux-amd64.tar.gz
# Install Go 1.24.9 (auto-detect architecture)
RUN ARCH=$(dpkg --print-architecture) && \
if [ "$ARCH" = "arm64" ] || [ "$ARCH" = "aarch64" ]; then \
GO_ARCH="arm64"; \
else \
GO_ARCH="amd64"; \
fi && \
wget https://go.dev/dl/go1.24.9.linux-${GO_ARCH}.tar.gz && \
tar -C /usr/local -xzf go1.24.9.linux-${GO_ARCH}.tar.gz && \
rm go1.24.9.linux-${GO_ARCH}.tar.gz

# Download openapi-generator-cli
RUN wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.18.0/openapi-generator-cli-7.18.0.jar \
-O /usr/local/bin/openapi-generator-cli.jar

RUN mkdir -p /local


# Copy the rest of the project
COPY openapi/openapi.yaml /local/openapi/openapi.yaml

Expand All @@ -20,12 +30,16 @@ ENV GOPATH="/uhc"
ENV GOBIN /usr/local/go/bin/
ENV CGO_ENABLED=0

# these git and go flags to avoid self signed certificate errors

WORKDIR /local

# Install go-bindata
RUN go install -a github.com/go-bindata/go-bindata/...@v3.1.2
RUN bash /usr/local/bin/docker-entrypoint.sh generate -i /local/openapi/openapi.yaml -g go -o /local/pkg/api/openapi

# Generate OpenAPI client
RUN java -jar /usr/local/bin/openapi-generator-cli.jar generate \
-i /local/openapi/openapi.yaml \
-g go \
-o /local/pkg/api/openapi

RUN rm /local/pkg/api/openapi/go.mod /local/pkg/api/openapi/go.sum
RUN rm -r /local/pkg/api/openapi/test
45 changes: 31 additions & 14 deletions cmd/hyperfleet-api/environments/framework.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
package environments

import (
"log/slog"
"os"
"strings"

"github.com/golang/glog"
"github.com/spf13/pflag"

"github.com/openshift-hyperfleet/hyperfleet-api/cmd/hyperfleet-api/environments/registry"
"github.com/openshift-hyperfleet/hyperfleet-api/pkg/api"
"github.com/openshift-hyperfleet/hyperfleet-api/pkg/client/ocm"
"github.com/openshift-hyperfleet/hyperfleet-api/pkg/config"
"github.com/openshift-hyperfleet/hyperfleet-api/pkg/errors"
"github.com/openshift-hyperfleet/hyperfleet-api/pkg/logger"
)

func init() {
Expand Down Expand Up @@ -64,38 +66,52 @@ func (e *Env) AddFlags(flags *pflag.FlagSet) error {
// This should be called after the e.Config has been set appropriately though AddFlags and pasing, done elsewhere
// The environment does NOT handle flag parsing
func (e *Env) Initialize() error {
glog.Infof("Initializing %s environment", e.Name)
// Initialize structured logging first, before any other operations
logger.Initialize(logger.Config{
Level: e.Config.Logging.Level,
Format: e.Config.Logging.Format,
Output: e.Config.Logging.Output,
Version: api.Version,
})

slog.Info("Initializing environment", "environment", e.Name)

envImpl, found := environments[e.Name]
if !found {
glog.Fatalf("Unknown runtime environment: %s", e.Name)
slog.Error("Unknown runtime environment", "environment", e.Name)
os.Exit(1)
}

if err := envImpl.OverrideConfig(e.Config); err != nil {
glog.Fatalf("Failed to configure ApplicationConfig: %s", err)
slog.Error("Failed to configure ApplicationConfig", "error", err)
os.Exit(1)
}

messages := environment.Config.ReadFiles()
if len(messages) != 0 {
glog.Fatalf("unable to read configuration files:\n%s", strings.Join(messages, "\n"))
slog.Error("Unable to read configuration files", "errors", strings.Join(messages, "\n"))
os.Exit(1)
}

// each env will set db explicitly because the DB impl has a `once` init section
if err := envImpl.OverrideDatabase(&e.Database); err != nil {
glog.Fatalf("Failed to configure Database: %s", err)
slog.Error("Failed to configure Database", "error", err)
os.Exit(1)
}

err := e.LoadClients()
if err != nil {
return err
}
if err := envImpl.OverrideClients(&e.Clients); err != nil {
glog.Fatalf("Failed to configure Clients: %s", err)
slog.Error("Failed to configure Clients", "error", err)
os.Exit(1)
}

e.LoadServices()
if err := envImpl.OverrideServices(&e.Services); err != nil {
glog.Fatalf("Failed to configure Services: %s", err)
slog.Error("Failed to configure Services", "error", err)
os.Exit(1)
}

seedErr := e.Seed()
Expand All @@ -104,7 +120,8 @@ func (e *Env) Initialize() error {
}

if err := envImpl.OverrideHandlers(&e.Handlers); err != nil {
glog.Fatalf("Failed to configure Handlers: %s", err)
slog.Error("Failed to configure Handlers", "error", err)
os.Exit(1)
}

return nil
Expand Down Expand Up @@ -136,13 +153,13 @@ func (e *Env) LoadClients() error {

// Create OCM Authz client
if e.Config.OCM.EnableMock {
glog.Infof("Using Mock OCM Authz Client")
slog.Info("Using Mock OCM Authz Client")
e.Clients.OCM, err = ocm.NewClientMock(ocmConfig)
} else {
e.Clients.OCM, err = ocm.NewClient(ocmConfig)
}
if err != nil {
glog.Errorf("Unable to create OCM Authz client: %s", err.Error())
slog.Error("Unable to create OCM Authz client", "error", err)
return err
}

Expand All @@ -152,20 +169,20 @@ func (e *Env) LoadClients() error {
func (e *Env) Teardown() {
if e.Database.SessionFactory != nil {
if err := e.Database.SessionFactory.Close(); err != nil {
glog.Errorf("Error closing database session factory: %s", err.Error())
slog.Error("Error closing database session factory", "error", err)
}
}
if e.Clients.OCM != nil {
if err := e.Clients.OCM.Close(); err != nil {
glog.Errorf("Error closing OCM client: %v", err)
slog.Error("Error closing OCM client", "error", err)
}
}
}

func setConfigDefaults(flags *pflag.FlagSet, defaults map[string]string) error {
for name, value := range defaults {
if err := flags.Set(name, value); err != nil {
glog.Errorf("Error setting flag %s: %v", name, err)
slog.Error("Error setting flag", "flag", name, "error", err)
return err
}
}
Expand Down
21 changes: 4 additions & 17 deletions cmd/hyperfleet-api/main.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package main

import (
"flag"
"log/slog"
"os"

"github.com/golang/glog"
"github.com/spf13/cobra"

"github.com/openshift-hyperfleet/hyperfleet-api/cmd/hyperfleet-api/migrate"
Expand All @@ -20,20 +20,6 @@ import (
// nolint

func main() {
// This is needed to make `glog` believe that the flags have already been parsed, otherwise
// every log messages is prefixed by an error message stating the the flags haven't been
// parsed.
if err := flag.CommandLine.Parse([]string{}); err != nil {
glog.Fatalf("Failed to parse flags: %v", err)
}

//pflag.CommandLine.AddGoFlagSet(flag.CommandLine)

// Always log to stderr by default
if err := flag.Set("logtostderr", "true"); err != nil {
glog.Infof("Unable to set logtostderr to true")
}

rootCmd := &cobra.Command{
Use: "hyperfleet",
Long: "hyperfleet serves as a template for new microservices",
Expand All @@ -47,6 +33,7 @@ func main() {
rootCmd.AddCommand(migrateCmd, serveCmd)

if err := rootCmd.Execute(); err != nil {
glog.Fatalf("error running command: %v", err)
slog.Error("Error running command", "error", err)
os.Exit(1)
}
}
11 changes: 7 additions & 4 deletions cmd/hyperfleet-api/migrate/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ package migrate
import (
"context"
"flag"
"log/slog"
"os"

"github.com/golang/glog"
"github.com/openshift-hyperfleet/hyperfleet-api/pkg/db/db_session"
"github.com/spf13/cobra"

"github.com/openshift-hyperfleet/hyperfleet-api/pkg/config"
"github.com/openshift-hyperfleet/hyperfleet-api/pkg/db"
"github.com/openshift-hyperfleet/hyperfleet-api/pkg/db/db_session"
)

var dbConfig = config.NewDatabaseConfig()
Expand All @@ -31,11 +32,13 @@ func NewMigrateCommand() *cobra.Command {
func runMigrate(_ *cobra.Command, _ []string) {
err := dbConfig.ReadFiles()
if err != nil {
glog.Fatal(err)
slog.Error("Failed to read database config", "error", err)
os.Exit(1)
}

connection := db_session.NewProdFactory(dbConfig)
if err := db.Migrate(connection.New(context.Background())); err != nil {
glog.Fatal(err)
slog.Error("Migration failed", "error", err)
os.Exit(1)
}
}
10 changes: 7 additions & 3 deletions cmd/hyperfleet-api/servecmd/cmd.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package servecmd

import (
"github.com/golang/glog"
"log/slog"
"os"

"github.com/spf13/cobra"

"github.com/openshift-hyperfleet/hyperfleet-api/cmd/hyperfleet-api/environments"
Expand All @@ -17,7 +19,8 @@ func NewServeCommand() *cobra.Command {
}
err := environments.Environment().AddFlags(cmd.PersistentFlags())
if err != nil {
glog.Fatalf("Unable to add environment flags to serve command: %s", err.Error())
slog.Error("Unable to add environment flags to serve command", "error", err)
os.Exit(1)
}

return cmd
Expand All @@ -26,7 +29,8 @@ func NewServeCommand() *cobra.Command {
func runServe(cmd *cobra.Command, args []string) {
err := environments.Environment().Initialize()
if err != nil {
glog.Fatalf("Unable to initialize environment: %s", err.Error())
slog.Error("Unable to initialize environment", "error", err)
os.Exit(1)
}

// Run the servers
Expand Down
20 changes: 11 additions & 9 deletions cmd/hyperfleet-api/server/api_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ package server
import (
"context"
"fmt"
"log/slog"
"net"
"net/http"
"os"
"time"

_ "github.com/auth0/go-jwt-middleware"
_ "github.com/golang-jwt/jwt/v4"
"github.com/golang/glog"
gorillahandlers "github.com/gorilla/handlers"
sdk "github.com/openshift-online/ocm-sdk-go"
"github.com/openshift-online/ocm-sdk-go/authentication"
Expand Down Expand Up @@ -37,9 +38,9 @@ func NewAPIServer() Server {

if env().Config.Server.EnableJWT {
// Create the logger for the authentication handler:
authnLogger, err := sdk.NewGlogLoggerBuilder().
InfoV(glog.Level(1)).
DebugV(glog.Level(5)).
authnLogger, err := sdk.NewStdLoggerBuilder().
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was curios and looked at the definition of this, which says

// NewStdLoggerBuilder has been moved to the logging package.
func NewStdLoggerBuilder() *StdLoggerBuilder {
	return logging.NewStdLoggerBuilder()
}

We could update it to call that logging.NewStdLoggerBuilder() directly and not the depcrecated one.

Streams(os.Stdout, os.Stderr).
Debug(false).
Build()
check(err, "Unable to create authentication logger")

Expand Down Expand Up @@ -117,16 +118,16 @@ func (s apiServer) Serve(listener net.Listener) {
}

// Serve with TLS
glog.Infof("Serving with TLS at %s", env().Config.Server.BindAddress)
slog.Info("Serving with TLS", "address", env().Config.Server.BindAddress)
err = s.httpServer.ServeTLS(listener, env().Config.Server.HTTPSCertFile, env().Config.Server.HTTPSKeyFile)
} else {
glog.Infof("Serving without TLS at %s", env().Config.Server.BindAddress)
slog.Info("Serving without TLS", "address", env().Config.Server.BindAddress)
err = s.httpServer.Serve(listener)
}

// Web server terminated.
check(err, "Web server terminated with errors")
glog.Info("Web server terminated")
slog.Info("Web server terminated")
}

// Listen only start the listener, not the server.
Expand All @@ -139,15 +140,16 @@ func (s apiServer) Listen() (listener net.Listener, err error) {
func (s apiServer) Start() {
listener, err := s.Listen()
if err != nil {
glog.Fatalf("Unable to start API server: %s", err)
slog.Error("Unable to start API server", "error", err)
os.Exit(1)
}
s.Serve(listener)

// after the server exits but before the application terminates
// we need to explicitly close Go's sql connection pool.
// this needs to be called *exactly* once during an app's lifetime.
if err := env().Database.SessionFactory.Close(); err != nil {
glog.Errorf("Error closing database connection: %v", err)
slog.Error("Error closing database connection", "error", err)
}
}

Expand Down
8 changes: 4 additions & 4 deletions cmd/hyperfleet-api/server/healthcheck_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ package server
import (
"context"
"fmt"
"log/slog"
"net"
"net/http"

health "github.com/docker/go-healthcheck"
"github.com/golang/glog"
"github.com/gorilla/mux"
)

Expand Down Expand Up @@ -50,14 +50,14 @@ func (s healthCheckServer) Start() {
}

// Serve with TLS
glog.Infof("Serving HealthCheck with TLS at %s", env().Config.HealthCheck.BindAddress)
slog.Info("Serving HealthCheck with TLS", "address", env().Config.HealthCheck.BindAddress)
err = s.httpServer.ListenAndServeTLS(env().Config.Server.HTTPSCertFile, env().Config.Server.HTTPSKeyFile)
} else {
glog.Infof("Serving HealthCheck without TLS at %s", env().Config.HealthCheck.BindAddress)
slog.Info("Serving HealthCheck without TLS", "address", env().Config.HealthCheck.BindAddress)
err = s.httpServer.ListenAndServe()
}
check(err, "HealthCheck server terminated with errors")
glog.Infof("HealthCheck server terminated")
slog.Info("HealthCheck server terminated")
}

func (s healthCheckServer) Stop() error {
Expand Down
Loading