/
register.go
126 lines (111 loc) · 2.9 KB
/
register.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
125
126
package consul
import (
"errors"
"fmt"
"log"
"net"
"os"
"strconv"
"strings"
"time"
"github.com/fabiolb/fabio/config"
"github.com/hashicorp/consul/api"
)
// register keeps a service registered in consul.
//
// When a value is sent in the dereg channel the service is deregistered from
// consul. To wait for completion the caller should read the next value from
// the dereg channel.
//
// dereg <- true // trigger deregistration
// <-dereg // wait for completion
//
func register(c *api.Client, service *api.AgentServiceRegistration) chan bool {
registered := func(serviceID string) bool {
if serviceID == "" {
return false
}
services, err := c.Agent().Services()
if err != nil {
log.Printf("[ERROR] consul: Cannot get service list. %s", err)
return false
}
return services[serviceID] != nil
}
register := func() string {
if err := c.Agent().ServiceRegister(service); err != nil {
log.Printf("[ERROR] consul: Cannot register fabio in consul. %s", err)
return ""
}
log.Printf("[INFO] consul: Registered fabio with id %q", service.ID)
log.Printf("[INFO] consul: Registered fabio with address %q", service.Address)
log.Printf("[INFO] consul: Registered fabio with tags %q", strings.Join(service.Tags, ","))
log.Printf("[INFO] consul: Registered fabio with health check to %q", service.Check.HTTP)
return service.ID
}
deregister := func(serviceID string) {
log.Printf("[INFO] consul: Deregistering fabio")
c.Agent().ServiceDeregister(serviceID)
}
dereg := make(chan bool)
go func() {
var serviceID string
for {
if !registered(serviceID) {
serviceID = register()
}
select {
case <-dereg:
deregister(serviceID)
dereg <- true
return
case <-time.After(time.Second):
// continue
}
}
}()
return dereg
}
func serviceRegistration(cfg *config.Consul) (*api.AgentServiceRegistration, error) {
hostname, err := os.Hostname()
if err != nil {
return nil, err
}
ipstr, portstr, err := net.SplitHostPort(cfg.ServiceAddr)
if err != nil {
return nil, err
}
port, err := strconv.Atoi(portstr)
if err != nil {
return nil, err
}
ip := net.ParseIP(ipstr)
if ip == nil {
ip, err = config.LocalIP()
if err != nil {
return nil, err
}
if ip == nil {
return nil, errors.New("no local ip")
}
}
serviceID := fmt.Sprintf("%s-%s-%d", cfg.ServiceName, hostname, port)
checkURL := fmt.Sprintf("%s://%s:%d/health", cfg.CheckScheme, ip, port)
if ip.To16() != nil {
checkURL = fmt.Sprintf("%s://[%s]:%d/health", cfg.CheckScheme, ip, port)
}
service := &api.AgentServiceRegistration{
ID: serviceID,
Name: cfg.ServiceName,
Address: ip.String(),
Port: port,
Tags: cfg.ServiceTags,
Check: &api.AgentServiceCheck{
HTTP: checkURL,
Interval: cfg.CheckInterval.String(),
Timeout: cfg.CheckTimeout.String(),
TLSSkipVerify: cfg.CheckTLSSkipVerify,
},
}
return service, nil
}