aboutsummaryrefslogtreecommitdiffstats
path: root/src/monitor/cmd/manager/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/monitor/cmd/manager/main.go')
-rw-r--r--src/monitor/cmd/manager/main.go162
1 files changed, 162 insertions, 0 deletions
diff --git a/src/monitor/cmd/manager/main.go b/src/monitor/cmd/manager/main.go
new file mode 100644
index 00000000..dc41033e
--- /dev/null
+++ b/src/monitor/cmd/manager/main.go
@@ -0,0 +1,162 @@
+package main
+
+import (
+ "context"
+ "flag"
+ "fmt"
+ "os"
+ "runtime"
+
+ // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
+ _ "k8s.io/client-go/plugin/pkg/client/auth"
+ "k8s.io/client-go/rest"
+
+ "monitor/pkg/apis"
+ "monitor/pkg/controller"
+
+ "github.com/operator-framework/operator-sdk/pkg/k8sutil"
+ kubemetrics "github.com/operator-framework/operator-sdk/pkg/kube-metrics"
+ "github.com/operator-framework/operator-sdk/pkg/leader"
+ "github.com/operator-framework/operator-sdk/pkg/log/zap"
+ "github.com/operator-framework/operator-sdk/pkg/metrics"
+ "github.com/operator-framework/operator-sdk/pkg/restmapper"
+ sdkVersion "github.com/operator-framework/operator-sdk/version"
+ "github.com/spf13/pflag"
+ v1 "k8s.io/api/core/v1"
+ "k8s.io/apimachinery/pkg/util/intstr"
+ "sigs.k8s.io/controller-runtime/pkg/client/config"
+ "sigs.k8s.io/controller-runtime/pkg/manager"
+ logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
+ "sigs.k8s.io/controller-runtime/pkg/runtime/signals"
+)
+
+// Change below variables to serve metrics on different host or port.
+var (
+ metricsHost = "0.0.0.0"
+ metricsPort int32 = 8383
+ operatorMetricsPort int32 = 8686
+)
+var log = logf.Log.WithName("cmd")
+
+func printVersion() {
+ log.Info(fmt.Sprintf("Go Version: %s", runtime.Version()))
+ log.Info(fmt.Sprintf("Go OS/Arch: %s/%s", runtime.GOOS, runtime.GOARCH))
+ log.Info(fmt.Sprintf("Version of operator-sdk: %v", sdkVersion.Version))
+}
+
+func main() {
+ // Add the zap logger flag set to the CLI. The flag set must
+ // be added before calling pflag.Parse().
+ pflag.CommandLine.AddFlagSet(zap.FlagSet())
+
+ // Add flags registered by imported packages (e.g. glog and
+ // controller-runtime)
+ pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
+
+ pflag.Parse()
+
+ // Use a zap logr.Logger implementation. If none of the zap
+ // flags are configured (or if the zap flag set is not being
+ // used), this defaults to a production zap logger.
+ //
+ // The logger instantiated here can be changed to any logger
+ // implementing the logr.Logger interface. This logger will
+ // be propagated through the whole operator, generating
+ // uniform and structured logs.
+ logf.SetLogger(zap.Logger())
+
+ printVersion()
+
+ namespace, err := k8sutil.GetWatchNamespace()
+ if err != nil {
+ log.Error(err, "Failed to get watch namespace")
+ os.Exit(1)
+ }
+
+ // Get a config to talk to the apiserver
+ cfg, err := config.GetConfig()
+ if err != nil {
+ log.Error(err, "")
+ os.Exit(1)
+ }
+
+ ctx := context.TODO()
+ // Become the leader before proceeding
+ err = leader.Become(ctx, "monitor-lock")
+ if err != nil {
+ log.Error(err, "")
+ os.Exit(1)
+ }
+
+ // Create a new Cmd to provide shared dependencies and start components
+ mgr, err := manager.New(cfg, manager.Options{
+ Namespace: namespace,
+ MapperProvider: restmapper.NewDynamicRESTMapper,
+ MetricsBindAddress: fmt.Sprintf("%s:%d", metricsHost, metricsPort),
+ })
+ if err != nil {
+ log.Error(err, "")
+ os.Exit(1)
+ }
+
+ log.Info("Registering Components.")
+
+ // Setup Scheme for all resources
+ if err := apis.AddToScheme(mgr.GetScheme()); err != nil {
+ log.Error(err, "")
+ os.Exit(1)
+ }
+
+ // Setup all Controllers
+ if err := controller.AddToManager(mgr); err != nil {
+ log.Error(err, "")
+ os.Exit(1)
+ }
+
+ if err = serveCRMetrics(cfg); err != nil {
+ log.Info("Could not generate and serve custom resource metrics", "error", err.Error())
+ }
+
+ // Add to the below struct any other metrics ports you want to expose.
+ servicePorts := []v1.ServicePort{
+ {Port: metricsPort, Name: metrics.OperatorPortName, Protocol: v1.ProtocolTCP, TargetPort: intstr.IntOrString{Type: intstr.Int, IntVal: metricsPort}},
+ {Port: operatorMetricsPort, Name: metrics.CRPortName, Protocol: v1.ProtocolTCP, TargetPort: intstr.IntOrString{Type: intstr.Int, IntVal: operatorMetricsPort}},
+ }
+ // Create Service object to expose the metrics port(s).
+ _, err = metrics.CreateMetricsService(ctx, cfg, servicePorts)
+ if err != nil {
+ log.Info(err.Error())
+ }
+
+ log.Info("Starting the Cmd.")
+
+ // Start the Cmd
+ if err := mgr.Start(signals.SetupSignalHandler()); err != nil {
+ log.Error(err, "Manager exited non-zero")
+ os.Exit(1)
+ }
+}
+
+// serveCRMetrics gets the Operator/CustomResource GVKs and generates metrics based on those types.
+// It serves those metrics on "http://metricsHost:operatorMetricsPort".
+func serveCRMetrics(cfg *rest.Config) error {
+ // Below function returns filtered operator/CustomResource specific GVKs.
+ // For more control override the below GVK list with your own custom logic.
+ filteredGVK, err := k8sutil.GetGVKsFromAddToScheme(apis.AddToScheme)
+ if err != nil {
+ return err
+ }
+ // Get the namespace the operator is currently deployed in.
+ operatorNs, err := k8sutil.GetOperatorNamespace()
+ if err != nil {
+ return err
+ }
+ // To generate metrics in other namespaces, add the values below.
+ ns := []string{operatorNs}
+ // Generate and serve custom resource specific metrics.
+ err = kubemetrics.GenerateAndServeCRMetrics(cfg, ns, filteredGVK, metricsHost, operatorMetricsPort)
+ if err != nil {
+ return err
+ }
+ return nil
+}