func (r *fakeRouter) RemoveRoute(name string, address *url.URL) error { backendName, err := router.Retrieve(name) if err != nil { return err } if !r.HasBackend(backendName) { return router.ErrBackendNotFound } r.mutex.Lock() defer r.mutex.Unlock() if r.failuresByIp[address.String()] { return ErrForcedFailure } index := -1 routes := r.backends[backendName] for i := range routes { if routes[i] == address.String() { index = i break } } if index < 0 { return router.ErrRouteNotFound } routes[index] = routes[len(routes)-1] r.backends[backendName] = routes[:len(routes)-1] return nil }
func (s *ExternalSuite) TestSwap(c *check.C) { backend1 := "b1" backend2 := "b2" r, err := router.Get("fake") c.Assert(err, check.IsNil) r.AddBackend(backend1) addr1, _ := url.Parse("http://127.0.0.1") r.AddRoute(backend1, addr1) r.AddBackend(backend2) addr2, _ := url.Parse("http://10.10.10.10") r.AddRoute(backend2, addr2) err = router.Swap(r, backend1, backend2) c.Assert(err, check.IsNil) routes1, err := r.Routes(backend1) c.Assert(err, check.IsNil) c.Assert(routes1, check.DeepEquals, []*url.URL{addr1}) routes2, err := r.Routes(backend2) c.Assert(err, check.IsNil) c.Assert(routes2, check.DeepEquals, []*url.URL{addr2}) name1, err := router.Retrieve(backend1) c.Assert(err, check.IsNil) c.Assert(name1, check.Equals, backend2) name2, err := router.Retrieve(backend2) c.Assert(err, check.IsNil) c.Assert(name2, check.Equals, backend1) }
func (s *RouterSuite) TestRemoveBackendKeepsInRouter(c *check.C) { _, err := router.Retrieve(testBackend1) c.Assert(err, check.Equals, router.ErrBackendNotFound) err = s.Router.AddBackend(testBackend1) c.Assert(err, check.IsNil) name, err := router.Retrieve(testBackend1) c.Assert(err, check.IsNil) c.Assert(name, check.Equals, testBackend1) err = s.Router.RemoveBackend(testBackend1) c.Assert(err, check.IsNil) name, err = router.Retrieve(testBackend1) c.Assert(err, check.IsNil) c.Assert(name, check.Equals, testBackend1) }
func (s *ExternalSuite) TestSwapCnameOnly(c *check.C) { backend1 := "bx1" backend2 := "bx2" r, err := router.Get("fake") c.Assert(err, check.IsNil) cnameRouter, ok := r.(router.CNameRouter) c.Assert(ok, check.Equals, true) err = r.AddBackend(backend1) c.Assert(err, check.IsNil) addr1, err := url.Parse("http://127.0.0.1") c.Assert(err, check.IsNil) r.AddRoute(backend1, addr1) err = cnameRouter.SetCName("cname.com", backend1) c.Assert(err, check.IsNil) err = r.AddBackend(backend2) c.Assert(err, check.IsNil) addr2, err := url.Parse("http://10.10.10.10") c.Assert(err, check.IsNil) r.AddRoute(backend2, addr2) err = router.Swap(r, backend1, backend2, true) c.Assert(err, check.IsNil) routes1, err := r.Routes(backend1) c.Assert(err, check.IsNil) c.Assert(routes1, check.DeepEquals, []*url.URL{addr1}) routes2, err := r.Routes(backend2) c.Assert(err, check.IsNil) c.Assert(routes2, check.DeepEquals, []*url.URL{addr2}) name1, err := router.Retrieve(backend1) c.Assert(err, check.IsNil) c.Assert(name1, check.Equals, backend1) name2, err := router.Retrieve(backend2) c.Assert(err, check.IsNil) c.Assert(name2, check.Equals, backend2) cnames, err := cnameRouter.CNames(backend1) c.Assert(err, check.IsNil) c.Assert(cnames, check.HasLen, 0) expected := []*url.URL{{Host: "cname.com"}} cnames, err = cnameRouter.CNames(backend2) c.Assert(err, check.IsNil) c.Assert(expected, check.DeepEquals, cnames) err = router.Swap(r, backend1, backend2, true) c.Assert(err, check.IsNil) cnames, err = cnameRouter.CNames(backend1) c.Assert(err, check.IsNil) c.Assert(expected, check.DeepEquals, cnames) cnames, err = cnameRouter.CNames(backend2) c.Assert(err, check.IsNil) c.Assert(cnames, check.HasLen, 0) }
func (r *fakeRouter) RemoveRoutes(name string, addresses []*url.URL) error { backendName, err := router.Retrieve(name) if err != nil { return err } if !r.HasBackend(backendName) { return router.ErrBackendNotFound } r.mutex.Lock() defer r.mutex.Unlock() for _, addr := range addresses { if r.failuresByIp[addr.Host] { return ErrForcedFailure } } routes := r.backends[backendName] for _, addr := range addresses { for i := range routes { if routes[i] == addr.Host { routes = append(routes[:i], routes[i+1:]...) break } } } r.backends[backendName] = routes return nil }
func (s *S) TestRemoveBackend(c *check.C) { s.handler.RspCode = http.StatusNoContent err := router.Store("myapp", "myapp", routerName) c.Assert(err, check.IsNil) data := galebData{ Name: "myapp", BackendPoolId: s.server.URL + "/api/backend1", RootRuleId: s.server.URL + "/api/rule1", VirtualHostId: s.server.URL + "/api/vh1", CNames: []galebCNameData{ {CName: "my.1.cname", VirtualHostId: s.server.URL + "/api/vh2"}, {CName: "my.2.cname", VirtualHostId: s.server.URL + "/api/vh3"}, }, } err = data.save() c.Assert(err, check.IsNil) gRouter, err := createRouter("routers:galeb") c.Assert(err, check.IsNil) err = gRouter.RemoveBackend("myapp") c.Assert(err, check.IsNil) c.Assert(s.handler.Url, check.DeepEquals, []string{ "/api/vh1", "/api/vh2", "/api/vh3", "/api/rule1", "/api/backend1", }) _, err = router.Retrieve("myapp") c.Assert(err, check.Equals, router.ErrBackendNotFound) _, err = getGalebData("myapp") c.Assert(err, check.ErrorMatches, "not found") }
func (r *fakeRouter) RemoveRoute(name, ip string) error { backendName, err := router.Retrieve(name) if err != nil { return err } if !r.HasBackend(backendName) { return ErrBackendNotFound } r.mutex.Lock() defer r.mutex.Unlock() index := -1 routes := r.backends[backendName] for i := range routes { if routes[i] == ip { index = i break } } if index < 0 { return errors.New("Route not found") } routes[index] = routes[len(routes)-1] r.backends[backendName] = routes[:len(routes)-1] return nil }
func (r *galebRouter) SetCName(cname, name string) error { backendName, err := router.Retrieve(name) if err != nil { return err } domain, err := config.GetString(r.prefix + ":domain") if err != nil { return err } if !router.ValidCName(cname, domain) { return router.ErrCNameNotAllowed } data, err := getGalebData(backendName) if err != nil { return err } client, err := r.getClient() if err != nil { return err } for _, val := range data.CNames { if val.CName == cname { return router.ErrCNameExists } } virtualHostParams := galebClient.VirtualHostParams{ Name: cname, RuleDefault: data.RootRuleId, } virtualHostId, err := client.AddVirtualHost(&virtualHostParams) if err != nil { return err } return data.addCName(cname, virtualHostId) }
func (r *hipacheRouter) Routes(name string) ([]*url.URL, error) { backendName, err := router.Retrieve(name) if err != nil { return nil, err } domain, err := config.GetString(r.prefix + ":domain") if err != nil { return nil, &router.RouterError{Op: "routes", Err: err} } frontend := "frontend:" + backendName + "." + domain conn := r.connect() defer conn.Close() routes, err := redis.Strings(conn.Do("LRANGE", frontend, 1, -1)) if err != nil { return nil, &router.RouterError{Op: "routes", Err: err} } result := make([]*url.URL, len(routes)) for i, route := range routes { result[i], err = url.Parse(route) if err != nil { return nil, err } } return result, nil }
func (r *vulcandRouter) SetCName(cname, name string) error { usedName, err := router.Retrieve(name) if err != nil { return err } if !router.ValidCName(cname, r.domain) { return router.ErrCNameNotAllowed } frontendName := r.frontendName(cname) if found, _ := r.client.GetFrontend(engine.FrontendKey{Id: frontendName}); found != nil { return router.ErrCNameExists } frontend, err := engine.NewHTTPFrontend( frontendName, r.backendName(usedName), fmt.Sprintf(`Host(%q)`, cname), engine.HTTPFrontendSettings{}, ) if err != nil { return &router.RouterError{Err: err, Op: "set-cname"} } err = r.client.UpsertFrontend(*frontend, engine.NoTTL) if err != nil { return &router.RouterError{Err: err, Op: "set-cname"} } return nil }
func (r *hipacheRouter) SetCName(cname, name string) error { backendName, err := router.Retrieve(name) if err != nil { return err } domain, err := config.GetString(r.prefix + ":domain") if err != nil { return &routeError{"setCName", err} } if !r.validCName(cname) { err := errors.New(fmt.Sprintf("Invalid CNAME %s. You can't use tsuru's application domain.", cname)) return &routeError{"setCName", err} } frontend := "frontend:" + backendName + "." + domain conn := r.connect() defer conn.Close() routes, err := redis.Strings(conn.Do("LRANGE", frontend, 0, -1)) if err != nil { return &routeError{"get", err} } _, err = conn.Do("RPUSH", "cname:"+backendName, cname) if err != nil { return &routeError{"set", err} } frontend = "frontend:" + cname for _, r := range routes { _, err := conn.Do("RPUSH", frontend, r) if err != nil { return &routeError{"setCName", err} } } return nil }
func (r *hipacheRouter) RemoveRoute(name string, address *url.URL) error { backendName, err := router.Retrieve(name) if err != nil { return err } domain, err := config.GetString(r.prefix + ":domain") if err != nil { return &routeError{"remove", err} } frontend := "frontend:" + backendName + "." + domain if err := r.removeElement(frontend, address.String()); err != nil { return err } cnames, err := r.getCNames(backendName) if err != nil { return &routeError{"remove", err} } if cnames == nil { return nil } for _, cname := range cnames { err = r.removeElement("frontend:"+cname, address.String()) if err != nil { return err } } return nil }
func (r *hipacheRouter) AddRoute(name string, address *url.URL) error { backendName, err := router.Retrieve(name) if err != nil { return err } domain, err := config.GetString(r.prefix + ":domain") if err != nil { log.Errorf("error on getting hipache domain in add route for %s - %s", backendName, address) return &routeError{"add", err} } frontend := "frontend:" + backendName + "." + domain if err := r.addRoute(frontend, address.String()); err != nil { log.Errorf("error on add route for %s - %s", backendName, address) return &routeError{"add", err} } cnames, err := r.getCNames(backendName) if err != nil { log.Errorf("error on get cname in add route for %s - %s", backendName, address) return err } if cnames == nil { return nil } for _, cname := range cnames { err = r.addRoute("frontend:"+cname, address.String()) if err != nil { return err } } return nil }
func (r *galebRouter) AddRoutes(name string, addresses []*url.URL) error { backendName, err := router.Retrieve(name) if err != nil { return err } return r.client.AddBackends(addresses, r.poolName(backendName)) }
func (r *galebRouter) AddRoute(name string, address *url.URL) error { backendName, err := router.Retrieve(name) if err != nil { return err } data, err := getGalebData(backendName) if err != nil { return err } for _, r := range data.Reals { if r.Real == address.Host { return router.ErrRouteExists } } client, err := r.getClient() if err != nil { return err } host, portStr, _ := net.SplitHostPort(address.Host) port, _ := strconv.Atoi(portStr) params := galebClient.BackendParams{ Ip: host, Port: port, BackendPool: data.BackendPoolId, } backendId, err := client.AddBackend(¶ms) if err != nil { return err } return data.addReal(address.Host, backendId) }
func (r *hipacheRouter) UnsetCName(cname, name string) error { backendName, err := router.Retrieve(name) if err != nil { return err } conn := r.connect() defer conn.Close() currentCnames, err := redis.Strings(conn.Do("LRANGE", "cname:"+backendName, 0, -1)) found := false for _, n := range currentCnames { if n == cname { found = true break } } if !found { return router.ErrCNameNotFound } _, err = conn.Do("LREM", "cname:"+backendName, 0, cname) if err != nil { return &router.RouterError{Op: "unsetCName", Err: err} } _, err = conn.Do("DEL", "frontend:"+cname) if err != nil { return &router.RouterError{Op: "unsetCName", Err: err} } return nil }
func (r *galebRouter) RemoveRoutes(name string, addresses []*url.URL) error { backendName, err := router.Retrieve(name) if err != nil { return err } addressMap := map[string]struct{}{} for _, addr := range addresses { addressMap[addr.Host] = struct{}{} } targets, err := r.client.FindTargetsByParent(r.poolName(backendName)) if err != nil { return err } var ids []string for _, target := range targets { parsedAddr, err := url.Parse(target.Name) if err != nil { return err } if _, ok := addressMap[parsedAddr.Host]; ok { ids = append(ids, target.FullId()) } } if len(ids) == 0 { return nil } return r.client.RemoveBackendsByIDs(ids) }
func (r *galebRouter) Addr(name string) (string, error) { backendName, err := router.Retrieve(name) if err != nil { return "", err } return r.virtualHostName(backendName), nil }
func (r *fakeRouter) AddRoutes(name string, addresses []*url.URL) error { backendName, err := router.Retrieve(name) if err != nil { return err } if !r.HasBackend(backendName) { return router.ErrBackendNotFound } r.mutex.Lock() defer r.mutex.Unlock() for _, addr := range addresses { if r.failuresByIp[addr.String()] { return ErrForcedFailure } } routes := r.backends[backendName] addresses: for _, addr := range addresses { for i := range routes { if routes[i] == addr.String() { continue addresses } } routes = append(routes, addr.String()) } r.backends[backendName] = routes return nil }
func (r *hipacheRouter) Routes(name string) ([]*url.URL, error) { backendName, err := router.Retrieve(name) if err != nil { return nil, err } domain, err := config.GetString(r.prefix + ":domain") if err != nil { return nil, &router.RouterError{Op: "routes", Err: err} } frontend := "frontend:" + backendName + "." + domain conn, err := r.connect() if err != nil { return nil, &router.RouterError{Op: "routes", Err: err} } routes, err := conn.LRange(frontend, 0, -1).Result() if err != nil { return nil, &router.RouterError{Op: "routes", Err: err} } if len(routes) == 0 { return nil, router.ErrBackendNotFound } routes = routes[1:] result := make([]*url.URL, len(routes)) for i, route := range routes { result[i], err = url.Parse(route) if err != nil { return nil, err } } return result, nil }
func (r *hipacheRouter) UnsetCName(cname, name string) error { backendName, err := router.Retrieve(name) if err != nil { return err } conn, err := r.connect() if err != nil { return &router.RouterError{Op: "unsetCName", Err: err} } currentCnames, err := conn.LRange("cname:"+backendName, 0, -1).Result() if err != nil { return &router.RouterError{Op: "unsetCName", Err: err} } found := false for _, n := range currentCnames { if n == cname { found = true break } } if !found { return router.ErrCNameNotFound } err = conn.LRem("cname:"+backendName, 0, cname).Err() if err != nil { return &router.RouterError{Op: "unsetCName", Err: err} } err = conn.Del("frontend:" + cname).Err() if err != nil { return &router.RouterError{Op: "unsetCName", Err: err} } return nil }
func (r *hipacheRouter) RemoveRoutes(name string, addresses []*url.URL) error { backendName, err := router.Retrieve(name) if err != nil { return err } domain, err := config.GetString(r.prefix + ":domain") if err != nil { return &router.RouterError{Op: "remove", Err: err} } toRemove := make([]string, len(addresses)) for i := range addresses { addresses[i].Scheme = router.HttpScheme toRemove[i] = addresses[i].String() } frontend := "frontend:" + backendName + "." + domain err = r.removeElements(frontend, toRemove) if err != nil { return err } cnames, err := r.getCNames(backendName) if err != nil { return &router.RouterError{Op: "remove", Err: err} } if cnames == nil { return nil } for _, cname := range cnames { err = r.removeElements("frontend:"+cname, toRemove) if err != nil { return err } } return nil }
func (r *hipacheRouter) RemoveRoute(name string, address *url.URL) error { backendName, err := router.Retrieve(name) if err != nil { return err } domain, err := config.GetString(r.prefix + ":domain") if err != nil { return &router.RouterError{Op: "remove", Err: err} } frontend := "frontend:" + backendName + "." + domain address.Scheme = router.HttpScheme count, err := r.removeElement(frontend, address.String()) if err != nil { return err } if count == 0 { return router.ErrRouteNotFound } cnames, err := r.getCNames(backendName) if err != nil { return &router.RouterError{Op: "remove", Err: err} } if cnames == nil { return nil } for _, cname := range cnames { _, err = r.removeElement("frontend:"+cname, address.String()) if err != nil { return err } } return nil }
func (r hipacheRouter) AddRoute(name, address string) error { backendName, err := router.Retrieve(name) if err != nil { return err } domain, err := config.GetString("hipache:domain") if err != nil { log.Errorf("error on getting hipache domain in add route for %s - %s", backendName, address) return &routeError{"add", err} } frontend := "frontend:" + backendName + "." + domain if err := r.addRoute(frontend, address); err != nil { log.Errorf("error on add route for %s - %s", backendName, address) return &routeError{"add", err} } cname, err := r.getCName(backendName) if err != nil { log.Errorf("error on get cname in add route for %s - %s", backendName, address) return err } if cname == "" { return nil } return r.addRoute("frontend:"+cname, address) }
func (r elbRouter) AddRoute(name, address string) error { backendName, err := router.Retrieve(name) if err != nil { return err } _, err = r.elb().RegisterInstancesWithLoadBalancer([]string{address}, backendName) return err }
func (s *S) TestSwap(c *gocheck.C) { instance1 := s.server.NewInstance() defer s.server.RemoveInstance(instance1) instance2 := s.server.NewInstance() defer s.server.RemoveInstance(instance2) backend1 := "b1" backend2 := "b2" elb := elbRouter{} err := elb.AddBackend(backend1) c.Assert(err, gocheck.IsNil) err = elb.AddRoute(backend1, instance1) c.Assert(err, gocheck.IsNil) err = elb.AddBackend(backend2) c.Assert(err, gocheck.IsNil) err = elb.AddRoute(backend2, instance2) c.Assert(err, gocheck.IsNil) retrieved1, err := router.Retrieve(backend1) c.Assert(err, gocheck.IsNil) c.Assert(retrieved1, gocheck.Equals, backend1) retrieved2, err := router.Retrieve(backend2) c.Assert(err, gocheck.IsNil) c.Assert(retrieved2, gocheck.Equals, backend2) err = elb.Swap(backend1, backend2) c.Assert(err, gocheck.IsNil) routes, err := elb.Routes(backend2) c.Assert(err, gocheck.IsNil) c.Assert(routes, gocheck.DeepEquals, []string{instance2}) routes, err = elb.Routes(backend1) c.Assert(err, gocheck.IsNil) c.Assert(routes, gocheck.DeepEquals, []string{instance1}) retrieved1, err = router.Retrieve(backend1) c.Assert(err, gocheck.IsNil) c.Assert(retrieved1, gocheck.Equals, backend2) retrieved2, err = router.Retrieve(backend2) c.Assert(err, gocheck.IsNil) c.Assert(retrieved2, gocheck.Equals, backend1) addr, err := elb.Addr(backend1) c.Assert(err, gocheck.IsNil) c.Assert(addr, gocheck.Equals, "b2-some-aws-stuff.us-east-1.elb.amazonaws.com") addr, err = elb.Addr(backend2) c.Assert(err, gocheck.IsNil) c.Assert(addr, gocheck.Equals, "b1-some-aws-stuff.us-east-1.elb.amazonaws.com") }
func (r *fakeRouter) SetHealthcheck(name string, data router.HealthcheckData) error { backendName, err := router.Retrieve(name) if err != nil { return err } r.mutex.Lock() defer r.mutex.Unlock() r.healthcheck[backendName] = data return nil }
func (r *fakeRouter) Routes(name string) ([]string, error) { backendName, err := router.Retrieve(name) if err != nil { return nil, err } r.mutex.Lock() defer r.mutex.Unlock() routes := r.backends[backendName] return routes, nil }
func (r *galebRouter) AddRoute(name string, address *url.URL) error { backendName, err := router.Retrieve(name) if err != nil { return err } _, err = r.client.AddBackend(address, poolName(backendName)) if err == galebClient.ErrItemAlreadyExists { return router.ErrRouteExists } return err }
func (r elbRouter) RemoveBackend(name string) error { backendName, err := router.Retrieve(name) if err != nil { return err } _, err = r.elb().DeleteLoadBalancer(backendName) if err != nil { return err } return router.Remove(backendName) }