Skip to content

Commit e7593fd

Browse files
committed
dockerdiscovery: support sub rules for frontend rule
1 parent 1af6e90 commit e7593fd

File tree

2 files changed

+74
-4
lines changed

2 files changed

+74
-4
lines changed

pkg/erdiscovery/dockerdiscovery/traefikannotations.go

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,21 @@ func traefikAnnotationsToApp(service Service) (*erconfig.Application, error) {
6363
}
6464

6565
frontend, err := func() (erconfig.Frontend, error) {
66+
parsed, err := parseTraefikFrontendRule(frontendRule)
67+
if err != nil {
68+
return erconfig.Frontend{}, err
69+
}
70+
71+
opts := []erconfig.FrontendOpt{}
72+
if parsed.PathPrefix != "" {
73+
opts = append(opts, erconfig.PathPrefix(parsed.PathPrefix))
74+
}
75+
6676
switch {
67-
case strings.HasPrefix(frontendRule, "Host:"):
68-
return erconfig.SimpleHostnameFrontend(frontendRule[len("Host:"):]), nil
69-
case strings.HasPrefix(frontendRule, "HostRegexp:"):
70-
return erconfig.RegexpHostnameFrontend(frontendRule[len("HostRegexp:"):]), nil
77+
case parsed.Host != "":
78+
return erconfig.SimpleHostnameFrontend(parsed.Host, opts...), nil
79+
case parsed.HostRegexp != "":
80+
return erconfig.RegexpHostnameFrontend(parsed.HostRegexp, opts...), nil
7181
default:
7282
return erconfig.Frontend{}, fmt.Errorf("unsupported frontend rule: %s", frontendRule)
7383
}
@@ -137,3 +147,33 @@ func traefikAnnotationsToApp(service Service) (*erconfig.Application, error) {
137147

138148
return &app, nil
139149
}
150+
151+
type traefikFrontendRule struct {
152+
Host string `json:",omitempty"` // `Host:...` rule
153+
PathPrefix string `json:",omitempty"` // `PathPrefix:...` rule
154+
HostRegexp string `json:",omitempty"` // `HostRegexp:...` rule
155+
}
156+
157+
// https://doc.traefik.io/traefik/v1.7/user-guide/examples/#using-labels-in-docker-composeyml
158+
func parseTraefikFrontendRule(rule string) (traefikFrontendRule, error) {
159+
parsed := traefikFrontendRule{}
160+
161+
// `Host:example.com;PathPrefix:/admin/`
162+
// => `["Host:example.com", "PathPrefix:/admin/"]`
163+
subRules := strings.Split(rule, ";")
164+
165+
for _, subRule := range subRules {
166+
switch {
167+
case strings.HasPrefix(subRule, "Host:"):
168+
parsed.Host = subRule[len("Host:"):]
169+
case strings.HasPrefix(subRule, "PathPrefix:"):
170+
parsed.PathPrefix = subRule[len("PathPrefix:"):]
171+
case strings.HasPrefix(subRule, "HostRegexp:"):
172+
parsed.HostRegexp = subRule[len("HostRegexp:"):]
173+
default:
174+
return parsed, fmt.Errorf("unsupported rule: '%s'", subRule)
175+
}
176+
}
177+
178+
return parsed, nil
179+
}

pkg/erdiscovery/dockerdiscovery/traefikannotations_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,28 @@ func TestTraefikAnnotationsToApp(t *testing.T) {
159159
}
160160
}
161161
}
162+
}`),
163+
mkTestCase("multiple_subrules", ip101, labels{
164+
"traefik.frontend.rule": "Host:example.com;PathPrefix:/admin/",
165+
"edgerouter.auth": "public",
166+
}, `{
167+
"id": "multiple_subrules",
168+
"frontends": [
169+
{
170+
"kind": "hostname",
171+
"hostname": "example.com",
172+
"path_prefix": "/admin/"
173+
}
174+
],
175+
"backend": {
176+
"kind": "reverse_proxy",
177+
"reverse_proxy_opts": {
178+
"origins": [
179+
"http://192.168.1.101:80"
180+
],
181+
"pass_host_header": true
182+
}
183+
}
162184
}`),
163185
}
164186

@@ -174,3 +196,11 @@ func TestTraefikAnnotationsToApp(t *testing.T) {
174196
})
175197
}
176198
}
199+
200+
func TestParseSubRules(t *testing.T) {
201+
rule, err := parseTraefikFrontendRule("Host:example.com;PathPrefix:/admin/")
202+
assert.Ok(t, err)
203+
asJSON, err := json.Marshal(rule)
204+
assert.Ok(t, err)
205+
assert.EqualString(t, string(asJSON), `{"Host":"example.com","PathPrefix":"/admin/"}`)
206+
}

0 commit comments

Comments
 (0)