739 lines
18 KiB
Go
739 lines
18 KiB
Go
package config
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"regexp"
|
|
"slices"
|
|
"strings"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/gookit/goutil/dump"
|
|
"github.com/joho/godotenv"
|
|
"github.com/spf13/viper"
|
|
)
|
|
|
|
// var routeRulesNames = []string{"Host", "Path", "PathPrefix"}
|
|
const DEFAULT_CONFIG_TYPE = "yaml"
|
|
|
|
var DEFAULT_CONFIG_PATH string
|
|
var DEFAULT_CONFIG_NAME string
|
|
|
|
var Data *Config
|
|
|
|
func init() {
|
|
err := godotenv.Load(".env")
|
|
if err != nil {
|
|
log.Fatalf("Error loading .env file: %v", err)
|
|
}
|
|
DEFAULT_CONFIG_PATH = os.Getenv("CONFIG_PATH")
|
|
DEFAULT_CONFIG_NAME = os.Getenv("CONFIG_NAME")
|
|
|
|
Data = ConfigBuild()
|
|
}
|
|
|
|
type Config struct {
|
|
Routers Routers
|
|
Services Services
|
|
EntryPoints EntryPoints
|
|
TLS TLS
|
|
AuthMap AuthMap
|
|
Health *Health
|
|
Logs *Logs
|
|
Context context.Context
|
|
}
|
|
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 {
|
|
Domain string
|
|
SessionSecret string
|
|
Paths *Paths
|
|
OpenID *OpenID
|
|
}
|
|
type OpenID struct {
|
|
EndPoints EndPoints
|
|
Realm string
|
|
ClientID string
|
|
ClientSecret string
|
|
}
|
|
type EndPoints struct {
|
|
Issuer string
|
|
AuthURL string
|
|
TokenURL string
|
|
UserURL string
|
|
LogoutURL string
|
|
Config string
|
|
RedirectURI string
|
|
PostLogoutRedirectUri string
|
|
JwksURI string
|
|
}
|
|
type Paths struct {
|
|
Prefix string
|
|
Login string
|
|
Logout string
|
|
Callback string
|
|
PostLogout 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 {
|
|
IsAuthRouter bool
|
|
StripPrefix bool
|
|
Priority int
|
|
Name string
|
|
Service string
|
|
EntryPoint string
|
|
Routes Routes
|
|
Auth RouterAuth
|
|
}
|
|
type RouterAuth struct {
|
|
JWT *JWT
|
|
Enabled bool
|
|
Provider string
|
|
}
|
|
type JWT struct {
|
|
AllowLists map[string][]string
|
|
}
|
|
type Routes map[string]*Route
|
|
|
|
type Route struct {
|
|
ID string
|
|
Router string
|
|
Rule map[string]string
|
|
}
|
|
|
|
type Services map[string]string
|
|
|
|
func (c *Config) InitContext(ctx context.Context) {
|
|
c.Context = ctx
|
|
}
|
|
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) string) {
|
|
for k, v := range r.Rule {
|
|
msg := fn(r.ID, k, v)
|
|
if msg == "break" {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
func BuildAuthPaths(authData any) *Paths {
|
|
pathsData := getMap(authData, "paths")
|
|
return &Paths{
|
|
Prefix: getMapString(pathsData, "prefix"),
|
|
Login: getMapString(pathsData, "login"),
|
|
Logout: getMapString(pathsData, "logout"),
|
|
Callback: getMapString(pathsData, "callback"),
|
|
PostLogout: getMapString(pathsData, "postlogout"),
|
|
}
|
|
}
|
|
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 {
|
|
vc := NewViperConfig()
|
|
c := InitConfigStruct()
|
|
// //Routers
|
|
// //Services
|
|
BuildRoutersConfig(vc, c, "routers")
|
|
BuildServicesConfig(vc, c, "services")
|
|
BuildCertProvidersConfig(vc, c, "tls.certproviders")
|
|
BuildEntryPointsConfig(vc, c, "entrypoints")
|
|
BuildAuthConfig(vc, c, "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 c
|
|
}
|
|
|
|
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 getMap(mp any, key string) map[string]any {
|
|
|
|
if val, ok := mp.(map[string]any)[key]; ok {
|
|
return val.(map[string]any)
|
|
} else {
|
|
return val.(map[string]any)
|
|
}
|
|
}
|
|
func getMapString(mp any, key string) string {
|
|
|
|
if val, ok := mp.(map[string]any)[key]; ok {
|
|
return val.(string)
|
|
} else {
|
|
return ""
|
|
}
|
|
}
|
|
func markWrapper(str string, mark []string) string {
|
|
return mark[0] + str + mark[1]
|
|
}
|
|
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 {
|
|
authData := viperConfig.Sub(key).AllSettings()
|
|
|
|
mark := []string{"<{{", "}}>"}
|
|
|
|
realmUrlMark := markWrapper("realm", mark)
|
|
authRootUrlMark := markWrapper("auth_root_url", mark)
|
|
targetRootUrlMark := markWrapper("target_root_url", mark)
|
|
authLocalRootUrlMark := markWrapper("auth_local_root_url", mark)
|
|
|
|
for authName, v := range authData {
|
|
auth := &Auth{}
|
|
openid := &OpenID{}
|
|
|
|
// dump.P(auth)
|
|
auth.Paths = BuildAuthPaths(v)
|
|
// endPoints := &EndPoints{}
|
|
|
|
authRootURL := getMapString(v, "auth_root_url")
|
|
targetRootURL := getMapString(v, "target_root_url")
|
|
authLocalRootURL := getMapString(v, "auth_local_root_url")
|
|
|
|
openidData := getMap(v, "openid")
|
|
endPointsData := getMap(openidData, "end_points")
|
|
|
|
// for k, v := range openidData {
|
|
// if k != "end_points" {
|
|
// v := v.(string)
|
|
// field := helper.CapitalizeFirstLetter(k)
|
|
// field = helper.CapitalizeAfterCharMulti(field, '_')
|
|
// field = strings.ReplaceAll(field, "_", "")
|
|
// if strings.HasSuffix(field, "Id") {
|
|
// field, _ = strings.CutSuffix(field, "Id")
|
|
// field += "ID"
|
|
// }
|
|
// helper.InsertStringValueIntoField(openid, field, v)
|
|
// dump.P(field, v)
|
|
|
|
// }
|
|
|
|
// }
|
|
openid.Realm = openidData["realm"].(string)
|
|
openid.ClientID = openidData["client_id"].(string)
|
|
openid.ClientSecret = openidData["client_secret"].(string)
|
|
|
|
endPointsMapStringString := make(map[string]string)
|
|
for k, v := range endPointsData {
|
|
val := v.(string)
|
|
if strings.Contains(val, realmUrlMark) {
|
|
val = strings.ReplaceAll(val, realmUrlMark, openid.Realm)
|
|
}
|
|
if strings.Contains(val, authRootUrlMark) {
|
|
val = strings.ReplaceAll(val, authRootUrlMark, authRootURL)
|
|
}
|
|
if strings.Contains(val, targetRootUrlMark) {
|
|
val = strings.ReplaceAll(val, targetRootUrlMark, targetRootURL)
|
|
}
|
|
if strings.Contains(val, authLocalRootUrlMark) {
|
|
val = strings.ReplaceAll(val, authLocalRootUrlMark, authLocalRootURL)
|
|
}
|
|
endPointsMapStringString[k] = val
|
|
}
|
|
|
|
if epData, ok := endPointsMapStringString["issuer"]; ok {
|
|
openid.EndPoints.Issuer = epData
|
|
}
|
|
if epData, ok := endPointsMapStringString["redirect_uri"]; ok {
|
|
|
|
openid.EndPoints.RedirectURI = epData
|
|
}
|
|
if epData, ok := endPointsMapStringString["post_logout_redirect_uri"]; ok {
|
|
openid.EndPoints.PostLogoutRedirectUri = epData
|
|
}
|
|
if epData, ok := endPointsMapStringString["config"]; ok {
|
|
openid.EndPoints.Config = epData
|
|
}
|
|
if epData, ok := endPointsMapStringString["authurl"]; ok {
|
|
openid.EndPoints.AuthURL = epData
|
|
}
|
|
if epData, ok := endPointsMapStringString["tokenurl"]; ok {
|
|
openid.EndPoints.TokenURL = epData
|
|
}
|
|
if epData, ok := endPointsMapStringString["userurl"]; ok {
|
|
openid.EndPoints.UserURL = epData
|
|
}
|
|
if epData, ok := endPointsMapStringString["logouturl"]; ok {
|
|
openid.EndPoints.LogoutURL = epData
|
|
}
|
|
if epData, ok := endPointsMapStringString["jwksuri"]; ok {
|
|
openid.EndPoints.JwksURI = epData
|
|
}
|
|
|
|
auth.OpenID = openid
|
|
config.AuthMap[authName] = auth
|
|
|
|
}
|
|
|
|
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)
|
|
|
|
// var (
|
|
// routes []any
|
|
// service string
|
|
// entryPoint string
|
|
// priority int
|
|
// stripPrefix bool
|
|
// )
|
|
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
|
|
}
|
|
if _, ok := data["stripprefix"]; !ok {
|
|
data["stripprefix"] = false
|
|
}
|
|
routes := data["routes"].([]any)
|
|
service := data["service"].(string)
|
|
entryPoint := data["entrypoint"].(string)
|
|
priority := data["priority"].(int)
|
|
stripPrefix := data["stripprefix"].(bool)
|
|
isAuthRouter := false
|
|
if _, ok := data["is_auth_router"]; ok {
|
|
isAuthRouter = data["is_auth_router"].(bool)
|
|
}
|
|
|
|
//AUTH
|
|
authEnabled := false
|
|
provider := ""
|
|
jwt := &JWT{
|
|
AllowLists: map[string][]string{},
|
|
}
|
|
|
|
if d, ok := data["auth"]; ok {
|
|
|
|
if _, ok := d.(map[string]any)["enabled"]; ok {
|
|
authEnabled = d.(map[string]any)["enabled"].(bool)
|
|
}
|
|
|
|
provider = d.(map[string]any)["provider"].(string)
|
|
if jwtData, ok := d.(map[string]any)["jwt"]; ok {
|
|
if allow, ok := jwtData.(map[string]any)["allow"]; ok {
|
|
a := allow.(map[string]any)
|
|
for f, s := range a {
|
|
field := f
|
|
slice := []string{}
|
|
for _, v := range s.([]any) {
|
|
slice = append(slice, v.(string))
|
|
}
|
|
jwt.AllowLists[field] = slice
|
|
dump.P(slice)
|
|
}
|
|
|
|
}
|
|
}
|
|
// if _, ok := d.(map[string]any)["emails"]; ok {
|
|
// for _, e := range d.(map[string]any)["emails"].([]any) {
|
|
// email := e.(string)
|
|
// emails = append(emails, email)
|
|
// }
|
|
// }
|
|
}
|
|
|
|
router := &Router{
|
|
Name: routerName,
|
|
IsAuthRouter: isAuthRouter,
|
|
Priority: priority,
|
|
Service: service,
|
|
EntryPoint: entryPoint,
|
|
StripPrefix: stripPrefix,
|
|
Routes: Routes{},
|
|
Auth: RouterAuth{
|
|
Enabled: authEnabled,
|
|
Provider: provider,
|
|
JWT: jwt,
|
|
// Emails: emails,
|
|
},
|
|
}
|
|
|
|
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
|
|
routeStatmentsLogicSplit := strings.Split(rawRoute, "&&")
|
|
for _, logicPart := range routeStatmentsLogicSplit {
|
|
logicPart = strings.TrimSpace(logicPart)
|
|
routeStatmentsSlice := splitStatementByRegex(logicPart, "\\(`(.*?)`\\)")
|
|
for i, v := range routeStatmentsSlice {
|
|
if i&1 == 0 {
|
|
if i+1 < len(routeStatmentsSlice) {
|
|
route.Rule[v] = routeStatmentsSlice[i+1]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// routeStatmentsSlice := splitStatementByRegex(rawRoute, "\\(`(.*?)`\\)")
|
|
|
|
// for i, v := range routeStatmentsSlice {
|
|
// if i&1 == 0 {
|
|
// if i+1 < len(routeStatmentsSlice) {
|
|
// route.Rule[v] = routeStatmentsSlice[i+1]
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
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()
|
|
// }
|
|
// }
|
|
|
|
// return vc
|
|
// }
|
|
func NewViperConfig() *viper.Viper {
|
|
vc := viper.New()
|
|
vc.AddConfigPath(DEFAULT_CONFIG_PATH)
|
|
vc.SetConfigType(DEFAULT_CONFIG_TYPE)
|
|
vc.SetConfigName(DEFAULT_CONFIG_NAME)
|
|
err := vc.ReadInConfig()
|
|
if err != nil {
|
|
dump.P(err.Error())
|
|
}
|
|
// vc1 := viper.New()
|
|
// vc1.AddConfigPath(DEFAULT_CONFIG_PATH)
|
|
// vc1.SetConfigType(DEFAULT_CONFIG_TYPE)
|
|
// vc1.SetConfigName("auth")
|
|
// vc1.ReadInConfig()
|
|
|
|
// vc.MergeConfigMap(vc1.AllSettings())
|
|
// vc.MergeConfigMap(vc1.AllSettings())
|
|
|
|
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()
|
|
}
|
|
}
|
|
|
|
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 && fileExt != "" {
|
|
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
|
|
}
|