Skip to content
Open
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
1 change: 0 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ make undeploy
- **pkg/controllers/**: Event processing controllers and framework
- **pkg/client/**: CloudEvents clients for MQTT and gRPC communication
- **pkg/config/**: Configuration management for database, message brokers, and servers
- **pkg/auth/**: Authentication and authorization middleware

### Key Concepts
- **Resources**: Kubernetes manifests stored in the database and transported via CloudEvents
Expand Down
6 changes: 0 additions & 6 deletions cmd/maestro/environments/e_development.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ func (e *devEnvImpl) VisitMessageBroker(c *MessageBroker) error {
}

func (e *devEnvImpl) VisitConfig(c *ApplicationConfig) error {
c.ApplicationConfig.HTTPServer.EnableJWT = false
c.ApplicationConfig.HTTPServer.EnableHTTPS = false
return nil
}

Expand All @@ -41,14 +39,10 @@ func (e *devEnvImpl) VisitClients(c *Clients) error {
func (e *devEnvImpl) Flags() map[string]string {
return map[string]string{
"v": "10",
"enable-authz": "false",
"ocm-debug": "false",
"enable-ocm-mock": "true",
"enable-https": "false",
"enable-metrics-https": "false",
"server-hostname": "localhost",
"http-server-bindport": "8000",
"enable-sentry": "false",
"source-id": "maestro",
}
}
5 changes: 0 additions & 5 deletions cmd/maestro/environments/e_integration_testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,8 @@ func (e *testingEnvImpl) Flags() map[string]string {
return map[string]string{
"v": "0",
"logtostderr": "true",
"ocm-base-url": "https://api.integration.openshift.com",
"enable-https": "false",
"enable-metrics-https": "false",
"enable-authz": "true",
"ocm-debug": "false",
"enable-ocm-mock": "true",
"enable-sentry": "false",
"source-id": "maestro",
}
}
7 changes: 2 additions & 5 deletions cmd/maestro/environments/e_production.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,7 @@ func (e *productionEnvImpl) VisitClients(c *Clients) error {

func (e *productionEnvImpl) Flags() map[string]string {
return map[string]string{
"v": "1",
"ocm-debug": "false",
"enable-ocm-mock": "true",
"enable-sentry": "false",
"source-id": "maestro",
"v": "1",
"source-id": "maestro",
}
}
75 changes: 0 additions & 75 deletions cmd/maestro/environments/framework.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ package environments
import (
"fmt"
"log"
"os"
"strings"

"github.com/getsentry/sentry-go"
"github.com/spf13/pflag"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
Expand All @@ -18,7 +16,6 @@ import (
envtypes "github.com/openshift-online/maestro/cmd/maestro/environments/types"
"github.com/openshift-online/maestro/pkg/client/cloudevents"
"github.com/openshift-online/maestro/pkg/client/grpcauthorizer"
"github.com/openshift-online/maestro/pkg/client/ocm"
"github.com/openshift-online/maestro/pkg/config"
"github.com/openshift-online/maestro/pkg/errors"
)
Expand Down Expand Up @@ -84,8 +81,6 @@ func (e *Env) Initialize() error {

messages := environment.Config.ReadFiles()
if len(messages) != 0 {
err := fmt.Errorf("unable to read configuration files:\n%s", strings.Join(messages, "\n"))
sentry.CaptureException(err)
log.Fatalf("Unable to read configuration files:\n%s", strings.Join(messages, "\n"))
}

Expand All @@ -112,11 +107,6 @@ func (e *Env) Initialize() error {
log.Fatalf("Failed to visit Clients: %s", err)
}

err = e.InitializeSentry()
if err != nil {
return fmt.Errorf("failed to initialize sentry: %w", err)
}

seedErr := e.Seed()
if seedErr != nil {
return seedErr
Expand Down Expand Up @@ -144,28 +134,6 @@ func (e *Env) LoadServices() {
}

func (e *Env) LoadClients() error {
var err error

ocmConfig := ocm.Config{
BaseURL: e.Config.OCM.BaseURL,
ClientID: e.Config.OCM.ClientID,
ClientSecret: e.Config.OCM.ClientSecret,
SelfToken: e.Config.OCM.SelfToken,
TokenURL: e.Config.OCM.TokenURL,
Debug: e.Config.OCM.Debug,
}

// Create OCM Authz client
if e.Config.OCM.EnableMock {
klog.V(4).Info("Using Mock OCM Authz Client")
e.Clients.OCM, err = ocm.NewClientMock(ocmConfig)
} else {
e.Clients.OCM, err = ocm.NewClient(ocmConfig)
}
if err != nil {
return fmt.Errorf("Unable to create OCM Authz client: %v", err)
}

// Create CloudEvents Source client
if e.Config.MessageBroker.EnableMock {
klog.V(4).Info("Using Mock CloudEvents Source Client")
Expand Down Expand Up @@ -218,54 +186,11 @@ func (e *Env) LoadClients() error {
return nil
}

func (e *Env) InitializeSentry() error {
options := sentry.ClientOptions{}

if e.Config.Sentry.Enabled {
key := e.Config.Sentry.Key
url := e.Config.Sentry.URL
project := e.Config.Sentry.Project
klog.V(4).Infof("Sentry error reporting enabled to %s on project %s", url, project)
options.Dsn = fmt.Sprintf("https://%s@%s/%s", key, url, project)
} else {
// Setting the DSN to an empty string effectively disables sentry
// See https://godoc.org/github.com/getsentry/sentry-go#ClientOptions Dsn
klog.V(4).Info("Disabling Sentry error reporting")
options.Dsn = ""
}

transport := sentry.NewHTTPTransport()
transport.Timeout = e.Config.Sentry.Timeout
// since sentry.HTTPTransport is asynchronous, Sentry needs a buffer to cache pending requests.
// the BufferSize is the size of the buffer. Sentry drops requests when the buffer is full:
// https://github.com/getsentry/sentry-go/blob/4f72d7725080f61e924409c8ddd008739fd4a837/transport.go#L312
// errors in our system are relatively sparse, we don't need a large BufferSize.
transport.BufferSize = 10
options.Transport = transport
options.Debug = e.Config.Sentry.Debug
options.AttachStacktrace = true
options.Environment = e.Name

hostname, err := os.Hostname()
if err != nil && hostname != "" {
options.ServerName = hostname
}
// TODO figure out some way to set options.Release and options.Dist

err = sentry.Init(options)
if err != nil {
return fmt.Errorf("Unable to initialize sentry integration: %s", err.Error())
}

return nil
}

func (e *Env) Teardown() {
if e.Name != envtypes.TestingEnv {
if err := e.Database.SessionFactory.Close(); err != nil {
log.Fatalf("Unable to close db connection: %s", err.Error())
}
e.Clients.OCM.Close()
}
}

Expand Down
6 changes: 6 additions & 0 deletions cmd/maestro/environments/framework_test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package environments

import (
"flag"
"os/exec"
"reflect"
"testing"

"github.com/spf13/pflag"
"k8s.io/klog/v2"
)

func BenchmarkGetResources(b *testing.B) {
Expand All @@ -23,6 +25,10 @@ func BenchmarkGetResources(b *testing.B) {
}

func TestLoadServices(t *testing.T) {
// Initialize klog flags first (same as main.go does)
klog.InitFlags(nil)
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)

env := Environment()
// Override environment name
env.Name = "testing"
Expand Down
5 changes: 0 additions & 5 deletions cmd/maestro/environments/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ package environments
import (
"sync"

"github.com/openshift-online/maestro/pkg/auth"
"github.com/openshift-online/maestro/pkg/client/cloudevents"
"github.com/openshift-online/maestro/pkg/client/grpcauthorizer"
"github.com/openshift-online/maestro/pkg/client/ocm"
"github.com/openshift-online/maestro/pkg/config"
"github.com/openshift-online/maestro/pkg/db"
)
Expand Down Expand Up @@ -36,7 +34,6 @@ type MessageBroker struct {
}

type Handlers struct {
AuthMiddleware auth.JWTMiddleware
}

type Services struct {
Expand All @@ -48,7 +45,6 @@ type Services struct {
}

type Clients struct {
OCM *ocm.Client
GRPCAuthorizer grpcauthorizer.GRPCAuthorizer
CloudEventsSource cloudevents.SourceClient
}
Expand All @@ -57,7 +53,6 @@ type ConfigDefaults struct {
Server map[string]interface{}
Metrics map[string]interface{}
Database map[string]interface{}
OCM map[string]interface{}
Options map[string]interface{}
}

Expand Down
68 changes: 1 addition & 67 deletions cmd/maestro/server/api_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,8 @@ import (
"net/http"
"time"

sentryhttp "github.com/getsentry/sentry-go/http"
"github.com/ghodss/yaml"
_ "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"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
"k8s.io/klog/v2"

Expand All @@ -40,72 +35,11 @@ func NewAPIServer(ctx context.Context, eventBroadcaster *event.EventBroadcaster)

mainRouter := s.routes(ctx)

// Sentryhttp middleware performs two operations:
// 1) Attaches an instance of *sentry.Hub to the request’s context. Accessit by using the sentry.GetHubFromContext() method on the request
// NOTE this is the only way middleware, handlers, and services should be reporting to sentry, through the hub
// 2) Reports panics to the configured sentry service
if env().Config.Sentry.Enabled {
sentryhttpOptions := sentryhttp.Options{
Repanic: true,
WaitForDelivery: false,
Timeout: env().Config.Sentry.Timeout,
}
sentryMW := sentryhttp.New(sentryhttpOptions)
mainRouter.Use(sentryMW.Handle)
}

// referring to the router as type http.Handler allows us to add middleware via more handlers
var mainHandler http.Handler = mainRouter

if env().Config.HTTPServer.EnableJWT {
// Create the logger for the authentication handler:
authnLogger, err := sdk.NewGlogLoggerBuilder().
InfoV(glog.Level(1)).
DebugV(glog.Level(5)).
Build()
check(ctx, err, "Unable to create authentication logger")

// Create the handler that verifies that tokens are valid:
mainHandler, err = authentication.NewHandler().
Logger(authnLogger).
KeysFile(env().Config.HTTPServer.JwkCertFile).
KeysURL(env().Config.HTTPServer.JwkCertURL).
ACLFile(env().Config.HTTPServer.ACLFile).
Public("^/api/maestro/?$").
Public("^/api/maestro/v1/?$").
Public("^/api/maestro/v1/openapi/?$").
Public("^/api/maestro/v1/errors(/.*)?$").
Next(mainHandler).
Build()
check(ctx, err, "Unable to create authentication handler")
}

// TODO: remove all cloud.redhat.com once migration to console.redhat.com is complete
// refer to: https://issues.redhat.com/browse/RHCLOUD-14695
mainHandler = gorillahandlers.CORS(
gorillahandlers.AllowedOrigins([]string{
// OCM UI local development URLs
"https://qa.foo.redhat.com:1337",
"https://prod.foo.redhat.com:1337",
"https://ci.foo.redhat.com:1337",
"https://cloud.redhat.com", // TODO: remove
"https://console.redhat.com", // Production / candidate
// Staging and test environments
"https://qaprodauth.cloud.redhat.com", // TODO: remove
"https://qa.cloud.redhat.com", // TODO: remove
"https://ci.cloud.redhat.com", // TODO: remove
"https://qaprodauth.console.redhat.com",
"https://qa.console.redhat.com",
"https://ci.console.redhat.com",
"https://console.stage.redhat.com",
// API docs UI
"https://api.stage.openshift.com",
"https://api.openshift.com",
// Customer portal
"https://access.qa.redhat.com",
"https://access.stage.redhat.com",
"https://access.redhat.com",
}),
gorillahandlers.AllowedOrigins([]string{}),
gorillahandlers.AllowedMethods([]string{
http.MethodDelete,
http.MethodGet,
Expand Down
8 changes: 0 additions & 8 deletions cmd/maestro/server/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (

"github.com/openshift-online/maestro/cmd/maestro/server/logging"
"github.com/openshift-online/maestro/pkg/api"
"github.com/openshift-online/maestro/pkg/auth"
"github.com/openshift-online/maestro/pkg/db"
"github.com/openshift-online/maestro/pkg/handlers"
"github.com/openshift-online/maestro/pkg/logger"
Expand All @@ -27,9 +26,6 @@ func (s *apiServer) routes(ctx context.Context) *mux.Router {
consumerHandler := handlers.NewConsumerHandler(services.Consumers(), services.Resources(), services.Generic())
errorsHandler := handlers.NewErrorsHandler()

authMiddleware := &auth.AuthMiddlewareMock{}
authzMiddleware := auth.NewAuthzMiddlewareMock()

// mainRouter is top level "/"
mainRouter := mux.NewRouter()
mainRouter.NotFoundHandler = http.HandlerFunc(api.SendNotFound)
Expand Down Expand Up @@ -63,8 +59,6 @@ func (s *apiServer) routes(ctx context.Context) *mux.Router {
apiV1ResourceBundleRouter.HandleFunc("", resourceBundleHandler.List).Methods(http.MethodGet)
apiV1ResourceBundleRouter.HandleFunc("/{id}", resourceBundleHandler.Get).Methods(http.MethodGet)
apiV1ResourceBundleRouter.HandleFunc("/{id}", resourceBundleHandler.Delete).Methods(http.MethodDelete)
apiV1ResourceBundleRouter.Use(authMiddleware.AuthenticateAccountJWT)
apiV1ResourceBundleRouter.Use(authzMiddleware.AuthorizeApi)

// /api/maestro/v1/consumers
apiV1ConsumersRouter := apiV1Router.PathPrefix("/consumers").Subrouter()
Expand All @@ -73,8 +67,6 @@ func (s *apiServer) routes(ctx context.Context) *mux.Router {
apiV1ConsumersRouter.HandleFunc("", consumerHandler.Create).Methods(http.MethodPost)
apiV1ConsumersRouter.HandleFunc("/{id}", consumerHandler.Patch).Methods(http.MethodPatch)
apiV1ConsumersRouter.HandleFunc("/{id}", consumerHandler.Delete).Methods(http.MethodDelete)
apiV1ConsumersRouter.Use(authMiddleware.AuthenticateAccountJWT)
apiV1ConsumersRouter.Use(authzMiddleware.AuthorizeApi)

return mainRouter
}
Expand Down
5 changes: 0 additions & 5 deletions cmd/maestro/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@ import (
"os"
"strings"

"github.com/getsentry/sentry-go"
"k8s.io/klog/v2"

"github.com/openshift-online/maestro/cmd/maestro/environments"
)

type Server interface {
Expand All @@ -32,8 +29,6 @@ func check(ctx context.Context, err error, msg string) {
if err != nil && err != http.ErrServerClosed {
logger := klog.FromContext(ctx)
logger.Error(err, msg)
sentry.CaptureException(err)
sentry.Flush(environments.Environment().Config.Sentry.Timeout)
os.Exit(1)
}
}
Loading
Loading