forked from kobolog/gorb
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.go
135 lines (108 loc) · 4.42 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
/*
Copyright (c) 2015 Andrey Sibiryov <[email protected]>
Copyright (c) 2015 Other contributors as noted in the AUTHORS file.
This file is part of GORB - Go Routing and Balancing.
GORB is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
GORB is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package main
import (
"flag"
"fmt"
"net"
"net/http"
"os"
"github.com/qk4l/gorb/core"
"github.com/qk4l/gorb/util"
"github.com/gorilla/mux"
log "github.com/sirupsen/logrus"
_ "net/http/pprof"
"strings"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
var (
// Version get dynamically set to git rev by ldflags at build time
Version = "0.3.0"
debug = flag.Bool("v", false, "enable verbose output")
device = flag.String("i", "eth0", "default interface to bind services on")
flush = flag.Bool("f", false, "flush IPVS pools on start")
listen = flag.String("l", ":4672", "endpoint to listen for HTTP requests")
consul = flag.String("c", "", "URL for Consul HTTP API")
vipInterface = flag.String("vipi", "", "interface to add VIPs")
storeURLs = flag.String("store", "", "comma delimited list of store urls for sync data. All urls must have"+
" identical schemes and paths.")
storeUseTLS = flag.Bool("store-use-tls", false, "Use TLS to connect to store backend")
storeSyncTime = flag.Int64("store-sync-time", 60, "sync-time for store")
storeServicePath = flag.String("store-service-path", "services", "store service path")
storeBackendPath = flag.String("store-backend-path", "backends", "store backend path")
)
func main() {
// Called first to interrupt bootstrap and display usage if the user passed -h.
flag.Parse()
if *debug {
log.SetLevel(log.DebugLevel)
}
log.Info("starting GORB Daemon v" + Version)
if os.Geteuid() != 0 {
log.Fatalf("this program has to be run with root priveleges to access IPVS")
}
hostIPs, err := util.InterfaceIPs(*device)
if err != nil {
log.Fatalf("error while obtaining interface addresses: %s", err)
}
listenAddr, err := net.ResolveTCPAddr("tcp", *listen)
listenPort := uint16(0)
if err != nil {
log.Fatalf("error while obtaining listening port from '%s': %s", *listen, err)
} else {
listenPort = uint16(listenAddr.Port)
}
if *debug {
go func() {
log.Println(http.ListenAndServe(fmt.Sprintf("%s:6061", listenAddr.IP), nil))
}()
}
ctx, err := core.NewContext(core.ContextOptions{
Disco: *consul,
Endpoints: hostIPs,
Flush: *flush,
ListenPort: listenPort,
VipInterface: *vipInterface})
if err != nil {
log.Fatalf("error while initializing server context: %s", err)
}
// While it's not strictly required, close IPVS socket explicitly.
defer ctx.Close()
var store *core.Store
// sync with external store
if storeURLs != nil && len(*storeURLs) > 0 {
urls := strings.Split(*storeURLs, ",")
store, err = core.NewStore(urls, *storeServicePath, *storeBackendPath, *storeSyncTime, *storeUseTLS, ctx)
if err != nil {
log.Fatalf("error while initializing external store sync: %s", err)
}
defer store.Close()
}
core.RegisterPrometheusExporter(ctx)
r := mux.NewRouter()
r.Handle("/service/{vsID}", serviceCreateHandler{ctx}).Methods("PUT")
r.Handle("/service/{vsID}/{rsID}", backendCreateHandler{ctx}).Methods("PUT")
r.Handle("/service/{vsID}", serviceRemoveHandler{ctx}).Methods("DELETE")
r.Handle("/service/{vsID}/{rsID}", backendRemoveHandler{ctx}).Methods("DELETE")
r.Handle("/service", serviceListHandler{ctx}).Methods("GET")
r.Handle("/service/{vsID}", serviceStatusHandler{ctx}).Methods("GET")
r.Handle("/service/{vsID}/{rsID}", backendStatusHandler{ctx}).Methods("GET")
r.Handle("/store/sync", storeSyncHandler{store}).Methods("GET")
r.Handle("/store/sync/status", storeSyncStatusHandler{store}).Methods("GET")
r.Handle("/metrics", promhttp.Handler()).Methods("GET")
log.Infof("setting up HTTP server on %s", *listen)
log.Fatal(http.ListenAndServe(*listen, r))
}