From b5450279695c99e4ed5651b3f8de1548c45a6b53 Mon Sep 17 00:00:00 2001 From: Jonas Kaninda Date: Mon, 18 Nov 2024 12:58:49 +0100 Subject: [PATCH] chore: add route config check --- internal/check-config.go | 66 ---------------------- internal/check_config.go | 118 +++++++++++++++++++++++++++++++++++++++ internal/route.go | 8 ++- internal/route_config.go | 8 --- internal/server_test.go | 4 ++ util/constants.go | 3 +- 6 files changed, 131 insertions(+), 76 deletions(-) delete mode 100644 internal/check-config.go create mode 100644 internal/check_config.go diff --git a/internal/check-config.go b/internal/check-config.go deleted file mode 100644 index 3ca5bd6..0000000 --- a/internal/check-config.go +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2024 Jonas Kaninda - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package pkg - -import ( - "fmt" - "github.com/jkaninda/goma-gateway/util" - "gopkg.in/yaml.v3" - "os" -) - -func CheckConfig(fileName string) error { - if !util.FileExists(fileName) { - return fmt.Errorf("config file not found: %s", fileName) - } - buf, err := os.ReadFile(fileName) - if err != nil { - return err - } - c := &GatewayConfig{} - err = yaml.Unmarshal(buf, c) - if err != nil { - return fmt.Errorf("parsing the configuration file %q: %w", fileName, err) - } - gateway := &GatewayServer{ - ctx: nil, - version: c.Version, - gateway: c.GatewayConfig, - middlewares: c.Middlewares, - } - for index, route := range gateway.gateway.Routes { - if len(route.Name) == 0 { - fmt.Printf("Warning: route name is empty, index: [%d]", index) - } - if route.Destination == "" && len(route.Backends) == 0 { - fmt.Printf("Error: no destination or backends specified for route: %s | index: [%d] \n", route.Name, index) - } - } - - // Check middlewares - for index, mid := range c.Middlewares { - if util.HasWhitespace(mid.Name) { - fmt.Printf("Warning: Middleware contains whitespace: %s | index: [%d], please remove whitespace characters\n", mid.Name, index) - } - } - - fmt.Printf("Routes count=%d Middlewares count=%d\n", len(gateway.gateway.Routes), len(gateway.middlewares)) - - return nil - -} diff --git a/internal/check_config.go b/internal/check_config.go new file mode 100644 index 0000000..bfc44fb --- /dev/null +++ b/internal/check_config.go @@ -0,0 +1,118 @@ +/* + * Copyright 2024 Jonas Kaninda + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package pkg + +import ( + "fmt" + "github.com/jkaninda/goma-gateway/util" + "gopkg.in/yaml.v3" + "os" + "slices" +) + +func CheckConfig(fileName string) error { + if !util.FileExists(fileName) { + return fmt.Errorf("config file not found: %s", fileName) + } + buf, err := os.ReadFile(fileName) + if err != nil { + return err + } + c := &GatewayConfig{} + err = yaml.Unmarshal(buf, c) + if err != nil { + return fmt.Errorf("parsing the configuration file %q: %w", fileName, err) + } + gateway := &GatewayServer{ + ctx: nil, + version: c.Version, + gateway: c.GatewayConfig, + middlewares: c.Middlewares, + } + dynamicRoutes = gateway.gateway.Routes + // Check middlewares + fmt.Println("Checking middlewares...") + for index, mid := range c.Middlewares { + if len(mid.Name) == 0 { + fmt.Printf("Warning: Middleware name required: index: [%d]\n", index) + } + if util.HasWhitespace(mid.Name) { + fmt.Printf("Warning: Middleware contains whitespace: %s | index: [%d], please remove whitespace characters\n", mid.Name, index) + } + } + fmt.Println("Checking middlewares...done") + //Check additional routes + fmt.Println("Checking routes...") + // Load Extra Routes + if len(gateway.gateway.ExtraRoutes.Directory) != 0 { + extraRoutes, err := loadExtraRoutes(gateway.gateway.ExtraRoutes.Directory) + if err != nil { + fmt.Printf("Error: %v\n", err.Error()) + } + if len(extraRoutes) == 0 { + fmt.Printf("no extra routes found in %s\n", gateway.gateway.ExtraRoutes.Directory) + } else { + dynamicRoutes = append(dynamicRoutes, extraRoutes...) + fmt.Printf("Loaded %d extra routes from %s\n", len(extraRoutes), gateway.gateway.ExtraRoutes.Directory) + } + } + // Check routes + checkRoutes(dynamicRoutes, gateway.middlewares) + fmt.Println("Checking routes...done") + + fmt.Printf("Routes count=%d Middlewares count=%d\n", len(dynamicRoutes), len(gateway.middlewares)) + + return nil + +} + +func checkRoutes(routes []Route, middlewares []Middleware) { + midNames := middlewareNames(middlewares) + for index, route := range routes { + if len(route.Name) == 0 { + fmt.Printf("Warning: route name is empty, index: [%d]\n", index) + } + if route.Destination == "" && len(route.Backends) == 0 { + fmt.Printf("Error: no destination or backends specified for route: %s | index: [%d] \n", route.Name, index) + } + //checking middleware applied to routes + for _, middleware := range route.Middlewares { + if !slices.Contains(midNames, middleware) { + fmt.Printf("Couldn't find a middleware with the name: %s | route: %s \n", middleware, route.Name) + } + } + } + // find duplicated route name + duplicates := findDuplicateRouteNames(routes) + if len(duplicates) != 0 { + for _, duplicate := range duplicates { + fmt.Printf("Duplicated route name was found: %s \n", duplicate) + } + } +} + +func middlewareNames(middlewares []Middleware) []string { + + var names []string + + for _, mid := range middlewares { + names = append(names, mid.Name) + + } + return names +} diff --git a/internal/route.go b/internal/route.go index 77fea94..867bd81 100644 --- a/internal/route.go +++ b/internal/route.go @@ -38,11 +38,17 @@ func (gatewayServer GatewayServer) Initialize() *mux.Router { dynamicRoutes = gateway.Routes // Load Extra Routes if len(gateway.ExtraRoutes.Directory) != 0 { + logger.Info("Loading additional routes from %s", gateway.ExtraRoutes.Directory) extraRoutes, err := loadExtraRoutes(gateway.ExtraRoutes.Directory) if err != nil { logger.Error("Error: %v", err.Error()) } - dynamicRoutes = append(dynamicRoutes, extraRoutes...) + if len(extraRoutes) == 0 { + logger.Info("no extra routes found in %s", gateway.ExtraRoutes.Directory) + } else { + dynamicRoutes = append(dynamicRoutes, extraRoutes...) + logger.Info("Loaded %d extra routes from %s", len(extraRoutes), gateway.ExtraRoutes.Directory) + } } // find duplicated route name duplicates := findDuplicateRouteNames(dynamicRoutes) diff --git a/internal/route_config.go b/internal/route_config.go index 77fd94f..051a4b4 100644 --- a/internal/route_config.go +++ b/internal/route_config.go @@ -19,14 +19,12 @@ package pkg import ( "fmt" - "github.com/jkaninda/goma-gateway/pkg/logger" "gopkg.in/yaml.v3" "os" ) // loadExtraRoutes loads additional routes func loadExtraRoutes(routePath string) ([]Route, error) { - logger.Info("Loading additional routes from %s", routePath) yamlFiles, err := loadExtraFiles(routePath) if err != nil { return nil, fmt.Errorf("error loading extra files: %v", err) @@ -44,12 +42,6 @@ func loadExtraRoutes(routePath string) ([]Route, error) { } extraRoutes = append(extraRoutes, ex.Routes...) - } - if len(extraRoutes) == 0 { - return nil, fmt.Errorf("no extra routes found in %s", routePath) - } else { - logger.Info("Loaded %d extra routes from %s", len(extraRoutes), routePath) - } return extraRoutes, nil } diff --git a/internal/server_test.go b/internal/server_test.go index 4fc0ce6..f243bca 100644 --- a/internal/server_test.go +++ b/internal/server_test.go @@ -49,6 +49,10 @@ func TestStart(t *testing.T) { if err != nil { t.Fatalf("Error creating extra routes file: %s", err.Error()) } + err = CheckConfig(configFile) + if err != nil { + t.Fatalf("Error checking config: %s", err.Error()) + } ctx := context.Background() g := GatewayServer{} gatewayServer, err := g.Config(configFile, ctx) diff --git a/util/constants.go b/util/constants.go index 37a1e99..ed4f589 100644 --- a/util/constants.go +++ b/util/constants.go @@ -28,4 +28,5 @@ func FullVersion() { const MainExample = "Initialize config: config init --output config.yml\n" + "Start server: server \n" + - "Start server with custom config file: server --config config.yml" + "Start server with custom config file: server --config config.yml \n" + + "Check config file: config init -f -o config.yml"