Upgrade operator-sdk bump version to 0.9.0
[demo.git] / vnfs / DAaaS / microservices / collectd-operator / cmd / manager / main.go
1 package main
2
3 import (
4         "context"
5         "flag"
6         "fmt"
7         "os"
8         "runtime"
9
10         // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
11         _ "k8s.io/client-go/plugin/pkg/client/auth"
12         "k8s.io/client-go/rest"
13
14         "collectd-operator/pkg/apis"
15         "collectd-operator/pkg/controller"
16
17         "github.com/operator-framework/operator-sdk/pkg/k8sutil"
18         kubemetrics "github.com/operator-framework/operator-sdk/pkg/kube-metrics"
19         "github.com/operator-framework/operator-sdk/pkg/leader"
20         "github.com/operator-framework/operator-sdk/pkg/log/zap"
21         "github.com/operator-framework/operator-sdk/pkg/metrics"
22         "github.com/operator-framework/operator-sdk/pkg/restmapper"
23         sdkVersion "github.com/operator-framework/operator-sdk/version"
24         "github.com/spf13/pflag"
25         v1 "k8s.io/api/core/v1"
26         "k8s.io/apimachinery/pkg/util/intstr"
27         "sigs.k8s.io/controller-runtime/pkg/client/config"
28         "sigs.k8s.io/controller-runtime/pkg/manager"
29         logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
30         "sigs.k8s.io/controller-runtime/pkg/runtime/signals"
31 )
32
33 // Change below variables to serve metrics on different host or port.
34 var (
35         metricsHost               = "0.0.0.0"
36         metricsPort         int32 = 8383
37         operatorMetricsPort int32 = 8686
38 )
39 var log = logf.Log.WithName("cmd")
40
41 func printVersion() {
42         log.Info(fmt.Sprintf("Go Version: %s", runtime.Version()))
43         log.Info(fmt.Sprintf("Go OS/Arch: %s/%s", runtime.GOOS, runtime.GOARCH))
44         log.Info(fmt.Sprintf("Version of operator-sdk: %v", sdkVersion.Version))
45 }
46
47 func main() {
48         // Add the zap logger flag set to the CLI. The flag set must
49         // be added before calling pflag.Parse().
50         pflag.CommandLine.AddFlagSet(zap.FlagSet())
51
52         // Add flags registered by imported packages (e.g. glog and
53         // controller-runtime)
54         pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
55
56         pflag.Parse()
57
58         // Use a zap logr.Logger implementation. If none of the zap
59         // flags are configured (or if the zap flag set is not being
60         // used), this defaults to a production zap logger.
61         //
62         // The logger instantiated here can be changed to any logger
63         // implementing the logr.Logger interface. This logger will
64         // be propagated through the whole operator, generating
65         // uniform and structured logs.
66         logf.SetLogger(zap.Logger())
67
68         printVersion()
69
70         namespace, err := k8sutil.GetWatchNamespace()
71         if err != nil {
72                 log.Error(err, "Failed to get watch namespace")
73                 os.Exit(1)
74         }
75
76         // Get a config to talk to the apiserver
77         cfg, err := config.GetConfig()
78         if err != nil {
79                 log.Error(err, "")
80                 os.Exit(1)
81         }
82
83         ctx := context.TODO()
84         // Become the leader before proceeding
85         err = leader.Become(ctx, "collectd-operator-lock")
86         if err != nil {
87                 log.Error(err, "")
88                 os.Exit(1)
89         }
90
91         // Create a new Cmd to provide shared dependencies and start components
92         mgr, err := manager.New(cfg, manager.Options{
93                 Namespace:          namespace,
94                 MapperProvider:     restmapper.NewDynamicRESTMapper,
95                 MetricsBindAddress: fmt.Sprintf("%s:%d", metricsHost, metricsPort),
96         })
97         if err != nil {
98                 log.Error(err, "")
99                 os.Exit(1)
100         }
101
102         log.Info("Registering Components.")
103
104         // Setup Scheme for all resources
105         if err := apis.AddToScheme(mgr.GetScheme()); err != nil {
106                 log.Error(err, "")
107                 os.Exit(1)
108         }
109
110         // Setup all Controllers
111         if err := controller.AddToManager(mgr); err != nil {
112                 log.Error(err, "")
113                 os.Exit(1)
114         }
115
116         if err = serveCRMetrics(cfg); err != nil {
117                 log.Info("Could not generate and serve custom resource metrics", "error", err.Error())
118         }
119
120         // Add to the below struct any other metrics ports you want to expose.
121         servicePorts := []v1.ServicePort{
122                 {Port: metricsPort, Name: metrics.OperatorPortName, Protocol: v1.ProtocolTCP, TargetPort: intstr.IntOrString{Type: intstr.Int, IntVal: metricsPort}},
123                 {Port: operatorMetricsPort, Name: metrics.CRPortName, Protocol: v1.ProtocolTCP, TargetPort: intstr.IntOrString{Type: intstr.Int, IntVal: operatorMetricsPort}},
124         }
125         // Create Service object to expose the metrics port(s).
126         _, err = metrics.CreateMetricsService(ctx, cfg, servicePorts)
127         if err != nil {
128                 log.Info(err.Error())
129         }
130
131         log.Info("Starting the Cmd.")
132
133         // Start the Cmd
134         if err := mgr.Start(signals.SetupSignalHandler()); err != nil {
135                 log.Error(err, "Manager exited non-zero")
136                 os.Exit(1)
137         }
138 }
139
140 // serveCRMetrics gets the Operator/CustomResource GVKs and generates metrics based on those types.
141 // It serves those metrics on "http://metricsHost:operatorMetricsPort".
142 func serveCRMetrics(cfg *rest.Config) error {
143         // Below function returns filtered operator/CustomResource specific GVKs.
144         // For more control override the below GVK list with your own custom logic.
145         filteredGVK, err := k8sutil.GetGVKsFromAddToScheme(apis.AddToScheme)
146         if err != nil {
147                 return err
148         }
149         // Get the namespace the operator is currently deployed in.
150         operatorNs, err := k8sutil.GetOperatorNamespace()
151         if err != nil {
152                 return err
153         }
154         // To generate metrics in other namespaces, add the values below.
155         ns := []string{operatorNs}
156         // Generate and serve custom resource specific metrics.
157         err = kubemetrics.GenerateAndServeCRMetrics(cfg, ns, filteredGVK, metricsHost, operatorMetricsPort)
158         if err != nil {
159                 return err
160         }
161         return nil
162 }