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
parent
c68fb1da6c
commit
d44546bc86
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Reference in New Issue