Commit 9838a846 authored by qiuqunfeng's avatar qiuqunfeng
Browse files

create waf

parent cb8cd6a0
...@@ -29,14 +29,27 @@ LICENSE_SECRET?=sit ...@@ -29,14 +29,27 @@ LICENSE_SECRET?=sit
## 指定bin目录 ## 指定bin目录
BIN_DIR = $(shell pwd)/bin/ BIN_DIR = $(shell pwd)/bin/
GOBIN ?= go
.PHONY: help .PHONY: help
help: help:
@fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/##//' @fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/##//'
download:
$(GOBIN) mod tidy
.PHONY: build
build: download
@echo "build waf-console"
$(GOBIN) build -v \
-tags=jsoniter -o dist/waf-console gitlab.com/tensorsecurity-rd/waf-console/cmd
#upx --lzma --best dist/waf-console
.PHONY: waf-console .PHONY: waf-console
waf-console: waf-console:
@echo "build waf-console" @echo "build waf-console"
go build -v \ $(GOBIN) build -v \
-tags=jsoniter -o dist/waf-console gitlab.com/tensorsecurity-rd/waf-console/cmd -tags=jsoniter -o dist/waf-console gitlab.com/tensorsecurity-rd/waf-console/cmd
#upx --lzma --best dist/waf-console #upx --lzma --best dist/waf-console
docker build -t $(REPOPREFIX)/waf-console:$(IMAGETAG) -f ./build/Dockerfile . docker build -t $(REPOPREFIX)/waf-console:$(IMAGETAG) -f ./build/Dockerfile .
...@@ -5,19 +5,18 @@ import ( ...@@ -5,19 +5,18 @@ import (
"net/http" "net/http"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"gitlab.com/security-rd/go-pkg/logging" "github.com/rs/zerolog/log"
"gitlab.com/tensorsecurity-rd/waf-console/internal/config" "gitlab.com/tensorsecurity-rd/waf-console/internal/config"
"gitlab.com/tensorsecurity-rd/waf-console/internal/utils" "gitlab.com/tensorsecurity-rd/waf-console/internal/utils"
"gitlab.com/tensorsecurity-rd/waf-console/pkg/generated/clientset/versioned"
"gorm.io/gorm" "gorm.io/gorm"
) )
func SetRouters(db *gorm.DB, client *versioned.Clientset) *gin.Engine { func SetRouters(db *gorm.DB, clusterClientManager *utils.ClusterClientManager) *gin.Engine {
var engine *gin.Engine var engine *gin.Engine
if !config.Conf.Debug { if !config.Conf.Debug {
// 生产模式 // 生产模式
logging.Get().Info().Msg("release mode") log.Info().Msg("release mode")
engine = ReleaseRouter() engine = ReleaseRouter()
engine.Use( engine.Use(
// middleware.RequestCostHandler(), // middleware.RequestCostHandler(),
...@@ -27,7 +26,7 @@ func SetRouters(db *gorm.DB, client *versioned.Clientset) *gin.Engine { ...@@ -27,7 +26,7 @@ func SetRouters(db *gorm.DB, client *versioned.Clientset) *gin.Engine {
) )
} else { } else {
// 开发调试模式 // 开发调试模式
logging.Get().Info().Msg("debug mode") log.Info().Msg("debug mode")
engine = gin.New() engine = gin.New()
engine.Use( engine.Use(
// middleware.RequestCostHandler(), // middleware.RequestCostHandler(),
...@@ -62,7 +61,7 @@ func SetRouters(db *gorm.DB, client *versioned.Clientset) *gin.Engine { ...@@ -62,7 +61,7 @@ func SetRouters(db *gorm.DB, client *versioned.Clientset) *gin.Engine {
// }, // },
// // BearerToken: "1234567890", // // BearerToken: "1234567890",
// }) // })
SetWafRouter(engine, client, db) SetWafRouter(engine, clusterClientManager, db)
// 统一处理 404 // 统一处理 404
engine.NoRoute(func(c *gin.Context) { engine.NoRoute(func(c *gin.Context) {
......
...@@ -3,16 +3,21 @@ package api ...@@ -3,16 +3,21 @@ package api
import ( import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"gitlab.com/tensorsecurity-rd/waf-console/internal/controller" "gitlab.com/tensorsecurity-rd/waf-console/internal/controller"
"gitlab.com/tensorsecurity-rd/waf-console/pkg/generated/clientset/versioned" "gitlab.com/tensorsecurity-rd/waf-console/internal/utils"
"gorm.io/gorm" "gorm.io/gorm"
) )
func SetWafRouter(e *gin.Engine, client *versioned.Clientset, db *gorm.DB) { func SetWafRouter(e *gin.Engine, clusterClientManager *utils.ClusterClientManager, db *gorm.DB) {
v1 := e.Group("v1/api") v1 := e.Group("v1/api/waf")
wafController := controller.NewWafController(client, db) wafController := controller.NewWafController(clusterClientManager, db)
v1.GET("waf/:gateway_name", wafController.Waf) v1.GET("/:region_code/:namespace/:gateway_name", wafController.Waf)
v1.POST("waf", wafController.CreateWaf) v1.POST("/", wafController.CreateWaf)
v1.PUT("mode", wafController.UpdateMode) v1.PUT("mode", wafController.UpdateMode)
v1.PUT("rules", wafController.UpdateRule)
v1.PUT("listener/enable", wafController.EnableListenerWaf)
v1.PUT("gateway/enable", wafController.EnableGatewayWaf)
v1.DELETE("listener/:region_code/:namespace/:gateway_name/:port", wafController.DeleteListenerWaf)
v1.DELETE("gateway/:region_code/:namespace/:gateway_name", wafController.DeleteGatewayWaf)
v1.POST("debug/savecatagory", wafController.SaveRuleCategoryToDB) v1.POST("debug/savecatagory", wafController.SaveRuleCategoryToDB)
} }
...@@ -5,9 +5,10 @@ import ( ...@@ -5,9 +5,10 @@ import (
"fmt" "fmt"
"os" "os"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"gitlab.com/security-rd/go-pkg/logging"
"gitlab.com/tensorsecurity-rd/waf-console/api" "gitlab.com/tensorsecurity-rd/waf-console/api"
"gitlab.com/tensorsecurity-rd/waf-console/internal/utils"
"gitlab.com/tensorsecurity-rd/waf-console/pkg/generated/clientset/versioned" "gitlab.com/tensorsecurity-rd/waf-console/pkg/generated/clientset/versioned"
"gorm.io/driver/mysql" "gorm.io/driver/mysql"
"gorm.io/gorm" "gorm.io/gorm"
...@@ -22,7 +23,7 @@ func NewRootCommand() *cobra.Command { ...@@ -22,7 +23,7 @@ func NewRootCommand() *cobra.Command {
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
config := LoadConfig() config := LoadConfig()
debugMode := os.Getenv("DEBUG_MODE") debugMode := os.Getenv("DEBUG_MODE")
logging.Get().Info().Msgf("DEBUG_MODE: %s", debugMode) log.Info().Msgf("DEBUG_MODE: %s", debugMode)
if debugMode == "true" { if debugMode == "true" {
config.Debug = true config.Debug = true
// config.Conf.Debug = true // config.Conf.Debug = true
...@@ -40,30 +41,43 @@ func NewRootCommand() *cobra.Command { ...@@ -40,30 +41,43 @@ func NewRootCommand() *cobra.Command {
panic("dbConfig is nil") panic("dbConfig is nil")
} }
caData, err := base64.StdEncoding.DecodeString(config.RegionConfigs[0].CAData) clusterClientManager := utils.NewClusterClientManager()
for _, regionConfig := range config.RegionConfigs {
var caData []byte
var clientCertData []byte
var clientKeyData []byte
if regionConfig.CAData != "" {
caData, err = base64.StdEncoding.DecodeString(regionConfig.CAData)
if err != nil { if err != nil {
panic(err) panic(err)
} }
clientCertData, err := base64.StdEncoding.DecodeString(config.RegionConfigs[0].ClientCertData) }
if regionConfig.ClientCertData != "" {
clientCertData, err = base64.StdEncoding.DecodeString(regionConfig.ClientCertData)
if err != nil { if err != nil {
panic(err) panic(err)
} }
clientKeyData, err := base64.StdEncoding.DecodeString(config.RegionConfigs[0].ClientKeyData) }
if regionConfig.ClientKeyData != "" {
clientKeyData, err = base64.StdEncoding.DecodeString(regionConfig.ClientKeyData)
if err != nil { if err != nil {
panic(err) panic(err)
} }
}
client := versioned.NewForConfigOrDie(&rest.Config{ client := versioned.NewForConfigOrDie(&rest.Config{
Host: config.RegionConfigs[0].ApiServer, Host: regionConfig.ApiServer,
TLSClientConfig: rest.TLSClientConfig{ TLSClientConfig: rest.TLSClientConfig{
Insecure: false, Insecure: regionConfig.Insecure,
CAData: caData, CAData: caData,
CertData: clientCertData, CertData: clientCertData,
KeyData: clientKeyData, KeyData: clientKeyData,
}, },
// BearerToken: "1234567890", // BearerToken: "1234567890",
}) })
clusterClientManager.AddClient(regionConfig.RegionCode, client)
}
e := api.SetRouters(db, client) e := api.SetRouters(db, clusterClientManager)
return e.Run(":8080") return e.Run(":8080")
}, },
} }
......
...@@ -3,7 +3,7 @@ package app ...@@ -3,7 +3,7 @@ package app
import ( import (
"os" "os"
"gitlab.com/security-rd/go-pkg/logging" "github.com/rs/zerolog/log"
"gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
) )
...@@ -36,6 +36,7 @@ type RegionConfig struct { ...@@ -36,6 +36,7 @@ type RegionConfig struct {
Token string `yaml:"token"` Token string `yaml:"token"`
ClientCertData string `yaml:"client_cert_data"` ClientCertData string `yaml:"client_cert_data"`
ClientKeyData string `yaml:"client_key_data"` ClientKeyData string `yaml:"client_key_data"`
Insecure bool `yaml:"insecure"`
} }
func LoadConfig() *Config { func LoadConfig() *Config {
...@@ -46,13 +47,13 @@ func LoadConfig() *Config { ...@@ -46,13 +47,13 @@ func LoadConfig() *Config {
data, err := os.ReadFile(configFile) data, err := os.ReadFile(configFile)
if err != nil { if err != nil {
logging.Get().Error().Err(err).Msgf("Failed to read config file: %s", configFile) log.Err(err).Msgf("Failed to read config file: %s", configFile)
return nil return nil
} }
var config Config var config Config
if err := yaml.Unmarshal(data, &config); err != nil { if err := yaml.Unmarshal(data, &config); err != nil {
logging.Get().Error().Err(err).Msg("Failed to parse config file") log.Err(err).Msg("Failed to parse config file")
return nil return nil
} }
// 如果config.DBConfig为nil,则使用默认值 // 如果config.DBConfig为nil,则使用默认值
......
...@@ -4,7 +4,7 @@ import ( ...@@ -4,7 +4,7 @@ import (
"os" "os"
"github.com/rs/zerolog" "github.com/rs/zerolog"
"gitlab.com/security-rd/go-pkg/logging" "github.com/rs/zerolog/log"
"gitlab.com/tensorsecurity-rd/waf-console/cmd/app" "gitlab.com/tensorsecurity-rd/waf-console/cmd/app"
) )
...@@ -14,14 +14,13 @@ const ( ...@@ -14,14 +14,13 @@ const (
) )
func main() { func main() {
logLevel := zerolog.InfoLevel
logging.Get().SetLevel(logLevel) zerolog.SetGlobalLevel(zerolog.InfoLevel)
logging.Get().Info().Msg("starting gateway") log.Info().Msg("starting gateway")
rootCmd := app.NewRootCommand() rootCmd := app.NewRootCommand()
if err := rootCmd.Execute(); err != nil { if err := rootCmd.Execute(); err != nil {
logging.Get().Err(err) log.Err(err)
os.Exit(-1) os.Exit(-1)
} }
} }
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: testaaa-lsnr-aaaa
namespace: tensorsec
labels:
apigateway: testaaa
spec:
selector:
istio: ingressgateway
servers:
- hosts:
- "*"
port:
name: http2-9999
number: 9999
protocol: HTTP2
\ No newline at end of file
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: waf-console name: tensorsec-waf-console
spec: spec:
selector: selector:
matchLabels: matchLabels:
app: waf-console app: tensorsec-waf-console
template: template:
metadata: metadata:
labels: labels:
app: waf-console app: tensorsec-waf-console
app.kubernetes.io/name: waf-console
spec: spec:
imagePullSecrets:
- name: harbor-admin-secret
containers: containers:
- name: waf-console - name: waf-console
image: harbor.tensorsecurity.com/tensorsecurity/waf-console:testcn image: harbor.tensorsecurity.com/tensorsecurity/waf-console:testcn
imagePullPolicy: Always
resources: resources:
limits: limits:
memory: "128Mi" memory: "128Mi"
...@@ -36,10 +40,10 @@ spec: ...@@ -36,10 +40,10 @@ spec:
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
name: waf-console name: tensorsec-waf-console
spec: spec:
selector: selector:
app: waf-console app: tensorsec-waf-console
ports: ports:
- port: 8080 - port: 8080
targetPort: 8080 targetPort: 8080
This diff is collapsed.
...@@ -2,14 +2,14 @@ ...@@ -2,14 +2,14 @@
CREATE TABLE waf_services ( CREATE TABLE waf_services (
id SERIAL PRIMARY KEY, id SERIAL PRIMARY KEY,
gateway_name VARCHAR(255) NOT NULL, gateway_name VARCHAR(255) NOT NULL,
port INTEGER NOT NULL,
namespace VARCHAR(255) NOT NULL, namespace VARCHAR(255) NOT NULL,
region_code VARCHAR(50) NOT NULL, region_code VARCHAR(50) NOT NULL,
host TEXT NOT NULL, -- Stored as comma-separated string
mode VARCHAR(50) NOT NULL, mode VARCHAR(50) NOT NULL,
rule_num INTEGER DEFAULT 0, rule_num INTEGER DEFAULT 0,
attack_num INTEGER DEFAULT 0, attack_num INTEGER DEFAULT 0,
rule_category_status JSONB NOT NULL rule_category_status JSON,
status INTEGER NOT NULL,
port INTEGER NOT NULL
); );
-- Create waf_rules table -- Create waf_rules table
...@@ -33,7 +33,7 @@ CREATE TABLE waf_rule_categories ( ...@@ -33,7 +33,7 @@ CREATE TABLE waf_rule_categories (
description_en TEXT, description_en TEXT,
description_zh TEXT, description_zh TEXT,
status INTEGER NOT NULL, status INTEGER NOT NULL,
rules JSONB NOT NULL rules JSON NOT NULL
); );
-- Add indexes for better query performance -- Add indexes for better query performance
......
module gitlab.com/tensorsecurity-rd/waf-console module gitlab.com/tensorsecurity-rd/waf-console
go 1.22.1 go 1.20
require ( require (
github.com/gin-gonic/gin v1.10.0 github.com/gin-gonic/gin v1.10.0
gitlab.com/security-rd/go-pkg v0.2.5
gorm.io/driver/mysql v1.5.0 gorm.io/driver/mysql v1.5.0
gorm.io/gorm v1.25.12 gorm.io/gorm v1.25.12
k8s.io/apimachinery v0.27.2 k8s.io/apimachinery v0.27.2
...@@ -42,7 +41,7 @@ require ( ...@@ -42,7 +41,7 @@ require (
google.golang.org/appengine v1.6.7 // indirect google.golang.org/appengine v1.6.7 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1
k8s.io/api v0.27.2 // indirect k8s.io/api v0.27.2 // indirect
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c // indirect k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c // indirect
k8s.io/klog/v2 v2.90.1 // indirect k8s.io/klog/v2 v2.90.1 // indirect
...@@ -53,10 +52,7 @@ require ( ...@@ -53,10 +52,7 @@ require (
sigs.k8s.io/yaml v1.3.0 // indirect sigs.k8s.io/yaml v1.3.0 // indirect
) )
require ( require github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7
github.com/inconshreveable/mousetrap v1.1.0 // indirect
)
require ( require (
github.com/bytedance/sonic v1.12.1 // indirect github.com/bytedance/sonic v1.12.1 // indirect
...@@ -89,5 +85,3 @@ require ( ...@@ -89,5 +85,3 @@ require (
golang.org/x/text v0.21.0 // indirect golang.org/x/text v0.21.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect google.golang.org/protobuf v1.34.2 // indirect
) )
replace gitlab.com/security-rd/go-pkg => scm.tensorsecurity.cn/tensorsecurity-rd/go-pkg v0.2.101
...@@ -58,7 +58,6 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh ...@@ -58,7 +58,6 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
...@@ -69,7 +68,6 @@ github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9 ...@@ -69,7 +68,6 @@ github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
...@@ -106,13 +104,10 @@ github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ ...@@ -106,13 +104,10 @@ github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec=
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
...@@ -135,7 +130,6 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN ...@@ -135,7 +130,6 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
...@@ -169,10 +163,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8m ...@@ -169,10 +163,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8m
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c h1:Hww8mOyEKTeON4bZn7FrlLismspbPc1teNRUVH7wLQ8= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c h1:Hww8mOyEKTeON4bZn7FrlLismspbPc1teNRUVH7wLQ8=
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo/v2 v2.9.1 h1:zie5Ly042PD3bsCvsSOPvRnFwyo3rKe64TJlD6nu0mk= github.com/onsi/ginkgo/v2 v2.9.1 h1:zie5Ly042PD3bsCvsSOPvRnFwyo3rKe64TJlD6nu0mk=
github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E= github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E=
github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ=
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
...@@ -181,7 +173,6 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb ...@@ -181,7 +173,6 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc= github.com/rs/zerolog v1.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc=
github.com/rs/zerolog v1.29.1/go.mod h1:Le6ESbR7hc+DP6Lt1THiV8CQSdkkNrd3R0XbEgp3ZBU= github.com/rs/zerolog v1.29.1/go.mod h1:Le6ESbR7hc+DP6Lt1THiV8CQSdkkNrd3R0XbEgp3ZBU=
...@@ -253,7 +244,6 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ ...@@ -253,7 +244,6 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
...@@ -362,8 +352,6 @@ k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3 ...@@ -362,8 +352,6 @@ k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3
k8s.io/utils v0.0.0-20230505201702-9f6742963106 h1:EObNQ3TW2D+WptiYXlApGNLVy0zm/JIBVY9i+M4wpAU= k8s.io/utils v0.0.0-20230505201702-9f6742963106 h1:EObNQ3TW2D+WptiYXlApGNLVy0zm/JIBVY9i+M4wpAU=
k8s.io/utils v0.0.0-20230505201702-9f6742963106/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= k8s.io/utils v0.0.0-20230505201702-9f6742963106/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
scm.tensorsecurity.cn/tensorsecurity-rd/go-pkg v0.2.101 h1:fmZdjUOeCwXnGRsq4cmaIbJCT+FIfjZkUJR6My2sJ3A=
scm.tensorsecurity.cn/tensorsecurity-rd/go-pkg v0.2.101/go.mod h1:7iA3d/FiV1buGqWtcrcSH1/wlT7DNQpMmxzBtq3/zbY=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
......
...@@ -2,12 +2,12 @@ package controller ...@@ -2,12 +2,12 @@ package controller
import ( import (
"context" "context"
"strconv"
"time" "time"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"gitlab.com/tensorsecurity-rd/waf-console/internal/service" "gitlab.com/tensorsecurity-rd/waf-console/internal/service"
"gitlab.com/tensorsecurity-rd/waf-console/internal/utils" "gitlab.com/tensorsecurity-rd/waf-console/internal/utils"
"gitlab.com/tensorsecurity-rd/waf-console/pkg/generated/clientset/versioned"
"gorm.io/gorm" "gorm.io/gorm"
) )
...@@ -15,9 +15,9 @@ type WafController struct { ...@@ -15,9 +15,9 @@ type WafController struct {
service service.Service service service.Service
} }
func NewWafController(client *versioned.Clientset, db *gorm.DB) *WafController { func NewWafController(clusterClientManager *utils.ClusterClientManager, db *gorm.DB) *WafController {
return &WafController{ return &WafController{
service: service.NewWafService(client, db), service: service.NewWafService(clusterClientManager, db),
} }
} }
...@@ -26,7 +26,9 @@ func (c *WafController) Waf(ctx *gin.Context) { ...@@ -26,7 +26,9 @@ func (c *WafController) Waf(ctx *gin.Context) {
defer cancel() defer cancel()
gatewayName := ctx.Param("gateway_name") gatewayName := ctx.Param("gateway_name")
waf, err := c.service.GetWaf(ctx1, gatewayName) regionCode := ctx.Param("region_code")
namespace := ctx.Param("namespace")
waf, err := c.service.GetWaf(ctx1, regionCode, namespace, gatewayName)
if err != nil { if err != nil {
// logging.Get().Err(err).Msgf("get waf") // logging.Get().Err(err).Msgf("get waf")
utils.AssembleResponse(ctx, nil, err) utils.AssembleResponse(ctx, nil, err)
...@@ -89,6 +91,24 @@ func (c *WafController) UpdateMode(ctx *gin.Context) { ...@@ -89,6 +91,24 @@ func (c *WafController) UpdateMode(ctx *gin.Context) {
utils.AssembleResponse(ctx, nil, nil) utils.AssembleResponse(ctx, nil, nil)
} }
func (c *WafController) UpdateRule(ctx *gin.Context) {
ctx1, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
var req service.RuleRequest
if err := ctx.BindJSON(&req); err != nil {
utils.AssembleResponse(ctx, nil, err)
return
}
err := c.service.UpdateRule(ctx1, &req)
if err != nil {
utils.AssembleResponse(ctx, nil, err)
return
}
utils.AssembleResponse(ctx, nil, nil)
}
func (c *WafController) SaveRuleCategoryToDB(ctx *gin.Context) { func (c *WafController) SaveRuleCategoryToDB(ctx *gin.Context) {
ctx1, cancel := context.WithTimeout(context.Background(), 10*time.Second) ctx1, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel() defer cancel()
...@@ -100,3 +120,87 @@ func (c *WafController) SaveRuleCategoryToDB(ctx *gin.Context) { ...@@ -100,3 +120,87 @@ func (c *WafController) SaveRuleCategoryToDB(ctx *gin.Context) {
} }
utils.AssembleResponse(ctx, nil, nil) utils.AssembleResponse(ctx, nil, nil)
} }
func (c *WafController) EnableListenerWaf(ctx *gin.Context) {
ctx1, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
var req service.EnableListenerWafReq
if err := ctx.BindJSON(&req); err != nil {
utils.AssembleResponse(ctx, nil, err)
return
}
err := c.service.EnableListenerWaf(ctx1, &req)
if err != nil {
utils.AssembleResponse(ctx, nil, err)
return
}
utils.AssembleResponse(ctx, nil, nil)
}
func (c *WafController) EnableGatewayWaf(ctx *gin.Context) {
ctx1, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
var req service.EnableGatewayWafReq
if err := ctx.BindJSON(&req); err != nil {
utils.AssembleResponse(ctx, nil, err)
return
}
err := c.service.EnableGatewayWaf(ctx1, &req)
if err != nil {
utils.AssembleResponse(ctx, nil, err)
return
}
utils.AssembleResponse(ctx, nil, nil)
}
func (c *WafController) DeleteListenerWaf(ctx *gin.Context) {
ctx1, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
regionCode := ctx.Param("region_code")
namespace := ctx.Param("namespace")
gatewayName := ctx.Param("gateway_name")
port, err := strconv.Atoi(ctx.Param("port"))
if err != nil {
utils.AssembleResponse(ctx, nil, err)
return
}
err = c.service.DeleteListenerWaf(ctx1, &service.DeleteListenerReq{
GatewateInfo: service.GatewateInfo{
RegionCode: regionCode,
Namespace: namespace,
GatewayName: gatewayName,
},
Port: port,
})
if err != nil {
utils.AssembleResponse(ctx, nil, err)
return
}
utils.AssembleResponse(ctx, nil, nil)
}
func (c *WafController) DeleteGatewayWaf(ctx *gin.Context) {
ctx1, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
regionCode := ctx.Param("region_code")
namespace := ctx.Param("namespace")
gatewayName := ctx.Param("gateway_name")
err := c.service.DeleteGatewayWaf(ctx1, &service.GatewateInfo{
RegionCode: regionCode,
Namespace: namespace,
GatewayName: gatewayName,
})
if err != nil {
utils.AssembleResponse(ctx, nil, err)
return
}
utils.AssembleResponse(ctx, nil, nil)
}
...@@ -18,10 +18,18 @@ func (h *HostList) Scan(src interface{}) error { ...@@ -18,10 +18,18 @@ func (h *HostList) Scan(src interface{}) error {
} }
type RuleCategoryStatus struct { type RuleCategoryStatus struct {
CategoryID string `json:"category_id"` CategoryID []string `json:"category_id"`
Status int `json:"status"` Status int `json:"status"`
} }
func (r *RuleCategoryStatus) Scan(src interface{}) error {
return json.Unmarshal(src.([]byte), r)
}
func (r RuleCategoryStatus) Value() (driver.Value, error) {
return json.Marshal(r)
}
type RuleCategoryStatusList []RuleCategoryStatus type RuleCategoryStatusList []RuleCategoryStatus
func (r RuleCategoryStatusList) Value() (driver.Value, error) { func (r RuleCategoryStatusList) Value() (driver.Value, error) {
...@@ -32,17 +40,22 @@ func (r *RuleCategoryStatusList) Scan(src interface{}) error { ...@@ -32,17 +40,22 @@ func (r *RuleCategoryStatusList) Scan(src interface{}) error {
return json.Unmarshal(src.([]byte), r) return json.Unmarshal(src.([]byte), r)
} }
const (
WafStatusEnable = 0
WafStatusDisable = 1
WafStatusUnknown = 2
)
type WafService struct { type WafService struct {
ID uint `gorm:"column:id;primaryKey;autoIncrement"` ID uint `gorm:"column:id;primaryKey;autoIncrement"`
GatewayName string `gorm:"column:gateway_name"` GatewayName string `gorm:"column:gateway_name"`
Port int `gorm:"column:port"`
Namespace string `gorm:"column:namespace"` Namespace string `gorm:"column:namespace"`
RegionCode string `gorm:"column:region_code"` RegionCode string `gorm:"column:region_code"`
Host HostList `gorm:"column:host"`
Mode string `gorm:"column:mode"` Mode string `gorm:"column:mode"`
RuleNum int `gorm:"column:rule_num"` RuleNum int `gorm:"column:rule_num"`
AttackNum int `gorm:"column:attack_num"` AttackNum int `gorm:"column:attack_num"`
RuleCategoryStatus RuleCategoryStatusList `gorm:"column:rule_category_status;type:json"` RuleCategoryStatus *RuleCategoryStatus `gorm:"column:rule_category_status;type:json"`
Host HostList `gorm:"column:host"`
} }
func (WafService) TableName() string { func (WafService) TableName() string {
...@@ -101,3 +114,16 @@ func (r *WafRuleCategory) Scan(src interface{}) error { ...@@ -101,3 +114,16 @@ func (r *WafRuleCategory) Scan(src interface{}) error {
func (r WafRuleCategory) Value() (driver.Value, error) { func (r WafRuleCategory) Value() (driver.Value, error) {
return json.Marshal(r) return json.Marshal(r)
} }
type GatewayListener struct {
ID int `gorm:"column:id;primaryKey;autoIncrement"`
GatewayName string `gorm:"column:gateway_name"`
Namespace string `gorm:"column:namespace"`
RegionCode string `gorm:"column:region_code"`
Port int `gorm:"column:port"`
Enable bool `gorm:"column:enable"`
}
func (GatewayListener) TableName() string {
return "gateway_listeners"
}
This diff is collapsed.
package service
import (
"encoding/json"
"fmt"
"io"
"net/http"
"strconv"
"gitlab.com/tensorsecurity-rd/waf-console/internal/model"
)
var fakePrivateData = `{
"data": [
{
"ioc": "159.203.93.255",
"host": "10.65.135.204",
"intelligence": [
{
"judgments": [
"Exploit"
],
"severity": "low",
"ban": {
"banned": 1,
"reason": "The IP address belongs to DigitalOcean, LLC, it is recommended to assess and handle it accordingly."
},
"basic": {
"carrier": "DigitalOcean, LLC",
"location": {
"country": "美国",
"country_code": "US",
"province": "新泽西州",
"city": "克利夫顿",
"lng": -74.16366,
"lat": 40.858402
}
},
"asn": {
"number": "14061",
"info": "DIGITALOCEAN-ASN - DigitalOcean, LLC, US"
},
"ioc_type": "ipv4",
"confidence_level": "low",
"is_malicious": true,
"source_name": "微步在线-IP信誉",
"update_time": 1719268503000
}
]
}
],
"response_code": 0,
"verbose_msg": "success"
}`
type ipServicePrivate struct {
URL string
ApiKey string
// ipQueryUrl string
ipReputationUrl string
// ipInfoMap map[string]IpInfo
// useCachedIPInfo bool
// ipInfoCache *expirable.LRU[string, IPInfoPrivate]
}
// func NewIpServicePrivate(url, apiKey string, useCachedIPInfo bool) Service {
// var ipReputationUrl string
// reputationUrl := os.Getenv("IP_REPUTATION_URL")
// logging.Get().Info().Msgf("reputationUrl: %s", reputationUrl)
// if reputationUrl != "" {
// ipReputationUrl = reputationUrl
// } else {
// ipReputationUrl = fmt.Sprintf("%s?apikey=%s&resource=", ipReputation, apiKey)
// }
// logging.Get().Info().Msgf("ipReputationUrl: %s", ipReputationUrl)
// return &ipServicePrivate{
// URL: url,
// ApiKey: apiKey,
// ipReputationUrl: ipReputationUrl,
// }
// }
func (s *ipServicePrivate) QueryIP(ip string) (*model.IPInfo, error) {
url := s.ipReputationUrl + ip
respData, err := http.DefaultClient.Get(url)
if err != nil {
return nil, err
}
defer respData.Body.Close()
body, err := io.ReadAll(respData.Body)
if err != nil {
return nil, fmt.Errorf("query ip info failed: %w", err)
}
var resp IPInfoPrivateResp
if err := json.Unmarshal(body, &resp); err != nil {
return nil, fmt.Errorf("unmarshal response failed: %w", err)
}
if len(resp.Data) == 0 || len(resp.Data[0].Intelligence) == 0 {
return nil, fmt.Errorf("no data found for ip %s", ip)
}
info := resp.Data[0].Intelligence[0]
tagsClasses := make([]model.TagsClass, 0, 5)
for k, v := range info.TagsClasses {
for _, tag := range v {
tagsClasses = append(tagsClasses, model.TagsClass{
TagsType: k,
Tags: tag,
})
}
}
return &model.IPInfo{
Carrier: info.Basic.Carrier,
Location: model.Location{
Country: info.Basic.Location.Country,
CountryCode: info.Basic.Location.CountryCode,
Province: info.Basic.Location.Province,
City: info.Basic.Location.City,
Longitude: info.Basic.Location.Longitude,
Latitude: info.Basic.Location.Latitude,
},
Asn: model.ASN{
Number: func() int { n, _ := strconv.Atoi(info.ASN.Number); return n }(),
Info: info.ASN.Info,
},
Scene: info.Scene,
IsMalicious: info.IsMalicious,
Judgments: info.Judgments,
TagsClasses: tagsClasses,
}, nil
}
package service
import (
"encoding/json"
"fmt"
"reflect"
"testing"
"gitlab.com/tensorsecurity-rd/waf-console/internal/model"
)
func TestIPService_QueryIP(t *testing.T) {
type fields struct {
URL string
ApiKey string
}
type args struct {
ip string
}
tests := []struct {
name string
fields fields
args args
want *model.IPInfo
wantErr bool
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := &ipService{
URL: tt.fields.URL,
ApiKey: tt.fields.ApiKey,
}
got, err := s.QueryIP(tt.args.ip)
if (err != nil) != tt.wantErr {
t.Errorf("IPService.QueryIP() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("IPService.QueryIP() = %v, want %v", got, tt.want)
}
})
}
}
func TestParseIPInfo(t *testing.T) {
t.Run("test 1", func(t *testing.T) {
var respData RespData
err := json.Unmarshal([]byte(fakeData), &respData)
if err != nil {
t.Errorf("Unmarshal err %v", err)
}
if info, ok := respData.Data["87.236.176.199"]; ok {
var ipInfo IpInfo
d, err := info.MarshalJSON()
if err != nil {
t.Error(err)
}
err = json.Unmarshal(d, &ipInfo)
if err != nil {
t.Error(err)
}
fmt.Println(ipInfo.Judgments)
}
fmt.Println("ddddd")
})
}
func TestParseIPInfoPrivate(t *testing.T) {
t.Run("test 1", func(t *testing.T) {
var respData IPInfoPrivateResp
err := json.Unmarshal([]byte(fakePrivateData), &respData)
if err != nil {
t.Errorf("Unmarshal err %v", err)
}
if len(respData.Data) > 0 {
for _, v := range respData.Data {
fmt.Println(v)
}
}
fmt.Println("ddddd")
})
}
...@@ -4,8 +4,13 @@ import "context" ...@@ -4,8 +4,13 @@ import "context"
type Service interface { type Service interface {
// QueryIP(ip string) (*model.IPInfo, error) // QueryIP(ip string) (*model.IPInfo, error)
GetWaf(ctx context.Context, gatewayName string) (*Waf, error) GetWaf(ctx context.Context, regionCode, namespace, gatewayName string) (*WafService, error)
CreateWaf(ctx context.Context, req *CreateWafReq) (*Waf, error) CreateWaf(ctx context.Context, req *CreateWafReq) (*WafService, error)
UpdateMode(ctx context.Context, req *UpdateModeReq) (*Waf, error) UpdateMode(ctx context.Context, req *UpdateModeReq) (*WafService, error)
UpdateRule(ctx context.Context, req *RuleRequest) error
SaveRuleCategoryToDB(ctx context.Context) error SaveRuleCategoryToDB(ctx context.Context) error
EnableListenerWaf(ctx context.Context, req *EnableListenerWafReq) error
EnableGatewayWaf(ctx context.Context, req *EnableGatewayWafReq) error
DeleteGatewayWaf(ctx context.Context, req *GatewateInfo) error
DeleteListenerWaf(ctx context.Context, req *DeleteListenerReq) error
} }
...@@ -163,33 +163,64 @@ type IPInfoPrivateResp struct { ...@@ -163,33 +163,64 @@ type IPInfoPrivateResp struct {
VerboseMsg string `json:"verbose_msg"` VerboseMsg string `json:"verbose_msg"`
} }
type Waf struct { type WafService struct {
GatewayName string `json:"gateway_name"` GatewayName string `json:"gateway_name"`
Mode string `json:"mode"` Mode string `json:"mode"`
RuleNum int `json:"rule_num"` RuleNum int `json:"rule_num"`
AttackNum int `json:"attack_num"` AttackNum int `json:"attack_num"`
} // WAF configuration details } // WAF configuration details
type CreateWafReq struct { type GatewateInfo struct {
RegionCode string `json:"region_code"`
Namespace string `json:"namespace"`
GatewayName string `json:"gateway_name"` GatewayName string `json:"gateway_name"`
Namespace string `json:"namespace"`
RegionCode string `json:"region_code"`
ApiGatewayCrn string `json:"gateway_crn"`
Hosts []string `json:"hosts"`
}
type CreateWafReq struct {
GatewateInfo
Port uint32 `json:"port"` Port uint32 `json:"port"`
Host []string `json:"host"` Host []string `json:"host"`
} }
type DeleteWafReq struct {
GatewateInfo
Ports []int `json:"ports"`
}
type RuleRequest struct { type RuleRequest struct {
GatewateInfo
CategoryID []string `json:"category_id"` CategoryID []string `json:"category_id"`
Status int `json:"status"` Status int `json:"status"`
} }
type WafMode string
const (
WafModeProtect WafMode = "protect"
WafModeAlert WafMode = "alert"
WafModePassthrough WafMode = "passthrough"
)
type UpdateModeReq struct { type UpdateModeReq struct {
Mode string `json:"mode"` Mode WafMode `json:"mode"`
GatewayName string `json:"gateway_name"` GatewayName string `json:"gateway_name"`
Namespace string `json:"namespace"` Namespace string `json:"namespace"`
RegionCode string `json:"region_code"` RegionCode string `json:"region_code"`
} }
type EnableListenerWafReq struct {
GatewateInfo
Enable bool `json:"enable"`
Port int `json:"port"`
}
type EnableGatewayWafReq struct {
GatewateInfo
Enable bool `json:"enable"`
}
type WafRule struct { type WafRule struct {
ID int `json:"id"` ID int `json:"id"`
Level int `json:"level"` Level int `json:"level"`
...@@ -217,3 +248,21 @@ type WafRuleCategory struct { ...@@ -217,3 +248,21 @@ type WafRuleCategory struct {
Description Description `json:"description"` Description Description `json:"description"`
Rules []WafRule `json:"rules"` Rules []WafRule `json:"rules"`
} }
type GatewayListener struct {
GatewayName string `json:"gateway_name"`
Namespace string `json:"namespace"`
RegionCode string `json:"region_code"`
Port int `json:"port"`
Enable bool `json:"enable"`
}
type CreateListenerReq struct {
GatewateInfo
Port int `json:"port"`
}
type DeleteListenerReq struct {
GatewateInfo
Port int `json:"port"`
}
package service package service
import ( import (
"bytes"
"context" "context"
"encoding/json"
"fmt" "fmt"
"net/http"
"os" "os"
"strconv"
"strings"
"gitlab.com/tensorsecurity-rd/waf-console/internal/model" "gitlab.com/tensorsecurity-rd/waf-console/internal/model"
"gitlab.com/tensorsecurity-rd/waf-console/internal/utils"
"gitlab.com/tensorsecurity-rd/waf-console/pkg/apis/waf.security.io/v1alpha1" "gitlab.com/tensorsecurity-rd/waf-console/pkg/apis/waf.security.io/v1alpha1"
"gitlab.com/tensorsecurity-rd/waf-console/pkg/generated/clientset/versioned"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"gorm.io/gorm" "gorm.io/gorm"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
) )
type wafService struct { type wafService struct {
client *versioned.Clientset clusterClientManager *utils.ClusterClientManager
db *gorm.DB db *gorm.DB
} }
func NewWafService(client *versioned.Clientset, db *gorm.DB) Service { func NewWafService(clusterClientManager *utils.ClusterClientManager, db *gorm.DB) Service {
return &wafService{client: client, db: db} return &wafService{clusterClientManager: clusterClientManager, db: db}
} }
func (s *wafService) GetWaf(ctx context.Context, gatewayName string) (*Waf, error) { func (s *wafService) GetWaf(ctx context.Context, regionCode, namespace, gatewayName string) (*WafService, error) {
waf := &Waf{ wafService := &model.WafService{}
err := s.db.Model(&model.WafService{}).Where("gateway_name = ? AND region_code = ? AND namespace = ?", gatewayName, regionCode, namespace).First(wafService).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
// Create new WAF service record if not found
wafService = &model.WafService{
RegionCode: regionCode,
Namespace: namespace,
GatewayName: gatewayName, GatewayName: gatewayName,
Mode: "block", Mode: string(WafModeAlert),
RuleNum: 100, }
AttackNum: 100, if err := s.db.Create(wafService).Error; err != nil {
return nil, fmt.Errorf("failed to create WAF service: %v", err)
}
} else {
return nil, fmt.Errorf("failed to query WAF service: %v", err)
}
} }
return waf, nil return &WafService{
GatewayName: wafService.GatewayName,
Mode: wafService.Mode,
RuleNum: wafService.RuleNum,
AttackNum: wafService.AttackNum,
}, nil
} }
func (s *wafService) CreateWaf(ctx context.Context, req *CreateWafReq) (*Waf, error) { func (s *wafService) CreateWaf(ctx context.Context, req *CreateWafReq) (*WafService, error) {
// Create the WAF service resource
name := fmt.Sprintf("%s-%d", req.GatewayName, req.Port)
service := &v1alpha1.Service{ service := &v1alpha1.Service{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: req.GatewayName, Name: name,
Namespace: req.Namespace, Namespace: req.Namespace,
Labels: map[string]string{
"apigateway_name": req.GatewayName,
},
}, },
Spec: v1alpha1.ServiceSpec{ Spec: v1alpha1.ServiceSpec{
HostNames: req.Host, HostNames: req.Host,
...@@ -47,17 +74,126 @@ func (s *wafService) CreateWaf(ctx context.Context, req *CreateWafReq) (*Waf, er ...@@ -47,17 +74,126 @@ func (s *wafService) CreateWaf(ctx context.Context, req *CreateWafReq) (*Waf, er
Name: req.GatewayName, Name: req.GatewayName,
Namespace: req.Namespace, Namespace: req.Namespace,
}, },
Uri: &v1alpha1.StringMatch{
Prefix: "/",
},
LogConfig: &v1alpha1.LogConfig{
Enable: 1,
Level: "info",
},
Mode: "block",
}, },
} }
_, err := s.client.WafV1alpha1().Services(req.Namespace).Create(context.Background(), service, metav1.CreateOptions{})
// Get enabled rule categories from DB
var ruleCategories []model.WafRuleCategory
if err := s.db.Model(&model.WafRuleCategory{}).Where("status = ?", 0).Find(&ruleCategories).Error; err != nil {
return nil, fmt.Errorf("failed to get rule categories: %v", err)
}
// Get existing WAF service config if any
wafService := &model.WafService{}
err := s.db.Model(&model.WafService{}).Where("gateway_name = ? AND namespace = ? AND region_code = ?", req.GatewayName, req.Namespace, req.RegionCode).First(wafService).Error
if err != nil { if err != nil {
return nil, err if err == gorm.ErrRecordNotFound {
// Create new WAF service record if not found
wafService = &model.WafService{
RegionCode: req.RegionCode,
Namespace: req.Namespace,
GatewayName: req.GatewayName,
Mode: string(WafModeAlert),
Host: model.HostList(req.Host),
}
if err := s.db.Create(wafService).Error; err != nil {
return nil, fmt.Errorf("failed to create WAF service: %v", err)
}
} else {
return nil, fmt.Errorf("failed to query WAF service: %v", err)
}
}
// Determine which rule categories to enable
var enabledCategories []model.WafRuleCategory
if wafService.RuleCategoryStatus != nil && len(wafService.RuleCategoryStatus.CategoryID) > 0 {
// Only include categories not already enabled
for _, category := range ruleCategories {
for _, id := range wafService.RuleCategoryStatus.CategoryID {
if id == category.CategoryID {
enabledCategories = append(enabledCategories, category)
continue
}
}
}
} else {
// Enable all categories if none specified
enabledCategories = ruleCategories
}
// Add rules from enabled categories
for _, category := range enabledCategories {
for _, rule := range category.Rules {
service.Spec.Rules = append(service.Spec.Rules, v1alpha1.Rule{
ID: rule.ID,
Level: rule.Level,
Name: rule.Name,
Type: rule.Type,
Description: rule.Description,
Expr: rule.Expr,
Mode: rule.Mode,
})
}
}
// Create the WAF service in Kubernetes
client := s.clusterClientManager.GetClient(req.RegionCode)
if client == nil {
return nil, fmt.Errorf("failed to get cluster client: %v", err)
}
if _, err := client.WafV1alpha1().Services(req.Namespace).Create(ctx, service, metav1.CreateOptions{}); err != nil {
return nil, fmt.Errorf("failed to create WAF service: %v", err)
} }
return nil, nil return nil, nil
} }
func (s *wafService) UpdateMode(ctx context.Context, req *UpdateModeReq) (*Waf, error) { func (s *wafService) DeleteListenerWaf(ctx context.Context, req *DeleteListenerReq) error {
client := s.clusterClientManager.GetClient(req.RegionCode)
if client == nil {
return fmt.Errorf("failed to get cluster client")
}
name := fmt.Sprintf("%s-%d", req.GatewayName, req.Port)
if err := client.WafV1alpha1().Services(req.Namespace).Delete(ctx, name, metav1.DeleteOptions{}); err != nil {
return fmt.Errorf("failed to delete WAF service: %v", err)
}
return nil
}
func (s *wafService) UpdateMode(ctx context.Context, req *UpdateModeReq) (*WafService, error) {
// Check if WAF service exists
wafService := &model.WafService{}
err := s.db.Model(&model.WafService{}).Where("gateway_name = ?", req.GatewayName).First(wafService).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
// Create new WAF service record if not found
wafService = &model.WafService{
RegionCode: req.RegionCode,
Namespace: req.Namespace,
GatewayName: req.GatewayName,
Mode: string(req.Mode),
}
if err := s.db.Create(wafService).Error; err != nil {
return nil, fmt.Errorf("failed to create WAF service: %v", err)
}
} else {
return nil, fmt.Errorf("failed to query WAF service: %v", err)
}
} else {
// Update mode if service exists
if err := s.db.Model(wafService).Update("mode", string(req.Mode)).Error; err != nil {
return nil, fmt.Errorf("failed to update WAF service mode: %v", err)
}
}
return nil, nil return nil, nil
} }
...@@ -131,3 +267,240 @@ func (s *wafService) SaveRuleCategoryToDB(ctx context.Context) error { ...@@ -131,3 +267,240 @@ func (s *wafService) SaveRuleCategoryToDB(ctx context.Context) error {
return nil return nil
} }
func (s *wafService) CreateListener(ctx context.Context, req *CreateListenerReq) (*GatewayListener, error) {
listener := &model.GatewayListener{}
err := s.db.Model(&model.GatewayListener{}).Where("gateway_name = ? AND namespace = ? AND region_code = ?", req.GatewayName, req.Namespace, req.RegionCode).First(listener).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
listener = &model.GatewayListener{
GatewayName: req.GatewayName,
Namespace: req.Namespace,
RegionCode: req.RegionCode,
Port: req.Port,
Enable: true,
}
err = s.db.Model(&model.GatewayListener{}).Create(listener).Error
if err != nil {
return nil, err
}
} else {
return nil, err
}
}
return &GatewayListener{
GatewayName: listener.GatewayName,
Namespace: listener.Namespace,
RegionCode: listener.RegionCode,
Port: listener.Port,
Enable: listener.Enable,
}, nil
}
func (s *wafService) DeleteListener(ctx context.Context, req *DeleteListenerReq) error {
listener := &model.GatewayListener{}
err := s.db.Model(&model.GatewayListener{}).Where("gateway_name = ? AND namespace = ? AND region_code = ?", req.GatewayName, req.Namespace, req.RegionCode).First(listener).Error
if err != nil {
return err
}
err = s.db.Model(&model.GatewayListener{}).Where("gateway_name = ? AND namespace = ? AND region_code = ?", req.GatewayName, req.Namespace, req.RegionCode).Delete(listener).Error
if err != nil {
return err
}
return nil
}
func (s *wafService) EnableListenerWaf(ctx context.Context, req *EnableListenerWafReq) error {
listener := &model.GatewayListener{}
err := s.db.Model(&model.GatewayListener{}).Where("gateway_name = ? AND namespace = ? AND region_code = ?", req.GatewayName, req.Namespace, req.RegionCode).First(listener).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
listener = &model.GatewayListener{
GatewayName: req.GatewayName,
Namespace: req.Namespace,
RegionCode: req.RegionCode,
Port: int(req.Port),
Enable: req.Enable,
}
err = s.db.Model(&model.GatewayListener{}).Create(listener).Error
if err != nil {
return err
}
} else {
return err
}
}
listener.Enable = req.Enable
err = s.db.Model(&model.GatewayListener{}).Where("gateway_name = ? AND namespace = ? AND region_code = ?", req.GatewayName, req.Namespace, req.RegionCode).Update("enable", req.Enable).Error
if err != nil {
return err
}
wafService := &model.WafService{}
err = s.db.Model(&model.WafService{}).Where("gateway_name = ? AND namespace = ? AND region_code = ?", req.GatewayName, req.Namespace, req.RegionCode).First(wafService).Error
if err != nil && err != gorm.ErrRecordNotFound {
return err
}
if listener.Enable {
s.CreateWaf(ctx, &CreateWafReq{
GatewateInfo: GatewateInfo{
GatewayName: req.GatewayName,
Namespace: req.Namespace,
RegionCode: req.RegionCode,
},
Port: uint32(req.Port),
Host: wafService.Host,
})
} else {
s.DeleteListenerWaf(ctx, &DeleteListenerReq{
GatewateInfo: GatewateInfo{
GatewayName: req.GatewayName,
Namespace: req.Namespace,
RegionCode: req.RegionCode,
},
Port: req.Port,
})
}
return nil
}
func (s *wafService) EnableGatewayWaf(ctx context.Context, req *EnableGatewayWafReq) error {
if req.Enable {
// Get listener list from API
body, err := json.Marshal(map[string]string{
"apigateway_crn": req.ApiGatewayCrn,
"region_code": req.RegionCode,
})
if err != nil {
return fmt.Errorf("failed to marshal request body: %v", err)
}
resp, err := http.Post("https://csm.console.test.tg.unicom.local/apigatewaymng/listener/lf-tst7/list_listeners", "application/json", bytes.NewBuffer(body))
if err != nil {
return fmt.Errorf("failed to get listener list: %v", err)
}
defer resp.Body.Close()
// Parse response
var listeners []struct {
ApigatewayCrn string `json:"apigateway_crn"`
Port uint32 `json:"port"`
Hosts []string `json:"hosts"`
}
if err := json.NewDecoder(resp.Body).Decode(&listeners); err != nil {
return fmt.Errorf("failed to parse listener list: %v", err)
}
// Create WAF for each listener
for _, listener := range listeners {
if _, err := s.CreateWaf(ctx, &CreateWafReq{
GatewateInfo: GatewateInfo{
GatewayName: req.GatewayName,
Namespace: req.Namespace,
RegionCode: req.RegionCode,
},
Port: uint32(listener.Port),
Host: listener.Hosts,
}); err != nil {
return fmt.Errorf("failed to create WAF for listener %d: %v", listener.Port, err)
}
}
} else {
s.DeleteGatewayWaf(ctx, &GatewateInfo{
GatewayName: req.GatewayName,
Namespace: req.Namespace,
RegionCode: req.RegionCode,
})
}
return nil
}
func (s *wafService) DeleteGatewayWaf(ctx context.Context, req *GatewateInfo) error {
client := s.clusterClientManager.GetClient(req.RegionCode)
if client == nil {
return fmt.Errorf("failed to get cluster client")
}
labelSelector := fmt.Sprintf("apigateway_name=%s", req.GatewayName)
if err := client.WafV1alpha1().Services(req.Namespace).DeleteCollection(ctx, metav1.DeleteOptions{}, metav1.ListOptions{LabelSelector: labelSelector}); err != nil {
return fmt.Errorf("failed to delete WAF service: %v", err)
}
return nil
}
func (s *wafService) UpdateRule(ctx context.Context, req *RuleRequest) error {
wafService := &model.WafService{}
err := s.db.Model(&model.WafService{}).Where("gateway_name = ?", req.GatewayName).First(wafService).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
// Create new WAF service record if not found
wafService = &model.WafService{
RegionCode: req.RegionCode,
Namespace: req.Namespace,
GatewayName: req.GatewayName,
Mode: string(WafModeAlert),
RuleCategoryStatus: &model.RuleCategoryStatus{
CategoryID: req.CategoryID,
Status: req.Status,
},
}
if err := s.db.Create(wafService).Error; err != nil {
return fmt.Errorf("failed to create WAF service: %v", err)
}
} else {
return fmt.Errorf("failed to query WAF service: %v", err)
}
} else {
// Update mode if service exists
if err := s.db.Model(wafService).Update("rule_category_status", model.RuleCategoryStatus{
CategoryID: req.CategoryID,
Status: req.Status,
}).Error; err != nil {
return fmt.Errorf("failed to update WAF service mode: %v", err)
}
}
return nil
}
func (s *wafService) ListListenerWafStatus(ctx context.Context, req *GatewateInfo) ([]*GatewayListener, error) {
client := s.clusterClientManager.GetClient(req.RegionCode)
if client == nil {
return nil, fmt.Errorf("failed to get cluster client")
}
listenerList, err := client.WafV1alpha1().Services(req.Namespace).List(ctx, metav1.ListOptions{LabelSelector: fmt.Sprintf("apigateway_name=%s", req.GatewayName)})
if err != nil {
return nil, fmt.Errorf("failed to get listener list: %v", err)
}
listenerStatusList := []*GatewayListener{}
portList := []int{}
for _, listener := range listenerList.Items {
n := strings.LastIndex(listener.Name, "-")
if n == -1 {
return nil, fmt.Errorf("failed to get listener name: %v", listener.Name)
}
listenerPort := listener.Name[n+1:]
listenerPortInt, err := strconv.Atoi(listenerPort)
if err != nil {
return nil, fmt.Errorf("failed to get listener port: %v", err)
}
portList = append(portList, listenerPortInt)
}
for _, port := range portList {
listenerStatusList = append(listenerStatusList, &GatewayListener{
GatewayName: req.GatewayName,
Namespace: req.Namespace,
RegionCode: req.RegionCode,
Port: port,
Enable: true,
})
}
return listenerStatusList, nil
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment