fix: import ca-bunle even if there are several checluster CR (non all-namespace mode) (#1135)

Signed-off-by: Anatolii Bazko <abazko@redhat.com>
pull/1119/head^2
Anatolii Bazko 2021-10-09 09:27:27 +03:00 committed by GitHub
parent c68fb1da6c
commit d44546bc86
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 517 additions and 98 deletions

View File

@ -37,7 +37,6 @@ import (
corev1 "k8s.io/api/core/v1"
rbac "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/discovery"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/builder"
@ -137,7 +136,7 @@ func (r *CheClusterReconciler) SetupWithManager(mgr ctrl.Manager) error {
}
var toTrustedBundleConfigMapRequestMapper handler.MapFunc = func(obj client.Object) []ctrl.Request {
isTrusted, reconcileRequest := isTrustedBundleConfigMap(mgr, obj)
isTrusted, reconcileRequest := IsTrustedBundleConfigMap(r.nonCachedClient, r.namespace, obj)
if isTrusted {
return []ctrl.Request{reconcileRequest}
}
@ -145,7 +144,7 @@ func (r *CheClusterReconciler) SetupWithManager(mgr ctrl.Manager) error {
}
var toEclipseCheRelatedObjRequestMapper handler.MapFunc = func(obj client.Object) []ctrl.Request {
isEclipseCheRelatedObj, reconcileRequest := isEclipseCheRelatedObj(mgr, obj)
isEclipseCheRelatedObj, reconcileRequest := IsEclipseCheRelatedObj(r.nonCachedClient, r.namespace, obj)
if isEclipseCheRelatedObj {
return []ctrl.Request{reconcileRequest}
}
@ -654,43 +653,6 @@ func (r *CheClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request)
return ctrl.Result{}, nil
}
// isTrustedBundleConfigMap detects whether given config map is the config map with additional CA certificates to be trusted by Che
func isTrustedBundleConfigMap(mgr ctrl.Manager, obj client.Object) (bool, ctrl.Request) {
checlusters := &orgv1.CheClusterList{}
if err := mgr.GetClient().List(context.TODO(), checlusters, &client.ListOptions{}); err != nil {
return false, ctrl.Request{}
}
if len(checlusters.Items) != 1 {
return false, ctrl.Request{}
}
// Check if config map is the config map from CR
if checlusters.Items[0].Spec.Server.ServerTrustStoreConfigMapName != obj.GetName() {
// No, it is not form CR
// Check for labels
// Check for part of Che label
if value, exists := obj.GetLabels()[deploy.KubernetesPartOfLabelKey]; !exists || value != deploy.CheEclipseOrg {
// Labels do not match
return false, ctrl.Request{}
}
// Check for CA bundle label
if value, exists := obj.GetLabels()[deploy.CheCACertsConfigMapLabelKey]; !exists || value != deploy.CheCACertsConfigMapLabelValue {
// Labels do not match
return false, ctrl.Request{}
}
}
return true, ctrl.Request{
NamespacedName: types.NamespacedName{
Namespace: checlusters.Items[0].Namespace,
Name: checlusters.Items[0].Name,
},
}
}
func (r *CheClusterReconciler) autoEnableOAuth(deployContext *deploy.DeployContext, request ctrl.Request, isOpenShift4 bool) (reconcile.Result, error) {
var message, reason string
oauth := false
@ -769,31 +731,6 @@ func (r *CheClusterReconciler) autoEnableOAuth(deployContext *deploy.DeployConte
return reconcile.Result{}, nil
}
// isEclipseCheRelatedObj indicates if there is a object with
// the label 'app.kubernetes.io/part-of=che.eclipse.org' in a che namespace
func isEclipseCheRelatedObj(mgr ctrl.Manager, obj client.Object) (bool, ctrl.Request) {
checlusters := &orgv1.CheClusterList{}
if err := mgr.GetClient().List(context.TODO(), checlusters, &client.ListOptions{}); err != nil {
return false, ctrl.Request{}
}
if len(checlusters.Items) != 1 {
return false, ctrl.Request{}
}
if value, exists := obj.GetLabels()[deploy.KubernetesPartOfLabelKey]; !exists || value != deploy.CheEclipseOrg {
// Labels do not match
return false, ctrl.Request{}
}
return true, ctrl.Request{
NamespacedName: types.NamespacedName{
Namespace: checlusters.Items[0].Namespace,
Name: checlusters.Items[0].Name,
},
}
}
func (r *CheClusterReconciler) reconcileFinalizers(deployContext *deploy.DeployContext) {
if util.IsOpenShift && util.IsOAuthEnabled(deployContext.CheCluster) {
if err := deploy.ReconcileOAuthClientFinalizer(deployContext); err != nil {

View File

@ -0,0 +1,96 @@
//
// Copyright (c) 2012-2019 Red Hat, Inc.
// This program and the accompanying materials are made
// available under the terms of the Eclipse Public License 2.0
// which is available at https://www.eclipse.org/legal/epl-2.0/
//
// SPDX-License-Identifier: EPL-2.0
//
// Contributors:
// Red Hat, Inc. - initial API and implementation
//
package che
import (
"github.com/eclipse-che/che-operator/pkg/deploy"
"github.com/eclipse-che/che-operator/pkg/util"
"github.com/sirupsen/logrus"
"k8s.io/apimachinery/pkg/types"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
)
// IsTrustedBundleConfigMap detects whether given config map is the config map with additional CA certificates to be trusted by Che
func IsTrustedBundleConfigMap(cl client.Client, watchNamespace string, obj client.Object) (bool, ctrl.Request) {
if obj.GetNamespace() == "" {
// ignore cluster scope objects
return false, ctrl.Request{}
}
checluster, num, _ := util.FindCheClusterCRInNamespace(cl, watchNamespace)
if num != 1 {
logrus.Warn("More than one checluster Custom Resource found.")
return false, ctrl.Request{}
}
if checluster.Namespace != obj.GetNamespace() {
// ignore object in another namespace
return false, ctrl.Request{}
}
// Check if config map is the config map from CR
if checluster.Spec.Server.ServerTrustStoreConfigMapName != obj.GetName() {
// No, it is not form CR
// Check for component
if value, exists := obj.GetLabels()[deploy.KubernetesComponentLabelKey]; !exists || value != deploy.CheCACertsConfigMapLabelValue {
// Labels do not match
return false, ctrl.Request{}
}
// Check for part-of
if value, exists := obj.GetLabels()[deploy.KubernetesPartOfLabelKey]; !exists || value != deploy.CheEclipseOrg {
// ignore not matched labels
return false, ctrl.Request{}
}
}
return true, ctrl.Request{
NamespacedName: types.NamespacedName{
Namespace: checluster.Namespace,
Name: checluster.Name,
},
}
}
// isEclipseCheRelatedObj indicates if there is a object with
// the label 'app.kubernetes.io/part-of=che.eclipse.org' in a che namespace
func IsEclipseCheRelatedObj(cl client.Client, watchNamespace string, obj client.Object) (bool, ctrl.Request) {
if value, exists := obj.GetLabels()[deploy.KubernetesPartOfLabelKey]; !exists || value != deploy.CheEclipseOrg {
// ignore not matched labels
return false, ctrl.Request{}
}
if obj.GetNamespace() == "" {
// ignore cluster scope objects
return false, ctrl.Request{}
}
checluster, num, _ := util.FindCheClusterCRInNamespace(cl, watchNamespace)
if num != 1 {
logrus.Warn("More than one checluster Custom Resource found.")
return false, ctrl.Request{}
}
if checluster.Namespace != obj.GetNamespace() {
// ignore object in another namespace
return false, ctrl.Request{}
}
return true, ctrl.Request{
NamespacedName: types.NamespacedName{
Namespace: checluster.Namespace,
Name: checluster.Name,
},
}
}

View File

@ -0,0 +1,236 @@
//
// Copyright (c) 2012-2019 Red Hat, Inc.
// This program and the accompanying materials are made
// available under the terms of the Eclipse Public License 2.0
// which is available at https://www.eclipse.org/legal/epl-2.0/
//
// SPDX-License-Identifier: EPL-2.0
//
// Contributors:
// Red Hat, Inc. - initial API and implementation
//
package che
import (
"testing"
orgv1 "github.com/eclipse-che/che-operator/api/v1"
"github.com/eclipse-che/che-operator/pkg/deploy"
"github.com/stretchr/testify/assert"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
)
func TestIsTrustedBundleConfigMap(t *testing.T) {
type testCase struct {
name string
initObjects []runtime.Object
checluster *orgv1.CheCluster
objNamespace string
objLabels map[string]string
watchNamespace string
expectedIsEclipseCheObj bool
}
testObject := &corev1.ConfigMap{
TypeMeta: metav1.TypeMeta{
Kind: "ConfigMap",
APIVersion: "v1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Labels: map[string]string{"app.kubernetes.io/part-of": "che.eclipse.org", "app.kubernetes.io/component": "ca-bundle"},
},
}
testCases := []testCase{
{
name: "Cluster scope object",
initObjects: []runtime.Object{},
objNamespace: "",
watchNamespace: "eclipse-che",
expectedIsEclipseCheObj: false,
},
{
name: "Object in 'eclipse-che' namespace",
initObjects: []runtime.Object{},
objNamespace: "eclipse-che",
watchNamespace: "eclipse-che",
expectedIsEclipseCheObj: true,
},
{
name: "Object in 'eclipse-che' namespace, not ca-bundle component",
initObjects: []runtime.Object{},
objLabels: map[string]string{"app.kubernetes.io/part-of": "che.eclipse.org"},
objNamespace: "eclipse-che",
watchNamespace: "eclipse-che",
expectedIsEclipseCheObj: false,
},
{
name: "Object in 'eclipse-che' namespace, not ca-bundle component, but trusted configmap",
initObjects: []runtime.Object{},
checluster: &orgv1.CheCluster{
ObjectMeta: metav1.ObjectMeta{Name: "eclipse-che", Namespace: "eclipse-che"},
Spec: orgv1.CheClusterSpec{
Server: orgv1.CheClusterSpecServer{
ServerTrustStoreConfigMapName: "test",
},
},
},
objLabels: map[string]string{},
objNamespace: "eclipse-che",
watchNamespace: "eclipse-che",
expectedIsEclipseCheObj: true,
},
{
name: "Object in another namespace than 'eclipse-che'",
initObjects: []runtime.Object{},
objNamespace: "test-eclipse-che",
watchNamespace: "eclipse-che",
expectedIsEclipseCheObj: false,
},
{
name: "Object in 'eclipse-che' namespace, several checluster CR",
initObjects: []runtime.Object{
// checluster CR in `default` namespace
&orgv1.CheCluster{ObjectMeta: metav1.ObjectMeta{Name: "eclipse-che", Namespace: "default"}},
},
objNamespace: "eclipse-che",
watchNamespace: "eclipse-che",
expectedIsEclipseCheObj: true,
},
{
name: "Cluster scope object, all-namespaces mode",
initObjects: []runtime.Object{},
objNamespace: "",
watchNamespace: "eclipse-che",
expectedIsEclipseCheObj: false,
},
{
name: "Object in 'eclipse-che' namespace, all-namespaces mode",
initObjects: []runtime.Object{},
objNamespace: "eclipse-che",
watchNamespace: "",
expectedIsEclipseCheObj: true,
},
{
name: "Object in another namespace than 'eclipse-che', all-namespaces mode",
initObjects: []runtime.Object{},
objNamespace: "test-eclipse-che",
watchNamespace: "",
expectedIsEclipseCheObj: false,
},
}
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
deployContext := deploy.GetTestDeployContext(testCase.checluster, testCase.initObjects)
newTestObject := testObject.DeepCopy()
newTestObject.ObjectMeta.Namespace = testCase.objNamespace
if testCase.objLabels != nil {
newTestObject.ObjectMeta.Labels = testCase.objLabels
}
isEclipseCheObj, req := IsTrustedBundleConfigMap(deployContext.ClusterAPI.NonCachedClient, testCase.watchNamespace, newTestObject)
assert.Equal(t, testCase.expectedIsEclipseCheObj, isEclipseCheObj)
if isEclipseCheObj {
assert.Equal(t, req.Namespace, deployContext.CheCluster.Namespace)
assert.Equal(t, req.Name, deployContext.CheCluster.Name)
}
})
}
}
func TestIsEclipseCheRelatedObj(t *testing.T) {
type testCase struct {
name string
initObjects []runtime.Object
objNamespace string
watchNamespace string
expectedIsEclipseCheObj bool
}
testObject := &corev1.ConfigMap{
TypeMeta: metav1.TypeMeta{
Kind: "ConfigMap",
APIVersion: "v1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Labels: map[string]string{"app.kubernetes.io/part-of": "che.eclipse.org"},
},
}
testCases := []testCase{
{
name: "Cluster scope object",
initObjects: []runtime.Object{},
objNamespace: "",
watchNamespace: "eclipse-che",
expectedIsEclipseCheObj: false,
},
{
name: "Object in 'eclipse-che' namespace",
initObjects: []runtime.Object{},
objNamespace: "eclipse-che",
watchNamespace: "eclipse-che",
expectedIsEclipseCheObj: true,
},
{
name: "Object in another namespace than 'eclipse-che'",
initObjects: []runtime.Object{},
objNamespace: "test-eclipse-che",
watchNamespace: "eclipse-che",
expectedIsEclipseCheObj: false,
},
{
name: "Object in 'eclipse-che' namespace, several checluster CR",
initObjects: []runtime.Object{
// checluster CR in `default` namespace
&orgv1.CheCluster{ObjectMeta: metav1.ObjectMeta{Name: "eclipse-che", Namespace: "default"}},
},
objNamespace: "eclipse-che",
watchNamespace: "eclipse-che",
expectedIsEclipseCheObj: true,
},
{
name: "Cluster scope object, all-namespaces mode",
initObjects: []runtime.Object{},
objNamespace: "",
watchNamespace: "eclipse-che",
expectedIsEclipseCheObj: false,
},
{
name: "Object in 'eclipse-che' namespace, all-namespaces mode",
initObjects: []runtime.Object{},
objNamespace: "eclipse-che",
watchNamespace: "",
expectedIsEclipseCheObj: true,
},
{
name: "Object in another namespace than 'eclipse-che', all-namespaces mode",
initObjects: []runtime.Object{},
objNamespace: "test-eclipse-che",
watchNamespace: "",
expectedIsEclipseCheObj: false,
},
}
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
deployContext := deploy.GetTestDeployContext(nil, testCase.initObjects)
testObject.ObjectMeta.Namespace = testCase.objNamespace
isEclipseCheObj, req := IsEclipseCheRelatedObj(deployContext.ClusterAPI.NonCachedClient, testCase.watchNamespace, testObject)
assert.Equal(t, testCase.expectedIsEclipseCheObj, isEclipseCheObj)
if isEclipseCheObj {
assert.Equal(t, req.Namespace, deployContext.CheCluster.Namespace)
assert.Equal(t, req.Name, deployContext.CheCluster.Name)
}
})
}
}

View File

@ -48,7 +48,7 @@ func NewBackupContext(r *ReconcileCheClusterBackup, backupCR *chev1.CheClusterBa
// After the preparations, a new reconcile loop will be triggered, so backupServer will not be nil any more.
}
cheCR, _, err := util.FindCheCRinNamespace(r.client, namespace)
cheCR, _, err := util.FindCheClusterCRInNamespace(r.client, namespace)
if err != nil {
return nil, err
}

View File

@ -124,7 +124,7 @@ func cleanPreviousInstallation(rctx *RestoreContext, dataDir string) (bool, erro
}
// Delete Che CR to stop operator from dealing with current installation
actualCheCR, cheCRCount, err := util.FindCheCRinNamespace(rctx.r.client, rctx.namespace)
actualCheCR, cheCRCount, err := util.FindCheClusterCRInNamespace(rctx.r.client, rctx.namespace)
if cheCRCount == -1 {
// error occurred while retreiving CheCluster CR
return false, err

View File

@ -38,7 +38,7 @@ func NewRestoreContext(r *ReconcileCheClusterRestore, restoreCR *chev1.CheCluste
return nil, err
}
cheCR, CRCount, err := util.FindCheCRinNamespace(r.client, namespace)
cheCR, CRCount, err := util.FindCheClusterCRInNamespace(r.client, namespace)
if err != nil {
// Check if Che CR is present
if CRCount > 0 {

View File

@ -47,8 +47,6 @@ const (
CheTLSSelfSignedCertificateSecretName = "self-signed-certificate"
DefaultCheTLSSecretName = "che-tls"
// CheCACertsConfigMapLabelKey is the label key which marks config map with additional CA certificates
CheCACertsConfigMapLabelKey = "app.kubernetes.io/component"
// CheCACertsConfigMapLabelKey is the label value which marks config map with additional CA certificates
CheCACertsConfigMapLabelValue = "ca-bundle"
// CheAllCACertsConfigMapName is the name of config map which contains all additional trusted by Che TLS CA certificates
@ -591,7 +589,7 @@ func SyncAdditionalCACertsConfigMapToCluster(deployContext *DeployContext) (bool
func GetCACertsConfigMaps(deployContext *DeployContext) ([]corev1.ConfigMap, error) {
CACertsConfigMapList := &corev1.ConfigMapList{}
caBundleLabelSelectorRequirement, _ := labels.NewRequirement(CheCACertsConfigMapLabelKey, selection.Equals, []string{CheCACertsConfigMapLabelValue})
caBundleLabelSelectorRequirement, _ := labels.NewRequirement(KubernetesComponentLabelKey, selection.Equals, []string{CheCACertsConfigMapLabelValue})
cheComponetLabelSelectorRequirement, _ := labels.NewRequirement(KubernetesPartOfLabelKey, selection.Equals, []string{CheEclipseOrg})
listOptions := &client.ListOptions{
LabelSelector: labels.NewSelector().Add(*cheComponetLabelSelectorRequirement).Add(*caBundleLabelSelectorRequirement),

View File

@ -0,0 +1,43 @@
//
// Copyright (c) 2012-2019 Red Hat, Inc.
// This program and the accompanying materials are made
// available under the terms of the Eclipse Public License 2.0
// which is available at https://www.eclipse.org/legal/epl-2.0/
//
// SPDX-License-Identifier: EPL-2.0
//
// Contributors:
// Red Hat, Inc. - initial API and implementation
//
package util
import (
"context"
"fmt"
orgv1 "github.com/eclipse-che/che-operator/api/v1"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
)
// Finds checluster custom resource in a given namespace.
// If namespace is empty then checluster will be found in any namespace.
func FindCheClusterCRInNamespace(cl client.Client, namespace string) (*orgv1.CheCluster, int, error) {
cheClusters := &orgv1.CheClusterList{}
listOptions := &client.ListOptions{Namespace: namespace}
if err := cl.List(context.TODO(), cheClusters, listOptions); err != nil {
return nil, -1, err
}
if len(cheClusters.Items) != 1 {
return nil, len(cheClusters.Items), fmt.Errorf("Expected one instance of CheCluster custom resources, but '%d' found.", len(cheClusters.Items))
}
checluster := &orgv1.CheCluster{}
namespacedName := types.NamespacedName{Namespace: cheClusters.Items[0].GetNamespace(), Name: cheClusters.Items[0].GetName()}
err := cl.Get(context.TODO(), namespacedName, checluster)
if err != nil {
return nil, -1, err
}
return checluster, 1, nil
}

View File

@ -0,0 +1,136 @@
//
// Copyright (c) 2012-2021 Red Hat, Inc.
// This program and the accompanying materials are made
// available under the terms of the Eclipse Public License 2.0
// which is available at https://www.eclipse.org/legal/epl-2.0/
//
// SPDX-License-Identifier: EPL-2.0
//
// Contributors:
// Red Hat, Inc. - initial API and implementation
//
package util
import (
"testing"
orgv1 "github.com/eclipse-che/che-operator/api/v1"
"github.com/stretchr/testify/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes/scheme"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
)
func TestFindCheCRinNamespace(t *testing.T) {
type testCase struct {
name string
initObjects []runtime.Object
watchNamespace string
expectedNumber int
expectedNamespace string
expectedErr bool
}
testCases := []testCase{
{
name: "CR in 'eclipse-che' namespace",
initObjects: []runtime.Object{
&orgv1.CheCluster{ObjectMeta: metav1.ObjectMeta{Name: "eclipse-che", Namespace: "eclipse-che"}},
},
watchNamespace: "eclipse-che",
expectedNumber: 1,
expectedErr: false,
expectedNamespace: "eclipse-che",
},
{
name: "CR in 'default' namespace",
initObjects: []runtime.Object{
&orgv1.CheCluster{ObjectMeta: metav1.ObjectMeta{Name: "eclipse-che", Namespace: "default"}},
},
watchNamespace: "eclipse-che",
expectedNumber: 0,
expectedErr: true,
},
{
name: "several CR in 'eclipse-che' namespace",
initObjects: []runtime.Object{
&orgv1.CheCluster{ObjectMeta: metav1.ObjectMeta{Name: "eclipse-che", Namespace: "eclipse-che"}},
&orgv1.CheCluster{ObjectMeta: metav1.ObjectMeta{Name: "test-eclipse-che", Namespace: "eclipse-che"}},
},
watchNamespace: "eclipse-che",
expectedNumber: 2,
expectedErr: true,
},
{
name: "several CR in different namespaces",
initObjects: []runtime.Object{
&orgv1.CheCluster{ObjectMeta: metav1.ObjectMeta{Name: "eclipse-che", Namespace: "eclipse-che"}},
&orgv1.CheCluster{ObjectMeta: metav1.ObjectMeta{Name: "eclipse-che", Namespace: "default"}},
},
watchNamespace: "eclipse-che",
expectedNumber: 1,
expectedErr: false,
expectedNamespace: "eclipse-che",
},
{
name: "CR in 'eclipse-che' namespace, all-namespace mode",
initObjects: []runtime.Object{
&orgv1.CheCluster{ObjectMeta: metav1.ObjectMeta{Name: "eclipse-che", Namespace: "eclipse-che"}},
},
watchNamespace: "",
expectedNumber: 1,
expectedErr: false,
expectedNamespace: "eclipse-che",
},
{
name: "CR in 'default' namespace, all-namespace mode",
initObjects: []runtime.Object{
&orgv1.CheCluster{ObjectMeta: metav1.ObjectMeta{Name: "eclipse-che", Namespace: "default"}},
},
watchNamespace: "",
expectedNumber: 1,
expectedErr: false,
expectedNamespace: "default",
},
{
name: "several CR in 'eclipse-che' namespace, all-namespace mode",
initObjects: []runtime.Object{
&orgv1.CheCluster{ObjectMeta: metav1.ObjectMeta{Name: "eclipse-che", Namespace: "eclipse-che"}},
&orgv1.CheCluster{ObjectMeta: metav1.ObjectMeta{Name: "test-eclipse-che", Namespace: "eclipse-che"}},
},
watchNamespace: "",
expectedNumber: 2,
expectedErr: true,
},
{
name: "several CR in different namespaces, all-namespace mode",
initObjects: []runtime.Object{
&orgv1.CheCluster{ObjectMeta: metav1.ObjectMeta{Name: "eclipse-che", Namespace: "eclipse-che"}},
&orgv1.CheCluster{ObjectMeta: metav1.ObjectMeta{Name: "eclipse-che", Namespace: "default"}},
},
watchNamespace: "",
expectedNumber: 2,
expectedErr: true,
},
}
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
scheme := scheme.Scheme
orgv1.SchemeBuilder.AddToScheme(scheme)
cli := fake.NewFakeClientWithScheme(scheme, testCase.initObjects...)
checluster, num, err := FindCheClusterCRInNamespace(cli, testCase.watchNamespace)
assert.Equal(t, testCase.expectedNumber, num)
if testCase.expectedErr {
assert.NotNil(t, err)
} else {
assert.Nil(t, err)
}
if num == 1 {
assert.Equal(t, testCase.expectedNamespace, checluster.Namespace)
}
})
}
}

View File

@ -561,33 +561,6 @@ func ComputeHash256(data []byte) string {
return base64.URLEncoding.EncodeToString(hasher.Sum(nil))
}
func ReloadCheCluster(client client.Client, cheCluster *orgv1.CheCluster) error {
return client.Get(
context.TODO(),
types.NamespacedName{Name: cheCluster.Name, Namespace: cheCluster.Namespace},
cheCluster)
}
func FindCheCRinNamespace(cl client.Client, namespace string) (*orgv1.CheCluster, int, error) {
cheClusters := &orgv1.CheClusterList{}
listOptions := &client.ListOptions{Namespace: namespace}
if err := cl.List(context.TODO(), cheClusters, listOptions); err != nil {
return nil, -1, err
}
if len(cheClusters.Items) != 1 {
return nil, len(cheClusters.Items), fmt.Errorf("expected an instance of CheCluster, but got %d instances", len(cheClusters.Items))
}
cheCR := &orgv1.CheCluster{}
namespacedName := types.NamespacedName{Namespace: namespace, Name: cheClusters.Items[0].GetName()}
err := cl.Get(context.TODO(), namespacedName, cheCR)
if err != nil {
return nil, -1, err
}
return cheCR, 1, nil
}
func UpdateBackupServerConfiguration(client client.Client, backupServerConfig *orgv1.CheBackupServerConfiguration) error {
err := client.Update(context.TODO(), backupServerConfig)
if err != nil {