generated from SAP/repository-template
/
main.go
159 lines (138 loc) · 4.31 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
152
153
154
155
156
157
158
159
/*
SPDX-FileCopyrightText: 2023 SAP SE or an SAP affiliate company and clustersecret-operator contributors
SPDX-License-Identifier: Apache-2.0
*/
package main
import (
"context"
"flag"
"io/ioutil"
"log"
"os"
"time"
"github.com/google/uuid"
"github.com/spf13/pflag"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/tools/leaderelection"
"k8s.io/client-go/tools/leaderelection/resourcelock"
"k8s.io/klog/v2"
"github.com/sap/clustersecret-operator/internal/controller"
coreclients "github.com/sap/clustersecret-operator/pkg/client/clientset/versioned"
)
var (
kubeconfig string
leaseNamespace string
leaseName string
leaseId string
)
func main() {
// initialize stderr logger
errlog := log.New(os.Stderr, "", 0)
// parse flags
pflag.StringVar(&kubeconfig, "kubeconfig", "", "Path to a kubeconfig. Only required/allowed if running out-of-cluster")
pflag.StringVar(&leaseNamespace, "lease_namespace", "", "Lease namespace. Required if running out-of-cluster; otherwise defaults to controller's namespace")
pflag.StringVar(&leaseName, "lease_name", "", "Lease name. Required")
pflag.StringVar(&leaseId, "lease_id", "", "Lease ID. Optional; if unspecified, a unique ID will be generated")
klog.InitFlags(nil)
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
pflag.CommandLine.SortFlags = false
pflag.Parse()
// check if running in-cluster or out-of-cluster
inCluster, namespace, err := checkIfRunningInCluster()
if err != nil {
klog.Fatalf("error checking whether running in-cluster or out-of-cluster: %s", err)
}
// use fallback from environment for certain flags
if kubeconfig == "" {
kubeconfig = os.Getenv("KUBECONFIG")
}
// check/default flags
if inCluster && kubeconfig != "" {
errlog.Fatal("flag --kubeconfig not allowed when running in-cluster")
}
if leaseNamespace == "" {
leaseNamespace = namespace
}
if leaseNamespace == "" {
errlog.Fatal("flag --lease_namespace empty or not provided; required if running out-of-cluster")
}
if leaseName == "" {
errlog.Fatal("flag --lease_name empty or not provided")
}
if leaseId == "" {
leaseId = uuid.New().String()
}
// setup api clients
cfg, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
if err != nil {
errlog.Fatalf("error building kubeconfig: %s", err)
}
kubeclient, err := kubernetes.NewForConfig(cfg)
if err != nil {
klog.Fatalf("error building kubernetes client: %s", err)
}
coreclient, err := coreclients.NewForConfig(cfg)
if err != nil {
klog.Fatalf("error building core client: %s", err)
}
// create main context
ctx, cancel := context.WithCancel(context.Background())
// create controller
controller := controller.NewController(ctx, kubeclient, coreclient, nil)
// trying to become leader
leaderelection.RunOrDie(
ctx,
leaderelection.LeaderElectionConfig{
Lock: &resourcelock.LeaseLock{
LeaseMeta: metav1.ObjectMeta{
Name: leaseName,
Namespace: leaseNamespace,
},
Client: kubeclient.CoordinationV1(),
LockConfig: resourcelock.ResourceLockConfig{
Identity: leaseId,
},
},
ReleaseOnCancel: false,
LeaseDuration: 15 * time.Second,
RenewDeadline: 10 * time.Second,
RetryPeriod: 2 * time.Second,
Callbacks: leaderelection.LeaderCallbacks{
OnStartedLeading: func(ctx context.Context) {
klog.Infof("successfully acquired leadership (my id: %s); starting controller", leaseId)
controller.Start()
},
OnStoppedLeading: func() {
klog.Infof("stopped leading (my id: %s)", leaseId)
cancel()
controller.Wait()
},
OnNewLeader: func(identity string) {
if identity == leaseId {
return
}
klog.Infof("observed new leader (my id: %s, new leader id: %s); waiting to become leader", leaseId, identity)
},
},
},
)
// exit
klog.Info("exiting")
}
func checkIfRunningInCluster() (bool, string, error) {
if _, err := os.Stat("/var/run/secrets/kubernetes.io/serviceaccount/namespace"); err == nil {
// running in-cluster
if raw, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace"); err == nil {
return true, string(raw), nil
} else {
return false, "", err
}
} else if os.IsNotExist(err) {
// running out-of-cluster
return false, "", nil
} else {
return false, "", err
}
}