Skip to content

Commit

Permalink
add cluster and klusterletaddonconfig webhook
Browse files Browse the repository at this point in the history
Signed-off-by: ldpliu <[email protected]>
  • Loading branch information
ldpliu committed Aug 12, 2024
1 parent 85c88cb commit ea669bd
Show file tree
Hide file tree
Showing 34 changed files with 2,523 additions and 352 deletions.
14 changes: 12 additions & 2 deletions manager/cmd/manager/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
"sigs.k8s.io/controller-runtime/pkg/webhook"

"github.com/stolostron/multicluster-global-hub/manager/pkg/addons"
"github.com/stolostron/multicluster-global-hub/manager/pkg/backup"
managerconfig "github.com/stolostron/multicluster-global-hub/manager/pkg/config"
"github.com/stolostron/multicluster-global-hub/manager/pkg/cronjob"
Expand Down Expand Up @@ -154,6 +155,8 @@ func parseFlags() *managerconfig.ManagerConfig {
"enable the global resource feature")
pflag.BoolVar(&managerConfig.WithACM, "with-acm", false,
"run on Red Hat Advanced Cluster Management")
pflag.BoolVar(&managerConfig.ImportClusterInHosted, "import-in-hosted", false,
"Import the managedhub cluster in hosted mode")
pflag.BoolVar(&managerConfig.EnablePprof, "enable-pprof", false, "enable the pprof tool")
pflag.Parse()
// set zap logger
Expand Down Expand Up @@ -207,7 +210,7 @@ func createManager(ctx context.Context,
NewCache: initCache,
}

if managerConfig.EnableGlobalResource {
if managerConfig.EnableGlobalResource || managerConfig.ImportClusterInHosted {
options.WebhookServer = &webhook.DefaultServer{
Options: webhook.Options{
Port: webhookPort,
Expand Down Expand Up @@ -275,6 +278,13 @@ func createManager(ctx context.Context,
return nil, fmt.Errorf("failed to add hubmanagement to manager - %w", err)
}

// Change addons namespaces for hosted mode
addons := addons.NewAddonsReconciler(mgr, managerConfig.ImportClusterInHosted)
err = addons.SetupWithManager(mgr)
if err != nil {
return nil, err
}

// need lock DB for backup
backupPVC := backup.NewBackupPVCReconciler(mgr, sqlConn)
err = backupPVC.SetupWithManager(mgr)
Expand Down Expand Up @@ -335,7 +345,7 @@ func doMain(ctx context.Context, restConfig *rest.Config) int {
return 1
}

if managerConfig.EnableGlobalResource {
if managerConfig.EnableGlobalResource || managerConfig.ImportClusterInHosted {
hookServer := mgr.GetWebhookServer()
setupLog.Info("registering webhooks to the webhook server")
hookServer.Register("/mutating", &webhook.Admission{
Expand Down
166 changes: 166 additions & 0 deletions manager/pkg/addons/addons_controller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
/*
Copyright 2023.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package addons

import (
"context"
"reflect"

"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/klog"
"open-cluster-management.io/api/addon/v1alpha1"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/builder"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/event"
"sigs.k8s.io/controller-runtime/pkg/manager"
"sigs.k8s.io/controller-runtime/pkg/predicate"

"github.com/stolostron/multicluster-global-hub/pkg/constants"
)

var addonList = sets.NewString(
"work-manager",
"cluster-proxy",
"managed-serviceaccount",
)

var newNamespaceConfig = v1alpha1.PlacementStrategy{
PlacementRef: v1alpha1.PlacementRef{
Namespace: "open-cluster-management-global-set",
Name: "global",
},
Configs: []v1alpha1.AddOnConfig{
{
ConfigReferent: v1alpha1.ConfigReferent{
Name: "global-hub",
Namespace: constants.GHDefaultNamespace,
},
ConfigGroupResource: v1alpha1.ConfigGroupResource{
Group: "addon.open-cluster-management.io",
Resource: "addondeploymentconfigs",
},
},
},
}

// BackupReconciler reconciles a MulticlusterGlobalHub object
type AddonsReconciler struct {
manager.Manager
client.Client
importClusterInHosted bool
}

func NewAddonsReconciler(mgr manager.Manager, importClusterInHosted bool) *AddonsReconciler {
return &AddonsReconciler{
Manager: mgr,
Client: mgr.GetClient(),
importClusterInHosted: importClusterInHosted,
}
}

// SetupWithManager sets up the controller with the Manager.
func (r *AddonsReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).Named("AddonsController").
For(&v1alpha1.ClusterManagementAddOn{},
builder.WithPredicates(addonPred)).
Complete(r)
}

var addonPred = predicate.Funcs{
CreateFunc: func(e event.CreateEvent) bool {
return addonList.Has(e.Object.GetName())
},
UpdateFunc: func(e event.UpdateEvent) bool {
return addonList.Has(e.ObjectNew.GetName())
},
DeleteFunc: func(e event.DeleteEvent) bool {
return false
},
}

func (r *AddonsReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
klog.V(2).Infof("Reconcile ClusterManagementAddOn: %v", req.NamespacedName)
cma := &v1alpha1.ClusterManagementAddOn{}
err := r.Client.Get(ctx, req.NamespacedName, cma)
if err != nil {
return ctrl.Result{}, err
}

needUpdate := false
if r.importClusterInHosted {
needUpdate = addAddonConfig(cma)
} else {
needUpdate = removeAddonConfig(cma)
}

if !needUpdate {
return ctrl.Result{}, nil
}
err = r.Client.Update(ctx, cma)
if err != nil {
klog.Errorf("Failed to update cma, err:%v", err)
return ctrl.Result{}, err
}
return ctrl.Result{}, nil
}

// addAddonConfig add the config to cma, will return true if the cma updated
func addAddonConfig(cma *v1alpha1.ClusterManagementAddOn) bool {
if len(cma.Spec.InstallStrategy.Placements) == 0 {
cma.Spec.InstallStrategy.Placements = append(cma.Spec.InstallStrategy.Placements, newNamespaceConfig)
return true
}
for _, pl := range cma.Spec.InstallStrategy.Placements {
if !reflect.DeepEqual(pl.PlacementRef, newNamespaceConfig.PlacementRef) {
continue
}
if reflect.DeepEqual(pl.Configs, newNamespaceConfig.Configs) {
return false
}
pl.Configs = append(pl.Configs, newNamespaceConfig.Configs...)
return true
}
cma.Spec.InstallStrategy.Placements = append(cma.Spec.InstallStrategy.Placements, newNamespaceConfig)
return true
}

// removeAddonConfig remove the config from cma, will return true if the cma updated
func removeAddonConfig(cma *v1alpha1.ClusterManagementAddOn) bool {
updated := false
if len(cma.Spec.InstallStrategy.Placements) == 0 {
return false
}
for i, pl := range cma.Spec.InstallStrategy.Placements {
if !reflect.DeepEqual(pl.PlacementRef, newNamespaceConfig.PlacementRef) {
continue
}
var removedConfigs []v1alpha1.AddOnConfig
for _, cfg := range pl.Configs {
if cfg != newNamespaceConfig.Configs[0] {
removedConfigs = append(removedConfigs, cfg)
continue
}
updated = true
}
if updated {
cma.Spec.InstallStrategy.Placements[i].Configs = removedConfigs
}
return updated
}
return false
}
Loading

0 comments on commit ea669bd

Please sign in to comment.