mirror of
https://github.com/yusing/godoxy.git
synced 2026-04-01 14:43:07 +02:00
correcting some behaviors for $DOCKER_HOST, now uses container's private IP instead of localhost
This commit is contained in:
@@ -21,29 +21,21 @@ type Client struct {
|
||||
l logrus.FieldLogger
|
||||
}
|
||||
|
||||
func ParseDockerHostname(host string) (string, E.NestedError) {
|
||||
switch host {
|
||||
case common.DockerHostFromEnv, "":
|
||||
return "localhost", nil
|
||||
}
|
||||
url, err := E.Check(client.ParseHostURL(host))
|
||||
if err != nil {
|
||||
return "", E.Invalid("host", host).With(err)
|
||||
}
|
||||
return url.Hostname(), nil
|
||||
}
|
||||
var (
|
||||
clientMap F.Map[string, Client] = F.NewMapOf[string, Client]()
|
||||
clientMapMu sync.Mutex
|
||||
|
||||
func (c Client) DaemonHostname() string {
|
||||
// DaemonHost should always return a valid host
|
||||
hostname, _ := ParseDockerHostname(c.DaemonHost())
|
||||
return hostname
|
||||
}
|
||||
clientOptEnvHost = []client.Opt{
|
||||
client.WithHostFromEnv(),
|
||||
client.WithAPIVersionNegotiation(),
|
||||
}
|
||||
)
|
||||
|
||||
func (c Client) Connected() bool {
|
||||
return c.Client != nil
|
||||
}
|
||||
|
||||
// if the client is still referenced, this is no-op
|
||||
// if the client is still referenced, this is no-op.
|
||||
func (c *Client) Close() error {
|
||||
if c.refCount.Add(-1) > 0 {
|
||||
return nil
|
||||
@@ -86,6 +78,8 @@ func ConnectClient(host string) (Client, E.NestedError) {
|
||||
var opt []client.Opt
|
||||
|
||||
switch host {
|
||||
case "":
|
||||
return Client{}, E.Invalid("docker host", "empty")
|
||||
case common.DockerHostFromEnv:
|
||||
opt = clientOptEnvHost
|
||||
default:
|
||||
@@ -139,15 +133,3 @@ func CloseAllClients() {
|
||||
clientMap.Clear()
|
||||
logger.Debug("closed all clients")
|
||||
}
|
||||
|
||||
var (
|
||||
clientMap F.Map[string, Client] = F.NewMapOf[string, Client]()
|
||||
clientMapMu sync.Mutex
|
||||
|
||||
clientOptEnvHost = []client.Opt{
|
||||
client.WithHostFromEnv(),
|
||||
client.WithAPIVersionNegotiation(),
|
||||
}
|
||||
|
||||
logger = logrus.WithField("module", "docker")
|
||||
)
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/client"
|
||||
|
||||
E "github.com/yusing/go-proxy/internal/error"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,45 +1,78 @@
|
||||
package docker
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/sirupsen/logrus"
|
||||
U "github.com/yusing/go-proxy/internal/utils"
|
||||
)
|
||||
|
||||
type Container struct {
|
||||
*types.Container
|
||||
*ProxyProperties
|
||||
}
|
||||
type (
|
||||
PortMapping = map[string]types.Port
|
||||
Container struct {
|
||||
_ U.NoCopy
|
||||
|
||||
func FromDocker(c *types.Container, dockerHost string) (res Container) {
|
||||
res.Container = c
|
||||
isExplicit := c.Labels[LabelAliases] != ""
|
||||
res.ProxyProperties = &ProxyProperties{
|
||||
DockerHost: dockerHost,
|
||||
ContainerName: res.getName(),
|
||||
ContainerID: c.ID,
|
||||
ImageName: res.getImageName(),
|
||||
PublicPortMapping: res.getPublicPortMapping(),
|
||||
PrivatePortMapping: res.getPrivatePortMapping(),
|
||||
NetworkMode: c.HostConfig.NetworkMode,
|
||||
Aliases: res.getAliases(),
|
||||
IsExcluded: U.ParseBool(res.getDeleteLabel(LabelExclude)),
|
||||
IsExplicit: isExplicit,
|
||||
IsDatabase: res.isDatabase(),
|
||||
IdleTimeout: res.getDeleteLabel(LabelIdleTimeout),
|
||||
WakeTimeout: res.getDeleteLabel(LabelWakeTimeout),
|
||||
StopMethod: res.getDeleteLabel(LabelStopMethod),
|
||||
StopTimeout: res.getDeleteLabel(LabelStopTimeout),
|
||||
StopSignal: res.getDeleteLabel(LabelStopSignal),
|
||||
Running: c.Status == "running" || c.State == "running",
|
||||
DockerHost string `json:"docker_host" yaml:"-"`
|
||||
ContainerName string `json:"container_name" yaml:"-"`
|
||||
ContainerID string `json:"container_id" yaml:"-"`
|
||||
ImageName string `json:"image_name" yaml:"-"`
|
||||
|
||||
Labels map[string]string `json:"labels" yaml:"-"`
|
||||
|
||||
PublicPortMapping PortMapping `json:"public_ports" yaml:"-"` // non-zero publicPort:types.Port
|
||||
PrivatePortMapping PortMapping `json:"private_ports" yaml:"-"` // privatePort:types.Port
|
||||
PublicIP string `json:"public_ip" yaml:"-"`
|
||||
PrivateIP string `json:"private_ip" yaml:"-"`
|
||||
NetworkMode string `json:"network_mode" yaml:"-"`
|
||||
|
||||
Aliases []string `json:"aliases" yaml:"-"`
|
||||
IsExcluded bool `json:"is_excluded" yaml:"-"`
|
||||
IsExplicit bool `json:"is_explicit" yaml:"-"`
|
||||
IsDatabase bool `json:"is_database" yaml:"-"`
|
||||
IdleTimeout string `json:"idle_timeout" yaml:"-"`
|
||||
WakeTimeout string `json:"wake_timeout" yaml:"-"`
|
||||
StopMethod string `json:"stop_method" yaml:"-"`
|
||||
StopTimeout string `json:"stop_timeout" yaml:"-"` // stop_method = "stop" only
|
||||
StopSignal string `json:"stop_signal" yaml:"-"` // stop_method = "stop" | "kill" only
|
||||
Running bool `json:"running" yaml:"-"`
|
||||
}
|
||||
)
|
||||
|
||||
func FromDocker(c *types.Container, dockerHost string) (res *Container) {
|
||||
isExplicit := c.Labels[LabelAliases] != ""
|
||||
helper := containerHelper{c}
|
||||
res = &Container{
|
||||
DockerHost: dockerHost,
|
||||
ContainerName: helper.getName(),
|
||||
ContainerID: c.ID,
|
||||
ImageName: helper.getImageName(),
|
||||
|
||||
Labels: c.Labels,
|
||||
|
||||
PublicPortMapping: helper.getPublicPortMapping(),
|
||||
PrivatePortMapping: helper.getPrivatePortMapping(),
|
||||
NetworkMode: c.HostConfig.NetworkMode,
|
||||
|
||||
Aliases: helper.getAliases(),
|
||||
IsExcluded: U.ParseBool(helper.getDeleteLabel(LabelExclude)),
|
||||
IsExplicit: isExplicit,
|
||||
IsDatabase: helper.isDatabase(),
|
||||
IdleTimeout: helper.getDeleteLabel(LabelIdleTimeout),
|
||||
WakeTimeout: helper.getDeleteLabel(LabelWakeTimeout),
|
||||
StopMethod: helper.getDeleteLabel(LabelStopMethod),
|
||||
StopTimeout: helper.getDeleteLabel(LabelStopTimeout),
|
||||
StopSignal: helper.getDeleteLabel(LabelStopSignal),
|
||||
Running: c.Status == "running" || c.State == "running",
|
||||
}
|
||||
res.setPrivateIP(helper)
|
||||
res.setPublicIP()
|
||||
return
|
||||
}
|
||||
|
||||
func FromJson(json types.ContainerJSON, dockerHost string) Container {
|
||||
func FromJSON(json types.ContainerJSON, dockerHost string) *Container {
|
||||
ports := make([]types.Port, 0)
|
||||
for k, bindings := range json.NetworkSettings.Ports {
|
||||
for _, v := range bindings {
|
||||
@@ -65,79 +98,32 @@ func FromJson(json types.ContainerJSON, dockerHost string) Container {
|
||||
return cont
|
||||
}
|
||||
|
||||
func (c Container) getDeleteLabel(label string) string {
|
||||
if l, ok := c.Labels[label]; ok {
|
||||
delete(c.Labels, label)
|
||||
return l
|
||||
func (c *Container) setPublicIP() {
|
||||
if c.PublicPortMapping == nil {
|
||||
return
|
||||
}
|
||||
return ""
|
||||
if strings.HasPrefix(c.DockerHost, "unix://") {
|
||||
c.PublicIP = "127.0.0.1"
|
||||
return
|
||||
}
|
||||
url, err := url.Parse(c.DockerHost)
|
||||
if err != nil {
|
||||
logrus.Errorf("invalid docker host %q: %v\nfalling back to 127.0.0.1", c.DockerHost, err)
|
||||
c.PublicIP = "127.0.0.1"
|
||||
return
|
||||
}
|
||||
c.PublicIP = url.Hostname()
|
||||
}
|
||||
|
||||
func (c Container) getAliases() []string {
|
||||
if l := c.getDeleteLabel(LabelAliases); l != "" {
|
||||
return U.CommaSeperatedList(l)
|
||||
} else {
|
||||
return []string{c.getName()}
|
||||
func (c *Container) setPrivateIP(helper containerHelper) {
|
||||
if !strings.HasPrefix(c.DockerHost, "unix://") {
|
||||
return
|
||||
}
|
||||
if helper.NetworkSettings == nil {
|
||||
return
|
||||
}
|
||||
for _, v := range helper.NetworkSettings.Networks {
|
||||
c.PrivateIP = v.IPAddress
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (c Container) getName() string {
|
||||
return strings.TrimPrefix(c.Names[0], "/")
|
||||
}
|
||||
|
||||
func (c Container) getImageName() string {
|
||||
colonSep := strings.Split(c.Image, ":")
|
||||
slashSep := strings.Split(colonSep[0], "/")
|
||||
return slashSep[len(slashSep)-1]
|
||||
}
|
||||
|
||||
func (c Container) getPublicPortMapping() PortMapping {
|
||||
res := make(PortMapping)
|
||||
for _, v := range c.Ports {
|
||||
if v.PublicPort == 0 {
|
||||
continue
|
||||
}
|
||||
res[fmt.Sprint(v.PublicPort)] = v
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (c Container) getPrivatePortMapping() PortMapping {
|
||||
res := make(PortMapping)
|
||||
for _, v := range c.Ports {
|
||||
res[fmt.Sprint(v.PrivatePort)] = v
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
var databaseMPs = map[string]struct{}{
|
||||
"/var/lib/postgresql/data": {},
|
||||
"/var/lib/mysql": {},
|
||||
"/var/lib/mongodb": {},
|
||||
"/var/lib/mariadb": {},
|
||||
"/var/lib/memcached": {},
|
||||
"/var/lib/rabbitmq": {},
|
||||
}
|
||||
|
||||
var databasePrivPorts = map[uint16]struct{}{
|
||||
5432: {}, // postgres
|
||||
3306: {}, // mysql, mariadb
|
||||
6379: {}, // redis
|
||||
11211: {}, // memcached
|
||||
27017: {}, // mongodb
|
||||
}
|
||||
|
||||
func (c Container) isDatabase() bool {
|
||||
for _, m := range c.Container.Mounts {
|
||||
if _, ok := databaseMPs[m.Destination]; ok {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
for _, v := range c.Ports {
|
||||
if _, ok := databasePrivPorts[v.PrivatePort]; ok {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
90
internal/docker/container_helper.go
Normal file
90
internal/docker/container_helper.go
Normal file
@@ -0,0 +1,90 @@
|
||||
package docker
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
U "github.com/yusing/go-proxy/internal/utils"
|
||||
)
|
||||
|
||||
type containerHelper struct {
|
||||
*types.Container
|
||||
}
|
||||
|
||||
// getDeleteLabel gets the value of a label and then deletes it from the container.
|
||||
// If the label does not exist, an empty string is returned.
|
||||
func (c containerHelper) getDeleteLabel(label string) string {
|
||||
if l, ok := c.Labels[label]; ok {
|
||||
delete(c.Labels, label)
|
||||
return l
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (c containerHelper) getAliases() []string {
|
||||
if l := c.getDeleteLabel(LabelAliases); l != "" {
|
||||
return U.CommaSeperatedList(l)
|
||||
}
|
||||
return []string{c.getName()}
|
||||
}
|
||||
|
||||
func (c containerHelper) getName() string {
|
||||
return strings.TrimPrefix(c.Names[0], "/")
|
||||
}
|
||||
|
||||
func (c containerHelper) getImageName() string {
|
||||
colonSep := strings.Split(c.Image, ":")
|
||||
slashSep := strings.Split(colonSep[0], "/")
|
||||
return slashSep[len(slashSep)-1]
|
||||
}
|
||||
|
||||
func (c containerHelper) getPublicPortMapping() PortMapping {
|
||||
res := make(PortMapping)
|
||||
for _, v := range c.Ports {
|
||||
if v.PublicPort == 0 {
|
||||
continue
|
||||
}
|
||||
res[U.PortString(v.PublicPort)] = v
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (c containerHelper) getPrivatePortMapping() PortMapping {
|
||||
res := make(PortMapping)
|
||||
for _, v := range c.Ports {
|
||||
res[U.PortString(v.PrivatePort)] = v
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
var databaseMPs = map[string]struct{}{
|
||||
"/var/lib/postgresql/data": {},
|
||||
"/var/lib/mysql": {},
|
||||
"/var/lib/mongodb": {},
|
||||
"/var/lib/mariadb": {},
|
||||
"/var/lib/memcached": {},
|
||||
"/var/lib/rabbitmq": {},
|
||||
}
|
||||
|
||||
var databasePrivPorts = map[uint16]struct{}{
|
||||
5432: {}, // postgres
|
||||
3306: {}, // mysql, mariadb
|
||||
6379: {}, // redis
|
||||
11211: {}, // memcached
|
||||
27017: {}, // mongodb
|
||||
}
|
||||
|
||||
func (c containerHelper) isDatabase() bool {
|
||||
for _, m := range c.Mounts {
|
||||
if _, ok := databaseMPs[m.Destination]; ok {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
for _, v := range c.Ports {
|
||||
if _, ok := databasePrivPorts[v.PrivatePort]; ok {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -18,9 +18,9 @@ type templateData struct {
|
||||
var loadingPage []byte
|
||||
var loadingPageTmpl = template.Must(template.New("loading_page").Parse(string(loadingPage)))
|
||||
|
||||
const headerCheckRedirect = "X-GoProxy-Check-Redirect"
|
||||
const headerCheckRedirect = "X-Goproxy-Check-Redirect"
|
||||
|
||||
func (w *watcher) makeRespBody(format string, args ...any) []byte {
|
||||
func (w *Watcher) makeRespBody(format string, args ...any) []byte {
|
||||
msg := fmt.Sprintf(format, args...)
|
||||
|
||||
data := new(templateData)
|
||||
|
||||
@@ -11,13 +11,13 @@ import (
|
||||
)
|
||||
|
||||
type Waker struct {
|
||||
*watcher
|
||||
*Watcher
|
||||
|
||||
client *http.Client
|
||||
rp *gphttp.ReverseProxy
|
||||
}
|
||||
|
||||
func NewWaker(w *watcher, rp *gphttp.ReverseProxy) *Waker {
|
||||
func NewWaker(w *Watcher, rp *gphttp.ReverseProxy) *Waker {
|
||||
orig := rp.ServeHTTP
|
||||
// workaround for stopped containers port become zero
|
||||
rp.ServeHTTP = func(rw http.ResponseWriter, r *http.Request) {
|
||||
@@ -33,7 +33,7 @@ func NewWaker(w *watcher, rp *gphttp.ReverseProxy) *Waker {
|
||||
orig(rw, r)
|
||||
}
|
||||
return &Waker{
|
||||
watcher: w,
|
||||
Watcher: w,
|
||||
client: &http.Client{
|
||||
Timeout: 1 * time.Second,
|
||||
Transport: rp.Transport,
|
||||
@@ -70,7 +70,9 @@ func (w *Waker) wake(next http.HandlerFunc, rw http.ResponseWriter, r *http.Requ
|
||||
rw.Header().Add("Cache-Control", "no-cache")
|
||||
rw.Header().Add("Cache-Control", "no-store")
|
||||
rw.Header().Add("Cache-Control", "must-revalidate")
|
||||
rw.Write(body)
|
||||
if _, err := rw.Write(body); err != nil {
|
||||
w.l.Errorf("error writing http response: %s", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
)
|
||||
|
||||
type (
|
||||
watcher struct {
|
||||
Watcher struct {
|
||||
*P.ReverseProxyEntry
|
||||
|
||||
client D.Client
|
||||
@@ -46,17 +46,17 @@ var (
|
||||
mainLoopCancel context.CancelFunc
|
||||
mainLoopWg sync.WaitGroup
|
||||
|
||||
watcherMap = F.NewMapOf[string, *watcher]()
|
||||
watcherMap = F.NewMapOf[string, *Watcher]()
|
||||
watcherMapMu sync.Mutex
|
||||
|
||||
portHistoryMap = F.NewMapOf[PT.Alias, string]()
|
||||
|
||||
newWatcherCh = make(chan *watcher)
|
||||
newWatcherCh = make(chan *Watcher)
|
||||
|
||||
logger = logrus.WithField("module", "idle_watcher")
|
||||
)
|
||||
|
||||
func Register(entry *P.ReverseProxyEntry) (*watcher, E.NestedError) {
|
||||
func Register(entry *P.ReverseProxyEntry) (*Watcher, E.NestedError) {
|
||||
failure := E.Failure("idle_watcher register")
|
||||
|
||||
if entry.IdleTimeout == 0 {
|
||||
@@ -83,7 +83,7 @@ func Register(entry *P.ReverseProxyEntry) (*watcher, E.NestedError) {
|
||||
return nil, failure.With(err)
|
||||
}
|
||||
|
||||
w := &watcher{
|
||||
w := &Watcher{
|
||||
ReverseProxyEntry: entry,
|
||||
client: client,
|
||||
refCount: &sync.WaitGroup{},
|
||||
@@ -104,7 +104,7 @@ func Register(entry *P.ReverseProxyEntry) (*watcher, E.NestedError) {
|
||||
return w, nil
|
||||
}
|
||||
|
||||
func (w *watcher) Unregister() {
|
||||
func (w *Watcher) Unregister() {
|
||||
w.refCount.Add(-1)
|
||||
}
|
||||
|
||||
@@ -138,29 +138,30 @@ func Stop() {
|
||||
mainLoopWg.Wait()
|
||||
}
|
||||
|
||||
func (w *watcher) containerStop() error {
|
||||
func (w *Watcher) containerStop() error {
|
||||
return w.client.ContainerStop(w.ctx, w.ContainerID, container.StopOptions{
|
||||
Signal: string(w.StopSignal),
|
||||
Timeout: &w.StopTimeout})
|
||||
Timeout: &w.StopTimeout,
|
||||
})
|
||||
}
|
||||
|
||||
func (w *watcher) containerPause() error {
|
||||
func (w *Watcher) containerPause() error {
|
||||
return w.client.ContainerPause(w.ctx, w.ContainerID)
|
||||
}
|
||||
|
||||
func (w *watcher) containerKill() error {
|
||||
func (w *Watcher) containerKill() error {
|
||||
return w.client.ContainerKill(w.ctx, w.ContainerID, string(w.StopSignal))
|
||||
}
|
||||
|
||||
func (w *watcher) containerUnpause() error {
|
||||
func (w *Watcher) containerUnpause() error {
|
||||
return w.client.ContainerUnpause(w.ctx, w.ContainerID)
|
||||
}
|
||||
|
||||
func (w *watcher) containerStart() error {
|
||||
func (w *Watcher) containerStart() error {
|
||||
return w.client.ContainerStart(w.ctx, w.ContainerID, container.StartOptions{})
|
||||
}
|
||||
|
||||
func (w *watcher) containerStatus() (string, E.NestedError) {
|
||||
func (w *Watcher) containerStatus() (string, E.NestedError) {
|
||||
json, err := w.client.ContainerInspect(w.ctx, w.ContainerID)
|
||||
if err != nil {
|
||||
return "", E.FailWith("inspect container", err)
|
||||
@@ -168,7 +169,7 @@ func (w *watcher) containerStatus() (string, E.NestedError) {
|
||||
return json.State.Status, nil
|
||||
}
|
||||
|
||||
func (w *watcher) wakeIfStopped() E.NestedError {
|
||||
func (w *Watcher) wakeIfStopped() E.NestedError {
|
||||
if w.ready.Load() || w.ContainerRunning {
|
||||
return nil
|
||||
}
|
||||
@@ -191,7 +192,7 @@ func (w *watcher) wakeIfStopped() E.NestedError {
|
||||
}
|
||||
}
|
||||
|
||||
func (w *watcher) getStopCallback() StopCallback {
|
||||
func (w *Watcher) getStopCallback() StopCallback {
|
||||
var cb func() error
|
||||
switch w.StopMethod {
|
||||
case PT.StopMethodPause:
|
||||
@@ -215,11 +216,11 @@ func (w *watcher) getStopCallback() StopCallback {
|
||||
}
|
||||
}
|
||||
|
||||
func (w *watcher) resetIdleTimer() {
|
||||
func (w *Watcher) resetIdleTimer() {
|
||||
w.ticker.Reset(w.IdleTimeout)
|
||||
}
|
||||
|
||||
func (w *watcher) watchUntilCancel() {
|
||||
func (w *Watcher) watchUntilCancel() {
|
||||
defer close(w.wakeCh)
|
||||
|
||||
w.ctx, w.cancel = context.WithCancel(mainLoopCtx)
|
||||
|
||||
@@ -7,13 +7,13 @@ import (
|
||||
E "github.com/yusing/go-proxy/internal/error"
|
||||
)
|
||||
|
||||
func (c Client) Inspect(containerID string) (Container, E.NestedError) {
|
||||
func (c Client) Inspect(containerID string) (*Container, E.NestedError) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
json, err := c.ContainerInspect(ctx, containerID)
|
||||
if err != nil {
|
||||
return Container{}, E.From(err)
|
||||
return nil, E.From(err)
|
||||
}
|
||||
return FromJson(json, c.key), nil
|
||||
return FromJSON(json, c.key), nil
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ func ApplyLabel[T any](obj *T, l *Label) E.NestedError {
|
||||
case *Label:
|
||||
var field reflect.Value
|
||||
objType := reflect.TypeFor[T]()
|
||||
for i := 0; i < reflect.TypeFor[T]().NumField(); i++ {
|
||||
for i := range reflect.TypeFor[T]().NumField() {
|
||||
if objType.Field(i).Tag.Get("yaml") == l.Attribute {
|
||||
field = reflect.ValueOf(obj).Elem().Field(i)
|
||||
break
|
||||
|
||||
@@ -8,14 +8,18 @@ import (
|
||||
. "github.com/yusing/go-proxy/internal/utils/testing"
|
||||
)
|
||||
|
||||
const (
|
||||
mName = "middleware1"
|
||||
mAttr = "prop1"
|
||||
v = "value1"
|
||||
)
|
||||
|
||||
func makeLabel(ns, name, attr string) string {
|
||||
return fmt.Sprintf("%s.%s.%s", ns, name, attr)
|
||||
}
|
||||
|
||||
func TestNestedLabel(t *testing.T) {
|
||||
mName := "middleware1"
|
||||
mAttr := "prop1"
|
||||
v := "value1"
|
||||
pl, err := ParseLabel(makeLabel(NSProxy, "foo", makeLabel("middlewares", mName, mAttr)), v)
|
||||
ExpectNoError(t, err.Error())
|
||||
sGot := ExpectType[*Label](t, pl.Value)
|
||||
@@ -28,9 +32,6 @@ func TestApplyNestedLabel(t *testing.T) {
|
||||
entry := new(struct {
|
||||
Middlewares NestedLabelMap `yaml:"middlewares"`
|
||||
})
|
||||
mName := "middleware1"
|
||||
mAttr := "prop1"
|
||||
v := "value1"
|
||||
pl, err := ParseLabel(makeLabel(NSProxy, "foo", makeLabel("middlewares", mName, mAttr)), v)
|
||||
ExpectNoError(t, err.Error())
|
||||
err = ApplyLabel(entry, pl)
|
||||
@@ -42,10 +43,6 @@ func TestApplyNestedLabel(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestApplyNestedLabelExisting(t *testing.T) {
|
||||
mName := "middleware1"
|
||||
mAttr := "prop1"
|
||||
v := "value1"
|
||||
|
||||
checkAttr := "prop2"
|
||||
checkV := "value2"
|
||||
entry := new(struct {
|
||||
@@ -71,9 +68,6 @@ func TestApplyNestedLabelExisting(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestApplyNestedLabelNoAttr(t *testing.T) {
|
||||
mName := "middleware1"
|
||||
v := "value1"
|
||||
|
||||
entry := new(struct {
|
||||
Middlewares NestedLabelMap `yaml:"middlewares"`
|
||||
})
|
||||
|
||||
5
internal/docker/logger.go
Normal file
5
internal/docker/logger.go
Normal file
@@ -0,0 +1,5 @@
|
||||
package docker
|
||||
|
||||
import "github.com/sirupsen/logrus"
|
||||
|
||||
var logger = logrus.WithField("module", "docker")
|
||||
@@ -1,25 +0,0 @@
|
||||
package docker
|
||||
|
||||
import "github.com/docker/docker/api/types"
|
||||
|
||||
type PortMapping = map[string]types.Port
|
||||
type ProxyProperties struct {
|
||||
DockerHost string `yaml:"-" json:"docker_host"`
|
||||
ContainerName string `yaml:"-" json:"container_name"`
|
||||
ContainerID string `yaml:"-" json:"container_id"`
|
||||
ImageName string `yaml:"-" json:"image_name"`
|
||||
PublicPortMapping PortMapping `yaml:"-" json:"public_port_mapping"` // non-zero publicPort:types.Port
|
||||
PrivatePortMapping PortMapping `yaml:"-" json:"private_port_mapping"` // privatePort:types.Port
|
||||
NetworkMode string `yaml:"-" json:"network_mode"`
|
||||
|
||||
Aliases []string `yaml:"-" json:"aliases"`
|
||||
IsExcluded bool `yaml:"-" json:"is_excluded"`
|
||||
IsExplicit bool `yaml:"-" json:"is_explicit"`
|
||||
IsDatabase bool `yaml:"-" json:"is_database"`
|
||||
IdleTimeout string `yaml:"-" json:"idle_timeout"`
|
||||
WakeTimeout string `yaml:"-" json:"wake_timeout"`
|
||||
StopMethod string `yaml:"-" json:"stop_method"`
|
||||
StopTimeout string `yaml:"-" json:"stop_timeout"` // stop_method = "stop" only
|
||||
StopSignal string `yaml:"-" json:"stop_signal"` // stop_method = "stop" | "kill" only
|
||||
Running bool `yaml:"-" json:"running"`
|
||||
}
|
||||
Reference in New Issue
Block a user