/
main.go
124 lines (100 loc) · 3.59 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
// Copyright (c) 2020 Red Hat, Inc.
// Copyright Contributors to the Open Cluster Management project
package main
import (
"context"
"flag"
"fmt"
"os"
"runtime"
"time"
"github.com/go-logr/logr"
"github.com/jackc/pgx/v4/pgxpool"
"github.com/operator-framework/operator-sdk/pkg/log/zap"
"github.com/spf13/pflag"
"github.com/stolostron/hub-of-hubs-status-sync/pkg/dbsyncers"
// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
_ "k8s.io/client-go/plugin/pkg/client/auth"
ctrl "sigs.k8s.io/controller-runtime"
)
const (
metricsHost = "0.0.0.0"
metricsPort int32 = 8384
environmentVariableControllerNamespace = "POD_NAMESPACE"
environmentVariableDatabaseURL = "DATABASE_URL"
environmentVariableSyncInterval = "HOH_STATUS_SYNC_INTERVAL"
)
func printVersion(log logr.Logger) {
log.Info(fmt.Sprintf("Go Version: %s", runtime.Version()))
log.Info(fmt.Sprintf("Go OS/Arch: %s/%s", runtime.GOOS, runtime.GOARCH))
}
// function to handle defers with exit, see https://stackoverflow.com/a/27629493/553720.
func doMain() int {
pflag.CommandLine.AddFlagSet(zap.FlagSet())
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
pflag.Parse()
ctrl.SetLogger(zap.Logger())
log := ctrl.Log.WithName("cmd")
printVersion(log)
leaderElectionNamespace, found := os.LookupEnv(environmentVariableControllerNamespace)
if !found {
log.Error(nil, "Not found:", "environment variable", environmentVariableControllerNamespace)
return 1
}
databaseURL, found := os.LookupEnv(environmentVariableDatabaseURL)
if !found {
log.Error(nil, "Not found:", "environment variable", environmentVariableDatabaseURL)
return 1
}
syncIntervalString, found := os.LookupEnv(environmentVariableSyncInterval)
if !found {
log.Error(nil, "Not found:", "environment variable", environmentVariableSyncInterval)
return 1
}
syncInterval, err := time.ParseDuration(syncIntervalString)
if err != nil {
log.Error(err, "the environment var ", environmentVariableSyncInterval, " is not valid duration")
return 1
}
// when switched to controller runtime 0.7, use the context returned by ctrl.SetupSignalHandler()
dbConnectionPool, err := pgxpool.Connect(context.TODO(), databaseURL)
if err != nil {
log.Error(err, "Failed to connect to the database")
return 1
}
defer dbConnectionPool.Close()
mgr, err := createManager(leaderElectionNamespace, metricsHost, metricsPort, dbConnectionPool, syncInterval)
if err != nil {
log.Error(err, "Failed to create manager")
return 1
}
log.Info("Starting the Cmd.")
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
log.Error(err, "Manager exited non-zero")
return 1
}
return 0
}
func createManager(leaderElectionNamespace, metricsHost string, metricsPort int32, dbConnectionPool *pgxpool.Pool,
syncInterval time.Duration) (ctrl.Manager, error) {
options := ctrl.Options{
MetricsBindAddress: fmt.Sprintf("%s:%d", metricsHost, metricsPort),
LeaderElection: true,
LeaderElectionID: "hub-of-hubs-status-sync-lock",
LeaderElectionNamespace: leaderElectionNamespace,
}
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), options)
if err != nil {
return nil, fmt.Errorf("failed to create a new manager: %w", err)
}
if err := dbsyncers.AddToScheme(mgr.GetScheme()); err != nil {
return nil, fmt.Errorf("failed to add schemes: %w", err)
}
if err := dbsyncers.AddDBSyncers(mgr, dbConnectionPool, syncInterval); err != nil {
return nil, fmt.Errorf("failed to add db syncers: %w", err)
}
return mgr, nil
}
func main() {
os.Exit(doMain())
}