add primitive priority order for discovered containers

This commit is contained in:
Umputun
2021-04-13 01:52:12 -05:00
parent 26647571af
commit af02a41147
3 changed files with 31 additions and 8 deletions

View File

@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"regexp"
"sort"
"strings"
"time"
@@ -125,6 +126,13 @@ func (d *Docker) List() ([]discovery.URLMapper, error) {
PingURL: pingURL, ProviderID: discovery.PIDocker})
}
}
// sort by len(SrcMatch) to have shorter matches after longer
// this way we can handle possible conflicts with more detailed match triggered before less detailed
sort.Slice(res, func(i, j int) bool {
return len(res[i].SrcMatch.String()) > len(res[j].SrcMatch.String())
})
return res, nil
}

View File

@@ -14,6 +14,16 @@ func TestDocker_List(t *testing.T) {
dclient := &DockerClientMock{
ListContainersFunc: func(opts dc.ListContainersOptions) ([]dc.APIContainers, error) {
return []dc.APIContainers{
{Names: []string{"c0"}, State: "running",
Networks: dc.NetworkList{
Networks: map[string]dc.ContainerNetwork{"bridge": {IPAddress: "127.0.0.2"}},
},
Ports: []dc.APIPort{
{PrivatePort: 12348},
},
Labels: map[string]string{"reproxy.route": "^/a/(.*)", "reproxy.dest": "/a/$1",
"reproxy.server": "example.com", "reproxy.ping": "/ping"},
},
{Names: []string{"c1"}, State: "running",
Networks: dc.NetworkList{
Networks: map[string]dc.ContainerNetwork{"bridge": {IPAddress: "127.0.0.2"}},
@@ -58,17 +68,22 @@ func TestDocker_List(t *testing.T) {
d := Docker{DockerClient: dclient, Network: "bridge"}
res, err := d.List()
require.NoError(t, err)
require.Equal(t, 2, len(res))
require.Equal(t, 3, len(res))
assert.Equal(t, "^/api/123/(.*)", res[0].SrcMatch.String())
assert.Equal(t, "http://127.0.0.2:12345/blah/$1", res[0].Dst)
assert.Equal(t, "example.com", res[0].Server)
assert.Equal(t, "http://127.0.0.2:12345/ping", res[0].PingURL)
assert.Equal(t, "^/(.*)", res[1].SrcMatch.String())
assert.Equal(t, "http://127.0.0.3:12346/$1", res[1].Dst)
assert.Equal(t, "http://127.0.0.3:12346/ping", res[1].PingURL)
assert.Equal(t, "*", res[1].Server)
assert.Equal(t, "^/a/(.*)", res[1].SrcMatch.String())
assert.Equal(t, "http://127.0.0.2:12348/a/$1", res[1].Dst)
assert.Equal(t, "http://127.0.0.2:12348/ping", res[1].PingURL)
assert.Equal(t, "example.com", res[1].Server)
assert.Equal(t, "^/(.*)", res[2].SrcMatch.String())
assert.Equal(t, "http://127.0.0.3:12346/$1", res[2].Dst)
assert.Equal(t, "http://127.0.0.3:12346/ping", res[2].PingURL)
assert.Equal(t, "*", res[2].Server)
}
func TestDocker_ListWithAutoAPI(t *testing.T) {

View File

@@ -46,12 +46,12 @@ func (h *Http) healthHandler(w http.ResponseWriter, _ *http.Request) {
if err != nil {
errMsg := strings.Replace(err.Error(), "\"", "", -1)
log.Printf("[WARN] failed to ping for health %s, %s", m.PingURL, errMsg)
outCh <- fmt.Errorf("(%s %s) %s, %v", m.Server, m.SrcMatch.String(), m.PingURL, errMsg)
outCh <- fmt.Errorf("%s %s: %s, %v", m.Server, m.SrcMatch.String(), m.PingURL, errMsg)
return
}
if resp.StatusCode != http.StatusOK {
log.Printf("[WARN] failed ping status for health %s (%s)", m.PingURL, resp.Status)
outCh <- fmt.Errorf("(%s %s) %s, %s", m.Server, m.SrcMatch.String(), m.PingURL, resp.Status)
outCh <- fmt.Errorf("%s %s: %s, %s", m.Server, m.SrcMatch.String(), m.PingURL, resp.Status)
return
}
}(m)
@@ -86,7 +86,7 @@ func (h *Http) healthHandler(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusOK)
_, err := fmt.Fprintf(w, `{"status": "ok", "services": %d}`, valid)
if err != nil {
log.Printf("[WARN] failed to send halth, %v", err)
log.Printf("[WARN] failed to send health, %v", err)
}
}