-
Notifications
You must be signed in to change notification settings - Fork 0
/
docker.go
124 lines (100 loc) · 3.15 KB
/
docker.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package main
import (
"context"
"fmt"
"os/exec"
"strconv"
"strings"
"time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
log "github.com/sirupsen/logrus"
)
// ContainerWatch checks for new containers and if they exist, add the sites and it's endpoints
func ContainerWatch(containerized bool, myPort int) {
address := "127.0.0.1"
if containerized {
address = containerizedIP()
}
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithVersion("1.22"))
if err != nil {
log.Error(err.Error())
return
}
for {
if containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{}); err == nil {
for _, container := range containers {
// Use container name as default host
vHost := container.Names[0][1:]
vDefaultPort := 80
vPubPort := 0
vPriPort := 0
// Check for default port 80
vPriPort = convertPrivatePortToPublic(container.Ports, vDefaultPort)
// Override default port with VIRTUAL_PORT
cJSON1, _ := cli.ContainerInspect(context.Background(), container.ID)
for _, conEnv1 := range cJSON1.Config.Env {
splits := strings.Split(conEnv1, "=")
key := splits[0]
val := splits[1]
// Check for overrides to port
if strings.HasPrefix(key, "VIRTUAL_PORT") {
vDefaultPort, _ := strconv.Atoi(val)
vPriPort = convertPrivatePortToPublic(container.Ports, vDefaultPort)
}
}
// Add default host (container name) and port
if vPriPort != 0 && vPriPort != myPort {
AddSite(vHost, fmt.Sprintf("http://%s:%d", address, vPriPort))
}
cJSON2, _ := cli.ContainerInspect(context.Background(), container.ID)
for _, conEnv2 := range cJSON2.Config.Env {
splits := strings.Split(conEnv2, "=")
key := splits[0]
val := splits[1]
// Check for overrides to hostname
if strings.HasPrefix(key, "VIRTUAL_HOST") {
if strings.Contains(val, ":") {
splits = strings.Split(val, ":")
vHost = splits[0]
vPubPort, _ = strconv.Atoi(splits[1])
} else {
vHost = val
vPubPort = vDefaultPort
}
vPriPort = convertPrivatePortToPublic(container.Ports, vPubPort)
// Add extra hosts
if vPriPort != 0 && vPriPort != myPort {
AddSite(vHost, fmt.Sprintf("http://%s:%d", address, vPriPort))
}
}
}
}
} else {
log.Error("Unable to connect to docker")
log.Error(err.Error())
}
// Every 5 seconds, check for new containers
<-time.After(5 * time.Second)
}
}
// Convert private port to public port
func convertPrivatePortToPublic(PortList []types.Port, PriPort int) int {
for _, port := range PortList {
if int(port.PrivatePort) == PriPort {
return int(port.PublicPort)
}
}
return 0
}
// containerizedIP returns a string with the ip address of the docker host
func containerizedIP() string {
cmd := exec.Command("sh", "-c", "/sbin/ip route|awk '/default/ { print $3 }'")
if output, err := cmd.Output(); err == nil {
log.WithFields(log.Fields{
"IP": strings.TrimSpace(string(output)),
}).Info("Auto detecting docker host IP Address")
return fmt.Sprintf("%s", strings.TrimSpace(string(output)))
}
return "127.0.0.1"
}