Merge pull request #105 from jkaninda/refactor
chore: add skip SSL certificate verification
This commit is contained in:
2
.github/workflows/bin-release.yml
vendored
2
.github/workflows/bin-release.yml
vendored
@@ -1,4 +1,4 @@
|
||||
# .github/workflows/release.yaml
|
||||
name: Bin release
|
||||
on:
|
||||
release:
|
||||
types: [created]
|
||||
|
||||
23
.github/workflows/lint.yml
vendored
Normal file
23
.github/workflows/lint.yml
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
name: Lint
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
name: Run on Ubuntu
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Clone the code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '~1.22'
|
||||
|
||||
- name: Run linter
|
||||
uses: golangci/golangci-lint-action@v6
|
||||
with:
|
||||
version: v1.61
|
||||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: CI
|
||||
name: Release
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
name: Go
|
||||
name: Test
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -135,6 +135,7 @@ gateway:
|
||||
- https://example.com
|
||||
- https://example2.com
|
||||
- https://example4.com
|
||||
insecureSkipVerify: true
|
||||
methods: []
|
||||
healthCheck:
|
||||
path: "/health/live"
|
||||
|
||||
@@ -87,6 +87,7 @@ gateway:
|
||||
backends:
|
||||
- https://example.com
|
||||
- https://example2.com
|
||||
insecureSkipVerify: true
|
||||
methods:
|
||||
- GET
|
||||
# Route healthcheck
|
||||
|
||||
@@ -30,8 +30,6 @@ import (
|
||||
"os"
|
||||
)
|
||||
|
||||
var cfg *Gateway
|
||||
|
||||
// Config reads config file and returns Gateway
|
||||
func (GatewayServer) Config(configFile string) (*GatewayServer, error) {
|
||||
if util.FileExists(configFile) {
|
||||
|
||||
37
internal/cors_type.go
Normal file
37
internal/cors_type.go
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
type Cors struct {
|
||||
// Cors Allowed origins,
|
||||
//e.g:
|
||||
//
|
||||
// - http://localhost:80
|
||||
//
|
||||
// - https://example.com
|
||||
Origins []string `yaml:"origins"`
|
||||
//
|
||||
//e.g:
|
||||
//
|
||||
//Access-Control-Allow-Origin: '*'
|
||||
//
|
||||
// Access-Control-Allow-Methods: 'GET, POST, PUT, DELETE, OPTIONS'
|
||||
//
|
||||
// Access-Control-Allow-Cors: 'Content-Type, Authorization'
|
||||
Headers map[string]string `yaml:"headers"`
|
||||
}
|
||||
57
internal/gateway_type.go
Normal file
57
internal/gateway_type.go
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
// Gateway contains Goma Proxy Gateway's configs
|
||||
type Gateway struct {
|
||||
// SSLCertFile SSL Certificate file
|
||||
SSLCertFile string `yaml:"sslCertFile" env:"GOMA_SSL_CERT_FILE, overwrite"`
|
||||
// SSLKeyFile SSL Private key file
|
||||
SSLKeyFile string `yaml:"sslKeyFile" env:"GOMA_SSL_KEY_FILE, overwrite"`
|
||||
// Redis contains redis database details
|
||||
Redis Redis `yaml:"redis"`
|
||||
// WriteTimeout defines proxy write timeout
|
||||
WriteTimeout int `yaml:"writeTimeout" env:"GOMA_WRITE_TIMEOUT, overwrite"`
|
||||
// ReadTimeout defines proxy read timeout
|
||||
ReadTimeout int `yaml:"readTimeout" env:"GOMA_READ_TIMEOUT, overwrite"`
|
||||
// IdleTimeout defines proxy idle timeout
|
||||
IdleTimeout int `yaml:"idleTimeout" env:"GOMA_IDLE_TIMEOUT, overwrite"`
|
||||
// RateLimit Defines the number of request peer minutes
|
||||
RateLimit int `yaml:"rateLimit" env:"GOMA_RATE_LIMIT, overwrite"`
|
||||
// BlockCommonExploits enable, disable block common exploits
|
||||
BlockCommonExploits bool `yaml:"blockCommonExploits"`
|
||||
AccessLog string `yaml:"accessLog" env:"GOMA_ACCESS_LOG, overwrite"`
|
||||
ErrorLog string `yaml:"errorLog" env:"GOMA_ERROR_LOG=, overwrite"`
|
||||
LogLevel string `yaml:"logLevel" env:"GOMA_LOG_LEVEL, overwrite"`
|
||||
// DisableHealthCheckStatus enable and disable routes health check
|
||||
DisableHealthCheckStatus bool `yaml:"disableHealthCheckStatus"`
|
||||
// DisableRouteHealthCheckError allows enabling and disabling backend healthcheck errors
|
||||
DisableRouteHealthCheckError bool `yaml:"disableRouteHealthCheckError"`
|
||||
//Disable allows enabling and disabling displaying routes on start
|
||||
DisableDisplayRouteOnStart bool `yaml:"disableDisplayRouteOnStart"`
|
||||
// DisableKeepAlive allows enabling and disabling KeepALive server
|
||||
DisableKeepAlive bool `yaml:"disableKeepAlive"`
|
||||
EnableMetrics bool `yaml:"enableMetrics"`
|
||||
// InterceptErrors holds the status codes to intercept the error from backend
|
||||
InterceptErrors []int `yaml:"interceptErrors"`
|
||||
// Cors holds proxy global cors
|
||||
Cors Cors `yaml:"cors"`
|
||||
|
||||
// Routes holds proxy routes
|
||||
Routes []Route `yaml:"routes"`
|
||||
}
|
||||
@@ -18,6 +18,7 @@ limitations under the License.
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/jkaninda/goma-gateway/pkg/logger"
|
||||
"net/http"
|
||||
@@ -56,32 +57,33 @@ func CORSHandler(cors Cors) mux.MiddlewareFunc {
|
||||
func ProxyErrorHandler(w http.ResponseWriter, r *http.Request, err error) {
|
||||
logger.Error("Proxy error: %v", err)
|
||||
w.WriteHeader(http.StatusBadGateway)
|
||||
_, err = w.Write([]byte("Bad Gateway"))
|
||||
_, err = w.Write([]byte(fmt.Sprintf("%d %s ", http.StatusBadGateway, http.StatusText(http.StatusBadGateway))))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// HealthCheckHandler handles health check of routes
|
||||
func (heathRoute HealthCheckRoute) HealthCheckHandler(w http.ResponseWriter, r *http.Request) {
|
||||
logger.Debug("%s %s %s %s", r.Method, r.RemoteAddr, r.URL, r.UserAgent())
|
||||
healthRoutes := healthCheckRoutes(heathRoute.Routes)
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(len(heathRoute.Routes))
|
||||
wg.Add(len(healthRoutes))
|
||||
var routes []HealthCheckRouteResponse
|
||||
for _, health := range healthCheckRoutes(heathRoute.Routes) {
|
||||
for _, health := range healthRoutes {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
err := health.Check()
|
||||
if err != nil {
|
||||
if heathRoute.DisableRouteHealthCheckError {
|
||||
routes = append(routes, HealthCheckRouteResponse{Name: health.Name, Status: "unhealthy", Error: "Route healthcheck errors disabled"})
|
||||
}
|
||||
} else {
|
||||
routes = append(routes, HealthCheckRouteResponse{Name: health.Name, Status: "unhealthy", Error: "Error: " + err.Error()})
|
||||
}
|
||||
} else {
|
||||
logger.Debug("Route %s is healthy", health.Name)
|
||||
routes = append(routes, HealthCheckRouteResponse{Name: health.Name, Status: "healthy", Error: ""})
|
||||
}
|
||||
defer wg.Done()
|
||||
|
||||
}()
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"github.com/jkaninda/goma-gateway/pkg/logger"
|
||||
"github.com/jkaninda/goma-gateway/util"
|
||||
@@ -36,8 +37,14 @@ func (health Health) Check() error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("error route %s: creating HealthCheck request: %v ", health.Name, err)
|
||||
}
|
||||
// Create custom transport with TLS configuration
|
||||
transport := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
InsecureSkipVerify: health.InsecureSkipVerify, // Skip SSL certificate verification
|
||||
},
|
||||
}
|
||||
// Perform the request to the route's healthcheck
|
||||
client := &http.Client{Timeout: health.TimeOut}
|
||||
client := &http.Client{Transport: transport, Timeout: health.TimeOut}
|
||||
healthResp, err := client.Do(healthReq)
|
||||
if err != nil {
|
||||
logger.Debug("Error route %s: performing HealthCheck request: %v ", health.Name, err)
|
||||
@@ -46,6 +53,7 @@ func (health Health) Check() error {
|
||||
defer func(Body io.ReadCloser) {
|
||||
err := Body.Close()
|
||||
if err != nil {
|
||||
logger.Debug("Error performing HealthCheck request: %v ", err)
|
||||
}
|
||||
}(healthResp.Body)
|
||||
if len(health.HealthyStatuses) > 0 {
|
||||
|
||||
@@ -122,6 +122,7 @@ func healthCheckRoutes(routes []Route) []Health {
|
||||
URL: backend + route.HealthCheck.Path,
|
||||
TimeOut: timeout,
|
||||
HealthyStatuses: route.HealthCheck.HealthyStatuses,
|
||||
InsecureSkipVerify: route.InsecureSkipVerify,
|
||||
}
|
||||
healthRoutes = append(healthRoutes, health)
|
||||
}
|
||||
@@ -132,6 +133,7 @@ func healthCheckRoutes(routes []Route) []Health {
|
||||
URL: route.Destination + route.HealthCheck.Path,
|
||||
TimeOut: timeout,
|
||||
HealthyStatuses: route.HealthCheck.HealthyStatuses,
|
||||
InsecureSkipVerify: route.InsecureSkipVerify,
|
||||
}
|
||||
healthRoutes = append(healthRoutes, health)
|
||||
}
|
||||
|
||||
@@ -19,11 +19,7 @@ func getMiddleware(rules []string, middlewares []Middleware) (Middleware, error)
|
||||
|
||||
func doesExist(tyName string) bool {
|
||||
middlewareList := []string{BasicAuth, JWTAuth, AccessMiddleware}
|
||||
if slices.Contains(middlewareList, tyName) {
|
||||
return true
|
||||
|
||||
}
|
||||
return false
|
||||
return slices.Contains(middlewareList, tyName)
|
||||
}
|
||||
func GetMiddleware(rule string, middlewares []Middleware) (Middleware, error) {
|
||||
for _, m := range middlewares {
|
||||
|
||||
@@ -79,7 +79,7 @@ func (jwtAuth JwtAuth) AuthMiddleware(next http.Handler) http.Handler {
|
||||
defer func(Body io.ReadCloser) {
|
||||
err := Body.Close()
|
||||
if err != nil {
|
||||
|
||||
logger.Error("Error closing body: %v", err)
|
||||
}
|
||||
}(authResp.Body)
|
||||
// Inject specific header tp the current request's header
|
||||
|
||||
@@ -32,7 +32,7 @@ type RateLimiter struct {
|
||||
clientMap map[string]*Client
|
||||
mu sync.Mutex
|
||||
origins []string
|
||||
hosts []string
|
||||
//hosts []string
|
||||
redisBased bool
|
||||
}
|
||||
|
||||
|
||||
31
internal/middleware_type.go
Normal file
31
internal/middleware_type.go
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
// Middleware defined the route middleware
|
||||
type Middleware struct {
|
||||
//Path contains the name of middleware and must be unique
|
||||
Name string `yaml:"name"`
|
||||
// Type contains authentication types
|
||||
//
|
||||
// basic, jwt, auth0, rateLimit, access
|
||||
Type string `yaml:"type"` // Middleware type [basic, jwt, auth0, rateLimit, access]
|
||||
Paths []string `yaml:"paths"` // Protected paths
|
||||
// Rule contains rule type of
|
||||
Rule interface{} `yaml:"rule"` // Middleware rule
|
||||
}
|
||||
@@ -236,10 +236,15 @@ func (gatewayServer GatewayServer) Initialize() *mux.Router {
|
||||
logger.Info("Block common exploits enabled")
|
||||
router.Use(middleware.BlockExploitsMiddleware)
|
||||
}
|
||||
id := string(rune(rIndex))
|
||||
if len(route.Name) != 0 {
|
||||
// Use route name as ID
|
||||
id = util.Slug(route.Name)
|
||||
}
|
||||
// Apply route rate limit
|
||||
if route.RateLimit > 0 {
|
||||
rateLimit := middleware.RateLimit{
|
||||
Id: string(rune(rIndex)), // Use route index as ID
|
||||
Id: id, // Use route index as ID
|
||||
Requests: route.RateLimit,
|
||||
Window: time.Minute, // requests per minute
|
||||
Origins: route.Cors.Origins,
|
||||
|
||||
58
internal/route_type.go
Normal file
58
internal/route_type.go
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
// Route defines gateway route
|
||||
type Route struct {
|
||||
// Path defines route path
|
||||
Path string `yaml:"path"`
|
||||
// Name defines route name
|
||||
Name string `yaml:"name"`
|
||||
//Host Domain/host based request routing
|
||||
//Host string `yaml:"host"`
|
||||
//Hosts Domains/hosts based request routing
|
||||
Hosts []string `yaml:"hosts"`
|
||||
// Rewrite rewrites route path to desired path
|
||||
//
|
||||
// E.g. /cart to / => It will rewrite /cart path to /
|
||||
Rewrite string `yaml:"rewrite"`
|
||||
//
|
||||
// Methods allowed method
|
||||
Methods []string `yaml:"methods"`
|
||||
// Destination Defines backend URL
|
||||
Destination string `yaml:"destination"`
|
||||
Backends []string `yaml:"backends"`
|
||||
InsecureSkipVerify bool `yaml:"insecureSkipVerify"`
|
||||
// HealthCheck Defines the backend is health
|
||||
HealthCheck RouteHealthCheck `yaml:"healthCheck"`
|
||||
// Cors contains the route cors headers
|
||||
Cors Cors `yaml:"cors"`
|
||||
RateLimit int `yaml:"rateLimit"`
|
||||
// DisableHostFording Disable X-forwarded header.
|
||||
//
|
||||
// [X-Forwarded-Host, X-Forwarded-For, Host, Scheme ]
|
||||
//
|
||||
// It will not match the backend route
|
||||
DisableHostFording bool `yaml:"disableHostFording"`
|
||||
// InterceptErrors holds the status codes to intercept the error from backend
|
||||
InterceptErrors []int `yaml:"interceptErrors"`
|
||||
// BlockCommonExploits enable, disable block common exploits
|
||||
BlockCommonExploits bool `yaml:"blockCommonExploits"`
|
||||
// Middlewares Defines route middleware from Middleware names
|
||||
Middlewares []string `yaml:"middlewares"`
|
||||
}
|
||||
@@ -24,11 +24,11 @@ func TestCheckConfig(t *testing.T) {
|
||||
TestInit(t)
|
||||
err := initConfig(configFile)
|
||||
if err != nil {
|
||||
t.Fatalf(err.Error())
|
||||
t.Fatal("Error init config:", err)
|
||||
}
|
||||
err = CheckConfig(configFile)
|
||||
if err != nil {
|
||||
t.Fatalf(err.Error())
|
||||
t.Fatalf("Error checking config: %s", err.Error())
|
||||
}
|
||||
log.Println("Goma Gateway configuration file checked successfully")
|
||||
}
|
||||
@@ -37,7 +37,7 @@ func TestStart(t *testing.T) {
|
||||
TestInit(t)
|
||||
err := initConfig(configFile)
|
||||
if err != nil {
|
||||
t.Fatalf(err.Error())
|
||||
t.Fatalf("Error initializing config: %s", err.Error())
|
||||
}
|
||||
g := GatewayServer{}
|
||||
gatewayServer, err := g.Config(configFile)
|
||||
|
||||
@@ -19,37 +19,14 @@ package pkg
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gorilla/mux"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
file string
|
||||
}
|
||||
type BasicRuleMiddleware struct {
|
||||
Username string `yaml:"username"`
|
||||
Password string `yaml:"password"`
|
||||
}
|
||||
|
||||
type Cors struct {
|
||||
// Cors Allowed origins,
|
||||
//e.g:
|
||||
//
|
||||
// - http://localhost:80
|
||||
//
|
||||
// - https://example.com
|
||||
Origins []string `yaml:"origins"`
|
||||
//
|
||||
//e.g:
|
||||
//
|
||||
//Access-Control-Allow-Origin: '*'
|
||||
//
|
||||
// Access-Control-Allow-Methods: 'GET, POST, PUT, DELETE, OPTIONS'
|
||||
//
|
||||
// Access-Control-Allow-Cors: 'Content-Type, Authorization'
|
||||
Headers map[string]string `yaml:"headers"`
|
||||
}
|
||||
|
||||
// JWTRuleMiddleware authentication using HTTP GET method
|
||||
//
|
||||
// JWTRuleMiddleware contains the authentication details
|
||||
@@ -114,101 +91,6 @@ type AccessRuleMiddleware struct {
|
||||
ResponseCode int `yaml:"responseCode"` // HTTP Response code
|
||||
}
|
||||
|
||||
// Middleware defined the route middleware
|
||||
type Middleware struct {
|
||||
//Path contains the name of middleware and must be unique
|
||||
Name string `yaml:"name"`
|
||||
// Type contains authentication types
|
||||
//
|
||||
// basic, jwt, auth0, rateLimit, access
|
||||
Type string `yaml:"type"` // Middleware type [basic, jwt, auth0, rateLimit, access]
|
||||
Paths []string `yaml:"paths"` // Protected paths
|
||||
// Rule contains rule type of
|
||||
Rule interface{} `yaml:"rule"` // Middleware rule
|
||||
}
|
||||
type MiddlewareName struct {
|
||||
name string `yaml:"name"`
|
||||
}
|
||||
|
||||
// Route defines gateway route
|
||||
type Route struct {
|
||||
// Path defines route path
|
||||
Path string `yaml:"path"`
|
||||
// Name defines route name
|
||||
Name string `yaml:"name"`
|
||||
//Host Domain/host based request routing
|
||||
//Host string `yaml:"host"`
|
||||
//Hosts Domains/hosts based request routing
|
||||
Hosts []string `yaml:"hosts"`
|
||||
// Rewrite rewrites route path to desired path
|
||||
//
|
||||
// E.g. /cart to / => It will rewrite /cart path to /
|
||||
Rewrite string `yaml:"rewrite"`
|
||||
//
|
||||
// Methods allowed method
|
||||
Methods []string `yaml:"methods"`
|
||||
// Destination Defines backend URL
|
||||
Destination string `yaml:"destination"`
|
||||
Backends []string `yaml:"backends"`
|
||||
InsecureSkipVerify bool `yaml:"insecureSkipVerify"`
|
||||
// HealthCheck Defines the backend is health
|
||||
HealthCheck RouteHealthCheck `yaml:"healthCheck"`
|
||||
// Cors contains the route cors headers
|
||||
Cors Cors `yaml:"cors"`
|
||||
RateLimit int `yaml:"rateLimit"`
|
||||
// DisableHostFording Disable X-forwarded header.
|
||||
//
|
||||
// [X-Forwarded-Host, X-Forwarded-For, Host, Scheme ]
|
||||
//
|
||||
// It will not match the backend route
|
||||
DisableHostFording bool `yaml:"disableHostFording"`
|
||||
// InterceptErrors holds the status codes to intercept the error from backend
|
||||
InterceptErrors []int `yaml:"interceptErrors"`
|
||||
// BlockCommonExploits enable, disable block common exploits
|
||||
BlockCommonExploits bool `yaml:"blockCommonExploits"`
|
||||
// Middlewares Defines route middleware from Middleware names
|
||||
Middlewares []string `yaml:"middlewares"`
|
||||
}
|
||||
|
||||
// Gateway contains Goma Proxy Gateway's configs
|
||||
type Gateway struct {
|
||||
// SSLCertFile SSL Certificate file
|
||||
SSLCertFile string `yaml:"sslCertFile" env:"GOMA_SSL_CERT_FILE, overwrite"`
|
||||
// SSLKeyFile SSL Private key file
|
||||
SSLKeyFile string `yaml:"sslKeyFile" env:"GOMA_SSL_KEY_FILE, overwrite"`
|
||||
// Redis contains redis database details
|
||||
Redis Redis `yaml:"redis"`
|
||||
// WriteTimeout defines proxy write timeout
|
||||
WriteTimeout int `yaml:"writeTimeout" env:"GOMA_WRITE_TIMEOUT, overwrite"`
|
||||
// ReadTimeout defines proxy read timeout
|
||||
ReadTimeout int `yaml:"readTimeout" env:"GOMA_READ_TIMEOUT, overwrite"`
|
||||
// IdleTimeout defines proxy idle timeout
|
||||
IdleTimeout int `yaml:"idleTimeout" env:"GOMA_IDLE_TIMEOUT, overwrite"`
|
||||
// RateLimit Defines the number of request peer minutes
|
||||
RateLimit int `yaml:"rateLimit" env:"GOMA_RATE_LIMIT, overwrite"`
|
||||
// BlockCommonExploits enable, disable block common exploits
|
||||
BlockCommonExploits bool `yaml:"blockCommonExploits"`
|
||||
AccessLog string `yaml:"accessLog" env:"GOMA_ACCESS_LOG, overwrite"`
|
||||
ErrorLog string `yaml:"errorLog" env:"GOMA_ERROR_LOG=, overwrite"`
|
||||
LogLevel string `yaml:"logLevel" env:"GOMA_LOG_LEVEL, overwrite"`
|
||||
// DisableHealthCheckStatus enable and disable routes health check
|
||||
DisableHealthCheckStatus bool `yaml:"disableHealthCheckStatus"`
|
||||
// DisableRouteHealthCheckError allows enabling and disabling backend healthcheck errors
|
||||
DisableRouteHealthCheckError bool `yaml:"disableRouteHealthCheckError"`
|
||||
//Disable allows enabling and disabling displaying routes on start
|
||||
DisableDisplayRouteOnStart bool `yaml:"disableDisplayRouteOnStart"`
|
||||
// DisableKeepAlive allows enabling and disabling KeepALive server
|
||||
DisableKeepAlive bool `yaml:"disableKeepAlive"`
|
||||
EnableMetrics bool `yaml:"enableMetrics"`
|
||||
// InterceptErrors holds the status codes to intercept the error from backend
|
||||
InterceptErrors []int `yaml:"interceptErrors"`
|
||||
// Cors holds proxy global cors
|
||||
Cors Cors `yaml:"cors"`
|
||||
|
||||
// Routes holds proxy routes
|
||||
Routes []Route `yaml:"routes"`
|
||||
}
|
||||
|
||||
type RouteHealthCheck struct {
|
||||
Path string `yaml:"path"`
|
||||
Interval string `yaml:"interval"`
|
||||
@@ -240,20 +122,12 @@ type ProxyRoute struct {
|
||||
rewrite string
|
||||
destination string
|
||||
backends []string
|
||||
healthCheck RouteHealthCheck
|
||||
//healthCheck RouteHealthCheck
|
||||
methods []string
|
||||
cors Cors
|
||||
disableHostFording bool
|
||||
insecureSkipVerify bool
|
||||
}
|
||||
type RoutePath struct {
|
||||
route Route
|
||||
path string
|
||||
rules []string
|
||||
middlewares []Middleware
|
||||
router *mux.Router
|
||||
}
|
||||
|
||||
type HealthCheckRoute struct {
|
||||
DisableRouteHealthCheckError bool
|
||||
Routes []Route
|
||||
@@ -287,6 +161,7 @@ type Health struct {
|
||||
TimeOut time.Duration
|
||||
Interval string
|
||||
HealthyStatuses []int
|
||||
InsecureSkipVerify bool
|
||||
}
|
||||
type Redis struct {
|
||||
// Addr redis hostname and port number :
|
||||
|
||||
@@ -3,16 +3,11 @@ package pkg
|
||||
const ConfigDir = "/etc/goma/" // Default configuration file
|
||||
const ConfigFile = "/etc/goma/goma.yml" // Default configuration file
|
||||
const accessControlAllowOrigin = "Access-Control-Allow-Origin" // Cors
|
||||
const serverName = "Goma"
|
||||
const gatewayName = "Goma Gateway"
|
||||
const AccessMiddleware = "access" // access middleware
|
||||
const BasicAuth = "basic" // basic authentication middleware
|
||||
const JWTAuth = "jwt" // JWT authentication middleware
|
||||
const OAuth = "oauth" // OAuth authentication middleware
|
||||
const applicationJson = "application/json"
|
||||
const textPlain = "text/plain"
|
||||
const applicationXml = "application/xml"
|
||||
|
||||
// Round-robin counter
|
||||
var counter uint32
|
||||
|
||||
|
||||
@@ -26,11 +26,6 @@ import (
|
||||
"github.com/jkaninda/goma-gateway/util"
|
||||
)
|
||||
|
||||
type Logger struct {
|
||||
msg string
|
||||
args interface{}
|
||||
}
|
||||
|
||||
// Info returns info log
|
||||
func Info(msg string, args ...interface{}) {
|
||||
log.SetOutput(getStd(util.GetStringEnv("GOMA_ACCESS_LOG", "/dev/stdout")))
|
||||
|
||||
@@ -142,3 +142,17 @@ func ParseDuration(durationStr string) (time.Duration, error) {
|
||||
}
|
||||
return duration, nil
|
||||
}
|
||||
|
||||
func Slug(text string) string {
|
||||
// Convert to lowercase
|
||||
text = strings.ToLower(text)
|
||||
|
||||
// Replace spaces and special characters with hyphens
|
||||
re := regexp.MustCompile(`[^\w]+`)
|
||||
text = re.ReplaceAllString(text, "-")
|
||||
|
||||
// Remove leading and trailing hyphens
|
||||
text = strings.Trim(text, "-")
|
||||
|
||||
return text
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user