diff --git a/.air.toml b/.air.toml new file mode 100644 index 0000000..7da9f98 --- /dev/null +++ b/.air.toml @@ -0,0 +1,52 @@ +root = "." +testdata_dir = "testdata" +tmp_dir = "tmp" + +[build] + args_bin = [] + bin = "./_tmp/main" + cmd = "go build -o ./_tmp/main ." + delay = 1000 + exclude_dir = ["assets", "tmp", "vendor", "testdata"] + exclude_file = [] + exclude_regex = ["_test.go"] + exclude_unchanged = false + follow_symlink = false + full_bin = "" + include_dir = [] + include_ext = ["go", "tpl", "tmpl", "html","yaml","yml","toml"] + include_file = [".air.toml"] + kill_delay = "0.5s" + log = "build-errors.log" + poll = false + poll_interval = 0 + post_cmd = [] + pre_cmd = [] + rerun = false + rerun_delay = 500 + send_interrupt = false + stop_on_error = false + +[color] + app = "" + build = "yellow" + main = "magenta" + runner = "green" + watcher = "cyan" + +[log] + main_only = false + silent = false + time = false + +[misc] + clean_on_exit = false + +[proxy] + app_port = 0 + enabled = false + proxy_port = 0 + +[screen] + clear_on_rebuild = false + keep_scroll = true diff --git a/_tmp/main b/_tmp/main new file mode 100755 index 0000000..5416201 Binary files /dev/null and b/_tmp/main differ diff --git a/assets/config/config.yml b/assets/config/config.yml index ae57894..73417b8 100644 --- a/assets/config/config.yml +++ b/assets/config/config.yml @@ -3,22 +3,36 @@ http: keycloak: entryPoint: https service: keycloak - rules: Domain(`keycloak.z.com`).Path(`/`) + rules: Domain(`keycloak.z.com`).PathPrefix(`/) tls: certProvider: default - app1: + # app1: + # entryPoint: https + # service: app1 + # rules: Domain(`app1.z.com`).Path(`/`) + # tls: + # certProvider: default + # app2: + # entryPoint: https + # service: app2 + # rules: Domain(`app2.z.com`).PathPrefix(`/test/`) + # tls: + # certProvider: default + aaa: entryPoint: https service: app1 - rules: Domain(`app1.z.com`).Path(`/`) - tls: - certProvider: default - app2: + rules: Domain(`a.z.com`).PathPrefix(`/`) + + bbb: entryPoint: https service: app2 - rules: Domain(`app2.z.com`).Path(`/`) - tls: - certProvider: default + rules: Domain(`a.z.com`).PathPrefix(`/app2/`) + # ccc: + # entryPoint: https + # service: keycloak + # rules: Domain(`a.z.com`).PathPrefix(`/`) + services: keycloak: http://192.168.10.2:8080 app1: http://192.168.10.2:3001 @@ -29,9 +43,11 @@ entryPoints: address: :443 tls: enabled: true + http: + address: :80 tls: certProviders: default: key: ./assets/certs/z.com.key.pem - cert: ./assets/certs/z.com.cert.pem \ No newline at end of file + cert: ./assets/certs/z.com.cert.pem diff --git a/internal/config/config.go b/internal/config/config.go index bda7fa1..d1ecee5 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -65,7 +65,7 @@ type Rule struct { Value string } -func NewConfig() *Config { +func New() *Config { c := config.NewConfig(VIPER_NAME, VIPER_TYPE, VIPER_PATH) c.Load() diff --git a/main.go b/main.go index 8840941..b4af9b3 100644 --- a/main.go +++ b/main.go @@ -1,8 +1,14 @@ package main import ( + "net/http" + "net/url" + "github.com/zeevdiukman/go-helper" + "github.com/zeevdiukman/go-reverseproxy" + "github.com/zeevdiukman/go-router" "github.com/zeevdiukman/go-zgate" + "github.com/zeevdiukman/go-zgate/pkg/config" ) // main is the entry point of the z application. @@ -10,13 +16,150 @@ import ( // configures routers, and starts the servers. It also starts test HTTP servers // for demonstration purposes. func main() { + helper.Clear() + helper.AppRunner(true, func() { - helper.Clear() + zGate := zgate.New() - zGate.BuildActiveEntryPoints() - zGate.BuildRouters() - zGate.ListenAndServe() + + //Enetry points building + zGate.Config.EntryPoints.ForEach(func(entryPointName string, entryPointConfig *config.EntryPoint) { + v, ok := isOKv(zGate.ActiveEntryPoints, entryPointName) + if ok && v { + port := zgate.StrAddressPortToInt(entryPointConfig.Address) + newEntryPoint := zGate.EntryPoints.NewEntryPoint(entryPointName) + newEntryPoint.Server.Port(port).Name(entryPointName) + newEntryPoint.Server.Router(newEntryPoint.Router) + if ok && entryPointConfig.TLS.Enabled { + zGate.EntryPoints[entryPointName].IsTLS = true + } + } + }) + + //Routers building + zGate.Config.HTTP.Routers.ForEach(func(rName string, rConfig *config.Router) { + epName := rConfig.EntryPoint + serviceName := rConfig.Service + isActive, _ := isOKv(zGate.ActiveEntryPoints, epName) + isEpExist := isOK(zGate.EntryPoints, epName) + isServiceExist := isOK(zGate.Config.HTTP.Services, serviceName) + ok := isActive && isEpExist && isServiceExist + if ok { + + entryPoint := zGate.EntryPoints[rConfig.EntryPoint] + if _, ok := entryPoint.HostRouters[rName]; !ok { + entryPoint.HostRouters = make(map[string]*router.DomainRouter) + } + applyMap := make(map[string]string) + rulesAvailable := []string{ + "Domain", + "Path", + "PathPrefix", + } + for _, ruleName := range rulesAvailable { + applyMap[ruleName] = rConfig.Rules.Get(ruleName) + } + + revereProxyHandler := zGate.NewReverseProxy(rConfig.Service) + revereProxyHandler.Director = func(r *http.Request) { + r = reverseproxy.StripPrefix(r, applyMap["PathPrefix"]) + r = r.WithContext(zGate.Context) + host := zGate.Config.HTTP.Services[rConfig.Service].URL + target, _ := url.Parse(host) + targetQuery := target.RawQuery + r.URL.Scheme = target.Scheme + r.URL.Host = target.Host + r.URL.Path, r.URL.RawPath = reverseproxy.JoinURLPath(target, r.URL) + if targetQuery == "" || r.URL.RawQuery == "" { + r.URL.RawQuery = targetQuery + r.URL.RawQuery + } else { + r.URL.RawQuery = targetQuery + "&" + r.URL.RawQuery + } + } + route1 := entryPoint.Router.NewRoute() + subRouter := route1.Host(applyMap["Domain"]).Subrouter() + subRouter.PathPrefix(applyMap["PathPrefix"]).Handler(revereProxyHandler) + // subRouter.NewRoute().Handler(revereProxyHandler) + + // readyRouter.MatcherFunc(func(r *http.Request, rm *mux.RouteMatch) bool { + // return r.URL.Path == applyMap["PathPrefix"] + // }).Handler(revereProxyHandler) + // } + + // readyRouter.PathPrefix(applyMap["Path"]).Handler(revereProxyHandler) + zGate.EntryPoints[rConfig.EntryPoint].Router = entryPoint.Router + + // } + // if applyMap["Domain"] && applyMap["Path"] { + // serviceURL := zGate.Config.HTTP.Services[rConfig.Service].URL + // reverseProxy := reverseproxy.New(zGate.Context, serviceURL) + + // domain := rConfig.Rules.Map["Domain"].Value + // hostRouter = entryPoint.Router.NewDomainRouter(domain,"Path") + + // pathPrefix := rConfig.Rules.Map["Path"].Value + // hostRouter.Path(pathPrefix).Handler(reverseProxy) + // zGate.EntryPoints[rConfig.EntryPoint].HostRouters[rName] = hostRouter + // } + + } + }) + + zGate.EntryPoints.ForEach(func(epNAme string, zGateEntryPoint *zgate.EntryPoint) { + if zGateEntryPoint.IsTLS { + zGateEntryPoint.Server.CertKey(zgate.CERTS_PATH, "z.com.cert.pem", "z.com.key.pem") + go zGateEntryPoint.Server.ListenAndServeTLS() + } else { + go zGateEntryPoint.Server.ListenAndServe() + } + + /* + //TODO: TLS per domain + // isTLS := false + + // zGate.Config.HTTP.Routers.ForEach(func(rName string, rConfig *config.Router) { + // rEntryPoint := rConfig.EntryPoint + // ep, isEpConfOK := isOK(zGate.Config.EntryPoints, rEntryPoint) + // activeEp, isActiveEpOK := isOK(zGate.ActiveEntryPoints, rEntryPoint) + // if isEpConfOK && isActiveEpOK && ep.TLS.Enabled && epNAme == rEntryPoint && activeEp { + // isTLS = true + // } + // }) + // zGate.Config.HTTP.Routers.ForEach(func(rName string, rConfig *config.Router) { + // rEntryPoint := rConfig.EntryPoint + // ep, ok := isOK(zGate.Config.EntryPoints, rEntryPoint) + // if ok && ep.TLS.Enabled && epNAme == rEntryPoint { + // isTLS = true + // } + // }) + + // zGateEntryPoint.Server.ConnState = func(c net.Conn, cs http.ConnState) { + // msg1 := c.RemoteAddr().String() + // msg2 := "Connection state: " + strconv.Itoa(int(cs)) + + // fmt.Println(msg1 + "\n" + msg2) + // fmt.Println("=======================") + // log.Println() + + // } + */ + }) helper.StartTestHTTPServer(3001, "app1") helper.StartTestHTTPServer(3002, "app2") }) } +func isOKv[K comparable, V comparable](mp map[K]V, key K) (V, bool) { + if v, ok := mp[key]; ok { + return v, true + } else { + return v, false + } +} + +func isOK[K comparable, V comparable](mp map[K]V, key K) bool { + if _, ok := mp[key]; ok { + return true + } else { + return false + } +} diff --git a/tmp/build-errors.log b/tmp/build-errors.log index 40900e3..520294b 100644 --- a/tmp/build-errors.log +++ b/tmp/build-errors.log @@ -1 +1 @@ -exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1 \ No newline at end of file +exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1 \ No newline at end of file diff --git a/tmp/main b/tmp/main index 9a00f63..eabe3bd 100755 Binary files a/tmp/main and b/tmp/main differ