Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,16 @@ spec:
- get
- patch
- update
- apiGroups:
- operator.open-cluster-management.io
resources:
- multiclusterhubs
verbs:
- get
- list
- patch
- update
- watch
- apiGroups:
- packages.operators.coreos.com
resources:
Expand Down
10 changes: 10 additions & 0 deletions operator/config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,16 @@ rules:
- get
- patch
- update
- apiGroups:
- operator.open-cluster-management.io
resources:
- multiclusterhubs
verbs:
- get
- list
- patch
- update
- watch
- apiGroups:
- packages.operators.coreos.com
resources:
Expand Down
2 changes: 2 additions & 0 deletions operator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
operatorsv1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1"
"github.com/spf13/pflag"
hypershiftdeploymentv1alpha1 "github.com/stolostron/hypershift-deployment-controller/api/v1alpha1"
mchv1 "github.com/stolostron/multiclusterhub-operator/api/v1"
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
appsv1 "k8s.io/api/apps/v1"
batchv1 "k8s.io/api/batch/v1"
Expand Down Expand Up @@ -98,6 +99,7 @@ func init() {
utilruntime.Must(policyv1.AddToScheme(scheme))
utilruntime.Must(applicationv1beta1.AddToScheme(scheme))
utilruntime.Must(admissionregistrationv1.AddToScheme(scheme))
utilruntime.Must(mchv1.AddToScheme(scheme))
// +kubebuilder:scaffold:scheme
}

Expand Down
14 changes: 14 additions & 0 deletions operator/pkg/condition/condition.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,13 @@ const (
CONDITION_MESSAGE_MANAGER_AVAILABLE = "Multicluster Global Hub Manager has been deployed"
)

// NOTE: the status of ManagerDeployed can only be True; otherwise there is no condition
const (
CONDITION_TYPE_GRC_DISABLED = "GRCDisabled"
CONDITION_REASON_GRC_DISABLED = "GRCDisabled"
CONDITION_MESSAGE_GRC_DISABLED = "GRC has been disabled in MultiClusterHub"
)

// NOTE: the status of LeafHubDeployed can only be True; otherwise there is no condition
const (
CONDITION_TYPE_LEAFHUB_DEPLOY = "LeafHubDeployed"
Expand Down Expand Up @@ -112,6 +119,13 @@ func SetConditionManagerAvailable(ctx context.Context, c client.Client, mgh *ope
CONDITION_REASON_MANAGER_AVAILABLE, CONDITION_MESSAGE_MANAGER_AVAILABLE)
}

func SetConditionGRCDisabled(ctx context.Context, c client.Client, mgh *operatorv1alpha2.MulticlusterGlobalHub,
status metav1.ConditionStatus,
) error {
return SetCondition(ctx, c, mgh, CONDITION_TYPE_GRC_DISABLED, status,
CONDITION_REASON_GRC_DISABLED, CONDITION_MESSAGE_GRC_DISABLED)
}

func SetConditionLeafHubDeployed(ctx context.Context, c client.Client, mgh *operatorv1alpha2.MulticlusterGlobalHub,
clusterName string, status metav1.ConditionStatus,
) error {
Expand Down
6 changes: 6 additions & 0 deletions operator/pkg/controllers/hubofhubs/globalhub_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ type MulticlusterGlobalHubReconciler struct {
// +kubebuilder:rbac:groups="admissionregistration.k8s.io",resources=mutatingwebhookconfigurations,verbs=get;list;watch;create;update;delete
// +kubebuilder:rbac:groups=addon.open-cluster-management.io,resources=clustermanagementaddons,verbs=create;delete;get;list;update;watch
// +kubebuilder:rbac:groups=addon.open-cluster-management.io,resources=clustermanagementaddons/finalizers,verbs=update
// +kubebuilder:rbac:groups=operator.open-cluster-management.io,resources=multiclusterhubs,verbs=get;list;patch;update;watch

// Reconcile is part of the main kubernetes reconciliation loop which aims to
// move the current state of the cluster closer to the desired state.
Expand Down Expand Up @@ -220,6 +221,11 @@ func (r *MulticlusterGlobalHubReconciler) reconcileLargeScaleGlobalHub(ctx conte
return err
}

// disable grc component in mch instance
if err := r.reconcileMCH(ctx, mgh); err != nil {
return err
}

// reconcile manager
if err := r.reconcileManager(ctx, mgh); err != nil {
return err
Expand Down
104 changes: 104 additions & 0 deletions operator/pkg/controllers/hubofhubs/globalhub_mch.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package hubofhubs

import (
"context"
"fmt"

mchv1 "github.com/stolostron/multiclusterhub-operator/api/v1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
"sigs.k8s.io/controller-runtime/pkg/client"

operatorv1alpha2 "github.com/stolostron/multicluster-global-hub/operator/apis/v1alpha2"
"github.com/stolostron/multicluster-global-hub/operator/pkg/condition"
)

func (r *MulticlusterGlobalHubReconciler) reconcileMCH(ctx context.Context,
mgh *operatorv1alpha2.MulticlusterGlobalHub,
) error {
mch, _ := getMCH(ctx, r.Client)
// skip reconcile mch if it is not found
if mch == nil {
return nil
}

mch, _ = disableGRCInMCH(mch)

// if grcDisabledByMGH {
// // set the annotation to remember grc status
// annotations := mgh.GetAnnotations()
// annotations[GRCDisabledByMGHAnnotation] = strconv.FormatBool(grcDisabledByMGH)
// mgh.SetAnnotations(annotations)
// if err := r.Client.Update(ctx, mgh, &client.UpdateOptions{}); err != nil {
// return fmt.Errorf("failed to annotation(%s) to mgh. err = %v", GRCDisabledByMGHAnnotation, err)
// }
// }

if err := r.Client.Update(ctx, mch); err != nil {
return fmt.Errorf("failed to update MCH instance. err = %v", err)
}

if err := condition.SetConditionGRCDisabled(ctx, r.Client, mgh,
condition.CONDITION_STATUS_TRUE); err != nil {
return condition.FailToSetConditionError(condition.CONDITION_STATUS_TRUE, err)
}

return nil
}

func disableGRCInMCH(mch *mchv1.MultiClusterHub) (*mchv1.MultiClusterHub, bool) {
grcDisabledByMGH := false
if mch.Spec.Overrides != nil {
found := false
for i, c := range mch.Spec.Overrides.Components {
if c.Name == "grc" {
if c.Enabled {
mch.Spec.Overrides.Components[i].Enabled = false
grcDisabledByMGH = true
}
found = true
break
}
}
if !found {
mch.Spec.Overrides.Components = append(mch.Spec.Overrides.Components,
mchv1.ComponentConfig{
Name: "grc",
Enabled: false,
})
grcDisabledByMGH = true
}
} else {
mch.Spec.Overrides = &mchv1.Overrides{
Components: []mchv1.ComponentConfig{
{
Name: "grc",
Enabled: false,
},
},
}
grcDisabledByMGH = true
}

return mch, grcDisabledByMGH
}

func getMCH(ctx context.Context, k8sClient client.Client) (*mchv1.MultiClusterHub, error) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There has a function to getMCH has been implemented before. Maybe we can just keep one of these to the pkg.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

they are not exactly the same.

mch := &mchv1.MultiClusterHubList{}
err := k8sClient.List(ctx, mch)
if errors.IsNotFound(err) {
return nil, nil
}
if meta.IsNoMatchError(err) {
return nil, nil
}
if err != nil {
return nil, err
}

if len(mch.Items) == 0 {
return nil, err
}

return &mch.Items[0], nil
}
110 changes: 110 additions & 0 deletions operator/pkg/controllers/hubofhubs/globalhub_mch_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package hubofhubs

import (
"testing"

mchv1 "github.com/stolostron/multiclusterhub-operator/api/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

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

func TestDisableGRCInMCH(t *testing.T) {
cases := []struct {
name string
mch *mchv1.MultiClusterHub
grcDisabled bool
}{
{
name: "no need to disable grc",
mch: &mchv1.MultiClusterHub{
ObjectMeta: metav1.ObjectMeta{
Name: "multiclusterhub",
Namespace: config.GetDefaultNamespace(),
},
Spec: mchv1.MultiClusterHubSpec{
Overrides: &mchv1.Overrides{
Components: []mchv1.ComponentConfig{
{
Name: "grc",
Enabled: false,
},
},
},
},
},
grcDisabled: false,
},
{
name: "disable grc explicitly",
mch: &mchv1.MultiClusterHub{
ObjectMeta: metav1.ObjectMeta{
Name: "multiclusterhub",
Namespace: config.GetDefaultNamespace(),
},
Spec: mchv1.MultiClusterHubSpec{
Overrides: &mchv1.Overrides{
Components: []mchv1.ComponentConfig{
{
Name: "grc",
Enabled: true,
},
},
},
},
},
grcDisabled: true,
},
{
name: "disable grc by adding component explicitly",
mch: &mchv1.MultiClusterHub{
ObjectMeta: metav1.ObjectMeta{
Name: "multiclusterhub",
Namespace: config.GetDefaultNamespace(),
},
Spec: mchv1.MultiClusterHubSpec{
Overrides: &mchv1.Overrides{
Components: []mchv1.ComponentConfig{},
},
},
},
grcDisabled: true,
},
{
name: "disable grc by adding overrides explicitly",
mch: &mchv1.MultiClusterHub{
ObjectMeta: metav1.ObjectMeta{
Name: "multiclusterhub",
Namespace: config.GetDefaultNamespace(),
},
Spec: mchv1.MultiClusterHubSpec{},
},
grcDisabled: true,
},
}

for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
newMCH, getGRCDisabled := disableGRCInMCH(tc.mch)
if newMCH.Spec.Overrides == nil {
t.Errorf("empty MCH component overrides")
}
foundGRC := false
for _, c := range newMCH.Spec.Overrides.Components {
if c.Name == "grc" {
foundGRC = true
if c.Enabled == true {
t.Errorf("GRC is not disabled in MCH")
}
break
}
}
if !foundGRC {
t.Errorf("GRC is not add to MCH component overrides")
}
if getGRCDisabled != tc.grcDisabled {
t.Errorf("unexpected grcDisabled, got: %v, want: %v", getGRCDisabled, tc.grcDisabled)
}
})
}
}
20 changes: 20 additions & 0 deletions operator/pkg/controllers/hubofhubs/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/kylelemons/godebug/diff"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
mchv1 "github.com/stolostron/multiclusterhub-operator/api/v1"
"gopkg.in/yaml.v2"
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -291,6 +292,25 @@ var _ = Describe("MulticlusterGlobalHub controller", Ordered, func() {
Type: corev1.SecretTypeOpaque,
})).Should(Succeed())

By("By creating a new MCH instance")
mch := &mchv1.MultiClusterHub{
ObjectMeta: metav1.ObjectMeta{
Name: "multiclusterhub",
Namespace: config.GetDefaultNamespace(),
},
Spec: mchv1.MultiClusterHubSpec{
Overrides: &mchv1.Overrides{
Components: []mchv1.ComponentConfig{
{
Name: "grc",
Enabled: true,
},
},
},
},
}
Expect(k8sClient.Create(ctx, mch)).Should(Succeed())

By("By creating a new MGH instance")
mgh.SetNamespace(config.GetDefaultNamespace())
Expect(k8sClient.Create(ctx, mgh)).Should(Succeed())
Expand Down
3 changes: 3 additions & 0 deletions operator/pkg/controllers/hubofhubs/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
routev1 "github.com/openshift/api/route/v1"
operatorsv1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1"
hypershiftdeploymentv1alpha1 "github.com/stolostron/hypershift-deployment-controller/api/v1alpha1"
mchv1 "github.com/stolostron/multiclusterhub-operator/api/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
Expand Down Expand Up @@ -130,6 +131,8 @@ var _ = BeforeSuite(func() {
Expect(err).NotTo(HaveOccurred())
err = policyv1.AddToScheme(scheme.Scheme)
Expect(err).NotTo(HaveOccurred())
err = mchv1.AddToScheme(scheme.Scheme)
Expect(err).NotTo(HaveOccurred())
//+kubebuilder:scaffold:scheme

k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme})
Expand Down