mirror of
https://github.com/yusing/godoxy.git
synced 2025-06-10 05:12:34 +02:00
fix(label): expand wildcard labels before unmarshaling and add corresponding test
This commit is contained in:
parent
421aaecba4
commit
25fbcc4ab9
3 changed files with 60 additions and 19 deletions
|
@ -1,6 +1,9 @@
|
||||||
package docker
|
package docker
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/yusing/go-proxy/internal/gperr"
|
"github.com/yusing/go-proxy/internal/gperr"
|
||||||
"github.com/yusing/go-proxy/internal/utils/strutils"
|
"github.com/yusing/go-proxy/internal/utils/strutils"
|
||||||
)
|
)
|
||||||
|
@ -13,6 +16,8 @@ func ParseLabels(labels map[string]string) (LabelMap, gperr.Error) {
|
||||||
nestedMap := make(LabelMap)
|
nestedMap := make(LabelMap)
|
||||||
errs := gperr.NewBuilder("labels error")
|
errs := gperr.NewBuilder("labels error")
|
||||||
|
|
||||||
|
ExpandWildcard(labels)
|
||||||
|
|
||||||
for lbl, value := range labels {
|
for lbl, value := range labels {
|
||||||
parts := strutils.SplitRune(lbl, '.')
|
parts := strutils.SplitRune(lbl, '.')
|
||||||
if parts[0] != NSProxy {
|
if parts[0] != NSProxy {
|
||||||
|
@ -50,3 +55,32 @@ func ParseLabels(labels map[string]string) (LabelMap, gperr.Error) {
|
||||||
|
|
||||||
return nestedMap, errs.Error()
|
return nestedMap, errs.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExpandWildcard(labels map[string]string) {
|
||||||
|
aliasLabels := make([]string, 0, len(labels))
|
||||||
|
wildcardLabels := make(map[string]string)
|
||||||
|
|
||||||
|
for lbl, value := range labels {
|
||||||
|
parts := strings.SplitN(lbl, ".", 3) // Split into proxy, alias, rest
|
||||||
|
if parts[0] != NSProxy || len(parts) < 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
alias := parts[1] // alias or wildcard alias
|
||||||
|
if alias == WildcardAlias {
|
||||||
|
delete(labels, lbl)
|
||||||
|
if len(parts) < 3 { // invalid wildcard label (no suffix)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
wildcardLabels[parts[2]] = value
|
||||||
|
} else {
|
||||||
|
// Extract just the alias part (first segment after proxy)
|
||||||
|
aliasLabels = append(aliasLabels, alias)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for lbl, v := range wildcardLabels {
|
||||||
|
for _, alias := range aliasLabels {
|
||||||
|
labels[fmt.Sprintf("%s.%s.%s", NSProxy, alias, lbl)] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,16 +3,38 @@ package docker_test
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/yusing/go-proxy/internal/docker"
|
"github.com/yusing/go-proxy/internal/docker"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestExpandWildcard(t *testing.T) {
|
||||||
|
labels := map[string]string{
|
||||||
|
"proxy.a.host": "localhost",
|
||||||
|
"proxy.b.port": "4444",
|
||||||
|
"proxy.b.scheme": "http",
|
||||||
|
"proxy.*.port": "5555",
|
||||||
|
"proxy.*.healthcheck.disable": "true",
|
||||||
|
}
|
||||||
|
|
||||||
|
docker.ExpandWildcard(labels)
|
||||||
|
|
||||||
|
require.Equal(t, map[string]string{
|
||||||
|
"proxy.a.host": "localhost",
|
||||||
|
"proxy.a.port": "5555",
|
||||||
|
"proxy.a.healthcheck.disable": "true",
|
||||||
|
"proxy.b.scheme": "http",
|
||||||
|
"proxy.b.port": "5555",
|
||||||
|
"proxy.b.healthcheck.disable": "true",
|
||||||
|
}, labels)
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkParseLabels(b *testing.B) {
|
func BenchmarkParseLabels(b *testing.B) {
|
||||||
for range b.N {
|
for b.Loop() {
|
||||||
_, _ = docker.ParseLabels(map[string]string{
|
_, _ = docker.ParseLabels(map[string]string{
|
||||||
"proxy.a.host": "localhost",
|
"proxy.a.host": "localhost",
|
||||||
"proxy.a.port": "4444",
|
"proxy.b.port": "4444",
|
||||||
"proxy.a.scheme": "http",
|
"proxy.*.scheme": "http",
|
||||||
"proxy.a.middlewares.request.hide_headers": "X-Header1,X-Header2",
|
"proxy.*.middlewares.request.hide_headers": "X-Header1,X-Header2",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,8 +127,6 @@ func (p *DockerProvider) routesFromContainerLabels(container *docker.Container)
|
||||||
m, err := docker.ParseLabels(container.Labels)
|
m, err := docker.ParseLabels(container.Labels)
|
||||||
errs.Add(err)
|
errs.Add(err)
|
||||||
|
|
||||||
var wildcardProps docker.LabelMap
|
|
||||||
|
|
||||||
for alias, entryMapAny := range m {
|
for alias, entryMapAny := range m {
|
||||||
if len(alias) == 0 {
|
if len(alias) == 0 {
|
||||||
errs.Add(gperr.New("empty alias"))
|
errs.Add(gperr.New("empty alias"))
|
||||||
|
@ -150,11 +148,6 @@ func (p *DockerProvider) routesFromContainerLabels(container *docker.Container)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if alias == docker.WildcardAlias {
|
|
||||||
wildcardProps = entryMap
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if it is an alias reference
|
// check if it is an alias reference
|
||||||
switch alias[0] {
|
switch alias[0] {
|
||||||
case aliasRefPrefix, aliasRefPrefixAlt:
|
case aliasRefPrefix, aliasRefPrefixAlt:
|
||||||
|
@ -189,14 +182,6 @@ func (p *DockerProvider) routesFromContainerLabels(container *docker.Container)
|
||||||
routes[alias] = r
|
routes[alias] = r
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if wildcardProps != nil {
|
|
||||||
for _, re := range routes {
|
|
||||||
if err := serialization.MapUnmarshalValidate(wildcardProps, re); err != nil {
|
|
||||||
errs.Add(err.Subject(docker.WildcardAlias))
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return routes, errs.Error()
|
return routes, errs.Error()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue