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 // }