/
main.go
115 lines (95 loc) · 2.82 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
package main
import (
"context"
"fmt"
"math/rand"
"os"
"os/signal"
"syscall"
"time"
"github.com/serverscom/serverscom-ingress-controller/internal/config"
"github.com/serverscom/serverscom-ingress-controller/internal/flags"
"github.com/serverscom/serverscom-ingress-controller/internal/ingress/controller"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/tools/leaderelection"
"k8s.io/client-go/tools/leaderelection/resourcelock"
"k8s.io/klog/v2"
)
var (
version string
gitCommit string
)
func main() {
klog.InitFlags(nil)
ctrlConf, err := flags.ParseFlags()
if err != nil {
klog.Fatal(err)
}
if ctrlConf.ShowVersion {
fmt.Printf("Version=%v GitCommit=%v\n", version, gitCommit)
os.Exit(0)
}
kubeClient, err := config.NewCubeClient("")
if err != nil {
klog.Fatalf(err.Error())
}
if ctrlConf.Namespace != "" {
_, err = kubeClient.CoreV1().Namespaces().Get(context.TODO(), ctrlConf.Namespace, metav1.GetOptions{})
if err != nil {
klog.Fatalf("No namespace with name %v found: %v", ctrlConf.Namespace, err)
}
}
ctrlConf.KubeClient = kubeClient
scClient, err := config.NewServerscomClient()
if err != nil {
klog.Fatal(err.Error())
}
scClient.SetupUserAgent(fmt.Sprintf("serverscom-ingress-controller/%s %s", version, gitCommit))
ic := controller.NewIngressController(ctrlConf, scClient, kubeClient)
hostname, err := os.Hostname()
if err != nil {
klog.Fatalf("unable to get hostname: %v", err)
}
id := fmt.Sprintf("%s_%d", hostname, rand.Intn(1e6))
lock := &resourcelock.LeaseLock{
LeaseMeta: metav1.ObjectMeta{
Name: config.DefaultLockObjectName,
Namespace: config.DefaultLockObjectNamespace,
},
Client: kubeClient.CoordinationV1(),
LockConfig: resourcelock.ResourceLockConfig{
Identity: id,
},
}
leConfig := leaderelection.LeaderElectionConfig{
Lock: lock,
LeaseDuration: ctrlConf.LeaderElectionCfg.LeaseDuration.Duration,
RenewDeadline: ctrlConf.LeaderElectionCfg.RenewDeadline.Duration,
RetryPeriod: ctrlConf.LeaderElectionCfg.RetryPeriod.Duration,
Callbacks: leaderelection.LeaderCallbacks{
OnStartedLeading: func(ctx context.Context) {
klog.Infof("%s starts leading", id)
stopCh := make(chan struct{})
defer close(stopCh)
go handleSigterm(ic, 5)
ic.Run(stopCh)
},
OnStoppedLeading: func() {
klog.Fatal("lost master")
},
},
}
leaderelection.RunOrDie(context.Background(), leConfig)
}
func handleSigterm(ic *controller.IngressController, delay int) {
signalChan := make(chan os.Signal, 1)
signal.Notify(signalChan, syscall.SIGTERM)
<-signalChan
klog.InfoS("Received SIGTERM, shutting down")
ic.Stop()
klog.Infof("Handled quit, delaying controller exit for %d seconds", delay)
time.Sleep(time.Duration(delay) * time.Second)
exitCode := 0
klog.Infof("Exiting with %v", exitCode)
os.Exit(exitCode)
}