Merge pull request #124 from jkaninda/develop
feat: add load additional middleware from a defined directory
This commit is contained in:
@@ -13,15 +13,16 @@ RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-X 'github.com/jkaninda/goma-gat
|
||||
|
||||
FROM alpine:3.20.3
|
||||
ENV TZ=UTC
|
||||
ARG WORKDIR="/etc/goma/"
|
||||
ARG WORKDIR="/etc/goma"
|
||||
ARG EXTRADIR="${WORKDIR}/extra"
|
||||
ARG appVersion=""
|
||||
ARG user="goma"
|
||||
LABEL author="Jonas Kaninda"
|
||||
LABEL version=${appVersion}
|
||||
LABEL github="github.com/jkaninda/goma-gateway"
|
||||
|
||||
RUN mkdir -p ${WORKDIR} && \
|
||||
chmod a+rw ${WORKDIR}
|
||||
RUN mkdir -p ${WORKDIR} ${EXTRADIR} && \
|
||||
chmod a+rw ${WORKDIR} ${EXTRADIR}
|
||||
COPY --from=build /app/goma /usr/local/bin/goma
|
||||
RUN chmod a+x /usr/local/bin/goma && \
|
||||
ln -s /usr/local/bin/goma /usr/bin/goma
|
||||
|
||||
@@ -2,6 +2,9 @@ package pkg
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"gopkg.in/yaml.v3"
|
||||
"os"
|
||||
"slices"
|
||||
"strings"
|
||||
)
|
||||
@@ -32,3 +35,45 @@ func GetMiddleware(rule string, middlewares []Middleware) (Middleware, error) {
|
||||
|
||||
return Middleware{}, errors.New("no middlewares found with name " + rule)
|
||||
}
|
||||
|
||||
// loadExtraMiddlewares loads additional middlewares
|
||||
func loadExtraMiddlewares(routePath string) ([]Middleware, error) {
|
||||
yamlFiles, err := loadExtraFiles(routePath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error loading extra files: %v", err)
|
||||
}
|
||||
var extraMiddlewares []Middleware
|
||||
for _, yamlFile := range yamlFiles {
|
||||
buf, err := os.ReadFile(yamlFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error loading extra file: %v", err)
|
||||
}
|
||||
ex := &ExtraMiddleware{}
|
||||
err = yaml.Unmarshal(buf, ex)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("in file %q: %w", ConfigFile, err)
|
||||
}
|
||||
extraMiddlewares = append(extraMiddlewares, ex.Middlewares...)
|
||||
|
||||
}
|
||||
if len(extraMiddlewares) == 0 {
|
||||
return nil, fmt.Errorf("no extra middleware found")
|
||||
}
|
||||
return extraMiddlewares, nil
|
||||
}
|
||||
|
||||
// findDuplicateMiddlewareNames finds duplicated middleware name
|
||||
func findDuplicateMiddlewareNames(middlewares []Middleware) []string {
|
||||
// Create a map to track occurrences of names
|
||||
nameMap := make(map[string]int)
|
||||
var duplicates []string
|
||||
|
||||
for _, mid := range middlewares {
|
||||
nameMap[mid.Name]++
|
||||
// If the count is ==2, it's a duplicate
|
||||
if nameMap[mid.Name] == 2 {
|
||||
duplicates = append(duplicates, mid.Name)
|
||||
}
|
||||
}
|
||||
return duplicates
|
||||
}
|
||||
|
||||
@@ -43,6 +43,9 @@ func loadExtraRoutes(routePath string) ([]Route, error) {
|
||||
extraRoutes = append(extraRoutes, ex.Routes...)
|
||||
|
||||
}
|
||||
if len(extraRoutes) == 0 {
|
||||
return nil, fmt.Errorf("no extra routes found")
|
||||
}
|
||||
return extraRoutes, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -61,3 +61,7 @@ type ExtraRoute struct {
|
||||
// Routes holds proxy routes
|
||||
Routes []Route `yaml:"routes"`
|
||||
}
|
||||
type ExtraMiddleware struct {
|
||||
// Routes holds proxy routes
|
||||
Middlewares []Middleware `yaml:"middlewares"`
|
||||
}
|
||||
|
||||
@@ -37,28 +37,41 @@ func init() {
|
||||
func (gatewayServer GatewayServer) Initialize() *mux.Router {
|
||||
gateway := gatewayServer.gateway
|
||||
dynamicRoutes = gateway.Routes
|
||||
dynamicMiddlewares = gatewayServer.middlewares
|
||||
if len(gateway.ExtraRoutes.Directory) == 0 {
|
||||
gateway.ExtraRoutes.Directory = ExtraDir
|
||||
}
|
||||
// Load Extra Middlewares
|
||||
logger.Info("Loading additional configurations...")
|
||||
extraMiddlewares, err := loadExtraMiddlewares(gateway.ExtraRoutes.Directory)
|
||||
if err == nil {
|
||||
dynamicMiddlewares = append(dynamicMiddlewares, extraMiddlewares...)
|
||||
logger.Info("Loaded %d additional middlewares", len(extraMiddlewares))
|
||||
|
||||
}
|
||||
// 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())
|
||||
}
|
||||
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)
|
||||
extraRoutes, err := loadExtraRoutes(gateway.ExtraRoutes.Directory)
|
||||
if err == nil {
|
||||
dynamicRoutes = append(dynamicRoutes, extraRoutes...)
|
||||
logger.Info("Loaded %d additional routes", len(extraRoutes))
|
||||
|
||||
}
|
||||
|
||||
// find duplicated middleware name
|
||||
duplicates := findDuplicateMiddlewareNames(dynamicMiddlewares)
|
||||
if len(duplicates) != 0 {
|
||||
for _, duplicate := range duplicates {
|
||||
logger.Fatal("Duplicated middleware name: %s, the name of the middleware should be unique.", duplicate)
|
||||
}
|
||||
}
|
||||
// find duplicated route name
|
||||
duplicates := findDuplicateRouteNames(dynamicRoutes)
|
||||
duplicates = findDuplicateRouteNames(dynamicRoutes)
|
||||
if len(duplicates) != 0 {
|
||||
for _, duplicate := range duplicates {
|
||||
logger.Error("Duplicated route name was found: %s ", duplicate)
|
||||
}
|
||||
}
|
||||
m := gatewayServer.middlewares
|
||||
m := dynamicMiddlewares
|
||||
redisBased := false
|
||||
if len(gateway.Redis.Addr) != 0 {
|
||||
redisBased = true
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package pkg
|
||||
|
||||
const ConfigDir = "/etc/goma/" // Default configuration file
|
||||
const ConfigDir = "/etc/goma/" // Default configuration file
|
||||
const ExtraDir = ConfigDir + "extra"
|
||||
const ConfigFile = "/etc/goma/goma.yml" // Default configuration file
|
||||
const accessControlAllowOrigin = "Access-Control-Allow-Origin" // Cors
|
||||
const gatewayName = "Goma Gateway"
|
||||
@@ -12,5 +13,6 @@ var (
|
||||
// Round-robin counter
|
||||
counter uint32
|
||||
// dynamicRoutes routes
|
||||
dynamicRoutes []Route
|
||||
dynamicRoutes []Route
|
||||
dynamicMiddlewares []Middleware
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user