mirror of
https://github.com/yusing/godoxy.git
synced 2026-04-25 01:38:30 +02:00
support inline yaml for docker labels, serveral minor fixes
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -13,6 +14,7 @@ import (
|
||||
U "github.com/yusing/go-proxy/internal/utils"
|
||||
"github.com/yusing/go-proxy/internal/utils/strutils"
|
||||
"github.com/yusing/go-proxy/internal/watcher"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type DockerProvider struct {
|
||||
@@ -125,11 +127,19 @@ func (p *DockerProvider) entriesFromContainerLabels(container *docker.Container)
|
||||
continue
|
||||
}
|
||||
|
||||
var ok bool
|
||||
entryMap, ok := entryMapAny.(docker.LabelMap)
|
||||
if !ok {
|
||||
errs.Add(E.Errorf("expect mapping, got %T", entryMap).Subject(alias))
|
||||
continue
|
||||
// try to deserialize to map
|
||||
entryMap = make(docker.LabelMap)
|
||||
yamlStr, ok := entryMapAny.(string)
|
||||
if !ok {
|
||||
// should not happen
|
||||
panic(fmt.Errorf("invalid entry map type %T", entryMapAny))
|
||||
}
|
||||
if err := yaml.Unmarshal([]byte(yamlStr), &entryMap); err != nil {
|
||||
errs.Add(E.From(err).Subject(alias))
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if alias == docker.WildcardAlias {
|
||||
@@ -153,8 +163,8 @@ func (p *DockerProvider) entriesFromContainerLabels(container *docker.Container)
|
||||
}
|
||||
|
||||
// init entry if not exist
|
||||
var en *route.RawEntry
|
||||
if en, ok = entries.Load(alias); !ok {
|
||||
en, ok := entries.Load(alias)
|
||||
if !ok {
|
||||
en = &route.RawEntry{
|
||||
Alias: alias,
|
||||
Container: container,
|
||||
@@ -171,10 +181,12 @@ func (p *DockerProvider) entriesFromContainerLabels(container *docker.Container)
|
||||
}
|
||||
}
|
||||
if wildcardProps != nil {
|
||||
entries.RangeAll(func(alias string, re *route.RawEntry) {
|
||||
entries.Range(func(alias string, re *route.RawEntry) bool {
|
||||
if err := U.Deserialize(wildcardProps, re); err != nil {
|
||||
errs.Add(err.Subject(alias))
|
||||
errs.Add(err.Subject(docker.WildcardAlias))
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
128
internal/route/provider/docker_labels.yaml
Normal file
128
internal/route/provider/docker_labels.yaml
Normal file
@@ -0,0 +1,128 @@
|
||||
proxy.aliases: app,app1
|
||||
# style 1 - inline yaml
|
||||
proxy.app: |
|
||||
scheme: http
|
||||
host: 10.0.0.254
|
||||
port: 80
|
||||
path_patterns: # Check https://pkg.go.dev/net/http#hdr-Patterns-ServeMux for syntax
|
||||
- GET / # accept any GET request
|
||||
- POST /auth # for /auth and /auth/* accept only POST
|
||||
- GET /home/{$} # for exactly /home
|
||||
healthcheck:
|
||||
disabled: false
|
||||
path: /
|
||||
interval: 5s
|
||||
load_balance:
|
||||
link: app
|
||||
mode: ip_hash
|
||||
options:
|
||||
header: X-Forwarded-For
|
||||
middlewares:
|
||||
cidr_whitelist:
|
||||
allow:
|
||||
- 127.0.0.1
|
||||
- 10.0.0.0/8
|
||||
status_code: 403
|
||||
message: IP not allowed
|
||||
hideXForwarded:
|
||||
homepage:
|
||||
name: Example App
|
||||
icon: png/example.png
|
||||
description: An example app
|
||||
category: example
|
||||
access_log:
|
||||
buffer_size: 100
|
||||
path: /var/log/example.log
|
||||
filters:
|
||||
status_codes:
|
||||
values:
|
||||
- 200-299
|
||||
- 101
|
||||
method:
|
||||
values:
|
||||
- GET
|
||||
host:
|
||||
values:
|
||||
- example.y.z
|
||||
headers:
|
||||
negative: true
|
||||
values:
|
||||
- foo=bar
|
||||
- baz
|
||||
cidr:
|
||||
values:
|
||||
- 192.168.10.0/24
|
||||
fields:
|
||||
headers:
|
||||
default: keep
|
||||
config:
|
||||
foo: redact
|
||||
query:
|
||||
default: drop
|
||||
config:
|
||||
foo: keep
|
||||
cookies:
|
||||
default: redact
|
||||
config:
|
||||
foo: keep
|
||||
|
||||
# style 2 - full labels and mixed
|
||||
proxy.app1.scheme: http
|
||||
proxy.app1.host: 10.0.0.254
|
||||
proxy.app1.port: 80
|
||||
proxy.app1.path_patterns:
|
||||
| # Check https://pkg.go.dev/net/http#hdr-Patterns-ServeMux for syntax
|
||||
GET / # accept any GET request
|
||||
POST /auth # for /auth and /auth/* accept only POST
|
||||
GET /home/{$} # for exactly /home
|
||||
proxy.app1.healthcheck.disabled: false
|
||||
proxy.app1.healthcheck.path: /
|
||||
proxy.app1.healthcheck.interval: 5s
|
||||
proxy.app1.load_balance.link: app
|
||||
proxy.app1.load_balance.mode: ip_hash
|
||||
proxy.app1.load_balance.options.header: X-Forwarded-For
|
||||
proxy.app1.middlewares.cidr_whitelist: |
|
||||
allow:
|
||||
- 127.0.0.1
|
||||
- 10.0.0.0/8
|
||||
status_code: 403
|
||||
message: IP not allowed
|
||||
proxy.app1.middlewares.hideXForwarded:
|
||||
proxy.app1.homepage.name: Example App
|
||||
proxy.app1.homepage.icon: png/example.png
|
||||
proxy.app1.homepage.description: An example app
|
||||
proxy.app1.homepage.category: example
|
||||
proxy.app1.access_log.buffer_size: 100
|
||||
proxy.app1.access_log.path: /var/log/example.log
|
||||
proxy.app1.access_log.filters: |
|
||||
status_codes:
|
||||
values:
|
||||
- 200-299
|
||||
- 101
|
||||
method:
|
||||
values:
|
||||
- GET
|
||||
host:
|
||||
values:
|
||||
- example.y.z
|
||||
headers:
|
||||
negative: true
|
||||
values:
|
||||
- foo=bar
|
||||
- baz
|
||||
cidr:
|
||||
values:
|
||||
- 192.168.10.0/24
|
||||
proxy.app1.access_log.fields: |
|
||||
headers:
|
||||
default: keep
|
||||
config:
|
||||
foo: redact
|
||||
query:
|
||||
default: drop
|
||||
config:
|
||||
foo: keep
|
||||
cookies:
|
||||
default: redact
|
||||
config:
|
||||
foo: keep
|
||||
36
internal/route/provider/docker_labels_test.go
Normal file
36
internal/route/provider/docker_labels_test.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/yusing/go-proxy/internal/docker"
|
||||
. "github.com/yusing/go-proxy/internal/utils/testing"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
_ "embed"
|
||||
)
|
||||
|
||||
//go:embed docker_labels.yaml
|
||||
var testDockerLabelsYAML []byte
|
||||
|
||||
func TestParseDockerLabels(t *testing.T) {
|
||||
var provider DockerProvider
|
||||
|
||||
labels := make(map[string]string)
|
||||
ExpectNoError(t, yaml.Unmarshal(testDockerLabelsYAML, &labels))
|
||||
|
||||
routes, err := provider.entriesFromContainerLabels(
|
||||
docker.FromDocker(&types.Container{
|
||||
Names: []string{"container"},
|
||||
Labels: labels,
|
||||
State: "running",
|
||||
Ports: []types.Port{
|
||||
{Type: "tcp", PrivatePort: 1234, PublicPort: 1234},
|
||||
},
|
||||
}, "/var/run/docker.sock"),
|
||||
)
|
||||
ExpectNoError(t, err)
|
||||
ExpectTrue(t, routes.Has("app"))
|
||||
ExpectTrue(t, routes.Has("app1"))
|
||||
}
|
||||
@@ -9,9 +9,9 @@ import (
|
||||
)
|
||||
|
||||
//go:embed all_fields.yaml
|
||||
var yaml []byte
|
||||
var testAllFieldsYAML []byte
|
||||
|
||||
func TestFile(t *testing.T) {
|
||||
_, err := validate(yaml)
|
||||
_, err := validate(testAllFieldsYAML)
|
||||
ExpectNoError(t, err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user