...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package main
17
18 import (
19 "flag"
20 stdlog "log"
21 "net/http"
22 _ "net/http/pprof"
23 "os"
24
25 "github.com/99designs/gqlgen/graphql/handler"
26 "github.com/99designs/gqlgen/graphql/playground"
27 fxlogr "github.com/chaos-mesh/fx-logr"
28 "github.com/go-logr/logr"
29 "go.uber.org/fx"
30 authorizationv1 "k8s.io/client-go/kubernetes/typed/authorization/v1"
31 _ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
32 ctrl "sigs.k8s.io/controller-runtime"
33 controllermetrics "sigs.k8s.io/controller-runtime/pkg/metrics"
34 "sigs.k8s.io/controller-runtime/pkg/webhook"
35
36 "github.com/chaos-mesh/chaos-mesh/api/v1alpha1"
37 "github.com/chaos-mesh/chaos-mesh/cmd/chaos-controller-manager/provider"
38 "github.com/chaos-mesh/chaos-mesh/controllers"
39 ccfg "github.com/chaos-mesh/chaos-mesh/controllers/config"
40 "github.com/chaos-mesh/chaos-mesh/controllers/types"
41 "github.com/chaos-mesh/chaos-mesh/controllers/utils/chaosdaemon"
42 ctrlserver "github.com/chaos-mesh/chaos-mesh/pkg/ctrl"
43 grpcUtils "github.com/chaos-mesh/chaos-mesh/pkg/grpc"
44 "github.com/chaos-mesh/chaos-mesh/pkg/log"
45 "github.com/chaos-mesh/chaos-mesh/pkg/metrics"
46 "github.com/chaos-mesh/chaos-mesh/pkg/selector"
47 "github.com/chaos-mesh/chaos-mesh/pkg/version"
48 apiWebhook "github.com/chaos-mesh/chaos-mesh/pkg/webhook"
49 )
50
51 var (
52 printVersion bool
53
54
55 setupLog = ctrl.Log.WithName("setup")
56 )
57
58 func parseFlags() {
59 flag.BoolVar(&printVersion, "version", false, "print version information and exit")
60 flag.Parse()
61 }
62
63 func main() {
64 parseFlags()
65 version.PrintVersionInfo("Controller manager")
66 if printVersion {
67 os.Exit(0)
68 }
69
70 rootLogger, err := log.NewDefaultZapLogger()
71 if err != nil {
72 stdlog.Fatal("failed to create root logger", err)
73 }
74 log.ReplaceGlobals(rootLogger)
75 ctrl.SetLogger(rootLogger)
76 fxLogger := rootLogger.WithName("fx")
77
78
79 grpcUtils.RPCTimeout = ccfg.ControllerCfg.RPCTimeout
80 app := fx.New(
81 fx.WithLogger(fxlogr.WithLogr(&fxLogger)),
82 fx.Supply(controllermetrics.Registry),
83 fx.Supply(rootLogger),
84 fx.Provide(metrics.NewChaosControllerManagerMetricsCollector),
85 fx.Provide(ctrlserver.New),
86 fx.Options(
87 provider.Module,
88 controllers.Module,
89 selector.Module,
90 types.ChaosObjects,
91 types.WebhookObjects,
92 ),
93 fx.Invoke(Run),
94 )
95
96 app.Run()
97 }
98
99
100 type RunParams struct {
101 fx.In
102
103 Mgr ctrl.Manager
104
105 Logger logr.Logger
106
107 AuthCli *authorizationv1.AuthorizationV1Client
108
109 DaemonClientBuilder *chaosdaemon.ChaosDaemonClientBuilder
110
111 MetricsCollector *metrics.ChaosControllerManagerMetricsCollector
112
113 CtrlServer *handler.Server
114
115
116 Objs []types.Object `group:"objs"`
117
118 WebhookObjs []types.WebhookObject `group:"webhookObjs"`
119 }
120
121
122
123
124 func Run(params RunParams) error {
125 mgr := params.Mgr
126 authCli := params.AuthCli
127
128 var err error
129 for _, obj := range params.Objs {
130 if !ccfg.ShouldStartWebhook(obj.Name) {
131 continue
132 }
133
134 err = ctrl.NewWebhookManagedBy(mgr).
135 For(obj.Object).
136 Complete()
137 if err != nil {
138 return err
139 }
140 }
141
142 for _, obj := range params.WebhookObjs {
143 if !ccfg.ShouldStartWebhook(obj.Name) {
144 continue
145 }
146
147 err = ctrl.NewWebhookManagedBy(mgr).
148 For(obj.Object).
149 Complete()
150 if err != nil {
151 return err
152 }
153 }
154
155 if ccfg.ShouldStartWebhook("schedule") {
156
157 err = ctrl.NewWebhookManagedBy(mgr).
158 For(&v1alpha1.Schedule{}).
159 Complete()
160 if err != nil {
161 return err
162 }
163 }
164
165 if ccfg.ShouldStartWebhook("workflow") {
166 err = ctrl.NewWebhookManagedBy(mgr).
167 For(&v1alpha1.Workflow{}).
168 Complete()
169 if err != nil {
170 return err
171 }
172 }
173
174 setupLog.Info("Setting up webhook server")
175 hookServer := mgr.GetWebhookServer()
176
177 controllerRuntimeSignalHandler := ctrl.SetupSignalHandler()
178
179 if ccfg.ControllerCfg.PprofAddr != "0" {
180 go func() {
181 if err := http.ListenAndServe(ccfg.ControllerCfg.PprofAddr, nil); err != nil {
182 setupLog.Error(err, "unable to start pprof server")
183 os.Exit(1)
184 }
185 }()
186 }
187
188 if ccfg.ControllerCfg.CtrlAddr != "" {
189 go func() {
190 mutex := http.NewServeMux()
191 mutex.Handle("/", playground.Handler("GraphQL playground", "/query"))
192 mutex.Handle("/query", params.CtrlServer)
193 setupLog.Info("setup ctrlserver", "addr", ccfg.ControllerCfg.CtrlAddr)
194 setupLog.Error(http.ListenAndServe(ccfg.ControllerCfg.CtrlAddr, mutex), "unable to start ctrlserver")
195 }()
196 }
197
198 hookServer.Register("/validate-auth", &webhook.Admission{
199 Handler: apiWebhook.NewAuthValidator(ccfg.ControllerCfg.SecurityMode, authCli, mgr.GetScheme(),
200 ccfg.ControllerCfg.ClusterScoped, ccfg.ControllerCfg.TargetNamespace, ccfg.ControllerCfg.EnableFilterNamespace,
201 params.Logger.WithName("validate-auth"),
202 ),
203 },
204 )
205
206 setupLog.Info("Starting manager")
207 if err := mgr.Start(controllerRuntimeSignalHandler); err != nil {
208 setupLog.Error(err, "unable to start manager")
209
210 os.Exit(1)
211 }
212
213 return nil
214 }
215