forked from spotahome/kooper
/
main.go
125 lines (106 loc) · 3.03 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
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
"time"
"github.com/snebel29/kooper/client/crd"
applogger "github.com/snebel29/kooper/log"
apiextensionscli "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
"k8s.io/client-go/kubernetes"
_ "k8s.io/client-go/plugin/pkg/client/auth"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
podtermk8scli "github.com/snebel29/kooper/examples/pod-terminator-operator/client/k8s/clientset/versioned"
"github.com/snebel29/kooper/examples/pod-terminator-operator/log"
"github.com/snebel29/kooper/examples/pod-terminator-operator/operator"
)
// Main is the main program.
type Main struct {
flags *Flags
config operator.Config
logger log.Logger
}
// New returns the main application.
func New(logger log.Logger) *Main {
f := NewFlags()
return &Main{
flags: f,
config: f.OperatorConfig(),
logger: logger,
}
}
// Run runs the app.
func (m *Main) Run(stopC <-chan struct{}) error {
m.logger.Infof("initializing pod termination operator")
// Get kubernetes rest client.
ptCli, crdCli, k8sCli, err := m.getKubernetesClients()
if err != nil {
return err
}
// Create the operator and run
op, err := operator.New(m.config, ptCli, crdCli, k8sCli, m.logger)
if err != nil {
return err
}
return op.Run(stopC)
}
// getKubernetesClients returns all the required clients to communicate with
// kubernetes cluster: CRD type client, pod terminator types client, kubernetes core types client.
func (m *Main) getKubernetesClients() (podtermk8scli.Interface, crd.Interface, kubernetes.Interface, error) {
var err error
var cfg *rest.Config
// If devel mode then use configuration flag path.
if m.flags.Development {
cfg, err = clientcmd.BuildConfigFromFlags("", m.flags.KubeConfig)
if err != nil {
return nil, nil, nil, fmt.Errorf("could not load configuration: %s", err)
}
} else {
cfg, err = rest.InClusterConfig()
if err != nil {
return nil, nil, nil, fmt.Errorf("error loading kubernetes configuration inside cluster, check app is running outside kubernetes cluster or run in development mode: %s", err)
}
}
// Create clients.
k8sCli, err := kubernetes.NewForConfig(cfg)
if err != nil {
return nil, nil, nil, err
}
// App CRD k8s types client.
ptCli, err := podtermk8scli.NewForConfig(cfg)
if err != nil {
return nil, nil, nil, err
}
// CRD cli.
aexCli, err := apiextensionscli.NewForConfig(cfg)
if err != nil {
return nil, nil, nil, err
}
crdCli := crd.NewClient(aexCli, m.logger)
return ptCli, crdCli, k8sCli, nil
}
func main() {
logger := &applogger.Std{}
stopC := make(chan struct{})
finishC := make(chan error)
signalC := make(chan os.Signal, 1)
signal.Notify(signalC, syscall.SIGTERM, syscall.SIGINT)
m := New(logger)
// Run in background the operator.
go func() {
finishC <- m.Run(stopC)
}()
select {
case err := <-finishC:
if err != nil {
fmt.Fprintf(os.Stderr, "error running operator: %s", err)
os.Exit(1)
}
case <-signalC:
logger.Infof("Signal captured, exiting...")
}
close(stopC)
time.Sleep(5 * time.Second)
}