/
discovery.go
133 lines (106 loc) · 2.71 KB
/
discovery.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
127
128
129
130
131
132
133
package ZookeeperServiceDiscovery
import (
"encoding/json"
"errors"
"fmt"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/resolver"
"io"
"net"
"net/http"
"os"
)
type EcsZkDiscovery struct {
zk *zkClient
schema string
path string
}
func NewEcsZkServiceDiscovery(zkServers []string, zkTimeout int, registrationPath string, args ...string) (*EcsZkDiscovery, error) {
var schema string
if len(args) > 0 {
schema = args[0]
} else {
schema = "zk"
}
zkClient, err := newZkClient(zkServers, zkTimeout)
if err != nil {
return nil, err
}
sd := &EcsZkDiscovery{
zk: zkClient,
schema: schema,
path: registrationPath,
}
return sd, nil
}
func (sd *EcsZkDiscovery) RegisterService(port string, args ...string) error {
metadataEndpoint, isEcs := os.LookupEnv("ECS_CONTAINER_METADATA_URI_V4")
var ip string
if len(args) > 0 {
ip = args[0]
} else if isEcs {
grpclog.Infof("Running inside ECS, getting IP from ECS metadata endpoint")
resp, err := http.Get(metadataEndpoint)
if err != nil {
grpclog.Errorf("Failed to get ECS metadata: %v", err)
return err
}
b, err := io.ReadAll(resp.Body)
if err != nil {
grpclog.Errorf("Failed to get ECS metadata body: %v", err)
return err
}
var jsonData interface{}
json.Unmarshal(b, &jsonData)
m := jsonData.(map[string]interface{})
network := m["Networks"].([]interface{})[0].(map[string]interface{})
networkMode := network["NetworkMode"].(string)
if networkMode == "awsvpc" {
ip = network["IPv4Addresses"].([]interface{})[0].(string)
} else {
// get EC2 instance IP
ec2MetadataEndpoint, isEnvVar := os.LookupEnv("EC2_METADATA_IP")
if !isEnvVar {
ec2MetadataEndpoint = "http://169.254.169.254"
}
resp, err := http.Get(ec2MetadataEndpoint + "/latest/meta-data/local-ipv4")
if err != nil {
grpclog.Errorf("Failed to get EC2 metadata: %v", err)
return err
}
b, err := io.ReadAll(resp.Body)
if err != nil {
grpclog.Errorf("Failed to get ECS metadata body: %v", err)
return err
}
ip = string(b)
}
} else {
grpclog.Infof("Getting first public IP from interfaces")
addrs, err := net.InterfaceAddrs()
if err != nil {
grpclog.Errorf("Error while getting IP: %v", err)
return err
}
for _, addr := range addrs {
ipnet, ok := addr.(*net.IPNet)
if ok && !ipnet.IP.IsLoopback() {
ip = ipnet.IP.String()
break
}
}
}
if ip == "" {
return errors.New("Could not get public IP address")
}
return sd.zk.RegisterNode(sd.path, fmt.Sprintf("%s:%s", ip, port))
}
func (sd *EcsZkDiscovery) Unregister() {
sd.zk.Close()
}
func (sd *EcsZkDiscovery) RegisterResolver() {
resolver.Register(&zkResolverBuilder{
scheme: sd.schema,
zk: sd.zk,
})
}