517 lines
14 KiB
Go
517 lines
14 KiB
Go
package main
|
|
|
|
// import (
|
|
// "errors"
|
|
// "os"
|
|
// "path/filepath"
|
|
// "regexp"
|
|
// "slices"
|
|
// "strings"
|
|
|
|
// "github.com/google/uuid"
|
|
// "github.com/gookit/goutil/dump"
|
|
// "github.com/spf13/viper"
|
|
// )
|
|
|
|
// // var routeRulesNames = []string{"Host", "Path", "PathPrefix"}
|
|
// const DEFAULT_CONFIG_PATH = "./z/config"
|
|
// const DEFAULT_CONFIG_TYPE = "yaml"
|
|
// const DEFAULT_CONFIG_NAME = "config"
|
|
|
|
// var config = ConfigBuild()
|
|
|
|
// type Config struct {
|
|
// Routers Routers
|
|
// Services Services
|
|
// EntryPoints EntryPoints
|
|
// TLS TLS
|
|
// AuthMap AuthMap
|
|
// Health *Health
|
|
// Logs *Logs
|
|
// }
|
|
// type Logs struct {
|
|
// ConfigBuild []string
|
|
// }
|
|
// type Health struct {
|
|
// ConfigHealth *ConfigHealth
|
|
// }
|
|
// type ConfigHealth struct {
|
|
// Routers bool
|
|
// Services bool
|
|
// EntryPoints bool
|
|
// AuthBuild bool
|
|
// }
|
|
// type ConfigLog map[string][]string
|
|
|
|
// type AuthMap map[string]*Auth
|
|
// type Auth struct {
|
|
// SessionSecret string
|
|
// Paths *Paths
|
|
// OpenID *OpenID
|
|
// }
|
|
// type OpenID struct {
|
|
// Realm string
|
|
// Issuer string
|
|
// ClientID string
|
|
// ClientSecret string
|
|
// AuthURL string
|
|
// TokenURL string
|
|
// UserURL string
|
|
// LogoutURL string
|
|
// Config string
|
|
// RedirectURI string
|
|
// PostLogoutRedirectUri string
|
|
// }
|
|
// type Paths struct {
|
|
// Prefix string
|
|
// Login string
|
|
// Logout string
|
|
// Callback string
|
|
// }
|
|
// type EntryPoints map[string]*EntryPoint
|
|
// type EntryPoint struct {
|
|
// Address string
|
|
// TLS *EntryPointTLS
|
|
// }
|
|
// type EntryPointTLS struct {
|
|
// Enabled bool
|
|
// }
|
|
// type TLS struct {
|
|
// CertProviders CertProviders
|
|
// }
|
|
// type CertProviders map[string]*certProvider
|
|
// type certProvider struct {
|
|
// Cert string
|
|
// Key string
|
|
// }
|
|
// type Routers map[string]*Router
|
|
|
|
// type Router struct {
|
|
// Priority int
|
|
// Name string
|
|
// Service string
|
|
// EntryPoint string
|
|
// Routes Routes
|
|
// Auth RouterAuth
|
|
// }
|
|
// type RouterAuth struct {
|
|
// Enabled bool
|
|
// Provider string
|
|
// }
|
|
// type Routes map[string]*Route
|
|
|
|
// type Route struct {
|
|
// ID string
|
|
// Router string
|
|
// Rule map[string]string
|
|
// }
|
|
|
|
// type Services map[string]string
|
|
|
|
// func (e EntryPoints) ForEach(fn func(name string, data *EntryPoint)) {
|
|
// for name, data := range e {
|
|
// fn(name, data)
|
|
// }
|
|
// }
|
|
// func (r Routers) ForEach(fn func(name string, data *Router) string) {
|
|
|
|
// for name, data := range r {
|
|
// msg := fn(name, data)
|
|
// if msg == "break" {
|
|
// break
|
|
// }
|
|
// if msg == "continue" {
|
|
// continue
|
|
// }
|
|
// }
|
|
// }
|
|
// func (r Routers) ForEachByPriority(fn func(name string, data *Router)) {
|
|
// slc := r.getSlicesByPriority()
|
|
// for _, n := range slc {
|
|
// d := r[n]
|
|
// fn(n, d)
|
|
// }
|
|
// }
|
|
// func (r Routers) getSlicesByPriority() []string {
|
|
|
|
// routersSlice := []string{}
|
|
// r.ForEach(func(routerName string, routerData *Router) string {
|
|
// routersSlice = append(routersSlice, routerName)
|
|
// return ""
|
|
// })
|
|
// slices.SortFunc(routersSlice, func(a, b string) int {
|
|
// if r[a].Priority == r[b].Priority {
|
|
// return 0
|
|
// }
|
|
// if r[a].Priority > r[b].Priority {
|
|
// return -1
|
|
// }
|
|
// if r[a].Priority < r[b].Priority {
|
|
// return 1
|
|
// }
|
|
// return r[a].Priority - r[b].Priority
|
|
// })
|
|
// return routersSlice
|
|
|
|
// }
|
|
// func (r *Router) GetRouteByID(routeID string) *Route {
|
|
// return r.Routes[routeID]
|
|
// }
|
|
// func (r Routes) ForEach(fn func(routeID string, v *Route) string) {
|
|
|
|
// for routeID, v := range r {
|
|
// msg := fn(routeID, v)
|
|
// if msg == "break" {
|
|
// break
|
|
// }
|
|
// if msg == "continue" {
|
|
// continue
|
|
// }
|
|
// }
|
|
// }
|
|
// func (r Route) ForEachRule(fn func(routeID string, ruleName string, ruleValue string)) {
|
|
// for k, v := range r.Rule {
|
|
// fn(r.ID, k, v)
|
|
// }
|
|
// }
|
|
// func InitConfigStruct() *Config {
|
|
// config := &Config{
|
|
// Routers: Routers{},
|
|
// Services: Services{},
|
|
// EntryPoints: EntryPoints{},
|
|
// TLS: TLS{
|
|
// CertProviders: CertProviders{},
|
|
// },
|
|
// AuthMap: AuthMap{},
|
|
// Health: &Health{
|
|
// ConfigHealth: &ConfigHealth{
|
|
// Routers: false,
|
|
// Services: false,
|
|
// EntryPoints: false,
|
|
// AuthBuild: false,
|
|
// },
|
|
// },
|
|
// Logs: &Logs{
|
|
// ConfigBuild: []string{},
|
|
// },
|
|
// }
|
|
|
|
// return config
|
|
// }
|
|
// func ConfigBuild() *Config {
|
|
// viperConfig := NewViperConfig()
|
|
// config := InitConfigStruct()
|
|
// // //Routers
|
|
// // //Services
|
|
// BuildRoutersConfig(viperConfig, config, "routers")
|
|
// BuildServicesConfig(viperConfig, config, "services")
|
|
// BuildEntryPointsConfig(viperConfig, config, "entrypoints")
|
|
// BuildCertProvidersConfig(viperConfig, config, "tls.certproviders")
|
|
// BuildAuthConfig(viperConfig, config, "auth")
|
|
|
|
// // if !BuildServicesConfig(viperConfig, config, "services") {
|
|
// // err = errors.Join(errors.New("build services config error ="))
|
|
// // }
|
|
// // if !BuildRoutersConfig(viperConfig, config, "routers") {
|
|
// // err = errors.Join(errors.New("build routers config error"))
|
|
// // }
|
|
|
|
// // // //Entrypoints
|
|
// // if !BuildEntryPointsConfig(viperConfig, config, "entryPoints") {
|
|
// // err = errors.Join(errors.New("build entry points config error"))
|
|
// // }
|
|
// // // //TLS Certificate Providers
|
|
// // if !BuildCertProvidersConfig(viperConfig, config, "tls.certproviders") {
|
|
// // err = errors.Join(errors.New("build cert providers config error"))
|
|
// // }
|
|
// // if !BuildAuthConfig(viperConfig, config, "auth") {
|
|
// // // err = errors.Join(errors.New("build auth config error"))
|
|
// // }
|
|
// return config
|
|
// }
|
|
|
|
// func BuildCertProvidersConfig(viperConfig *viper.Viper, config *Config, key string) bool {
|
|
// if viperConfig.Sub(key) == nil {
|
|
// config.Logs.ConfigBuild = append(config.Logs.ConfigBuild, "Missing \""+key+"\" in Config")
|
|
// return false
|
|
// } else {
|
|
// certProviders := viperConfig.Sub(key).AllSettings()
|
|
|
|
// // config.TLS.CertProviders = make(CertProviders)
|
|
// for k, v := range certProviders {
|
|
// v := v.(map[string]any)
|
|
// cert := v["cert"].(string)
|
|
// key := v["key"].(string)
|
|
// config.TLS.CertProviders[k] = &certProvider{
|
|
// Cert: cert,
|
|
// Key: key,
|
|
// }
|
|
// }
|
|
// return true
|
|
// }
|
|
// }
|
|
// func BuildServicesConfig(viperConfig *viper.Viper, config *Config, key string) bool {
|
|
// if viperConfig.Sub(key) == nil {
|
|
|
|
// config.Logs.ConfigBuild = append(config.Logs.ConfigBuild, "Missing \""+key+"\" in Config")
|
|
// dump.P("Missing \"" + key + "\" in Config")
|
|
// return false
|
|
// } else {
|
|
// config.Services = make(Services)
|
|
// services := viperConfig.Sub(key).AllSettings()
|
|
// for k, v := range services {
|
|
// config.Services[k] = v.(string)
|
|
// }
|
|
// return true
|
|
// }
|
|
// }
|
|
// func BuildEntryPointsConfig(viperConfig *viper.Viper, config *Config, key string) bool {
|
|
// if viperConfig.Sub(key) == nil {
|
|
// config.Logs.ConfigBuild = append(config.Logs.ConfigBuild, "Missing \""+key+"\" in Config")
|
|
// dump.P("Missing \"" + key + "\" in Config")
|
|
|
|
// return false
|
|
// } else {
|
|
// entryPoints := viperConfig.Sub(key).AllSettings()
|
|
// for k, v := range entryPoints {
|
|
|
|
// entryPoint := &EntryPoint{
|
|
// Address: "",
|
|
// TLS: &EntryPointTLS{
|
|
// Enabled: false,
|
|
// },
|
|
// }
|
|
// v := v.(map[string]any)
|
|
|
|
// if _, ok := v["address"]; ok {
|
|
// entryPoint.Address = v["address"].(string)
|
|
// }
|
|
// if _, ok := v["tls"]; ok {
|
|
// tls := v["tls"].(map[string]any)
|
|
// enabled := tls["enabled"].(bool)
|
|
// entryPoint.TLS = &EntryPointTLS{
|
|
// Enabled: enabled,
|
|
// }
|
|
// }
|
|
|
|
// config.EntryPoints[k] = entryPoint
|
|
// }
|
|
// return true
|
|
// }
|
|
// }
|
|
// func BuildAuthConfig(viperConfig *viper.Viper, config *Config, key string) bool {
|
|
// if viperConfig.Sub(key) == nil {
|
|
// config.Logs.ConfigBuild = append(config.Logs.ConfigBuild, "Missing \""+key+"\" in Config")
|
|
// dump.P("Missing \"" + key + "\" in Config")
|
|
|
|
// return false
|
|
// } else {
|
|
// auth := viperConfig.Sub(key).AllSettings()
|
|
// for k, v := range auth {
|
|
// paths := v.(map[string]any)["paths"].(map[string]any)
|
|
// openID := v.(map[string]any)["openid"].(map[string]any)
|
|
// sessionSecret := v.(map[string]any)["sessionsecret"].(string)
|
|
|
|
// config.AuthMap[k] = &Auth{
|
|
// SessionSecret: sessionSecret,
|
|
// Paths: &Paths{
|
|
// Prefix: paths["prefix"].(string),
|
|
// Login: paths["login"].(string),
|
|
// Logout: paths["logout"].(string),
|
|
// Callback: paths["callback"].(string),
|
|
// },
|
|
// OpenID: &OpenID{
|
|
// Realm: openID["realm"].(string),
|
|
// Issuer: openID["issuer"].(string),
|
|
// ClientID: openID["client_id"].(string),
|
|
// ClientSecret: openID["client_secret"].(string),
|
|
// RedirectURI: openID["redirect_uri"].(string),
|
|
// PostLogoutRedirectUri: openID["post_logout_redirect_uri"].(string),
|
|
// Config: openID["config"].(string),
|
|
// AuthURL: openID["authurl"].(string),
|
|
// TokenURL: openID["tokenurl"].(string),
|
|
// UserURL: openID["userurl"].(string),
|
|
// LogoutURL: openID["logouturl"].(string),
|
|
// },
|
|
// }
|
|
// }
|
|
// return true
|
|
// }
|
|
// }
|
|
// func splitStatementByRegex(str string, regx string) []string {
|
|
|
|
// input := str
|
|
// re := regexp.MustCompile(regx)
|
|
// matches := re.FindAllStringSubmatch(input, -1)
|
|
// if len(matches) == 0 {
|
|
// return []string{str} // Return original if no backticks found
|
|
// }
|
|
|
|
// result := []string{}
|
|
// lastIndex := 0
|
|
|
|
// for _, match := range matches {
|
|
|
|
// startIndex := strings.Index(input, match[0])
|
|
|
|
// if startIndex > lastIndex {
|
|
// str := input[lastIndex:startIndex]
|
|
// str, _ = strings.CutPrefix(str, ".")
|
|
// result = append(result, str)
|
|
// }
|
|
// str := match[1]
|
|
// str, _ = strings.CutPrefix(str, ".")
|
|
// result = append(result, str) // Append the content within backticks
|
|
// lastIndex = startIndex + len(match[0])
|
|
// }
|
|
|
|
// if lastIndex < len(input) {
|
|
// str := input[lastIndex:]
|
|
// str, _ = strings.CutPrefix(str, ".")
|
|
// result = append(result, str)
|
|
// }
|
|
|
|
// return result
|
|
// }
|
|
// func BuildRoutersConfig(viperConfig *viper.Viper, config *Config, key string) bool {
|
|
// if viperConfig.Sub(key) == nil {
|
|
// config.Logs.ConfigBuild = append(config.Logs.ConfigBuild, "Missing \""+key+"\" in Config")
|
|
// dump.P("Missing \"" + key + "\" in Config")
|
|
// return false
|
|
// } else {
|
|
// routers := viperConfig.Sub(key).AllSettings()
|
|
// for routerName, d := range routers {
|
|
// data := d.(map[string]any)
|
|
// if _, ok := data["routes"]; !ok {
|
|
// continue
|
|
// }
|
|
// if _, ok := data["service"]; !ok {
|
|
// continue
|
|
// }
|
|
// if _, ok := data["entrypoint"]; !ok {
|
|
// continue
|
|
// }
|
|
// if _, ok := data["priority"]; !ok {
|
|
// data["priority"] = 1000
|
|
// }
|
|
// if _, ok := data["routes"]; !ok {
|
|
// continue
|
|
// }
|
|
// routes := data["routes"].([]any)
|
|
// service := data["service"].(string)
|
|
// entryPoint := data["entrypoint"].(string)
|
|
// priority := data["priority"].(int)
|
|
|
|
// enabled := false
|
|
// provider := ""
|
|
// if _, ok := data["auth"]; ok {
|
|
// enabled = data["auth"].(map[string]any)["enabled"].(bool)
|
|
// provider = data["auth"].(map[string]any)["provider"].(string)
|
|
// }
|
|
|
|
// router := &Router{
|
|
// Name: routerName,
|
|
// Priority: priority,
|
|
// Service: service,
|
|
// EntryPoint: entryPoint,
|
|
// Routes: Routes{},
|
|
// Auth: RouterAuth{
|
|
// Enabled: enabled,
|
|
// Provider: provider,
|
|
// },
|
|
// }
|
|
|
|
// for _, v := range routes {
|
|
// routeID := uuid.New().String()
|
|
// route := &Route{
|
|
// ID: routeID,
|
|
// Router: routerName,
|
|
// Rule: map[string]string{},
|
|
// }
|
|
// rawRoute := v.(string)
|
|
// route.Rule["raw"] = rawRoute
|
|
|
|
// routeStatmentsSlice := splitStatementByRegex(rawRoute, "\\(`(.*?)`\\)")
|
|
|
|
// for i, v := range routeStatmentsSlice {
|
|
// if i&1 == 0 {
|
|
// if i+1 < len(routeStatmentsSlice) {
|
|
// route.Rule[v] = routeStatmentsSlice[i+1]
|
|
// }
|
|
// }
|
|
// }
|
|
// // if _, ok := route.Rule["Auth"]; !ok {
|
|
// // route.Rule["Auth"] = ""
|
|
// // }
|
|
// router.Routes[routeID] = route
|
|
|
|
// // router.Routes = append(router.Routes, route)
|
|
// }
|
|
// config.Routers[routerName] = router
|
|
|
|
// }
|
|
// return true
|
|
|
|
// }
|
|
// }
|
|
// func NewViperConfig() *viper.Viper {
|
|
// vc := viper.New()
|
|
// vc.AddConfigPath(DEFAULT_CONFIG_PATH)
|
|
// vc.SetConfigType(DEFAULT_CONFIG_TYPE)
|
|
// vc.SetConfigName(DEFAULT_CONFIG_NAME)
|
|
// vc.ReadInConfig()
|
|
|
|
// fileNames, err := getFileNames(DEFAULT_CONFIG_PATH, DEFAULT_CONFIG_NAME)
|
|
// if err != nil {
|
|
// dump.Println("No extra config files" + err.Error())
|
|
// } else {
|
|
// for _, fileName := range fileNames {
|
|
// vc.SetConfigName(fileName)
|
|
// vc.MergeInConfig()
|
|
// dump.P("TEST")
|
|
// }
|
|
// }
|
|
|
|
// return vc
|
|
// }
|
|
// func getYamlFileNameExcExt(fileName string, exts ...string) (string, error) {
|
|
// var fileExt string
|
|
// for _, ext := range exts {
|
|
// if strings.HasSuffix(fileName, ext) {
|
|
// fileExt = ext
|
|
// break
|
|
// }
|
|
// }
|
|
|
|
// if name, ok := strings.CutSuffix(fileName, fileExt); ok {
|
|
// return name, nil
|
|
// } else {
|
|
// return "", errors.New("Error: no file extension found!")
|
|
// }
|
|
// }
|
|
// func getFileNames(folderPath string, skipFileName string) ([]string, error) {
|
|
// var fileNames []string
|
|
|
|
// err := filepath.Walk(folderPath, func(path string, info os.FileInfo, err error) error {
|
|
// if err != nil {
|
|
// return err
|
|
// }
|
|
|
|
// if !info.IsDir() { // Only add files, not directories
|
|
// filename := info.Name()
|
|
// filesize := info.Size()
|
|
// filenameNoExt, _ := getYamlFileNameExcExt(filename, ".yaml", ".yml")
|
|
// if skipFileName == filenameNoExt || filesize == 0 {
|
|
// return nil
|
|
// }
|
|
// fileNames = append(fileNames, filenameNoExt)
|
|
// }
|
|
// return nil
|
|
// })
|
|
|
|
// if err != nil {
|
|
// return nil, err
|
|
// }
|
|
|
|
// return fileNames, nil
|
|
// }
|