Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[release-2.11] ACM-12773: Fix clusterVersion check for OCP3 #1532

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 @@ -18,6 +18,7 @@ import (
corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/api/errors"
meta "k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
Expand Down Expand Up @@ -213,10 +214,15 @@ func (r *ObservabilityAddonReconciler) Reconcile(ctx context.Context, req ctrl.R

clusterID, err = openshift.GetClusterID(ctx, r.Client)
if err != nil {
if !errors.IsNotFound(err) {
if meta.IsNoMatchError(err) {
// ClusterVersion kind does not exist in OCP 3.x
log.Info("ClusterVersion kind does not exist, treat spoke as OCP 3.x", "error", err)
} else if errors.IsNotFound(err) {
// If no ClusterVersion found, treat it as OCP 3.x (should not happen)
log.Info("Cluster id not found, treat spoke as OCP 3.x", "error", err)
} else {
return ctrl.Result{}, fmt.Errorf("failed to get cluster id: %w", err)
}
log.Error(err, "Failed to get cluster id")

// OCP 3.11 has no cluster id, set it as empty string
clusterID = ""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,17 @@ import (
corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/api/errors"
meta "k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes/scheme"
clusterv1 "open-cluster-management.io/api/cluster/v1"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"sigs.k8s.io/controller-runtime/pkg/client/interceptor"

addonv1alpha1 "open-cluster-management.io/api/addon/v1alpha1"

Expand Down Expand Up @@ -297,30 +300,6 @@ alertmanager-router-ca: |
t.Fatal("Finalizer not set in observabilityAddon")
}

// test reconcile w/o clusterversion(OCP 3.11)
c.Delete(ctx, cv)
req = ctrl.Request{
NamespacedName: types.NamespacedName{
Name: "install",
Namespace: testNamespace,
},
}
_, err = r.Reconcile(ctx, req)
if err != nil {
t.Fatalf("reconcile: (%v)", err)
}
err = c.Get(ctx, types.NamespacedName{Name: metricsCollectorName,
Namespace: namespace}, deploy)
if err != nil {
t.Fatalf("Metrics collector deployment not created: (%v)", err)
}
commands := deploy.Spec.Template.Spec.Containers[0].Command
for _, cmd := range commands {
if strings.Contains(cmd, "clusterID=") && !strings.Contains(cmd, "test-cluster") {
t.Fatalf("Found wrong clusterID in command: (%s)", cmd)
}
}

// test reconcile metrics collector deployment updated if cert secret updated
found := &appv1.Deployment{}
err = c.Get(ctx, types.NamespacedName{Name: metricsCollectorName,
Expand Down Expand Up @@ -422,3 +401,132 @@ alertmanager-router-ca: |
t.Fatal("Finalizer not removed from observabilityAddon")
}
}

func TestObservabilityAddonController_OCP3(t *testing.T) {
hubInfoData := []byte(`
endpoint: "http://test-endpoint"
alertmanager-endpoint: "http://test-alertamanger-endpoint"
alertmanager-router-ca: |
-----BEGIN CERTIFICATE-----
xxxxxxxxxxxxxxxxxxxxxxxxxxx
-----END CERTIFICATE-----
`)

hubObjs := []runtime.Object{
newObservabilityAddon(name, testHubNamspace),
}
hubInfo := newHubInfoSecret(hubInfoData, testNamespace)
amAccessSrt := newAMAccessorSecret(testNamespace)
allowList := getAllowlistCM()
images := newImagesCM(testNamespace)
objs := []runtime.Object{hubInfo, amAccessSrt, allowList, images, infra,
&corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "extension-apiserver-authentication",
Namespace: "kube-system",
},
Data: map[string]string{
"client-ca-file": "test",
},
},
&corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "test-ns",
},
},
newObservabilityAddon(name, testNamespace),
newPromSvc(),
}

scheme := scheme.Scheme
addonv1alpha1.AddToScheme(scheme)
mcov1beta2.AddToScheme(scheme)
oav1beta1.AddToScheme(scheme)
corev1.AddToScheme(scheme)
clusterv1.AddToScheme(scheme)
ocinfrav1.AddToScheme(scheme)

hubClient := fake.NewClientBuilder().
WithScheme(scheme).
WithRuntimeObjects(hubObjs...).
WithStatusSubresource(
&addonv1alpha1.ManagedClusterAddOn{},
&mcov1beta2.MultiClusterObservability{},
&oav1beta1.ObservabilityAddon{},
).
Build()

var errClientGetInterceptor error

c := fake.NewClientBuilder().
WithScheme(scheme).
WithRuntimeObjects(objs...).
WithStatusSubresource(
&addonv1alpha1.ManagedClusterAddOn{},
&mcov1beta2.MultiClusterObservability{},
&oav1beta1.ObservabilityAddon{},
).
WithInterceptorFuncs(interceptor.Funcs{
Get: func(ctx context.Context, client client.WithWatch, key types.NamespacedName, obj client.Object, opts ...client.GetOption) error {
if _, ok := obj.(*ocinfrav1.ClusterVersion); ok {
return errClientGetInterceptor
}
return client.Get(ctx, key, obj, opts...)
},
}).
Build()

hubClientWithReload, err := util.NewReloadableHubClientWithReloadFunc(func() (client.Client, error) {
return hubClient, nil
})
if err != nil {
t.Fatalf("Failed to create hub client with reload: %v", err)
}
r := &ObservabilityAddonReconciler{
Client: c,
HubClient: hubClientWithReload,
}

checkMetricsCollector := func() {
deploy := &appv1.Deployment{}
err = c.Get(context.Background(), types.NamespacedName{Name: metricsCollectorName,
Namespace: namespace}, deploy)
if err != nil {
t.Fatalf("Metrics collector deployment not created: (%v)", err)
}
commands := deploy.Spec.Template.Spec.Containers[0].Command
for _, cmd := range commands {
if strings.Contains(cmd, "clusterID=") && !strings.Contains(cmd, "test-cluster") {
t.Fatalf("Found wrong clusterID in command: (%s)", cmd)
}
}
}

// test reconcile successfully
// ClusterVersion CRD does not exist
errClientGetInterceptor = &meta.NoKindMatchError{
GroupKind: schema.GroupKind{Group: "example.com", Kind: "CustomResource"},
SearchedVersions: []string{"v1"},
}
req := ctrl.Request{
NamespacedName: types.NamespacedName{
Name: "install",
Namespace: testNamespace,
},
}

_, err = r.Reconcile(context.Background(), req)
if err != nil {
t.Fatalf("reconcile: (%v)", err)
}
checkMetricsCollector()

// test reconcile successfully
// ClusterVersion is not found
errClientGetInterceptor = errors.NewNotFound(schema.GroupResource{Group: "config.openshift.io", Resource: "clusterversions"}, "version")
_, err = r.Reconcile(context.Background(), req)
if err != nil {
t.Fatalf("reconcile: (%v)", err)
}
checkMetricsCollector()
}