github.com/operator-framework/operator-lifecycle-manager@v0.30.0/cmd/olm/main.go (about) 1 package main 2 3 import ( 4 "context" 5 "flag" 6 "fmt" 7 "net/http" 8 "os" 9 "strings" 10 "time" 11 12 configclientset "github.com/openshift/client-go/config/clientset/versioned" 13 configv1client "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1" 14 "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/validatingroundtripper" 15 "github.com/sirupsen/logrus" 16 "github.com/spf13/pflag" 17 corev1 "k8s.io/api/core/v1" 18 "k8s.io/client-go/metadata" 19 "k8s.io/klog" 20 ctrl "sigs.k8s.io/controller-runtime" 21 22 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned" 23 "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/olm" 24 "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/openshift" 25 "github.com/operator-framework/operator-lifecycle-manager/pkg/feature" 26 "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient" 27 "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorstatus" 28 "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/queueinformer" 29 "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/server" 30 "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/signals" 31 "github.com/operator-framework/operator-lifecycle-manager/pkg/metrics" 32 olmversion "github.com/operator-framework/operator-lifecycle-manager/pkg/version" 33 ) 34 35 const ( 36 defaultWakeupInterval = 5 * time.Minute 37 defaultOperatorName = "" 38 defaultPackageServerStatusName = "" 39 ) 40 41 // config flags defined globally so that they appear on the test binary as well 42 var ( 43 wakeupInterval = pflag.Duration( 44 "interval", defaultWakeupInterval, "wake up interval") 45 46 watchedNamespaces = pflag.String( 47 "watchedNamespaces", "", "comma separated list of namespaces for olm operator to watch. "+ 48 "If not set, or set to the empty string (e.g. `-watchedNamespaces=\"\"`), "+ 49 "olm operator will watch all namespaces in the cluster.") 50 51 writeStatusName = pflag.String( 52 "writeStatusName", defaultOperatorName, "ClusterOperator name in which to write status, set to \"\" to disable.") 53 54 writePackageServerStatusName = pflag.String( 55 "writePackageServerStatusName", defaultPackageServerStatusName, "ClusterOperator name in which to write status for package API server, set to \"\" to disable.") 56 57 debug = pflag.Bool( 58 "debug", false, "use debug log level") 59 60 version = pflag.Bool("version", false, "displays olm version") 61 62 tlsKeyPath = pflag.String( 63 "tls-key", "", "Path to use for private key (requires tls-cert)") 64 65 protectedCopiedCSVNamespaces = pflag.String("protectedCopiedCSVNamespaces", 66 "", "A comma-delimited set of namespaces where global Copied CSVs will always appear, even if Copied CSVs are disabled") 67 68 tlsCertPath = pflag.String( 69 "tls-cert", "", "Path to use for certificate key (requires tls-key)") 70 71 _ = pflag.Bool("profiling", false, "deprecated") 72 73 clientCAPath = pflag.String("client-ca", "", "path to watch for client ca bundle") 74 75 namespace = pflag.String( 76 "namespace", "", "namespace where cleanup runs") 77 ) 78 79 func init() { 80 metrics.RegisterOLM() 81 82 // Add feature gates before parsing 83 feature.AddFlag(pflag.CommandLine) 84 } 85 86 // main function - entrypoint to OLM operator 87 func main() { 88 // Get exit signal context 89 ctx, cancel := context.WithCancel(signals.Context()) 90 defer cancel() 91 92 klogFlags := flag.NewFlagSet("klog", flag.ExitOnError) 93 klog.InitFlags(klogFlags) 94 95 pflag.Parse() 96 97 // Parse the command-line flags. 98 99 // Check if version flag was set 100 if *version { 101 fmt.Print(olmversion.String()) 102 103 // Exit early 104 os.Exit(0) 105 } 106 107 // `namespaces` will always contain at least one entry: if `*watchedNamespaces` is 108 // the empty string, the resulting array will be `[]string{""}`. 109 namespaces := strings.Split(*watchedNamespaces, ",") 110 for _, ns := range namespaces { 111 if ns == corev1.NamespaceAll { 112 namespaces = []string{corev1.NamespaceAll} 113 break 114 } 115 } 116 117 // Set log level to debug if `debug` flag set 118 logger := logrus.New() 119 if *debug { 120 logger.SetLevel(logrus.DebugLevel) 121 klogVerbosity := klogFlags.Lookup("v") 122 klogVerbosity.Value.Set("99") 123 } 124 logger.Infof("log level %s", logger.Level) 125 126 listenAndServe, err := server.GetListenAndServeFunc(server.WithLogger(logger), server.WithTLS(tlsCertPath, tlsKeyPath, clientCAPath), server.WithDebug(*debug)) 127 if err != nil { 128 logger.Fatalf("Error setting up health/metric/pprof service: %v", err) 129 } 130 131 go func() { 132 if err := listenAndServe(); err != nil && err != http.ErrServerClosed { 133 logger.Error(err) 134 } 135 }() 136 137 mgr, err := Manager(ctx, *debug) 138 if err != nil { 139 logger.WithError(err).Fatal("error configuring controller manager") 140 } 141 config := mgr.GetConfig() 142 143 // create a config that validates we're creating objects with labels 144 validatingConfig := validatingroundtripper.Wrap(config) 145 146 versionedConfigClient, err := configclientset.NewForConfig(config) 147 if err != nil { 148 logger.WithError(err).Fatal("error configuring openshift proxy client") 149 } 150 configClient, err := configv1client.NewForConfig(config) 151 if err != nil { 152 logger.WithError(err).Fatal("error configuring config client") 153 } 154 opClient, err := operatorclient.NewClientFromRestConfig(validatingConfig) 155 if err != nil { 156 logger.WithError(err).Fatal("error configuring operator client") 157 } 158 crClient, err := versioned.NewForConfig(config) 159 if err != nil { 160 logger.WithError(err).Fatal("error configuring custom resource client") 161 } 162 metadataClient, err := metadata.NewForConfig(config) 163 if err != nil { 164 logger.WithError(err).Fatal("error configuring metadata client") 165 } 166 167 // Create a new instance of the operator. 168 op, err := olm.NewOperator( 169 ctx, 170 olm.WithLogger(logger), 171 olm.WithWatchedNamespaces(namespaces...), 172 olm.WithResyncPeriod(queueinformer.ResyncWithJitter(*wakeupInterval, 0.2)), 173 olm.WithExternalClient(crClient), 174 olm.WithMetadataClient(metadataClient), 175 olm.WithOperatorClient(opClient), 176 olm.WithRestConfig(validatingConfig), 177 olm.WithConfigClient(versionedConfigClient), 178 olm.WithProtectedCopiedCSVNamespaces(*protectedCopiedCSVNamespaces), 179 ) 180 if err != nil { 181 logger.WithError(err).Fatal("error configuring operator") 182 return 183 } 184 185 op.Run(ctx) 186 <-op.Ready() 187 188 // Emit CSV metric 189 if err = op.EnsureCSVMetric(); err != nil { 190 logger.WithError(err).Fatal("error emitting metrics for existing CSV") 191 } 192 193 if *writeStatusName != "" { 194 reconciler, err := openshift.NewClusterOperatorReconciler( 195 openshift.WithClient(mgr.GetClient()), 196 openshift.WithScheme(mgr.GetScheme()), 197 openshift.WithLog(ctrl.Log.WithName("controllers").WithName("clusteroperator")), 198 openshift.WithName(*writeStatusName), 199 openshift.WithNamespace(*namespace), 200 openshift.WithSyncChannel(op.AtLevel()), 201 openshift.WithOLMOperator(), 202 ) 203 if err != nil { 204 logger.WithError(err).Fatal("error configuring openshift integration") 205 return 206 } 207 208 if err := reconciler.SetupWithManager(mgr); err != nil { 209 logger.WithError(err).Fatal("error configuring openshift integration") 210 return 211 } 212 } 213 214 if *writePackageServerStatusName != "" { 215 logger.Info("Initializing cluster operator monitor for package server") 216 217 names := *writePackageServerStatusName 218 discovery := opClient.KubernetesInterface().Discovery() 219 monitor, sender := operatorstatus.NewMonitor(logger, discovery, configClient, names) 220 221 handler := operatorstatus.NewCSVWatchNotificationHandler(logger, op.GetCSVSetGenerator(), op.GetReplaceFinder(), sender) 222 op.RegisterCSVWatchNotification(handler) 223 224 go monitor.Run(op.Done()) 225 } 226 227 // Start the controller manager 228 if err := mgr.Start(ctx); err != nil { 229 logger.WithError(err).Fatal("controller manager stopped") 230 } 231 232 <-op.Done() 233 }