-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
151 lines (127 loc) · 4.1 KB
/
main.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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package main
import (
"flag"
"github.com/Sirupsen/logrus"
"github.com/rancher/external-lb/metadata"
"github.com/rancher/external-lb/model"
"github.com/rancher/external-lb/providers"
_ "github.com/rancher/external-lb/providers/elbv1"
_ "github.com/rancher/external-lb/providers/f5"
"os"
"reflect"
"strings"
"time"
)
const (
pollInterval = 1000
// if metadata wasn't updated in 1 min, force update would be executed
forceUpdateInterval = 1
)
var (
providerName = flag.String("provider", "f5_BigIP", "External LB provider name")
debug = flag.Bool("debug", false, "Debug")
logFile = flag.String("log", "", "Log file")
provider providers.Provider
m *metadata.MetadataClient
c *CattleClient
targetPoolSuffix string
metadataLBConfigsCached = make(map[string]model.LBConfig)
)
func setEnv() {
flag.Parse()
if *debug {
logrus.SetLevel(logrus.DebugLevel)
}
if *logFile != "" {
if output, err := os.OpenFile(*logFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666); err != nil {
logrus.Fatalf("Failed to log to file %s: %v", *logFile, err)
} else {
logrus.SetOutput(output)
formatter := &logrus.TextFormatter{
FullTimestamp: true,
}
logrus.SetFormatter(formatter)
}
}
// initialize metadata client
var err error
m, err = metadata.NewMetadataClient()
if err != nil {
logrus.Fatalf("Failed to initialize Rancher metadata client: %v", err)
}
// initialize cattle client
c, err = NewCattleClientFromEnvironment()
if err != nil {
logrus.Fatalf("Failed to initialize Rancher API client: %v", err)
}
// initialize provider
provider, err = providers.GetProvider(*providerName)
if err != nil {
logrus.Fatalf("Failed to initialize provider '%s': %v", *providerName, err)
}
targetPoolSuffix = os.Getenv("LB_TARGET_RANCHER_SUFFIX")
if len(targetPoolSuffix) == 0 {
logrus.Info("LB_TARGET_RANCHER_SUFFIX is not set, using default suffix 'rancher.internal'")
targetPoolSuffix = "rancher.internal"
}
logrus.Debugf("version: %s", "0.2" )
}
func main() {
logrus.Infof("Starting Rancher External LoadBalancer service")
setEnv()
go startHealthcheck()
version := "init"
lastUpdated := time.Now()
ticker := time.NewTicker(time.Duration(pollInterval) * time.Millisecond)
defer ticker.Stop()
for range ticker.C {
update, updateForced := false, false
newVersion, err := m.GetVersion()
if err != nil {
logrus.Errorf("Failed to get metadata version: %v", err)
} else if version != newVersion {
logrus.Debugf("Metadata version changed. Old: %s New: %s.", version, newVersion)
version = newVersion
update = true
} else {
if time.Since(lastUpdated).Minutes() >= forceUpdateInterval {
logrus.Debugf("Executing force update as metadata version hasn't changed in: %d minutes",
forceUpdateInterval)
updateForced = true
}
}
if update || updateForced {
// get records from metadata
metadataLBConfigs, err := m.GetMetadataLBConfigs(targetPoolSuffix)
if err != nil {
logrus.Errorf("Failed to get LB configs from metadata: %v", err)
continue
}
logrus.Debugf("LB configs from metadata: %v", metadataLBConfigs)
// A flapping service might cause the metadata version to change
// in short intervals. Caching the previous LB Configs allows
// us to check if the actual LB Configs have changed, so we
// don't end up flooding the provider with unnecessary requests.
if !reflect.DeepEqual(metadataLBConfigs, metadataLBConfigsCached) || updateForced {
// update the provider
updatedFqdn, err := UpdateProviderLBConfigs(metadataLBConfigs)
if err != nil {
logrus.Errorf("Failed to update provider: %v", err)
}
// update the service FQDN in Cattle
for fqdn, config := range updatedFqdn {
// service_stack_environment_suffix
parts := strings.Split(config.LBTargetPoolName, "_")
err := c.UpdateServiceFqdn(parts[0], parts[1], fqdn)
if err != nil {
logrus.Errorf("Failed to update service FQDN: %v", err)
}
}
metadataLBConfigsCached = metadataLBConfigs
lastUpdated = time.Now()
} else {
logrus.Debugf("LB configs from metadata did not change")
}
}
}
}