@@ -17,27 +17,39 @@ limitations under the License.
1717package main
1818
1919import (
20+ "context"
2021 "crypto/tls"
2122 "flag"
23+ "fmt"
2224 "os"
2325 "path/filepath"
2426
2527 // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
2628 // to ensure that exec-entrypoint and run can make use of them.
2729 _ "k8s.io/client-go/plugin/pkg/client/auth"
30+ "k8s.io/client-go/rest"
31+
32+ apisv1alpha1 "github.com/kcp-dev/kcp/sdk/apis/apis/v1alpha1"
33+ "github.com/kcp-dev/multicluster-provider/virtualworkspace"
34+ mcbuilder "github.com/multicluster-runtime/multicluster-runtime/pkg/builder"
35+ mcmanager "github.com/multicluster-runtime/multicluster-runtime/pkg/manager"
36+ mcreconcile "github.com/multicluster-runtime/multicluster-runtime/pkg/reconcile"
2837
2938 "k8s.io/apimachinery/pkg/runtime"
3039 utilruntime "k8s.io/apimachinery/pkg/util/runtime"
3140 clientgoscheme "k8s.io/client-go/kubernetes/scheme"
3241 ctrl "sigs.k8s.io/controller-runtime"
3342 "sigs.k8s.io/controller-runtime/pkg/certwatcher"
3443 "sigs.k8s.io/controller-runtime/pkg/healthz"
44+ "sigs.k8s.io/controller-runtime/pkg/log"
3545 "sigs.k8s.io/controller-runtime/pkg/log/zap"
46+ "sigs.k8s.io/controller-runtime/pkg/manager/signals"
3647 "sigs.k8s.io/controller-runtime/pkg/metrics/filters"
3748 metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
49+ "sigs.k8s.io/controller-runtime/pkg/reconcile"
3850 "sigs.k8s.io/controller-runtime/pkg/webhook"
3951
40- apisv1alpha1 "github.com/kcp-dev/multicluster-provider/examples/crd/api/v1alpha1"
52+ applicationapisv1alpha1 "github.com/kcp-dev/multicluster-provider/examples/crd/api/v1alpha1"
4153 "github.com/kcp-dev/multicluster-provider/examples/crd/internal/controller"
4254 // +kubebuilder:scaffold:imports
4355)
4961
5062func init () {
5163 utilruntime .Must (clientgoscheme .AddToScheme (scheme ))
52-
64+ // MULTICLUSTER: This is where it differ from the default scaffold.
65+ utilruntime .Must (applicationapisv1alpha1 .AddToScheme (scheme ))
5366 utilruntime .Must (apisv1alpha1 .AddToScheme (scheme ))
5467 // +kubebuilder:scaffold:scheme
5568}
@@ -63,6 +76,7 @@ func main() {
6376 var probeAddr string
6477 var secureMetrics bool
6578 var enableHTTP2 bool
79+ var server string
6680 var tlsOpts []func (* tls.Config )
6781 flag .StringVar (& metricsAddr , "metrics-bind-address" , "0" , "The address the metrics endpoint binds to. " +
6882 "Use :8443 for HTTPS or :8080 for HTTP, or leave as 0 to disable the metrics service." )
@@ -81,6 +95,8 @@ func main() {
8195 flag .StringVar (& metricsCertKey , "metrics-cert-key" , "tls.key" , "The name of the metrics server key file." )
8296 flag .BoolVar (& enableHTTP2 , "enable-http2" , false ,
8397 "If set, HTTP/2 will be enabled for the metrics and webhook servers" )
98+ // MULTICLUSTER: This is where it differ from the default scaffold.
99+ flag .StringVar (& server , "server" , "" , "Override for kubeconfig server URL" )
84100 opts := zap.Options {
85101 Development : true ,
86102 }
@@ -178,7 +194,25 @@ func main() {
178194 })
179195 }
180196
181- mgr , err := ctrl .NewManager (ctrl .GetConfigOrDie (), ctrl.Options {
197+ // MULTICLUSTER: This is where it differ from the default scaffold.
198+ ctx := signals .SetupSignalHandler ()
199+
200+ cfg := ctrl .GetConfigOrDie ()
201+ cfg = rest .CopyConfig (cfg )
202+ if server != "" {
203+ cfg .Host = server
204+ }
205+
206+ var err error
207+ provider , err := virtualworkspace .New (cfg , & apisv1alpha1.APIBinding {}, virtualworkspace.Options {
208+ Scheme : scheme ,
209+ })
210+ if err != nil {
211+ setupLog .Error (err , "unable to construct cluster provider" )
212+ os .Exit (1 )
213+ }
214+
215+ mgr , err := mcmanager .New (cfg , provider , ctrl.Options {
182216 Scheme : scheme ,
183217 Metrics : metricsServerOptions ,
184218 WebhookServer : webhookServer ,
@@ -202,30 +236,48 @@ func main() {
202236 os .Exit (1 )
203237 }
204238
205- if err = (& controller.ApplicationReconciler {
206- Client : mgr .GetClient (),
207- Scheme : mgr .GetScheme (),
208- }).SetupWithManager (mgr ); err != nil {
239+ if err := mcbuilder .ControllerManagedBy (mgr ).
240+ Named ("kcp-applications-controller" ).
241+ For (& applicationapisv1alpha1.Application {}).
242+ Complete (mcreconcile .Func (
243+ func (ctx context.Context , req mcreconcile.Request ) (ctrl.Result , error ) {
244+ log := log .FromContext (ctx ).WithValues ("cluster" , req .ClusterName )
245+ log .Info ("Reconciling Application" )
246+
247+ cl , err := mgr .GetCluster (ctx , req .ClusterName )
248+ if err != nil {
249+ return reconcile.Result {}, fmt .Errorf ("failed to get cluster: %w" , err )
250+ }
251+ client := cl .GetClient ()
252+
253+ reconciler := & controller.ApplicationReconciler {
254+ Client : client ,
255+ Scheme : cl .GetScheme (),
256+ }
257+ return reconciler .Reconcile (ctx , reconcile.Request {NamespacedName : req .NamespacedName })
258+ },
259+ )); err != nil {
209260 setupLog .Error (err , "unable to create controller" , "controller" , "Application" )
210261 os .Exit (1 )
211262 }
212263 // +kubebuilder:scaffold:builder
213264
214- if metricsCertWatcher != nil {
215- setupLog .Info ("Adding metrics certificate watcher to manager" )
216- if err := mgr .Add (metricsCertWatcher ); err != nil {
217- setupLog .Error (err , "unable to add metrics certificate watcher to manager" )
218- os .Exit (1 )
219- }
220- }
221-
222- if webhookCertWatcher != nil {
223- setupLog .Info ("Adding webhook certificate watcher to manager" )
224- if err := mgr .Add (webhookCertWatcher ); err != nil {
225- setupLog .Error (err , "unable to add webhook certificate watcher to manager" )
226- os .Exit (1 )
227- }
228- }
265+ // TODO(mjudeikis): This needs to be implemented in mcmanager.
266+ // if metricsCertWatcher != nil {
267+ // setupLog.Info("Adding metrics certificate watcher to manager")
268+ // if err := mgr.Add(metricsCertWatcher); err != nil {
269+ // setupLog.Error(err, "unable to add metrics certificate watcher to manager")
270+ // os.Exit(1)
271+ // }
272+ // }
273+ //
274+ // if webhookCertWatcher != nil {
275+ // setupLog.Info("Adding webhook certificate watcher to manager")
276+ // if err := mgr.Add(webhookCertWatcher); err != nil {
277+ // setupLog.Error(err, "unable to add webhook certificate watcher to manager")
278+ // os.Exit(1)
279+ // }
280+ // }
229281
230282 if err := mgr .AddHealthzCheck ("healthz" , healthz .Ping ); err != nil {
231283 setupLog .Error (err , "unable to set up health check" )
@@ -237,7 +289,18 @@ func main() {
237289 }
238290
239291 setupLog .Info ("starting manager" )
240- if err := mgr .Start (ctrl .SetupSignalHandler ()); err != nil {
292+ if provider != nil {
293+ setupLog .Info ("Starting provider" )
294+ go func () {
295+ if err := provider .Run (ctx , mgr ); err != nil {
296+ setupLog .Error (err , "unable to run provider" )
297+ os .Exit (1 )
298+ }
299+ }()
300+ }
301+
302+ setupLog .Info ("starting manager" , "server" , server )
303+ if err := mgr .Start (ctx ); err != nil {
241304 setupLog .Error (err , "problem running manager" )
242305 os .Exit (1 )
243306 }
0 commit comments