mirror of
https://github.com/umputun/reproxy.git
synced 2024-09-11 08:55:25 +03:00
support reproxy.port #21
defines which of exposed ports will be used for the destination in case if multiple ports exposed from the container
This commit is contained in:
parent
af02a41147
commit
f6491246f8
@ -66,6 +66,7 @@ This default can be changed with labels:
|
||||
- `reproxy.server` - server (hostname) to match. Also can be a list of comma-separated servers.
|
||||
- `reproxy.route` - source route (location)
|
||||
- `reproxy.dest` - destination path. Note: this is not full url, but just the path which will be appended to container's ip:port
|
||||
- `reproxy.port` - destination port for the discovered container
|
||||
- `reproxy.ping` - ping path for the destination container.
|
||||
- `reproxy.enabled` - enable (`yes`, `true`, `1`) or disable (`no`, `false`, `0`) container from reproxy destinations.
|
||||
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -43,7 +44,7 @@ type containerInfo struct {
|
||||
TS time.Time
|
||||
Labels map[string]string
|
||||
IP string
|
||||
Port int
|
||||
Ports []int
|
||||
}
|
||||
|
||||
// Events gets eventsCh with all containers-related docker events events
|
||||
@ -79,10 +80,16 @@ func (d *Docker) List() ([]discovery.URLMapper, error) {
|
||||
if d.AutoAPI {
|
||||
enabled = true
|
||||
srcURL = fmt.Sprintf("^/api/%s/(.*)", c.Name)
|
||||
|
||||
}
|
||||
destURL := fmt.Sprintf("http://%s:%d/$1", c.IP, c.Port)
|
||||
pingURL := fmt.Sprintf("http://%s:%d/ping", c.IP, c.Port)
|
||||
|
||||
port, err := d.matchedPort(c)
|
||||
if err != nil {
|
||||
log.Printf("[DEBUG] container %s disabled, %v", c.Name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
destURL := fmt.Sprintf("http://%s:%d/$1", c.IP, port)
|
||||
pingURL := fmt.Sprintf("http://%s:%d/ping", c.IP, port)
|
||||
server := "*"
|
||||
|
||||
// we don't care about value because disabled will be filtered before
|
||||
@ -97,7 +104,7 @@ func (d *Docker) List() ([]discovery.URLMapper, error) {
|
||||
|
||||
if v, ok := c.Labels["reproxy.dest"]; ok {
|
||||
enabled = true
|
||||
destURL = fmt.Sprintf("http://%s:%d%s", c.IP, c.Port, v)
|
||||
destURL = fmt.Sprintf("http://%s:%d%s", c.IP, port, v)
|
||||
}
|
||||
|
||||
if v, ok := c.Labels["reproxy.server"]; ok {
|
||||
@ -107,7 +114,7 @@ func (d *Docker) List() ([]discovery.URLMapper, error) {
|
||||
|
||||
if v, ok := c.Labels["reproxy.ping"]; ok {
|
||||
enabled = true
|
||||
pingURL = fmt.Sprintf("http://%s:%d%s", c.IP, c.Port, v)
|
||||
pingURL = fmt.Sprintf("http://%s:%d%s", c.IP, port, v)
|
||||
}
|
||||
|
||||
if !enabled {
|
||||
@ -136,6 +143,24 @@ func (d *Docker) List() ([]discovery.URLMapper, error) {
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (d *Docker) matchedPort(c containerInfo) (port int, err error) {
|
||||
port = c.Ports[0] // by default use the first exposed port
|
||||
if v, ok := c.Labels["reproxy.port"]; ok {
|
||||
rp, err := strconv.Atoi(v)
|
||||
if err != nil {
|
||||
return 0, errors.Wrapf(err, "invalid reproxy.port %s", v)
|
||||
}
|
||||
for _, p := range c.Ports {
|
||||
// set port to reproxy.port if matched with one of exposed
|
||||
if p == rp {
|
||||
port = rp
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return port, nil
|
||||
}
|
||||
|
||||
// activate starts blocking listener for all docker events
|
||||
// filters everything except "container" type, detects stop/start events and publishes signals to eventsCh
|
||||
func (d *Docker) events(ctx context.Context, client DockerClient, eventsCh chan discovery.ProviderID) error {
|
||||
@ -171,11 +196,14 @@ func (d *Docker) events(ctx context.Context, client DockerClient, eventsCh chan
|
||||
|
||||
func (d *Docker) listContainers() (res []containerInfo, err error) {
|
||||
|
||||
portExposed := func(c dc.APIContainers) (int, bool) {
|
||||
portsExposed := func(c dc.APIContainers) (ports []int) {
|
||||
if len(c.Ports) == 0 {
|
||||
return 0, false
|
||||
return nil
|
||||
}
|
||||
return int(c.Ports[0].PrivatePort), true
|
||||
for _, p := range c.Ports {
|
||||
ports = append(ports, int(p.PrivatePort))
|
||||
}
|
||||
return ports
|
||||
}
|
||||
|
||||
containers, err := d.DockerClient.ListContainers(dc.ListContainersOptions{All: false})
|
||||
@ -214,8 +242,8 @@ func (d *Docker) listContainers() (res []containerInfo, err error) {
|
||||
continue
|
||||
}
|
||||
|
||||
port, ok := portExposed(c)
|
||||
if !ok {
|
||||
ports := portsExposed(c)
|
||||
if len(ports) == 0 {
|
||||
log.Printf("[DEBUG] skip container %s, no exposed ports", c.Names[0])
|
||||
continue
|
||||
}
|
||||
@ -226,7 +254,7 @@ func (d *Docker) listContainers() (res []containerInfo, err error) {
|
||||
TS: time.Unix(c.Created/1000, 0),
|
||||
Labels: c.Labels,
|
||||
IP: ip,
|
||||
Port: port,
|
||||
Ports: ports,
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] running container added, %+v", ci)
|
||||
|
@ -95,10 +95,11 @@ func TestDocker_ListWithAutoAPI(t *testing.T) {
|
||||
Networks: map[string]dc.ContainerNetwork{"bridge": {IPAddress: "127.0.0.2"}},
|
||||
},
|
||||
Ports: []dc.APIPort{
|
||||
{PrivatePort: 1345},
|
||||
{PrivatePort: 12345},
|
||||
},
|
||||
Labels: map[string]string{"reproxy.route": "^/api/123/(.*)", "reproxy.dest": "/blah/$1",
|
||||
"reproxy.server": "example.com, example2.com", "reproxy.ping": "/ping"},
|
||||
"reproxy.port": "12345", "reproxy.server": "example.com, example2.com", "reproxy.ping": "/ping"},
|
||||
},
|
||||
{Names: []string{"c2"}, State: "running",
|
||||
Networks: dc.NetworkList{
|
||||
|
Loading…
Reference in New Issue
Block a user