github.com/nmstate/kubernetes-nmstate@v0.82.0/cmd/operator/main.go (about)

     1  /*
     2  Copyright The Kubernetes NMState Authors.
     3  
     4  
     5  Licensed under the Apache License, Version 2.0 (the "License");
     6  you may not use this file except in compliance with the License.
     7  You may obtain a copy of the License at
     8  
     9      http://www.apache.org/licenses/LICENSE-2.0
    10  
    11  Unless required by applicable law or agreed to in writing, software
    12  distributed under the License is distributed on an "AS IS" BASIS,
    13  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  See the License for the specific language governing permissions and
    15  limitations under the License.
    16  */
    17  
    18  package main
    19  
    20  import (
    21  	"flag"
    22  	"fmt"
    23  	"net/http"
    24  	"os"
    25  	"time"
    26  
    27  	"k8s.io/apimachinery/pkg/runtime"
    28  	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
    29  	clientgoscheme "k8s.io/client-go/kubernetes/scheme"
    30  	_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
    31  	ctrl "sigs.k8s.io/controller-runtime"
    32  	"sigs.k8s.io/controller-runtime/pkg/client"
    33  	"sigs.k8s.io/controller-runtime/pkg/log/zap"
    34  	"sigs.k8s.io/controller-runtime/pkg/manager"
    35  
    36  	// +kubebuilder:scaffold:imports
    37  
    38  	"github.com/kelseyhightower/envconfig"
    39  	"github.com/spf13/pflag"
    40  
    41  	openshiftconsolev1 "github.com/openshift/api/console/v1"
    42  	openshiftoperatorv1 "github.com/openshift/api/operator/v1"
    43  
    44  	nmstatev1 "github.com/nmstate/kubernetes-nmstate/api/v1"
    45  	nmstatev1alpha1 "github.com/nmstate/kubernetes-nmstate/api/v1alpha1"
    46  	nmstatev1beta1 "github.com/nmstate/kubernetes-nmstate/api/v1beta1"
    47  	controllers "github.com/nmstate/kubernetes-nmstate/controllers/operator"
    48  )
    49  
    50  type ProfilerConfig struct {
    51  	EnableProfiler bool   `envconfig:"ENABLE_PROFILER"`
    52  	ProfilerPort   string `envconfig:"PROFILER_PORT" default:"6060"`
    53  }
    54  
    55  var (
    56  	scheme   = runtime.NewScheme()
    57  	setupLog = ctrl.Log.WithName("setup")
    58  )
    59  
    60  func init() {
    61  	utilruntime.Must(clientgoscheme.AddToScheme(scheme))
    62  
    63  	utilruntime.Must(nmstatev1.AddToScheme(scheme))
    64  	utilruntime.Must(nmstatev1beta1.AddToScheme(scheme))
    65  	utilruntime.Must(nmstatev1alpha1.AddToScheme(scheme))
    66  	utilruntime.Must(openshiftoperatorv1.Install(scheme))
    67  	utilruntime.Must(openshiftconsolev1.Install(scheme))
    68  	// +kubebuilder:scaffold:scheme
    69  }
    70  
    71  func main() {
    72  	opt := zap.Options{}
    73  	opt.BindFlags(flag.CommandLine)
    74  	var logType string
    75  	pflag.StringVar(&logType, "v", "production", "Log type (debug/production).")
    76  	pflag.CommandLine.MarkDeprecated("v", "please use the --zap-devel flag for debug logging instead")
    77  	pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
    78  	pflag.Parse()
    79  
    80  	if logType == "debug" {
    81  		// workaround until --v flag got removed
    82  		flag.CommandLine.Set("zap-devel", "true")
    83  	}
    84  
    85  	ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opt)))
    86  
    87  	ctrlOptions := ctrl.Options{
    88  		Scheme:             scheme,
    89  		MetricsBindAddress: "0", // disable metrics
    90  	}
    91  
    92  	mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrlOptions)
    93  	if err != nil {
    94  		setupLog.Error(err, "unable to start manager")
    95  		os.Exit(1)
    96  	}
    97  
    98  	err = setupOperatorController(mgr)
    99  	if err != nil {
   100  		setupLog.Error(err, "unable to setup controller", "controller", "NMState")
   101  		os.Exit(1)
   102  	}
   103  
   104  	setProfiler()
   105  
   106  	setupLog.Info("starting manager")
   107  	if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
   108  		setupLog.Error(err, "problem running manager")
   109  		os.Exit(1)
   110  	}
   111  }
   112  
   113  func setupOperatorController(mgr manager.Manager) error {
   114  	apiClient, err := client.New(mgr.GetConfig(), client.Options{Scheme: mgr.GetScheme(), Mapper: mgr.GetRESTMapper()})
   115  	if err != nil {
   116  		return fmt.Errorf("failed creating non cached client: %w", err)
   117  	}
   118  
   119  	if err = (&controllers.NMStateReconciler{
   120  		Client:    mgr.GetClient(),
   121  		APIClient: apiClient,
   122  		Log:       ctrl.Log.WithName("controllers").WithName("NMState"),
   123  		Scheme:    mgr.GetScheme(),
   124  	}).SetupWithManager(mgr); err != nil {
   125  		return fmt.Errorf("failed creating NMState CR controller: %w", err)
   126  	}
   127  
   128  	return nil
   129  }
   130  
   131  // Start profiler on given port if ENABLE_PROFILER is True
   132  func setProfiler() {
   133  	cfg := ProfilerConfig{}
   134  	envconfig.Process("", &cfg)
   135  	if cfg.EnableProfiler {
   136  		setupLog.Info("Starting profiler")
   137  		go func() {
   138  			profilerAddress := fmt.Sprintf("0.0.0.0:%s", cfg.ProfilerPort)
   139  			setupLog.Info(fmt.Sprintf("Starting Profiler Server! \t Go to http://%s/debug/pprof/\n", profilerAddress))
   140  			server := &http.Server{ReadHeaderTimeout: 10 * time.Second, Addr: profilerAddress}
   141  			err := server.ListenAndServe()
   142  			if err != nil {
   143  				setupLog.Info("Failed to start the server! Error: %v", err)
   144  			}
   145  		}()
   146  	}
   147  }