forked from ehazlett/stellar
/
datastore.go
110 lines (98 loc) · 2.76 KB
/
datastore.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
package proxy
import (
"fmt"
"strings"
blackbirdapi "github.com/ehazlett/blackbird/api/v1"
nameserverapi "github.com/ehazlett/stellar/api/services/nameserver/v1"
"github.com/ehazlett/stellar/client"
"github.com/sirupsen/logrus"
)
type datastore struct {
client *client.Client
}
func newDatastore(client *client.Client) (*datastore, error) {
if err := client.Datastore().CreateBucket(dsProxyBucketName); err != nil {
return nil, err
}
return &datastore{
client: client,
}, nil
}
func (d *datastore) Name() string {
return "stellar"
}
func (d *datastore) Add(host string, srv *blackbirdapi.Server) error {
// since we grab the servers from the application service direct this is a noop
return nil
}
func (d *datastore) Remove(host string) error {
// since we grab the servers from the application service direct this is a noop
return nil
}
func (d *datastore) Servers() ([]*blackbirdapi.Server, error) {
apps, err := d.client.Application().List()
if err != nil {
return nil, err
}
servers := []*blackbirdapi.Server{}
hostServers := map[string]*blackbirdapi.Server{}
hostUpstreams := map[string][]string{}
for _, app := range apps {
for _, svc := range app.Services {
if len(svc.Endpoints) == 0 {
continue
}
// parse url and notify update
for _, ep := range svc.Endpoints {
if strings.ToLower(ep.Protocol.String()) != "http" {
logrus.Warnf("proxy: unsupported protocol %s for endpoint %s", ep.Protocol, ep.Service)
continue
}
// lookup the ip for faster resolves
records, err := d.client.Nameserver().Lookup(svc.Name)
if err != nil {
logrus.Warnf("proxy: unable to lookup service address: %s", err)
continue
}
v, exists := hostServers[ep.Host]
if !exists {
v = &blackbirdapi.Server{
Host: ep.Host,
Path: "/",
TLS: ep.TLS,
Policy: blackbirdapi.Policy_RANDOM,
Preset: "transparent",
}
hostServers[ep.Host] = v
}
// check for conflicting values in host
if ep.TLS != v.TLS {
logrus.Warnf("conflicting TLS setting for %s", ep.Host)
}
// build upstreams
upstreams := []string{}
for _, record := range records {
// only use A records
if record.Type != nameserverapi.RecordType_A {
continue
}
// TODO: support TLS on the upstream
upstreams = append(upstreams, fmt.Sprintf("http://%s:%d", record.Value, ep.Port))
}
if _, ok := hostUpstreams[ep.Host]; !ok {
hostUpstreams[ep.Host] = []string{}
}
hostUpstreams[ep.Host] = append(hostUpstreams[ep.Host], upstreams...)
}
}
}
for host, srv := range hostServers {
up, ok := hostUpstreams[host]
if !ok {
logrus.Warnf("no upstreams found for %s", host)
}
srv.Upstreams = up
servers = append(servers, srv)
}
return servers, nil
}