Add Custom header parsing to Docker Provider

This commit is contained in:
Daniel Tomcej 2017-10-20 10:14:03 -05:00 committed by Traefiker
parent 7192aa86b5
commit d973096464
4 changed files with 55 additions and 0 deletions

View file

@ -169,6 +169,8 @@ Labels can be used on containers to override default behaviour.
| `traefik.frontend.entryPoints=http,https` | Assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints` | | `traefik.frontend.entryPoints=http,https` | Assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints` |
| `traefik.frontend.auth.basic=EXPR` | Sets basic authentication for that frontend in CSV format: `User:Hash,User:Hash` | | `traefik.frontend.auth.basic=EXPR` | Sets basic authentication for that frontend in CSV format: `User:Hash,User:Hash` |
| `traefik.frontend.whitelistSourceRange:RANGE` | List of IP-Ranges which are allowed to access. An unset or empty list allows all Source-IPs to access. If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. | | `traefik.frontend.whitelistSourceRange:RANGE` | List of IP-Ranges which are allowed to access. An unset or empty list allows all Source-IPs to access. If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. |
| `traefik.frontend.headers.customrequestheaders=EXPR ` | Provides the container with custom request headers that will be appended to each request forwarded to the container. Format: `HEADER:value,HEADER2:value2` |
| `traefik.frontend.headers.customresponseheaders=EXPR` | Appends the headers to each response returned by the container, before forwarding the response to the client. Format: `HEADER:value,HEADER2:value2` |
| `traefik.docker.network` | Set the docker network to use for connections to this container. If a container is linked to several networks, be sure to set the proper network name (you can check with `docker inspect <container_id>`) otherwise it will randomly pick one (depending on how docker is returning them). For instance when deploying docker `stack` from compose files, the compose defined networks will be prefixed with the `stack` name. | | `traefik.docker.network` | Set the docker network to use for connections to this container. If a container is linked to several networks, be sure to set the proper network name (you can check with `docker inspect <container_id>`) otherwise it will randomly pick one (depending on how docker is returning them). For instance when deploying docker `stack` from compose files, the compose defined networks will be prefixed with the `stack` name. |
### On Service ### On Service

View file

@ -291,6 +291,10 @@ func (p *Provider) loadDockerConfig(containersInspected []dockerData) *types.Con
"getServicePriority": p.getServicePriority, "getServicePriority": p.getServicePriority,
"getServiceBackend": p.getServiceBackend, "getServiceBackend": p.getServiceBackend,
"getWhitelistSourceRange": p.getWhitelistSourceRange, "getWhitelistSourceRange": p.getWhitelistSourceRange,
"getRequestHeaders": p.getRequestHeaders,
"getResponseHeaders": p.getResponseHeaders,
"hasRequestHeaders": p.hasRequestHeaders,
"hasResponseHeaders": p.hasResponseHeaders,
} }
// filter containers // filter containers
filteredContainers := fun.Filter(func(container dockerData) bool { filteredContainers := fun.Filter(func(container dockerData) bool {
@ -726,6 +730,41 @@ func (p *Provider) getBasicAuth(container dockerData) []string {
return []string{} return []string{}
} }
func (p *Provider) hasRequestHeaders(container dockerData) bool {
label, err := getLabel(container, types.LabelFrontendRequestHeader)
return err == nil && len(label) > 0
}
func (p *Provider) hasResponseHeaders(container dockerData) bool {
label, err := getLabel(container, types.LabelFrontendResponseHeader)
return err == nil && len(label) > 0
}
func (p *Provider) getRequestHeaders(container dockerData) map[string]string {
return parseCustomHeaders(container, types.LabelFrontendRequestHeader)
}
func (p *Provider) getResponseHeaders(container dockerData) map[string]string {
return parseCustomHeaders(container, types.LabelFrontendResponseHeader)
}
func parseCustomHeaders(container dockerData, containerType string) map[string]string {
customHeaders := make(map[string]string)
if label, err := getLabel(container, containerType); err == nil {
for _, headers := range strings.Split(label, ",") {
pair := strings.Split(headers, ":")
if len(pair) != 2 {
log.Warnf("Could not load header %v, skipping...", pair)
} else {
customHeaders[pair[0]] = pair[1]
}
}
}
if len(customHeaders) == 0 {
log.Errorf("Could not load any custom headers")
}
return customHeaders
}
func isContainerEnabled(container dockerData, exposedByDefault bool) bool { func isContainerEnabled(container dockerData, exposedByDefault bool) bool {
return exposedByDefault && container.Labels[types.LabelEnable] != "false" || container.Labels[types.LabelEnable] == "true" return exposedByDefault && container.Labels[types.LabelEnable] != "false" || container.Labels[types.LabelEnable] == "true"
} }

View file

@ -78,6 +78,18 @@
basicAuth = [{{range getBasicAuth $container}} basicAuth = [{{range getBasicAuth $container}}
"{{.}}", "{{.}}",
{{end}}] {{end}}]
{{if hasRequestHeaders $container}}
[frontends."frontend-{{$frontend}}".headers.customrequestheaders]
{{range $k, $v := getRequestHeaders $container}}
{{$k}} = "{{$v}}"
{{end}}
{{end}}
{{if hasResponseHeaders $container}}
[frontends."frontend-{{$frontend}}".headers.customresponseheaders]
{{range $k, $v := getResponseHeaders $container}}
{{$k}} = "{{$v}}"
{{end}}
{{end}}
[frontends."frontend-{{$frontend}}".routes."route-frontend-{{$frontend}}"] [frontends."frontend-{{$frontend}}".routes."route-frontend-{{$frontend}}"]
rule = "{{getFrontendRule $container}}" rule = "{{getFrontendRule $container}}"
{{end}} {{end}}

View file

@ -14,6 +14,8 @@ const (
LabelWeight = LabelPrefix + "weight" LabelWeight = LabelPrefix + "weight"
LabelFrontendAuthBasic = LabelPrefix + "frontend.auth.basic" LabelFrontendAuthBasic = LabelPrefix + "frontend.auth.basic"
LabelFrontendEntryPoints = LabelPrefix + "frontend.entryPoints" LabelFrontendEntryPoints = LabelPrefix + "frontend.entryPoints"
LabelFrontendRequestHeader = LabelPrefix + "frontend.headers.customrequestheaders"
LabelFrontendResponseHeader = LabelPrefix + "frontend.headers.customresoponseheaders"
LabelFrontendPassHostHeader = LabelPrefix + "frontend.passHostHeader" LabelFrontendPassHostHeader = LabelPrefix + "frontend.passHostHeader"
LabelFrontendPriority = LabelPrefix + "frontend.priority" LabelFrontendPriority = LabelPrefix + "frontend.priority"
LabelFrontendRule = LabelPrefix + "frontend.rule" LabelFrontendRule = LabelPrefix + "frontend.rule"