Exemple #1
0
func watchBackend() {
	var (
		last   string
		svccfg string
		mancfg string
	)

	svc := registry.Default.WatchServices()
	man := registry.Default.WatchManual()

	for {
		select {
		case svccfg = <-svc:
		case mancfg = <-man:
		}

		// manual config overrides service config
		// order matters
		next := svccfg + "\n" + mancfg
		if next == last {
			continue
		}

		t, err := route.ParseString(next)
		if err != nil {
			log.Printf("[WARN] %s", err)
			continue
		}
		route.SetTable(t)

		last = next
	}
}
Exemple #2
0
func (w *Watcher) Watch() {
	var (
		auto   []string
		manual []string
		t      route.Table
		err    error

		autoConfig   = make(chan []string)
		manualConfig = make(chan []string)
	)

	go watchAutoConfig(w.client, w.tagPrefix, autoConfig)
	go watchManualConfig(w.client, w.configPath, manualConfig)

	for {
		select {
		case auto = <-autoConfig:
		case manual = <-manualConfig:
		}

		if len(auto) == 0 && len(manual) == 0 {
			continue
		}

		input := strings.Join(append(auto, manual...), "\n")
		t, err = route.ParseString(input)
		if err != nil {
			log.Printf("[WARN] %s", err)
			continue
		}
		route.SetTable(t)
	}
}
Exemple #3
0
func TestBuildInstruction(t *testing.T) {
	for _, each := range []struct {
		spec, inst string
	}{
		{"src=http://in.com/&dst=http://0.0.0.0:8080/here",
			"route add test-node-001 in.com/ http://10.20.30.40:8080/here tags \"tic,tac\""},
		{"src=http://in.com&dst=http://0.0.0.0:8080",
			"route add test-node-001 in.com/ http://10.20.30.40:8080/ tags \"tic,tac\""},
		{"src=http://in.com:80&dst=http://0.0.0.0:80",
			"route add test-node-001 in.com:80/ http://10.20.30.40:80/ tags \"tic,tac\""},
	} {
		i := new(compute.Instance)
		i.Name = "test-node-001"
		i.NetworkInterfaces = []*compute.NetworkInterface{&compute.NetworkInterface{NetworkIP: "10.20.30.40"}}
		i.Tags = &compute.Tags{Items: []string{"tic", "tac"}}
		r := buildInstruction(i, each.spec)
		_, err := route.ParseString(r)
		if err != nil {
			t.Errorf("parse failed:%v", err)
			return
		}
		if got, want := r, each.inst; got != want {
			t.Errorf("got %q want %q", got, want)
		}
	}
}
Exemple #4
0
func initDynamicRoutes() {
	go func() {
		ch := be.Watch()
		for {
			r := <-ch
			t, err := route.ParseString(r)
			if err != nil {
				log.Printf("[WARN] %s", err)
				continue
			}
			route.SetTable(t)
		}
	}()
}
Exemple #5
0
func initStaticRoutes(routes string) {
	var err error
	var t route.Table

	if strings.HasPrefix(routes, "@") {
		routes = routes[1:]
		log.Print("[INFO] Using static routes from ", routes)
		t, err = route.ParseFile(routes)
	} else {
		log.Print("[INFO] Using static routes from config file")
		t, err = route.ParseString(routes)
	}

	if err != nil {
		log.Fatal("[FATAL] ", err)
	}

	route.SetTable(t)
}
Exemple #6
0
func TestGracefulShutdown(t *testing.T) {
	req := func(url string) int {
		resp, err := http.Get(url)
		if err != nil {
			t.Fatal(err)
		}
		defer resp.Body.Close()
		return resp.StatusCode
	}

	// start a server which responds after the shutdown has been triggered.
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		<-quit // wait for shutdown signal
		return
	}))
	defer srv.Close()

	// load the routing table
	tbl, err := route.ParseString("route add svc / " + srv.URL)
	if err != nil {
		t.Fatal(err)
	}
	route.SetTable(tbl)

	// start proxy with graceful shutdown period long enough
	// to complete one more request.
	var wg sync.WaitGroup
	l := config.Listen{Addr: "127.0.0.1:57777"}
	wg.Add(1)
	go func() {
		defer wg.Done()
		startListeners([]config.Listen{l}, 250*time.Millisecond, route.NewProxy(http.DefaultTransport, config.Proxy{}))
	}()

	// trigger shutdown after some time
	shutdownDelay := 100 * time.Millisecond
	go func() {
		time.Sleep(shutdownDelay)
		close(quit)
	}()

	// give proxy some time to start up
	// needs to be done before shutdown is triggered
	time.Sleep(shutdownDelay / 2)

	// make 200 OK request
	// start before and complete after shutdown was triggered
	if got, want := req("http://"+l.Addr+"/"), 200; got != want {
		t.Fatalf("request 1: got %v want %v", got, want)
	}

	// make 503 request
	// start and complete after shutdown was triggered
	if got, want := req("http://"+l.Addr+"/"), 503; got != want {
		t.Fatalf("got %v want %v", got, want)
	}

	// wait for listen() to return
	// note that the actual listeners have not returned yet
	wg.Wait()
}