in cmd/memberagent/main.go [275:438]
func Start(ctx context.Context, hubCfg, memberConfig *rest.Config, hubOpts, memberOpts ctrl.Options) error {
hubMgr, err := ctrl.NewManager(hubCfg, hubOpts)
if err != nil {
return fmt.Errorf("unable to start hub manager: %w", err)
}
memberMgr, err := ctrl.NewManager(memberConfig, memberOpts)
if err != nil {
return fmt.Errorf("unable to start member manager: %w", err)
}
if err := hubMgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
klog.ErrorS(err, "Failed to set up health check for hub manager")
return err
}
if err := hubMgr.AddReadyzCheck("readyz", healthz.Ping); err != nil {
klog.ErrorS(err, "Failed to set up ready check for hub manager")
return err
}
if err := memberMgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
klog.ErrorS(err, "Failed to set up health check for member manager")
return err
}
if err := memberMgr.AddReadyzCheck("readyz", healthz.Ping); err != nil {
klog.ErrorS(err, "Failed to set up ready check for member manager")
return err
}
spokeDynamicClient, err := dynamic.NewForConfig(memberConfig)
if err != nil {
klog.ErrorS(err, "Failed to create spoke dynamic client")
return err
}
httpClient, err := rest.HTTPClientFor(memberConfig)
if err != nil {
klog.ErrorS(err, "Failed to create spoke HTTP client")
return err
}
restMapper, err := apiutil.NewDynamicRESTMapper(memberConfig, httpClient)
if err != nil {
klog.ErrorS(err, "Failed to create spoke rest mapper")
return err
}
// In a recent refresh, the cache in use by the controller runtime has been upgraded to
// support multiple default namespaces (originally the number of default namespaces is
// limited to 1); however, the Fleet controllers still assume that only one default
// namespace is used, and for compatibility reasons, here we simply retrieve the first
// default namespace set (there should only be one set up anyway) and pass it to the
// Fleet controllers.
var targetNS string
for ns := range hubOpts.Cache.DefaultNamespaces {
targetNS = ns
break
}
discoverClient := discovery.NewDiscoveryClientForConfigOrDie(memberConfig)
if *enableV1Alpha1APIs {
gvk := workv1alpha1.SchemeGroupVersion.WithKind(workv1alpha1.AppliedWorkKind)
if err = utils.CheckCRDInstalled(discoverClient, gvk); err != nil {
klog.ErrorS(err, "unable to find the required CRD", "GVK", gvk)
return err
}
// create the work controller, so we can pass it to the internal member cluster reconciler
workController := workv1alpha1controller.NewApplyWorkReconciler(
hubMgr.GetClient(),
spokeDynamicClient,
memberMgr.GetClient(),
restMapper, hubMgr.GetEventRecorderFor("work_controller"), 5, targetNS)
if err = workController.SetupWithManager(hubMgr); err != nil {
klog.ErrorS(err, "Failed to create v1alpha1 controller", "controller", "work")
return err
}
klog.Info("Setting up the internalMemberCluster v1alpha1 controller")
if err = imcv1alpha1.NewReconciler(hubMgr.GetClient(), memberMgr.GetClient(), workController).SetupWithManager(hubMgr, "internalmemberclusterv1alpha1-controller"); err != nil {
klog.ErrorS(err, "Failed to create v1alpha1 controller", "controller", "internalMemberCluster")
return fmt.Errorf("unable to create internalMemberCluster v1alpha1 controller: %w", err)
}
}
if *enableV1Beta1APIs {
gvk := placementv1beta1.GroupVersion.WithKind(placementv1beta1.AppliedWorkKind)
if err = utils.CheckCRDInstalled(discoverClient, gvk); err != nil {
klog.ErrorS(err, "unable to find the required CRD", "GVK", gvk)
return err
}
// create the work controller, so we can pass it to the internal member cluster reconciler
workController := workapplier.NewReconciler(
hubMgr.GetClient(),
targetNS,
spokeDynamicClient,
memberMgr.GetClient(),
restMapper,
hubMgr.GetEventRecorderFor("work_applier"),
// The number of concurrent reconcilations. This is set to 5 to boost performance in
// resource processing.
5,
// Use the default worker count (4) for parallelized manifest processing.
parallelizer.DefaultNumOfWorkers,
time.Second*time.Duration(*availabilityCheckInterval),
time.Second*time.Duration(*driftDetectionInterval))
if err = workController.SetupWithManager(hubMgr); err != nil {
klog.ErrorS(err, "Failed to create v1beta1 controller", "controller", "work")
return err
}
klog.Info("Setting up the internalMemberCluster v1beta1 controller")
// Set up a provider provider (if applicable).
var pp propertyprovider.PropertyProvider
switch {
case propertyProvider != nil && *propertyProvider == azurePropertyProvider:
klog.V(2).Info("setting up the Azure property provider")
// Note that the property provider, though initialized here, is not started until
// the specific instance wins the leader election.
klog.V(1).InfoS("Property Provider is azure, loading cloud config", "cloudConfigFile", *cloudConfigFile)
// TODO (britaniar): load cloud config for Azure property provider.
pp = azure.New(region)
default:
// Fall back to not using any property provider if the provided type is none or
// not recognizable.
klog.V(2).Info("no property provider is specified, or the given type is not recognizable; start with no property provider")
pp = nil
}
// Set up the IMC controller.
imcReconciler, err := imcv1beta1.NewReconciler(
ctx,
hubMgr.GetClient(),
memberMgr.GetConfig(), memberMgr.GetClient(),
workController,
pp)
if err != nil {
klog.ErrorS(err, "Failed to create InternalMemberCluster v1beta1 reconciler")
return fmt.Errorf("failed to create InternalMemberCluster v1beta1 reconciler: %w", err)
}
if err := imcReconciler.SetupWithManager(hubMgr, "internalmembercluster-controller"); err != nil {
klog.ErrorS(err, "Failed to set up InternalMemberCluster v1beta1 controller with the controller manager")
return fmt.Errorf("failed to set up InternalMemberCluster v1beta1 controller with the controller manager: %w", err)
}
}
klog.InfoS("starting hub manager")
go func() {
defer klog.InfoS("shutting down hub manager")
if err := hubMgr.Start(ctx); err != nil {
klog.ErrorS(err, "Failed to start controller manager for the hub cluster")
return
}
}()
klog.InfoS("starting member manager")
defer klog.InfoS("shutting down member manager")
if err := memberMgr.Start(ctx); err != nil {
klog.ErrorS(err, "Failed to start controller manager for the member cluster")
return fmt.Errorf("problem starting member manager: %w", err)
}
return nil
}