func syncApps(jsontasks *MarathonTasks, jsonapps *MarathonApps) { apps = Apps{Apps: make(map[string]App)} apps.Lock() defer apps.Unlock() for _, task := range jsontasks.Tasks { // Use regex to remove characters that are not allowed in hostnames re := regexp.MustCompile("[^0-9a-z-]") appid := re.ReplaceAllLiteralString(task.AppId, "") for _, v := range jsonapps.Apps { if v.Id == task.AppId { if s, ok := v.Labels["moxy_subdomain"]; ok { appid = s } } } if len(task.HealthCheckResults) == 1 { if task.HealthCheckResults[0].Alive == false { continue } } if s, ok := apps.Apps[appid]; ok { s.Lb.UpsertServer(testutils.ParseURI("http://" + task.Host + ":" + strconv.FormatInt(task.Ports[0], 10))) s.Tasks = append(s.Tasks, task.Host+":"+strconv.FormatInt(task.Ports[0], 10)) apps.Apps[appid] = s } else { var s = App{} s.Fwd, _ = forward.New(forward.PassHostHeader(true)) s.Lb, _ = roundrobin.New(s.Fwd) s.Lb.UpsertServer(testutils.ParseURI("http://" + task.Host + ":" + strconv.FormatInt(task.Ports[0], 10))) s.Tasks = []string{task.Host + ":" + strconv.FormatInt(task.Ports[0], 10)} apps.Apps[appid] = s } } }
func NewUpdater(master string) (updater *Updater) { fwd, err := forward.New() lb, err := roundrobin.New(fwd) masterUrl, err := url.Parse(master) lb.UpsertServer(masterUrl) if err != nil { panic(err) } return &Updater{lb: lb, master: master} }
func syncApps(jsontasks *MarathonTasks, jsonapps *MarathonApps) { apps.Lock() defer apps.Unlock() appstmp := make(map[string]App) for _, task := range jsontasks.Tasks { // Use regex to remove characters that are not allowed in hostnames re := regexp.MustCompile("[^0-9a-z-]") appid := re.ReplaceAllLiteralString(task.AppId, "") apphealth := false for _, v := range jsonapps.Apps { if v.Id == task.AppId { if s, ok := v.Labels["moxy_subdomain"]; ok { appid = s } if len(v.HealthChecks) > 0 { apphealth = true } } } if apphealth { if len(task.HealthCheckResults) == 0 { // this means tasks is being deployed but not yet monitored as alive. Assume down. continue } alive := true for _, health := range task.HealthCheckResults { // check if health check is alive if health.Alive == false { alive = false } } if alive != true { // at least one health check has failed. Assume down. continue } } if s, ok := appstmp[appid]; ok { s.Lb.UpsertServer(testutils.ParseURI("http://" + task.Host + ":" + strconv.FormatInt(task.Ports[0], 10))) s.Tasks = append(s.Tasks, task.Host+":"+strconv.FormatInt(task.Ports[0], 10)) appstmp[appid] = s } else { var s = App{} s.Fwd, _ = forward.New(forward.PassHostHeader(true)) s.Lb, _ = roundrobin.New(s.Fwd) s.Lb.UpsertServer(testutils.ParseURI("http://" + task.Host + ":" + strconv.FormatInt(task.Ports[0], 10))) s.Tasks = []string{task.Host + ":" + strconv.FormatInt(task.Ports[0], 10)} appstmp[appid] = s } } apps.Apps = appstmp }
func new(c *C, p string) (*roundrobin.RoundRobin, *Streamer) { logger := utils.NewFileLogger(os.Stdout, utils.INFO) // forwarder will proxy the request to whatever destination fwd, err := forward.New(forward.Logger(logger)) c.Assert(err, IsNil) // load balancer will round robin request lb, err := roundrobin.New(fwd) c.Assert(err, IsNil) // stream handler will forward requests to redirect, make sure it uses files st, err := New(lb, Logger(logger), Retry(p), MemRequestBodyBytes(1)) c.Assert(err, IsNil) return lb, st }
func getBackend(r *http.Request) (Backend, bool) { var b = Backend{} host := strings.ToLower(r.Host) if b, ok := backends.Backends[host]; ok { return b, true } if bc, ok := getBackendConf(host); ok { b.Conf = bc b.Fwd, _ = forward.New(forward.PassHostHeader(true)) b.Lb, _ = roundrobin.New(b.Fwd) for _, upstream := range bc.UpStreams { b.Lb.UpsertServer(testutils.ParseURI(upstream)) } backends.Lock() backends.Backends[host] = b backends.Unlock() return b, true } return b, false }
func LoadConfig(configuration *Configuration, gloablConfiguration *GlobalConfiguration) (*mux.Router, error) { router := mux.NewRouter() router.NotFoundHandler = http.HandlerFunc(notFoundHandler) backends := map[string]http.Handler{} for frontendName, frontend := range configuration.Frontends { log.Debug("Creating frontend %s", frontendName) fwd, _ := forward.New(forward.Logger(oxyLogger)) newRoute := router.NewRoute().Name(frontendName) for routeName, route := range frontend.Routes { log.Debug("Creating route %s %s:%s", routeName, route.Rule, route.Value) newRouteReflect := Invoke(newRoute, route.Rule, route.Value) newRoute = newRouteReflect[0].Interface().(*mux.Route) } if backends[frontend.Backend] == nil { log.Debug("Creating backend %s", frontend.Backend) lb, _ := roundrobin.New(fwd) rb, _ := roundrobin.NewRebalancer(lb, roundrobin.RebalancerLogger(oxyLogger)) for serverName, server := range configuration.Backends[frontend.Backend].Servers { if url, err := url.Parse(server.Url); err != nil { return nil, err } else { log.Debug("Creating server %s %s", serverName, url.String()) rb.UpsertServer(url, roundrobin.Weight(server.Weight)) } } backends[frontend.Backend] = rb } else { log.Debug("Reusing backend %s", frontend.Backend) } // stream.New(backends[frontend.Backend], stream.Retry("IsNetworkError() && Attempts() <= " + strconv.Itoa(gloablConfiguration.Replay)), stream.Logger(oxyLogger)) var negroni = negroni.New() negroni.Use(middlewares.NewCircuitBreaker(backends[frontend.Backend], cbreaker.Logger(oxyLogger))) newRoute.Handler(negroni) err := newRoute.GetError() if err != nil { log.Error("Error building route ", err) } } return router, nil }
// LoadConfig returns a new gorrilla.mux Route from the specified global configuration and the dynamic // provider configurations. func LoadConfig(configurations configs, globalConfiguration *GlobalConfiguration) (*mux.Router, error) { router := mux.NewRouter() router.NotFoundHandler = http.HandlerFunc(notFoundHandler) backends := map[string]http.Handler{} for _, configuration := range configurations { for frontendName, frontend := range configuration.Frontends { log.Debugf("Creating frontend %s", frontendName) fwd, _ := forward.New(forward.Logger(oxyLogger), forward.PassHostHeader(frontend.PassHostHeader)) newRoute := router.NewRoute().Name(frontendName) for routeName, route := range frontend.Routes { log.Debugf("Creating route %s %s:%s", routeName, route.Rule, route.Value) newRouteReflect, err := invoke(newRoute, route.Rule, route.Value) if err != nil { return nil, err } newRoute = newRouteReflect[0].Interface().(*mux.Route) } if backends[frontend.Backend] == nil { log.Debugf("Creating backend %s", frontend.Backend) var lb http.Handler rr, _ := roundrobin.New(fwd) if configuration.Backends[frontend.Backend] == nil { return nil, errors.New("Backend not found: " + frontend.Backend) } lbMethod, err := types.NewLoadBalancerMethod(configuration.Backends[frontend.Backend].LoadBalancer) if err != nil { configuration.Backends[frontend.Backend].LoadBalancer = &types.LoadBalancer{Method: "wrr"} } switch lbMethod { case types.Drr: log.Infof("Creating load-balancer drr") rebalancer, _ := roundrobin.NewRebalancer(rr, roundrobin.RebalancerLogger(oxyLogger)) lb = rebalancer for serverName, server := range configuration.Backends[frontend.Backend].Servers { url, err := url.Parse(server.URL) if err != nil { return nil, err } log.Infof("Creating server %s %s", serverName, url.String()) rebalancer.UpsertServer(url, roundrobin.Weight(server.Weight)) } case types.Wrr: log.Infof("Creating load-balancer wrr") lb = middlewares.NewWebsocketUpgrader(rr) for serverName, server := range configuration.Backends[frontend.Backend].Servers { url, err := url.Parse(server.URL) if err != nil { return nil, err } log.Infof("Creating server %s %s", serverName, url.String()) rr.UpsertServer(url, roundrobin.Weight(server.Weight)) } } var negroni = negroni.New() if configuration.Backends[frontend.Backend].CircuitBreaker != nil { log.Infof("Creating circuit breaker %s", configuration.Backends[frontend.Backend].CircuitBreaker.Expression) negroni.Use(middlewares.NewCircuitBreaker(lb, configuration.Backends[frontend.Backend].CircuitBreaker.Expression, cbreaker.Logger(oxyLogger))) } else { negroni.UseHandler(lb) } backends[frontend.Backend] = negroni } else { log.Infof("Reusing backend %s", frontend.Backend) } // stream.New(backends[frontend.Backend], stream.Retry("IsNetworkError() && Attempts() <= " + strconv.Itoa(globalConfiguration.Replay)), stream.Logger(oxyLogger)) newRoute.Handler(backends[frontend.Backend]) err := newRoute.GetError() if err != nil { log.Errorf("Error building route: %s", err) } } } return router, nil }
// LoadConfig returns a new gorilla.mux Route from the specified global configuration and the dynamic // provider configurations. func (server *Server) loadConfig(configurations configs, globalConfiguration GlobalConfiguration) (map[string]serverEntryPoint, error) { serverEntryPoints := server.buildEntryPoints(globalConfiguration) redirectHandlers := make(map[string]http.Handler) backends := map[string]http.Handler{} for _, configuration := range configurations { frontendNames := sortedFrontendNamesForConfig(configuration) for _, frontendName := range frontendNames { frontend := configuration.Frontends[frontendName] log.Debugf("Creating frontend %s", frontendName) fwd, _ := forward.New(forward.Logger(oxyLogger), forward.PassHostHeader(frontend.PassHostHeader)) // default endpoints if not defined in frontends if len(frontend.EntryPoints) == 0 { frontend.EntryPoints = globalConfiguration.DefaultEntryPoints } for _, entryPointName := range frontend.EntryPoints { log.Debugf("Wiring frontend %s to entryPoint %s", frontendName, entryPointName) if _, ok := serverEntryPoints[entryPointName]; !ok { return nil, errors.New("Undefined entrypoint: " + entryPointName) } newRoute := serverEntryPoints[entryPointName].httpRouter.NewRoute().Name(frontendName) for routeName, route := range frontend.Routes { log.Debugf("Creating route %s %s:%s", routeName, route.Rule, route.Value) route, err := getRoute(newRoute, route.Rule, route.Value) if err != nil { return nil, err } newRoute = route } entryPoint := globalConfiguration.EntryPoints[entryPointName] if entryPoint.Redirect != nil { if redirectHandlers[entryPointName] != nil { newRoute.Handler(redirectHandlers[entryPointName]) } else if handler, err := server.loadEntryPointConfig(entryPointName, entryPoint); err != nil { return nil, err } else { newRoute.Handler(handler) redirectHandlers[entryPointName] = handler } } else { if backends[frontend.Backend] == nil { log.Debugf("Creating backend %s", frontend.Backend) var lb http.Handler rr, _ := roundrobin.New(fwd) if configuration.Backends[frontend.Backend] == nil { return nil, errors.New("Undefined backend: " + frontend.Backend) } lbMethod, err := types.NewLoadBalancerMethod(configuration.Backends[frontend.Backend].LoadBalancer) if err != nil { configuration.Backends[frontend.Backend].LoadBalancer = &types.LoadBalancer{Method: "wrr"} } switch lbMethod { case types.Drr: log.Debugf("Creating load-balancer drr") rebalancer, _ := roundrobin.NewRebalancer(rr, roundrobin.RebalancerLogger(oxyLogger)) lb = rebalancer for serverName, server := range configuration.Backends[frontend.Backend].Servers { url, err := url.Parse(server.URL) if err != nil { return nil, err } log.Debugf("Creating server %s at %s with weight %d", serverName, url.String(), server.Weight) rebalancer.UpsertServer(url, roundrobin.Weight(server.Weight)) } case types.Wrr: log.Debugf("Creating load-balancer wrr") lb = middlewares.NewWebsocketUpgrader(rr) for serverName, server := range configuration.Backends[frontend.Backend].Servers { url, err := url.Parse(server.URL) if err != nil { return nil, err } log.Debugf("Creating server %s at %s with weight %d", serverName, url.String(), server.Weight) rr.UpsertServer(url, roundrobin.Weight(server.Weight)) } } var negroni = negroni.New() if configuration.Backends[frontend.Backend].CircuitBreaker != nil { log.Debugf("Creating circuit breaker %s", configuration.Backends[frontend.Backend].CircuitBreaker.Expression) negroni.Use(middlewares.NewCircuitBreaker(lb, configuration.Backends[frontend.Backend].CircuitBreaker.Expression, cbreaker.Logger(oxyLogger))) } else { negroni.UseHandler(lb) } backends[frontend.Backend] = negroni } else { log.Debugf("Reusing backend %s", frontend.Backend) } server.wireFrontendBackend(frontend.Routes, newRoute, backends[frontend.Backend]) } err := newRoute.GetError() if err != nil { log.Errorf("Error building route: %s", err) } } } } return serverEntryPoints, nil }