From 021031f6df9cec84104d052eaa945e0afdad8e4e Mon Sep 17 00:00:00 2001 From: Mykola Morhun Date: Fri, 19 Nov 2021 18:35:22 +0200 Subject: [PATCH] feat: Use custom cache function in Che Operator (#1166) Use custom cache function to limit memory consumption of operator Signed-off-by: Mykola Morhun --- .../che-operator.clusterserviceversion.yaml | 5 +- .../che-operator_v1_serviceaccount.yaml | 1 + .../che-operator.clusterserviceversion.yaml | 7 +- .../che-operator_v1_serviceaccount.yaml | 1 + .../che-operator.clusterserviceversion.yaml | 5 +- .../che-operator_v1_serviceaccount.yaml | 1 + config/manager/manager.yaml | 4 +- config/rbac/cluster_role.yaml | 1 + config/rbac/cluster_rolebinding.yaml | 1 + config/rbac/role.yaml | 1 + config/rbac/role_binding.yaml | 1 + config/rbac/service_account.yaml | 1 + controllers/che/backup_test.go | 6 +- controllers/che/checluster_controller.go | 10 +- controllers/che/checluster_controller_test.go | 6 +- controllers/che/cheobj_verifier.go | 26 +- controllers/che/cheobj_verifier_test.go | 19 +- controllers/che/configmap_cert_test.go | 12 +- controllers/che/proxy_test.go | 6 +- .../checlusterbackup/backup_data_collector.go | 6 +- controllers/usernamespace/controller.go | 8 +- main.go | 90 +++++- pkg/deploy/checluster_test.go | 6 +- pkg/deploy/clusterrole_test.go | 6 +- pkg/deploy/clusterrolebinding_test.go | 12 +- pkg/deploy/configmap_test.go | 12 +- pkg/deploy/consolelink_test.go | 8 +- .../dashboard/dashboard_deployment_test.go | 24 +- pkg/deploy/dashboard/dashboard_test.go | 18 +- pkg/deploy/dashboard/deployment_dashboard.go | 2 +- pkg/deploy/data_types.go | 8 +- pkg/deploy/defaults.go | 3 + pkg/deploy/deployment_test.go | 18 +- pkg/deploy/dev-workspace/dev_workspace.go | 6 +- .../dev-workspace/dev_workspace_test.go | 10 +- .../devfileregistry/devfileregistry_test.go | 6 +- pkg/deploy/gateway/gateway_test.go | 18 +- .../deployment_keycloak_test.go | 6 +- .../identity-provider/identity_provider.go | 4 +- pkg/deploy/image-puller/imagepuller.go | 30 +- pkg/deploy/image-puller/imagepuller_test.go | 24 +- pkg/deploy/ingres_test.go | 1 + pkg/deploy/job.go | 3 +- pkg/deploy/job_test.go | 6 +- pkg/deploy/labels.go | 1 + .../on-reconcile-one-time-migration.go | 289 ++++++++++++++++++ pkg/deploy/openshift-oauth/openshiftoauth.go | 2 +- .../openshift-oauth/openshiftoauth_user.go | 4 +- .../pluginregistry/pluginregistry_test.go | 6 +- pkg/deploy/postgres/postgres_test.go | 6 +- pkg/deploy/pvc_test.go | 6 +- pkg/deploy/role.go | 2 + pkg/deploy/role_test.go | 6 +- pkg/deploy/rolebinding_test.go | 6 +- pkg/deploy/route_test.go | 2 + pkg/deploy/sercet_test.go | 12 +- pkg/deploy/server/server_deployment.go | 4 +- pkg/deploy/server/server_test.go | 24 +- pkg/deploy/service_test.go | 6 +- pkg/deploy/sync.go | 18 +- pkg/deploy/sync_test.go | 6 +- pkg/deploy/test_util.go | 8 +- pkg/deploy/tls.go | 82 +++-- pkg/deploy/tls_test.go | 6 +- 64 files changed, 683 insertions(+), 262 deletions(-) create mode 100644 pkg/deploy/migration/on-reconcile-one-time-migration.go diff --git a/bundle/next-all-namespaces/eclipse-che-preview-openshift/manifests/che-operator.clusterserviceversion.yaml b/bundle/next-all-namespaces/eclipse-che-preview-openshift/manifests/che-operator.clusterserviceversion.yaml index e813053ffb..1e8b80f89d 100644 --- a/bundle/next-all-namespaces/eclipse-che-preview-openshift/manifests/che-operator.clusterserviceversion.yaml +++ b/bundle/next-all-namespaces/eclipse-che-preview-openshift/manifests/che-operator.clusterserviceversion.yaml @@ -126,7 +126,7 @@ metadata: operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 repository: https://github.com/eclipse-che/che-operator support: Eclipse Foundation - name: eclipse-che-preview-openshift.v7.40.0-370.next + name: eclipse-che-preview-openshift.v7.40.0-373.next namespace: placeholder spec: apiservicedefinitions: {} @@ -1068,6 +1068,7 @@ spec: app.kubernetes.io/instance: che app.kubernetes.io/managed-by: olm app.kubernetes.io/name: che + app.kubernetes.io/part-of: che.eclipse.org spec: containers: - args: @@ -1426,4 +1427,4 @@ spec: maturity: stable provider: name: Eclipse Foundation - version: 7.40.0-370.next + version: 7.40.0-373.next diff --git a/bundle/next-all-namespaces/eclipse-che-preview-openshift/manifests/che-operator_v1_serviceaccount.yaml b/bundle/next-all-namespaces/eclipse-che-preview-openshift/manifests/che-operator_v1_serviceaccount.yaml index 5eead433ea..010a50d515 100644 --- a/bundle/next-all-namespaces/eclipse-che-preview-openshift/manifests/che-operator_v1_serviceaccount.yaml +++ b/bundle/next-all-namespaces/eclipse-che-preview-openshift/manifests/che-operator_v1_serviceaccount.yaml @@ -18,4 +18,5 @@ metadata: app.kubernetes.io/component: che-operator app.kubernetes.io/instance: che app.kubernetes.io/name: che + app.kubernetes.io/part-of: che.eclipse.org name: che-operator diff --git a/bundle/next/eclipse-che-preview-kubernetes/manifests/che-operator.clusterserviceversion.yaml b/bundle/next/eclipse-che-preview-kubernetes/manifests/che-operator.clusterserviceversion.yaml index a326b50e05..334f1391db 100644 --- a/bundle/next/eclipse-che-preview-kubernetes/manifests/che-operator.clusterserviceversion.yaml +++ b/bundle/next/eclipse-che-preview-kubernetes/manifests/che-operator.clusterserviceversion.yaml @@ -133,7 +133,7 @@ metadata: operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 repository: https://github.com/eclipse-che/che-operator support: Eclipse Foundation - name: eclipse-che-preview-kubernetes.v7.40.0-331.next + name: eclipse-che-preview-kubernetes.v7.40.0-334.next namespace: placeholder spec: apiservicedefinitions: {} @@ -1055,6 +1055,7 @@ spec: app.kubernetes.io/instance: che app.kubernetes.io/managed-by: olm app.kubernetes.io/name: che + app.kubernetes.io/part-of: che.eclipse.org spec: containers: - args: @@ -1083,7 +1084,7 @@ spec: - name: RELATED_IMAGE_devfile_registry value: quay.io/eclipse/che-devfile-registry:next - name: RELATED_IMAGE_che_tls_secrets_creation_job - value: quay.io/eclipse/che-tls-secret-creator:alpine-d1ed4ad + value: quay.io/eclipse/che-tls-secret-creator:alpine-01a4c34 - name: RELATED_IMAGE_pvc_jobs value: registry.access.redhat.com/ubi8-minimal:8.5-204 - name: RELATED_IMAGE_postgres @@ -1393,4 +1394,4 @@ spec: maturity: stable provider: name: Eclipse Foundation - version: 7.40.0-331.next + version: 7.40.0-334.next diff --git a/bundle/next/eclipse-che-preview-kubernetes/manifests/che-operator_v1_serviceaccount.yaml b/bundle/next/eclipse-che-preview-kubernetes/manifests/che-operator_v1_serviceaccount.yaml index 5eead433ea..010a50d515 100644 --- a/bundle/next/eclipse-che-preview-kubernetes/manifests/che-operator_v1_serviceaccount.yaml +++ b/bundle/next/eclipse-che-preview-kubernetes/manifests/che-operator_v1_serviceaccount.yaml @@ -18,4 +18,5 @@ metadata: app.kubernetes.io/component: che-operator app.kubernetes.io/instance: che app.kubernetes.io/name: che + app.kubernetes.io/part-of: che.eclipse.org name: che-operator diff --git a/bundle/next/eclipse-che-preview-openshift/manifests/che-operator.clusterserviceversion.yaml b/bundle/next/eclipse-che-preview-openshift/manifests/che-operator.clusterserviceversion.yaml index 80ee149457..342f730ef7 100644 --- a/bundle/next/eclipse-che-preview-openshift/manifests/che-operator.clusterserviceversion.yaml +++ b/bundle/next/eclipse-che-preview-openshift/manifests/che-operator.clusterserviceversion.yaml @@ -126,7 +126,7 @@ metadata: operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 repository: https://github.com/eclipse-che/che-operator support: Eclipse Foundation - name: eclipse-che-preview-openshift.v7.40.0-338.next + name: eclipse-che-preview-openshift.v7.40.0-341.next namespace: placeholder spec: apiservicedefinitions: {} @@ -1068,6 +1068,7 @@ spec: app.kubernetes.io/instance: che app.kubernetes.io/managed-by: olm app.kubernetes.io/name: che + app.kubernetes.io/part-of: che.eclipse.org spec: containers: - args: @@ -1426,4 +1427,4 @@ spec: maturity: stable provider: name: Eclipse Foundation - version: 7.40.0-338.next + version: 7.40.0-341.next diff --git a/bundle/next/eclipse-che-preview-openshift/manifests/che-operator_v1_serviceaccount.yaml b/bundle/next/eclipse-che-preview-openshift/manifests/che-operator_v1_serviceaccount.yaml index 5eead433ea..010a50d515 100644 --- a/bundle/next/eclipse-che-preview-openshift/manifests/che-operator_v1_serviceaccount.yaml +++ b/bundle/next/eclipse-che-preview-openshift/manifests/che-operator_v1_serviceaccount.yaml @@ -18,4 +18,5 @@ metadata: app.kubernetes.io/component: che-operator app.kubernetes.io/instance: che app.kubernetes.io/name: che + app.kubernetes.io/part-of: che.eclipse.org name: che-operator diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml index 129366bcf6..92f880cbe9 100644 --- a/config/manager/manager.yaml +++ b/config/manager/manager.yaml @@ -19,6 +19,7 @@ metadata: app: che-operator app.kubernetes.io/name: che app.kubernetes.io/instance: che + app.kubernetes.io/part-of: che.eclipse.org app.kubernetes.io/component: che-operator spec: replicas: 1 @@ -33,6 +34,7 @@ spec: app: che-operator app.kubernetes.io/name: che app.kubernetes.io/instance: che + app.kubernetes.io/part-of: che.eclipse.org app.kubernetes.io/component: che-operator spec: containers: @@ -68,7 +70,7 @@ spec: - name: RELATED_IMAGE_devfile_registry value: quay.io/eclipse/che-devfile-registry:next - name: RELATED_IMAGE_che_tls_secrets_creation_job - value: quay.io/eclipse/che-tls-secret-creator:alpine-d1ed4ad + value: quay.io/eclipse/che-tls-secret-creator:alpine-01a4c34 - name: RELATED_IMAGE_pvc_jobs value: registry.access.redhat.com/ubi8-minimal:8.5-204 - name: RELATED_IMAGE_postgres diff --git a/config/rbac/cluster_role.yaml b/config/rbac/cluster_role.yaml index c344be5196..f4a41e7a4e 100644 --- a/config/rbac/cluster_role.yaml +++ b/config/rbac/cluster_role.yaml @@ -17,6 +17,7 @@ metadata: labels: app.kubernetes.io/name: che app.kubernetes.io/instance: che + app.kubernetes.io/part-of: che.eclipse.org app.kubernetes.io/component: che-operator rules: ### CHE-OPERATOR ROLES ONLY: BEGIN diff --git a/config/rbac/cluster_rolebinding.yaml b/config/rbac/cluster_rolebinding.yaml index 07b7a54177..bb3bc3bceb 100644 --- a/config/rbac/cluster_rolebinding.yaml +++ b/config/rbac/cluster_rolebinding.yaml @@ -17,6 +17,7 @@ metadata: labels: app.kubernetes.io/name: che app.kubernetes.io/instance: che + app.kubernetes.io/part-of: che.eclipse.org app.kubernetes.io/component: che-operator subjects: - kind: ServiceAccount diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index df0a51b134..3bb8685597 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -17,6 +17,7 @@ metadata: labels: app.kubernetes.io/component: che-operator app.kubernetes.io/instance: che + app.kubernetes.io/part-of: che.eclipse.org app.kubernetes.io/name: che name: che-operator rules: diff --git a/config/rbac/role_binding.yaml b/config/rbac/role_binding.yaml index 5a54b8a8f0..8be6b8be23 100644 --- a/config/rbac/role_binding.yaml +++ b/config/rbac/role_binding.yaml @@ -17,6 +17,7 @@ metadata: labels: app.kubernetes.io/name: che app.kubernetes.io/instance: che + app.kubernetes.io/part-of: che.eclipse.org app.kubernetes.io/component: che-operator roleRef: apiGroup: rbac.authorization.k8s.io diff --git a/config/rbac/service_account.yaml b/config/rbac/service_account.yaml index 11fae7e5d2..6ba5efd267 100644 --- a/config/rbac/service_account.yaml +++ b/config/rbac/service_account.yaml @@ -17,4 +17,5 @@ metadata: labels: app.kubernetes.io/name: che app.kubernetes.io/instance: che + app.kubernetes.io/part-of: che.eclipse.org app.kubernetes.io/component: che-operator diff --git a/controllers/che/backup_test.go b/controllers/che/backup_test.go index e244c05530..a9338173ce 100644 --- a/controllers/che/backup_test.go +++ b/controllers/che/backup_test.go @@ -188,9 +188,9 @@ func TestGetBackupServerConfigurationNameForBackupBeforeUpdate(t *testing.T) { deployContext := &deploy.DeployContext{ CheCluster: testCase.cheCluster, ClusterAPI: deploy.ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme, }, } diff --git a/controllers/che/checluster_controller.go b/controllers/che/checluster_controller.go index beeba0e83d..07e36f7cd0 100644 --- a/controllers/che/checluster_controller.go +++ b/controllers/che/checluster_controller.go @@ -23,6 +23,7 @@ import ( "github.com/eclipse-che/che-operator/pkg/deploy/devfileregistry" "github.com/eclipse-che/che-operator/pkg/deploy/gateway" imagepuller "github.com/eclipse-che/che-operator/pkg/deploy/image-puller" + "github.com/eclipse-che/che-operator/pkg/deploy/migration" openshiftoauth "github.com/eclipse-che/che-operator/pkg/deploy/openshift-oauth" "github.com/eclipse-che/che-operator/pkg/deploy/pluginregistry" "github.com/eclipse-che/che-operator/pkg/deploy/postgres" @@ -87,6 +88,7 @@ func NewReconciler( // order does matter if !util.IsTestMode() { + reconcileManager.RegisterReconciler(migration.NewMigrator()) reconcileManager.RegisterReconciler(NewCheClusterValidator()) } reconcileManager.RegisterReconciler(imagepuller.NewImagePuller()) @@ -222,10 +224,10 @@ func (r *CheClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) tests := r.tests clusterAPI := deploy.ClusterAPI{ - Client: r.client, - NonCachedClient: r.nonCachedClient, - DiscoveryClient: r.discoveryClient, - Scheme: r.Scheme, + Client: r.client, + NonCachingClient: r.nonCachedClient, + DiscoveryClient: r.discoveryClient, + Scheme: r.Scheme, } // Fetch the CheCluster instance diff --git a/controllers/che/checluster_controller_test.go b/controllers/che/checluster_controller_test.go index 8861de1fcd..a87acad2ca 100644 --- a/controllers/che/checluster_controller_test.go +++ b/controllers/che/checluster_controller_test.go @@ -536,9 +536,9 @@ func TestCheController(t *testing.T) { } clusterAPI := deploy.ClusterAPI{ - Client: r.client, - NonCachedClient: r.client, - Scheme: r.Scheme, + Client: r.client, + NonCachingClient: r.client, + Scheme: r.Scheme, } deployContext := &deploy.DeployContext{ diff --git a/controllers/che/cheobj_verifier.go b/controllers/che/cheobj_verifier.go index f3c75d52e4..0c02523c7b 100644 --- a/controllers/che/cheobj_verifier.go +++ b/controllers/che/cheobj_verifier.go @@ -56,6 +56,12 @@ func IsTrustedBundleConfigMap(cl client.Client, watchNamespace string, obj clien // ignore not matched labels return false, ctrl.Request{} } + + // Check for instance label + if value, exists := obj.GetLabels()[deploy.KubernetesInstanceLabelKey]; !exists || value != deploy.DefaultCheFlavor(checluster) { + // Ignore config map with missing instance label + return false, ctrl.Request{} + } } return true, ctrl.Request{ @@ -66,14 +72,10 @@ func IsTrustedBundleConfigMap(cl client.Client, watchNamespace string, obj clien } } -// isEclipseCheRelatedObj indicates if there is a object with -// the label 'app.kubernetes.io/part-of=che.eclipse.org' in a che namespace +// isEclipseCheRelatedObj indicates if there is an object in a che namespace with the labels: +// - 'app.kubernetes.io/part-of=che.eclipse.org' +// - 'app.kubernetes.io/instance=che' 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{} @@ -92,6 +94,16 @@ func IsEclipseCheRelatedObj(cl client.Client, watchNamespace string, obj client. return false, ctrl.Request{} } + // Check for part-of label + if value, exists := obj.GetLabels()[deploy.KubernetesPartOfLabelKey]; !exists || value != deploy.CheEclipseOrg { + return false, ctrl.Request{} + } + + // Check for instance label + if value, exists := obj.GetLabels()[deploy.KubernetesInstanceLabelKey]; !exists || value != deploy.DefaultCheFlavor(checluster) { + return false, ctrl.Request{} + } + return true, ctrl.Request{ NamespacedName: types.NamespacedName{ Namespace: checluster.Namespace, diff --git a/controllers/che/cheobj_verifier_test.go b/controllers/che/cheobj_verifier_test.go index f09eaee705..27ec75fa5b 100644 --- a/controllers/che/cheobj_verifier_test.go +++ b/controllers/che/cheobj_verifier_test.go @@ -40,8 +40,12 @@ func TestIsTrustedBundleConfigMap(t *testing.T) { 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"}, + Name: "test", + Labels: map[string]string{ + "app.kubernetes.io/part-of": "che.eclipse.org", + "app.kubernetes.io/component": "ca-bundle", + "app.kubernetes.io/instance": "che", + }, }, } @@ -134,7 +138,7 @@ func TestIsTrustedBundleConfigMap(t *testing.T) { newTestObject.ObjectMeta.Labels = testCase.objLabels } - isEclipseCheObj, req := IsTrustedBundleConfigMap(deployContext.ClusterAPI.NonCachedClient, testCase.watchNamespace, newTestObject) + isEclipseCheObj, req := IsTrustedBundleConfigMap(deployContext.ClusterAPI.NonCachingClient, testCase.watchNamespace, newTestObject) assert.Equal(t, testCase.expectedIsEclipseCheObj, isEclipseCheObj) if isEclipseCheObj { @@ -160,8 +164,11 @@ func TestIsEclipseCheRelatedObj(t *testing.T) { APIVersion: "v1", }, ObjectMeta: metav1.ObjectMeta{ - Name: "test", - Labels: map[string]string{"app.kubernetes.io/part-of": "che.eclipse.org"}, + Name: "test", + Labels: map[string]string{ + "app.kubernetes.io/part-of": "che.eclipse.org", + "app.kubernetes.io/instance": "che", + }, }, } @@ -225,7 +232,7 @@ func TestIsEclipseCheRelatedObj(t *testing.T) { deployContext := deploy.GetTestDeployContext(nil, testCase.initObjects) testObject.ObjectMeta.Namespace = testCase.objNamespace - isEclipseCheObj, req := IsEclipseCheRelatedObj(deployContext.ClusterAPI.NonCachedClient, testCase.watchNamespace, testObject) + isEclipseCheObj, req := IsEclipseCheRelatedObj(deployContext.ClusterAPI.NonCachingClient, testCase.watchNamespace, testObject) assert.Equal(t, testCase.expectedIsEclipseCheObj, isEclipseCheObj) if isEclipseCheObj { diff --git a/controllers/che/configmap_cert_test.go b/controllers/che/configmap_cert_test.go index 35e3675dac..d830b3648a 100644 --- a/controllers/che/configmap_cert_test.go +++ b/controllers/che/configmap_cert_test.go @@ -43,9 +43,9 @@ func TestSyncTrustStoreConfigMapToCluster(t *testing.T) { }, }, ClusterAPI: deploy.ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, } @@ -81,9 +81,9 @@ func TestSyncExistedTrustStoreConfigMapToCluster(t *testing.T) { }, }, ClusterAPI: deploy.ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, } diff --git a/controllers/che/proxy_test.go b/controllers/che/proxy_test.go index 261bc0eb93..8f138fbbe3 100644 --- a/controllers/che/proxy_test.go +++ b/controllers/che/proxy_test.go @@ -328,9 +328,9 @@ func TestReadProxyConfiguration(t *testing.T) { deployContext := &deploy.DeployContext{ CheCluster: testCase.cheCluster, ClusterAPI: deploy.ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme, }, } diff --git a/controllers/checlusterbackup/backup_data_collector.go b/controllers/checlusterbackup/backup_data_collector.go index c8eecbc131..3eb79d2570 100644 --- a/controllers/checlusterbackup/backup_data_collector.go +++ b/controllers/checlusterbackup/backup_data_collector.go @@ -220,11 +220,7 @@ func backupConfigMaps(bctx *BackupContext, destDir string) (bool, error) { return true, err } - fakeDeployContext := &deploy.DeployContext{ - ClusterAPI: deploy.ClusterAPI{Client: bctx.r.nonCachingClient}, - CheCluster: bctx.cheCR, - } - caBundlesConfigmaps, err := deploy.GetCACertsConfigMaps(fakeDeployContext) + caBundlesConfigmaps, err := deploy.GetCACertsConfigMaps(bctx.r.nonCachingClient, bctx.cheCR.GetNamespace()) if err != nil { return false, err } diff --git a/controllers/usernamespace/controller.go b/controllers/usernamespace/controller.go index 72ef6d7ded..b52af0b384 100644 --- a/controllers/usernamespace/controller.go +++ b/controllers/usernamespace/controller.go @@ -205,10 +205,10 @@ func (r *CheUserNamespaceReconciler) Reconcile(ctx context.Context, req ctrl.Req deployContext := &deploy.DeployContext{ CheCluster: org.AsV1(checluster), ClusterAPI: deploy.ClusterAPI{ - Client: r.client, - NonCachedClient: r.client, - DiscoveryClient: nil, - Scheme: r.scheme, + Client: r.client, + NonCachingClient: r.client, + DiscoveryClient: nil, + Scheme: r.scheme, }, } diff --git a/main.go b/main.go index 1ddb2b1e42..57979b86b3 100644 --- a/main.go +++ b/main.go @@ -18,6 +18,7 @@ import ( "time" "github.com/devfile/devworkspace-operator/pkg/infrastructure" + "github.com/sirupsen/logrus" dwoApi "github.com/devfile/devworkspace-operator/apis/controller/v1alpha1" dwr "github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting" @@ -32,8 +33,11 @@ import ( "k8s.io/client-go/discovery" _ "k8s.io/client-go/plugin/pkg/client/auth" + "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/selection" ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/cache" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/healthz" "sigs.k8s.io/controller-runtime/pkg/log/zap" @@ -62,14 +66,17 @@ import ( operatorsv1 "github.com/operator-framework/api/pkg/operators/v1" operatorsv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1" packagesv1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1" - rbac "k8s.io/api/rbac/v1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" image_puller_api "github.com/che-incubator/kubernetes-image-puller-operator/api/v1alpha1" projectv1 "github.com/openshift/api/project/v1" routev1 "github.com/openshift/api/route/v1" userv1 "github.com/openshift/api/user/v1" + appsv1 "k8s.io/api/apps/v1" + batchv1 "k8s.io/api/batch/v1" corev1 "k8s.io/api/core/v1" + networkingv1 "k8s.io/api/networking/v1" + rbacv1 "k8s.io/api/rbac/v1" orgv2alpha1 "github.com/eclipse-che/che-operator/api/v2alpha1" //+kubebuilder:scaffold:imports @@ -126,7 +133,7 @@ func init() { utilruntime.Must(clientgoscheme.AddToScheme(scheme)) utilruntime.Must(admissionregistrationv1.AddToScheme(scheme)) utilruntime.Must(apiextensionsv1.AddToScheme(scheme)) - utilruntime.Must(rbac.AddToScheme(scheme)) + utilruntime.Must(rbacv1.AddToScheme(scheme)) // Setup Scheme for all resources utilruntime.Must(orgv1.AddToScheme(scheme)) @@ -216,6 +223,12 @@ func main() { enableLeaderElection = false } + cacheFunction, err := getCacheFunc() + if err != nil { + setupLog.Error(err, "failed to create cache function") + os.Exit(1) + } + mgr, err := ctrl.NewManager(config, ctrl.Options{ Scheme: scheme, MetricsBindAddress: metricsAddr, @@ -226,6 +239,7 @@ func main() { LeaderElectionReleaseOnCancel: true, LeaseDuration: &leaseDuration, RenewDeadline: &renewDeadline, + NewCache: cacheFunction, // NOTE: We CANNOT limit the manager to a single namespace, because that would limit the // devworkspace routing reconciler to a single namespace, which would make it totally unusable. @@ -238,15 +252,15 @@ func main() { os.Exit(1) } - noncachedClient, err := client.New(mgr.GetConfig(), client.Options{Scheme: scheme}) + nonCachingClient, err := client.New(mgr.GetConfig(), client.Options{Scheme: scheme}) if err != nil { setupLog.Error(err, "unable to initialize non cached client") os.Exit(1) } - cheReconciler := checontroller.NewReconciler(mgr.GetClient(), noncachedClient, discoveryClient, mgr.GetScheme(), watchNamespace) - backupReconciler := backupcontroller.NewReconciler(mgr.GetClient(), noncachedClient, mgr.GetScheme(), watchNamespace) - restoreReconciler := restorecontroller.NewReconciler(mgr.GetClient(), noncachedClient, mgr.GetScheme(), watchNamespace) + cheReconciler := checontroller.NewReconciler(mgr.GetClient(), nonCachingClient, discoveryClient, mgr.GetScheme(), watchNamespace) + backupReconciler := backupcontroller.NewReconciler(mgr.GetClient(), nonCachingClient, mgr.GetScheme(), watchNamespace) + restoreReconciler := restorecontroller.NewReconciler(mgr.GetClient(), nonCachingClient, mgr.GetScheme(), watchNamespace) if err = cheReconciler.SetupWithManager(mgr); err != nil { setupLog.Error(err, "unable to set up controller", "controller", "CheCluster") @@ -331,3 +345,67 @@ func main() { os.Exit(1) } } + +func getCacheFunc() (cache.NewCacheFunc, error) { + partOfCheRequirement, err := labels.NewRequirement(deploy.KubernetesPartOfLabelKey, selection.Equals, []string{deploy.CheEclipseOrg}) + if err != nil { + return nil, err + } + partOfCheObjectSelector := labels.NewSelector().Add(*partOfCheRequirement) + + logrus.Infof("Limit cache by selector: %s", partOfCheObjectSelector.String()) + + routeKey := &routev1.Route{} + selectors := cache.SelectorsByObject{ + &appsv1.Deployment{}: { + Label: partOfCheObjectSelector, + }, + &corev1.Pod{}: { + Label: partOfCheObjectSelector, + }, + &batchv1.Job{}: { + Label: partOfCheObjectSelector, + }, + &corev1.Service{}: { + Label: partOfCheObjectSelector, + }, + &networkingv1.Ingress{}: { + Label: partOfCheObjectSelector, + }, + routeKey: { + Label: partOfCheObjectSelector, + }, + &corev1.ConfigMap{}: { + Label: partOfCheObjectSelector, + }, + &corev1.Secret{}: { + Label: partOfCheObjectSelector, + }, + &corev1.ServiceAccount{}: { + Label: partOfCheObjectSelector, + }, + &rbacv1.Role{}: { + Label: partOfCheObjectSelector, + }, + &rbacv1.RoleBinding{}: { + Label: partOfCheObjectSelector, + }, + &rbacv1.ClusterRole{}: { + Label: partOfCheObjectSelector, + }, + &rbacv1.ClusterRoleBinding{}: { + Label: partOfCheObjectSelector, + }, + &corev1.PersistentVolumeClaim{}: { + Label: partOfCheObjectSelector, + }, + } + + if !util.IsOpenShift { + delete(selectors, routeKey) + } + + return cache.BuilderWithOptions(cache.Options{ + SelectorsByObject: selectors, + }), nil +} diff --git a/pkg/deploy/checluster_test.go b/pkg/deploy/checluster_test.go index 42df0ec3ad..ada9ee8e3e 100644 --- a/pkg/deploy/checluster_test.go +++ b/pkg/deploy/checluster_test.go @@ -43,9 +43,9 @@ func TestReload(t *testing.T) { deployContext := &DeployContext{ CheCluster: cheCluster, ClusterAPI: ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, } diff --git a/pkg/deploy/clusterrole_test.go b/pkg/deploy/clusterrole_test.go index 8722233017..5e00601301 100644 --- a/pkg/deploy/clusterrole_test.go +++ b/pkg/deploy/clusterrole_test.go @@ -36,9 +36,9 @@ func TestSyncClusterRole(t *testing.T) { }, }, ClusterAPI: ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, } diff --git a/pkg/deploy/clusterrolebinding_test.go b/pkg/deploy/clusterrolebinding_test.go index f80cf5856b..87fa01ee9b 100644 --- a/pkg/deploy/clusterrolebinding_test.go +++ b/pkg/deploy/clusterrolebinding_test.go @@ -37,9 +37,9 @@ func TestSyncClusterRoleBindingToCluster(t *testing.T) { }, }, ClusterAPI: ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, } @@ -83,9 +83,9 @@ func TestSyncClusterRoleBindingAndAddFinalizerToCluster(t *testing.T) { }, }, ClusterAPI: ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, } cli.Create(context.TODO(), deployContext.CheCluster) diff --git a/pkg/deploy/configmap_test.go b/pkg/deploy/configmap_test.go index f876212640..e657334172 100644 --- a/pkg/deploy/configmap_test.go +++ b/pkg/deploy/configmap_test.go @@ -36,9 +36,9 @@ func TestSyncConfigMapDataToCluster(t *testing.T) { }, }, ClusterAPI: ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, } @@ -86,9 +86,9 @@ func TestSyncConfigMapSpecDataToCluster(t *testing.T) { }, }, ClusterAPI: ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, } diff --git a/pkg/deploy/consolelink_test.go b/pkg/deploy/consolelink_test.go index b79b66c411..832f092e23 100644 --- a/pkg/deploy/consolelink_test.go +++ b/pkg/deploy/consolelink_test.go @@ -60,10 +60,10 @@ func TestReconcileConsoleLink(t *testing.T) { deployContext := &DeployContext{ CheCluster: cheCluster, ClusterAPI: ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme, - DiscoveryClient: fakeDiscovery, + Client: cli, + NonCachingClient: cli, + Scheme: scheme, + DiscoveryClient: fakeDiscovery, }, } diff --git a/pkg/deploy/dashboard/dashboard_deployment_test.go b/pkg/deploy/dashboard/dashboard_deployment_test.go index 90ec9308d6..736c7c5d84 100644 --- a/pkg/deploy/dashboard/dashboard_deployment_test.go +++ b/pkg/deploy/dashboard/dashboard_deployment_test.go @@ -52,9 +52,9 @@ func TestDashboardDeploymentSecurityContext(t *testing.T) { }, }, ClusterAPI: deploy.ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, Proxy: &deploy.Proxy{}, } @@ -127,9 +127,9 @@ func TestDashboardDeploymentResources(t *testing.T) { deployContext := &deploy.DeployContext{ CheCluster: testCase.cheCluster, ClusterAPI: deploy.ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, Proxy: &deploy.Proxy{}, } @@ -276,9 +276,9 @@ func TestDashboardDeploymentEnvVars(t *testing.T) { deployContext := &deploy.DeployContext{ CheCluster: testCase.cheCluster, ClusterAPI: deploy.ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, Proxy: &deploy.Proxy{}, } @@ -394,9 +394,9 @@ func TestDashboardDeploymentVolumes(t *testing.T) { deployContext := &deploy.DeployContext{ CheCluster: testCase.cheCluster, ClusterAPI: deploy.ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, Proxy: &deploy.Proxy{}, } diff --git a/pkg/deploy/dashboard/dashboard_test.go b/pkg/deploy/dashboard/dashboard_test.go index 1d704b6267..1fc307bca8 100644 --- a/pkg/deploy/dashboard/dashboard_test.go +++ b/pkg/deploy/dashboard/dashboard_test.go @@ -53,9 +53,9 @@ func TestDashboardOpenShift(t *testing.T) { deployContext := &deploy.DeployContext{ CheCluster: cheCluster, ClusterAPI: deploy.ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, } @@ -93,9 +93,9 @@ func TestDashboardKubernetes(t *testing.T) { deployContext := &deploy.DeployContext{ CheCluster: cheCluster, ClusterAPI: deploy.ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, } @@ -133,9 +133,9 @@ func TestDashboardClusterRBACFinalizerOnKubernetes(t *testing.T) { deployContext := &deploy.DeployContext{ CheCluster: cheCluster, ClusterAPI: deploy.ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, } diff --git a/pkg/deploy/dashboard/deployment_dashboard.go b/pkg/deploy/dashboard/deployment_dashboard.go index d9e3eb4e92..8cfbcfbccc 100644 --- a/pkg/deploy/dashboard/deployment_dashboard.go +++ b/pkg/deploy/dashboard/deployment_dashboard.go @@ -201,7 +201,7 @@ func (d *Dashboard) getDashboardDeploymentSpec() (*appsv1.Deployment, error) { func (d *Dashboard) evaluateOpenShiftConsoleURL() string { console := &configv1.Console{} - err := d.deployContext.ClusterAPI.NonCachedClient.Get(context.TODO(), types.NamespacedName{ + err := d.deployContext.ClusterAPI.NonCachingClient.Get(context.TODO(), types.NamespacedName{ Name: "cluster", Namespace: "openshift-console", }, console) diff --git a/pkg/deploy/data_types.go b/pkg/deploy/data_types.go index ca0da8e1b4..1eaad441bf 100644 --- a/pkg/deploy/data_types.go +++ b/pkg/deploy/data_types.go @@ -33,10 +33,10 @@ type DeployContext struct { } type ClusterAPI struct { - Client client.Client - NonCachedClient client.Client - DiscoveryClient discovery.DiscoveryInterface - Scheme *runtime.Scheme + Client client.Client + NonCachingClient client.Client + DiscoveryClient discovery.DiscoveryInterface + Scheme *runtime.Scheme } type Proxy struct { diff --git a/pkg/deploy/defaults.go b/pkg/deploy/defaults.go index 6ba5d6e57f..9da0b9d493 100644 --- a/pkg/deploy/defaults.go +++ b/pkg/deploy/defaults.go @@ -125,6 +125,9 @@ const ( // CheServiceAccountName - service account name for che-server. CheServiceAccountName = "che" + // Name of the secret that holds self-signed certificate for git connections + GitSelfSignedCertsConfigMapName = "che-git-self-signed-cert" + // limits DefaultDashboardMemoryLimit = "256Mi" DefaultDashboardMemoryRequest = "32Mi" diff --git a/pkg/deploy/deployment_test.go b/pkg/deploy/deployment_test.go index 156488fb8a..9c7e8778a9 100644 --- a/pkg/deploy/deployment_test.go +++ b/pkg/deploy/deployment_test.go @@ -313,9 +313,9 @@ func TestMountSecret(t *testing.T) { }, }, ClusterAPI: ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, } @@ -591,9 +591,9 @@ func TestMountConfigMaps(t *testing.T) { }, }, ClusterAPI: ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, } @@ -620,9 +620,9 @@ func TestSyncEnvVarDeploymentToCluster(t *testing.T) { }, }, ClusterAPI: ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, Proxy: &Proxy{}, } diff --git a/pkg/deploy/dev-workspace/dev_workspace.go b/pkg/deploy/dev-workspace/dev_workspace.go index d8a376568b..46e4fd428b 100644 --- a/pkg/deploy/dev-workspace/dev_workspace.go +++ b/pkg/deploy/dev-workspace/dev_workspace.go @@ -105,7 +105,7 @@ func ReconcileDevWorkspace(deployContext *deploy.DeployContext) (done bool, err } if !isCreated { namespace := &corev1.Namespace{} - err := deployContext.ClusterAPI.NonCachedClient.Get(context.TODO(), types.NamespacedName{Name: DevWorkspaceNamespace}, namespace) + err := deployContext.ClusterAPI.NonCachingClient.Get(context.TODO(), types.NamespacedName{Name: DevWorkspaceNamespace}, namespace) if err != nil { return false, err } @@ -193,7 +193,7 @@ func doesWebTerminalSubscriptionExist(deployContext *deploy.DeployContext) (bool } subscription := &operatorsv1alpha1.Subscription{} - if err := deployContext.ClusterAPI.NonCachedClient.Get( + if err := deployContext.ClusterAPI.NonCachingClient.Get( context.TODO(), types.NamespacedName{ Name: WebTerminalOperatorSubscriptionName, @@ -226,7 +226,7 @@ func createDwNamespace(deployContext *deploy.DeployContext) (bool, error) { func isOnlyOneOperatorManagesDWResources(deployContext *deploy.DeployContext) (bool, error) { cheClusters := &orgv1.CheClusterList{} - err := deployContext.ClusterAPI.NonCachedClient.List(context.TODO(), cheClusters) + err := deployContext.ClusterAPI.NonCachingClient.List(context.TODO(), cheClusters) if err != nil { return false, err } diff --git a/pkg/deploy/dev-workspace/dev_workspace_test.go b/pkg/deploy/dev-workspace/dev_workspace_test.go index 1934187ed6..09e3895508 100644 --- a/pkg/deploy/dev-workspace/dev_workspace_test.go +++ b/pkg/deploy/dev-workspace/dev_workspace_test.go @@ -247,7 +247,7 @@ func TestReconcileWhenWebTerminalSubscriptionExists(t *testing.T) { // verify that DWO is not provisioned namespace := &corev1.Namespace{} - err = deployContext.ClusterAPI.NonCachedClient.Get(context.TODO(), types.NamespacedName{Name: DevWorkspaceNamespace}, namespace) + err = deployContext.ClusterAPI.NonCachingClient.Get(context.TODO(), types.NamespacedName{Name: DevWorkspaceNamespace}, namespace) assert.True(t, k8sErrors.IsNotFound(err)) } @@ -356,7 +356,7 @@ func TestReconcileDevWorkspaceIfManagedDWONamespaceExists(t *testing.T) { }, } deployContext := deploy.GetTestDeployContext(cheCluster, []runtime.Object{}) - err := deployContext.ClusterAPI.NonCachedClient.Create(context.TODO(), dwoNamespace) + err := deployContext.ClusterAPI.NonCachingClient.Create(context.TODO(), dwoNamespace) assert.NoError(t, err) exists, err := deploy.Get(deployContext, @@ -404,7 +404,7 @@ func TestReconcileDevWorkspaceIfManagedDWOShouldBeTakenUnderControl(t *testing.T } deployContext := deploy.GetTestDeployContext(cheCluster, []runtime.Object{}) deployContext.ClusterAPI.Scheme.AddKnownTypes(crdv1.SchemeGroupVersion, &crdv1.CustomResourceDefinition{}) - err := deployContext.ClusterAPI.NonCachedClient.Create(context.TODO(), dwoNamespace) + err := deployContext.ClusterAPI.NonCachingClient.Create(context.TODO(), dwoNamespace) assert.NoError(t, err) exists, err := deploy.Get(deployContext, @@ -471,9 +471,9 @@ func TestReconcileDevWorkspaceIfManagedDWOShouldNotBeTakenUnderControl(t *testin } deployContext := deploy.GetTestDeployContext(cheCluster, []runtime.Object{}) deployContext.ClusterAPI.Scheme.AddKnownTypes(crdv1.SchemeGroupVersion, &crdv1.CustomResourceDefinition{}) - err := deployContext.ClusterAPI.NonCachedClient.Create(context.TODO(), dwoNamespace) + err := deployContext.ClusterAPI.NonCachingClient.Create(context.TODO(), dwoNamespace) assert.NoError(t, err) - err = deployContext.ClusterAPI.NonCachedClient.Create(context.TODO(), cheCluster2) + err = deployContext.ClusterAPI.NonCachingClient.Create(context.TODO(), cheCluster2) assert.NoError(t, err) exists, err := deploy.Get(deployContext, diff --git a/pkg/deploy/devfileregistry/devfileregistry_test.go b/pkg/deploy/devfileregistry/devfileregistry_test.go index a6f98557c8..ad8f32f185 100644 --- a/pkg/deploy/devfileregistry/devfileregistry_test.go +++ b/pkg/deploy/devfileregistry/devfileregistry_test.go @@ -44,9 +44,9 @@ func TestDevfileRegistrySyncAll(t *testing.T) { deployContext := &deploy.DeployContext{ CheCluster: cheCluster, ClusterAPI: deploy.ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, } diff --git a/pkg/deploy/gateway/gateway_test.go b/pkg/deploy/gateway/gateway_test.go index 02ffefa1a3..9947dacad6 100644 --- a/pkg/deploy/gateway/gateway_test.go +++ b/pkg/deploy/gateway/gateway_test.go @@ -49,9 +49,9 @@ func TestSyncAllToCluster(t *testing.T) { }, }, ClusterAPI: deploy.ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, } @@ -99,9 +99,9 @@ func TestNativeUserGateway(t *testing.T) { }, }, ClusterAPI: deploy.ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, } @@ -152,9 +152,9 @@ func TestNoGatewayForMultiHost(t *testing.T) { }, }, ClusterAPI: deploy.ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, } diff --git a/pkg/deploy/identity-provider/deployment_keycloak_test.go b/pkg/deploy/identity-provider/deployment_keycloak_test.go index f5e2a95002..8f7bc3e1ee 100644 --- a/pkg/deploy/identity-provider/deployment_keycloak_test.go +++ b/pkg/deploy/identity-provider/deployment_keycloak_test.go @@ -238,9 +238,9 @@ func TestSyncKeycloakDeploymentToCluster(t *testing.T) { }, }, ClusterAPI: deploy.ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, Proxy: &deploy.Proxy{}, } diff --git a/pkg/deploy/identity-provider/identity_provider.go b/pkg/deploy/identity-provider/identity_provider.go index f0aaad5955..ee2c769b9b 100644 --- a/pkg/deploy/identity-provider/identity_provider.go +++ b/pkg/deploy/identity-provider/identity_provider.go @@ -347,10 +347,10 @@ func ReconcileIdentityProvider(deployContext *deploy.DeployContext) (deleted boo if err == nil { oAuthClient := &oauth.OAuthClient{} oAuthClientName := deployContext.CheCluster.Spec.Auth.OAuthClientName - if err := deployContext.ClusterAPI.NonCachedClient.Get(context.TODO(), types.NamespacedName{Name: oAuthClientName, Namespace: ""}, oAuthClient); err != nil { + if err := deployContext.ClusterAPI.NonCachingClient.Get(context.TODO(), types.NamespacedName{Name: oAuthClientName, Namespace: ""}, oAuthClient); err != nil { logrus.Errorf("OAuthClient %s not found: %s", oAuthClient.Name, err.Error()) } - if err := deployContext.ClusterAPI.NonCachedClient.Delete(context.TODO(), oAuthClient); err != nil { + if err := deployContext.ClusterAPI.NonCachingClient.Delete(context.TODO(), oAuthClient); err != nil { logrus.Errorf("Failed to delete %s %s: %s", oAuthClient.Kind, oAuthClient.Name, err.Error()) } return true, nil diff --git a/pkg/deploy/image-puller/imagepuller.go b/pkg/deploy/image-puller/imagepuller.go index f4c4e2f63b..d96f686273 100644 --- a/pkg/deploy/image-puller/imagepuller.go +++ b/pkg/deploy/image-puller/imagepuller.go @@ -242,7 +242,7 @@ func ReconcileImagePullerFinalizer(ctx *deploy.DeployContext) (err error) { clusterServiceVersionName := deploy.DefaultKubernetesImagePullerOperatorCSV() logrus.Infof("Custom resource %s is being deleted. Deleting ClusterServiceVersion %s first", instance.Name, clusterServiceVersionName) clusterServiceVersion := &operatorsv1alpha1.ClusterServiceVersion{} - err := ctx.ClusterAPI.NonCachedClient.Get(context.TODO(), types.NamespacedName{Namespace: instance.Namespace, Name: clusterServiceVersionName}, clusterServiceVersion) + err := ctx.ClusterAPI.NonCachingClient.Get(context.TODO(), types.NamespacedName{Namespace: instance.Namespace, Name: clusterServiceVersionName}, clusterServiceVersion) if err != nil { logrus.Errorf("Error getting ClusterServiceVersion: %v", err) return err @@ -316,7 +316,7 @@ func CheckNeededImagePullerApis(ctx *deploy.DeployContext) (bool, bool, bool, er // Search for the kubernetes-imagepuller-operator PackageManifest func GetPackageManifest(ctx *deploy.DeployContext) (*packagesv1.PackageManifest, error) { packageManifest := &packagesv1.PackageManifest{} - err := ctx.ClusterAPI.NonCachedClient.Get(context.TODO(), types.NamespacedName{Namespace: ctx.CheCluster.Namespace, Name: "kubernetes-imagepuller-operator"}, packageManifest) + err := ctx.ClusterAPI.NonCachingClient.Get(context.TODO(), types.NamespacedName{Namespace: ctx.CheCluster.Namespace, Name: "kubernetes-imagepuller-operator"}, packageManifest) if err != nil { return packageManifest, err } @@ -327,7 +327,7 @@ func GetPackageManifest(ctx *deploy.DeployContext) (*packagesv1.PackageManifest, // OperatorGroup was created, and any error returned during the List and Create operation func CreateOperatorGroupIfNotFound(ctx *deploy.DeployContext) (bool, error) { operatorGroupList := &operatorsv1.OperatorGroupList{} - err := ctx.ClusterAPI.NonCachedClient.List(context.TODO(), operatorGroupList, &client.ListOptions{Namespace: ctx.CheCluster.Namespace}) + err := ctx.ClusterAPI.NonCachingClient.List(context.TODO(), operatorGroupList, &client.ListOptions{Namespace: ctx.CheCluster.Namespace}) if err != nil { return false, err } @@ -348,7 +348,7 @@ func CreateOperatorGroupIfNotFound(ctx *deploy.DeployContext) (bool, error) { }, } logrus.Infof("Creating kubernetes image puller OperatorGroup") - if err = ctx.ClusterAPI.NonCachedClient.Create(context.TODO(), operatorGroup, &client.CreateOptions{}); err != nil { + if err = ctx.ClusterAPI.NonCachingClient.Create(context.TODO(), operatorGroup, &client.CreateOptions{}); err != nil { return false, err } return true, nil @@ -358,14 +358,14 @@ func CreateOperatorGroupIfNotFound(ctx *deploy.DeployContext) (bool, error) { func CreateImagePullerSubscription(ctx *deploy.DeployContext, packageManifest *packagesv1.PackageManifest) (bool, error) { imagePullerOperatorSubscription := &operatorsv1alpha1.Subscription{} - err := ctx.ClusterAPI.NonCachedClient.Get(context.TODO(), types.NamespacedName{ + err := ctx.ClusterAPI.NonCachingClient.Get(context.TODO(), types.NamespacedName{ Name: "kubernetes-imagepuller-operator", Namespace: ctx.CheCluster.Namespace, }, imagePullerOperatorSubscription) if err != nil { if errors.IsNotFound(err) { logrus.Info("Creating kubernetes image puller operator Subscription") - err = ctx.ClusterAPI.NonCachedClient.Create(context.TODO(), GetExpectedSubscription(ctx, packageManifest), &client.CreateOptions{}) + err = ctx.ClusterAPI.NonCachingClient.Create(context.TODO(), GetExpectedSubscription(ctx, packageManifest), &client.CreateOptions{}) if err != nil { return false, err } @@ -397,7 +397,7 @@ func GetExpectedSubscription(ctx *deploy.DeployContext, packageManifest *package func GetActualSubscription(ctx *deploy.DeployContext) (*operatorsv1alpha1.Subscription, error) { actual := &operatorsv1alpha1.Subscription{} - err := ctx.ClusterAPI.NonCachedClient.Get(context.TODO(), types.NamespacedName{Namespace: ctx.CheCluster.Namespace, Name: "kubernetes-imagepuller-operator"}, actual) + err := ctx.ClusterAPI.NonCachingClient.Get(context.TODO(), types.NamespacedName{Namespace: ctx.CheCluster.Namespace, Name: "kubernetes-imagepuller-operator"}, actual) if err != nil { return nil, err } @@ -538,8 +538,8 @@ func GetExpectedKubernetesImagePuller(ctx *deploy.DeployContext) *chev1alpha1.Ku *metav1.NewControllerRef(ctx.CheCluster, ctx.CheCluster.GroupVersionKind()), }, Labels: map[string]string{ - "app.kubernetes.io/part-of": ctx.CheCluster.Name, - "app": "che", + "app.kubernetes.io/part-of": deploy.CheEclipseOrg, + "app": deploy.DefaultCheFlavor(ctx.CheCluster), "component": "kubernetes-image-puller", }, }, @@ -612,14 +612,14 @@ func UninstallImagePullerOperator(ctx *deploy.DeployContext) (bool, error) { if hasOperatorsAPIs { // Delete the ClusterServiceVersion csv := &operatorsv1alpha1.ClusterServiceVersion{} - err = ctx.ClusterAPI.NonCachedClient.Get(context.TODO(), types.NamespacedName{Namespace: ctx.CheCluster.Namespace, Name: deploy.DefaultKubernetesImagePullerOperatorCSV()}, csv) + err = ctx.ClusterAPI.NonCachingClient.Get(context.TODO(), types.NamespacedName{Namespace: ctx.CheCluster.Namespace, Name: deploy.DefaultKubernetesImagePullerOperatorCSV()}, csv) if err != nil && !errors.IsNotFound(err) { return updated, err } if csv.Name != "" { logrus.Infof("Deleting ClusterServiceVersion %v", csv.Name) - err := ctx.ClusterAPI.NonCachedClient.Delete(context.TODO(), csv, &client.DeleteOptions{}) + err := ctx.ClusterAPI.NonCachingClient.Delete(context.TODO(), csv, &client.DeleteOptions{}) if err != nil && !errors.IsNotFound(err) { return updated, err } @@ -627,28 +627,28 @@ func UninstallImagePullerOperator(ctx *deploy.DeployContext) (bool, error) { // Delete the Subscription subscription := &operatorsv1alpha1.Subscription{} - err = ctx.ClusterAPI.NonCachedClient.Get(context.TODO(), types.NamespacedName{Namespace: ctx.CheCluster.Namespace, Name: "kubernetes-imagepuller-operator"}, subscription) + err = ctx.ClusterAPI.NonCachingClient.Get(context.TODO(), types.NamespacedName{Namespace: ctx.CheCluster.Namespace, Name: "kubernetes-imagepuller-operator"}, subscription) if err != nil && !errors.IsNotFound(err) { return updated, err } if subscription.Name != "" { logrus.Infof("Deleting Subscription %v", subscription.Name) - err := ctx.ClusterAPI.NonCachedClient.Delete(context.TODO(), subscription, &client.DeleteOptions{}) + err := ctx.ClusterAPI.NonCachingClient.Delete(context.TODO(), subscription, &client.DeleteOptions{}) if err != nil && !errors.IsNotFound(err) { return updated, err } } // Delete the OperatorGroup if it was created operatorGroup := &operatorsv1.OperatorGroup{} - err = ctx.ClusterAPI.NonCachedClient.Get(context.TODO(), types.NamespacedName{Namespace: ctx.CheCluster.Namespace, Name: "kubernetes-imagepuller-operator"}, operatorGroup) + err = ctx.ClusterAPI.NonCachingClient.Get(context.TODO(), types.NamespacedName{Namespace: ctx.CheCluster.Namespace, Name: "kubernetes-imagepuller-operator"}, operatorGroup) if err != nil && !errors.IsNotFound(err) { return updated, err } if operatorGroup.Name != "" { logrus.Infof("Deleting OperatorGroup %v", operatorGroup.Name) - err := ctx.ClusterAPI.NonCachedClient.Delete(context.TODO(), operatorGroup, &client.DeleteOptions{}) + err := ctx.ClusterAPI.NonCachingClient.Delete(context.TODO(), operatorGroup, &client.DeleteOptions{}) if err != nil && !errors.IsNotFound(err) { return updated, err } diff --git a/pkg/deploy/image-puller/imagepuller_test.go b/pkg/deploy/image-puller/imagepuller_test.go index 50fffb4227..d6349f9729 100644 --- a/pkg/deploy/image-puller/imagepuller_test.go +++ b/pkg/deploy/image-puller/imagepuller_test.go @@ -225,9 +225,9 @@ func TestImagePullerConfiguration(t *testing.T) { Name: os.Getenv("CHE_FLAVOR") + "-image-puller", Namespace: namespace, Labels: map[string]string{ - "app": "che", + "app": os.Getenv("CHE_FLAVOR"), "component": "kubernetes-image-puller", - "app.kubernetes.io/part-of": os.Getenv("CHE_FLAVOR"), + "app.kubernetes.io/part-of": deploy.CheEclipseOrg, }, OwnerReferences: []metav1.OwnerReference{ { @@ -288,7 +288,7 @@ func TestImagePullerConfiguration(t *testing.T) { for _, obj := range testCase.initObjects { obj.(metav1.Object).SetResourceVersion("") - err := deployContext.ClusterAPI.NonCachedClient.Create(context.TODO(), obj.(client.Object)) + err := deployContext.ClusterAPI.NonCachingClient.Create(context.TODO(), obj.(client.Object)) if err != nil { t.Fatalf(err.Error()) } @@ -334,7 +334,7 @@ func TestImagePullerConfiguration(t *testing.T) { if testCase.expectedOperatorGroup != nil { gotOperatorGroup := &operatorsv1.OperatorGroup{} - err := deployContext.ClusterAPI.NonCachedClient.Get(context.TODO(), types.NamespacedName{Namespace: testCase.expectedOperatorGroup.Namespace, Name: testCase.expectedOperatorGroup.Name}, gotOperatorGroup) + err := deployContext.ClusterAPI.NonCachingClient.Get(context.TODO(), types.NamespacedName{Namespace: testCase.expectedOperatorGroup.Namespace, Name: testCase.expectedOperatorGroup.Name}, gotOperatorGroup) if err != nil { t.Errorf("Error getting OperatorGroup: %v", err) } @@ -344,7 +344,7 @@ func TestImagePullerConfiguration(t *testing.T) { } if testCase.expectedSubscription != nil { gotSubscription := &operatorsv1alpha1.Subscription{} - err := deployContext.ClusterAPI.NonCachedClient.Get(context.TODO(), types.NamespacedName{Namespace: testCase.expectedSubscription.Namespace, Name: testCase.expectedSubscription.Name}, gotSubscription) + err := deployContext.ClusterAPI.NonCachingClient.Get(context.TODO(), types.NamespacedName{Namespace: testCase.expectedSubscription.Namespace, Name: testCase.expectedSubscription.Name}, gotSubscription) if err != nil { t.Errorf("Error getting Subscription: %v", err) } @@ -402,19 +402,19 @@ func TestImagePullerConfiguration(t *testing.T) { } clusterServiceVersion := &operatorsv1alpha1.ClusterServiceVersion{} - err = deployContext.ClusterAPI.NonCachedClient.Get(context.TODO(), types.NamespacedName{Namespace: namespace, Name: csvName}, clusterServiceVersion) + err = deployContext.ClusterAPI.NonCachingClient.Get(context.TODO(), types.NamespacedName{Namespace: namespace, Name: csvName}, clusterServiceVersion) if err == nil || !errors.IsNotFound(err) { t.Fatalf("Should not have found ClusterServiceVersion: %v", err) } subscription := &operatorsv1alpha1.Subscription{} - err = deployContext.ClusterAPI.NonCachedClient.Get(context.TODO(), types.NamespacedName{Namespace: namespace, Name: "kubernetes-imagepuller-operator"}, subscription) + err = deployContext.ClusterAPI.NonCachingClient.Get(context.TODO(), types.NamespacedName{Namespace: namespace, Name: "kubernetes-imagepuller-operator"}, subscription) if err == nil || !errors.IsNotFound(err) { t.Fatalf("Should not have found Subscription: %v", err) } operatorGroup := &operatorsv1.OperatorGroup{} - err = deployContext.ClusterAPI.NonCachedClient.Get(context.TODO(), types.NamespacedName{Namespace: namespace, Name: "kubernetes-imagepuller-operator"}, operatorGroup) + err = deployContext.ClusterAPI.NonCachingClient.Get(context.TODO(), types.NamespacedName{Namespace: namespace, Name: "kubernetes-imagepuller-operator"}, operatorGroup) if err == nil || !errors.IsNotFound(err) { t.Fatalf("Should not have found OperatorGroup: %v", err) } @@ -752,8 +752,8 @@ func InitImagePuller(options ImagePullerOptions) *chev1alpha1.KubernetesImagePul Namespace: namespace, ResourceVersion: options.ObjectMetaResourceVersion, Labels: map[string]string{ - "app.kubernetes.io/part-of": os.Getenv("CHE_FLAVOR"), - "app": "che", + "app.kubernetes.io/part-of": deploy.CheEclipseOrg, + "app": os.Getenv("CHE_FLAVOR"), "component": "kubernetes-image-puller", }, OwnerReferences: []metav1.OwnerReference{ @@ -784,8 +784,8 @@ func getDefaultImagePuller() *chev1alpha1.KubernetesImagePuller { Name: os.Getenv("CHE_FLAVOR") + "-image-puller", Namespace: namespace, Labels: map[string]string{ - "app.kubernetes.io/part-of": os.Getenv("CHE_FLAVOR"), - "app": "che", + "app.kubernetes.io/part-of": deploy.CheEclipseOrg, + "app": os.Getenv("CHE_FLAVOR"), "component": "kubernetes-image-puller", }, OwnerReferences: []metav1.OwnerReference{ diff --git a/pkg/deploy/ingres_test.go b/pkg/deploy/ingres_test.go index 72113b20a5..475691b446 100644 --- a/pkg/deploy/ingres_test.go +++ b/pkg/deploy/ingres_test.go @@ -68,6 +68,7 @@ func TestIngressSpec(t *testing.T) { "type": "default", "app.kubernetes.io/component": DefaultCheFlavor(cheCluster), "app.kubernetes.io/instance": DefaultCheFlavor(cheCluster), + "app.kubernetes.io/part-of": "che.eclipse.org", "app.kubernetes.io/managed-by": DefaultCheFlavor(cheCluster) + "-operator", "app.kubernetes.io/name": DefaultCheFlavor(cheCluster), }, diff --git a/pkg/deploy/job.go b/pkg/deploy/job.go index 794bfa27b0..7efca88806 100644 --- a/pkg/deploy/job.go +++ b/pkg/deploy/job.go @@ -19,7 +19,6 @@ import ( "github.com/google/go-cmp/cmp/cmpopts" batchv1 "k8s.io/api/batch/v1" corev1 "k8s.io/api/core/v1" - v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -27,7 +26,7 @@ var ( jobDiffOpts = cmp.Options{ cmpopts.IgnoreFields(batchv1.Job{}, "TypeMeta", "ObjectMeta", "Status"), cmpopts.IgnoreFields(batchv1.JobSpec{}, "Selector", "TTLSecondsAfterFinished"), - cmpopts.IgnoreFields(v1.PodTemplateSpec{}, "ObjectMeta"), + cmpopts.IgnoreFields(corev1.PodTemplateSpec{}, "ObjectMeta"), cmpopts.IgnoreFields(corev1.Container{}, "TerminationMessagePath", "TerminationMessagePolicy"), cmpopts.IgnoreFields(corev1.PodSpec{}, "DNSPolicy", "SchedulerName", "SecurityContext"), cmp.Comparer(func(x, y []corev1.EnvVar) bool { diff --git a/pkg/deploy/job_test.go b/pkg/deploy/job_test.go index 23e68dc958..e59fa89487 100644 --- a/pkg/deploy/job_test.go +++ b/pkg/deploy/job_test.go @@ -35,9 +35,9 @@ func TestSyncJobToCluster(t *testing.T) { }, }, ClusterAPI: ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, } diff --git a/pkg/deploy/labels.go b/pkg/deploy/labels.go index b1f1e71223..f2dc592cf0 100644 --- a/pkg/deploy/labels.go +++ b/pkg/deploy/labels.go @@ -22,6 +22,7 @@ func GetLabels(cheCluster *orgv1.CheCluster, component string) map[string]string return map[string]string{ KubernetesNameLabelKey: cheFlavor, KubernetesInstanceLabelKey: cheFlavor, + KubernetesPartOfLabelKey: CheEclipseOrg, KubernetesComponentLabelKey: component, KubernetesManagedByLabelKey: cheFlavor + "-operator", } diff --git a/pkg/deploy/migration/on-reconcile-one-time-migration.go b/pkg/deploy/migration/on-reconcile-one-time-migration.go new file mode 100644 index 0000000000..e20547a723 --- /dev/null +++ b/pkg/deploy/migration/on-reconcile-one-time-migration.go @@ -0,0 +1,289 @@ +// +// Copyright (c) 2019-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 migration + +import ( + "context" + "fmt" + "time" + + "github.com/eclipse-che/che-operator/pkg/deploy" + "github.com/eclipse-che/che-operator/pkg/util" + routev1 "github.com/openshift/api/route/v1" + "github.com/sirupsen/logrus" + appsv1 "k8s.io/api/apps/v1" + batchv1 "k8s.io/api/batch/v1" + corev1 "k8s.io/api/core/v1" + networkingv1 "k8s.io/api/networking/v1" + rbacv1 "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/selection" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/reconcile" +) + +type Migrator struct { + deploy.Reconcilable + + migrationDone bool +} + +func NewMigrator() *Migrator { + return &Migrator{ + migrationDone: false, + } +} + +func (m *Migrator) Reconcile(ctx *deploy.DeployContext) (reconcile.Result, bool, error) { + if m.migrationDone { + return reconcile.Result{}, true, nil + } + + done, err := m.migrate(ctx) + if done && err == nil { + m.migrationDone = true + // Give some time for the migration resources to be flushed and rerun reconcile + return reconcile.Result{RequeueAfter: 5 * time.Second}, false, err + } + return reconcile.Result{}, done, err +} + +func (m *Migrator) Finalize(ctx *deploy.DeployContext) error { + return nil +} + +func (m *Migrator) migrate(ctx *deploy.DeployContext) (bool, error) { + if err := addPartOfCheLabeltoUserDefinedObjects(ctx); err != nil { + return false, err + } + + if err := addPartOfLabelForObjectsWithInstanceCheLabel(ctx); err != nil { + return false, err + } + + return true, nil +} + +// addPartOfCheLabeltoUserDefinedObjects processes the following objects to add 'app.kubernetes.io/part-of=che.eclipse.org' label: +// - spec.server.cheHostTLSSecret +// - spec.server.cheClusterRoles +// - spec.server.cheWorkspaceClusterRole +// - spec.server.serverTrustStoreConfigMapName +// - spec.server.gitSelfSignedCert ('che-git-self-signed-cert' config map) +// - spec.server.proxySecret +// - spec.database.chePostgresSecret +// - spec.auth.identityProviderSecret +// - spec.auth.identityProviderPostgresSecret +// - spec.auth.oAuthSecret +// - spec.k8s.tlsSecretName +// Note, most of the objects above are autogenerated and do not require any migration, +// but to handle the case when some were created manually or operator updated, the check is done here. +func addPartOfCheLabeltoUserDefinedObjects(ctx *deploy.DeployContext) error { + if !util.IsOpenShift { + // Kubernetes only + + tlsSecretName := deploy.DefaultCheTLSSecretName + if ctx.CheCluster.Spec.K8s.TlsSecretName != "" { + tlsSecretName = ctx.CheCluster.Spec.K8s.TlsSecretName + } + if err := addPartOfCheLabelToSecret(ctx, tlsSecretName); err != nil { + return err + } + } + + // TLS + if err := addPartOfCheLabelToSecret(ctx, deploy.CheTLSSelfSignedCertificateSecretName); err != nil { + return err + } + + if ctx.CheCluster.Spec.Server.CheHostTLSSecret != "" { + if err := addPartOfCheLabelToSecret(ctx, ctx.CheCluster.Spec.Server.CheHostTLSSecret); err != nil { + return err + } + } + + // Proxy credentials + if ctx.CheCluster.Spec.Server.ProxySecret != "" { + if err := addPartOfCheLabelToSecret(ctx, ctx.CheCluster.Spec.Server.ProxySecret); err != nil { + return err + } + } + + // Database credentials + if ctx.CheCluster.Spec.Database.ChePostgresSecret != "" { + if err := addPartOfCheLabelToSecret(ctx, ctx.CheCluster.Spec.Database.ChePostgresSecret); err != nil { + return err + } + } + + // Keycloak related secrets + if ctx.CheCluster.Spec.Auth.IdentityProviderSecret != "" { + if err := addPartOfCheLabelToSecret(ctx, ctx.CheCluster.Spec.Auth.IdentityProviderSecret); err != nil { + return err + } + } + + if ctx.CheCluster.Spec.Auth.IdentityProviderPostgresSecret != "" { + if err := addPartOfCheLabelToSecret(ctx, ctx.CheCluster.Spec.Auth.IdentityProviderPostgresSecret); err != nil { + return err + } + } + + // Legacy config map with additional CA certificates + if ctx.CheCluster.Spec.Server.ServerTrustStoreConfigMapName != "" { + if err := addPartOfCheLabelToConfigMap(ctx, ctx.CheCluster.Spec.Server.ServerTrustStoreConfigMapName); err != nil { + return err + } + } + + // Config map with CA certificates for git + if ctx.CheCluster.Spec.Server.GitSelfSignedCert { + if err := addPartOfCheLabelToConfigMap(ctx, deploy.GitSelfSignedCertsConfigMapName); err != nil { + return err + } + } + + return nil +} + +func addPartOfCheLabelToSecret(ctx *deploy.DeployContext, secretName string) error { + return addPartOfCheLabelToObject(ctx, secretName, &corev1.Secret{}) +} + +func addPartOfCheLabelToConfigMap(ctx *deploy.DeployContext, configMapName string) error { + return addPartOfCheLabelToObject(ctx, configMapName, &corev1.ConfigMap{}) +} + +// addPartOfCheLabelToObject adds 'app.kubernetes.io/part-of=che.eclipse.org' label to the object with given name to be cached by operator's k8s client. +// As the function doesn't know the kind of the object with given name an empty object should be passed, +// for example: addPartOfCheLabelToObject(ctx, "my-secret", &corev1.Secret{}) +func addPartOfCheLabelToObject(ctx *deploy.DeployContext, objectName string, obj client.Object) error { + // Check if the object is already migrated + if exists, _ := deploy.GetNamespacedObject(ctx, objectName, obj); exists { + // Default client sees the object in cache, no need in adding anything + return nil + } + + err := ctx.ClusterAPI.NonCachingClient.Get(context.TODO(), types.NamespacedName{Namespace: ctx.CheCluster.Namespace, Name: objectName}, obj) + if err != nil { + if errors.IsNotFound(err) { + // The object doesn't exist in cluster, nothing to do + return nil + } + return err + } + + if err := ctx.ClusterAPI.NonCachingClient.Update(context.TODO(), setPartOfLabel(obj)); err != nil { + return err + } + logrus.Info(getObjectMigratedMessage(obj)) + + return nil +} + +func setPartOfLabel(obj client.Object) client.Object { + labels := obj.GetLabels() + if labels == nil { + labels = make(map[string]string) + } + labels[deploy.KubernetesPartOfLabelKey] = deploy.CheEclipseOrg + obj.SetLabels(labels) + return obj +} + +// addPartOfLabelForObjectsWithInstanceCheLabel searches for objects in Che installation namespace, +// that have 'app.kubernetes.io/instance=che' label and adds 'app.kubernetes.io/part-of=che.eclipse.org' +func addPartOfLabelForObjectsWithInstanceCheLabel(ctx *deploy.DeployContext) error { + cheFlavor := deploy.DefaultCheFlavor(ctx.CheCluster) + + // Prepare selector for all instance=che objects in the installation namespace + instanceCheSelectorRequirement, err := labels.NewRequirement(deploy.KubernetesInstanceLabelKey, selection.Equals, []string{cheFlavor}) + if err != nil { + logrus.Error(getFailedToCreateSelectorErrorMessage()) + return err + } + notPartOfCheSelectorRequirement, err := labels.NewRequirement(deploy.KubernetesPartOfLabelKey, selection.NotEquals, []string{deploy.CheEclipseOrg}) + if err != nil { + logrus.Error(getFailedToCreateSelectorErrorMessage()) + return err + } + objectsToMigrateLabelSelector := labels.NewSelector().Add(*instanceCheSelectorRequirement).Add(*notPartOfCheSelectorRequirement) + listOptions := &client.ListOptions{ + LabelSelector: objectsToMigrateLabelSelector, + Namespace: ctx.CheCluster.GetNamespace(), + } + + // This list should be based on the list from the cache function (see NewCache filed of the managar in main.go) + kindsToMigrate := []client.ObjectList{ + &appsv1.DeploymentList{}, + &corev1.PodList{}, + &batchv1.JobList{}, + &corev1.ServiceList{}, + &networkingv1.IngressList{}, + &corev1.SecretList{}, + &corev1.ConfigMapList{}, + &corev1.ServiceAccountList{}, + &rbacv1.RoleList{}, + &rbacv1.RoleBindingList{}, + &rbacv1.ClusterRoleList{}, + &rbacv1.ClusterRoleBindingList{}, + &corev1.PersistentVolumeClaimList{}, + } + if util.IsOpenShift { + kindsToMigrate = append(kindsToMigrate, &routev1.RouteList{}) + } + + for _, listToGet := range kindsToMigrate { + if err := addPartOfCheLabelToObjectsBySelector(ctx, listOptions, listToGet); err != nil { + return err + } + } + + return nil +} + +// addPartOfCheLabelToObjectsBySelector adds 'app.kubernetes.io/part-of=che.eclipse.org' label to all objects +// of given objectsList kind that match the provided in listOptions selector and namespace. +func addPartOfCheLabelToObjectsBySelector(ctx *deploy.DeployContext, listOptions *client.ListOptions, objectsList client.ObjectList) error { + if err := ctx.ClusterAPI.NonCachingClient.List(context.TODO(), objectsList, listOptions); err != nil { + logrus.Warnf("Failed to get %s to add %s label", objectsList.GetObjectKind().GroupVersionKind().Kind, deploy.KubernetesPartOfLabelKey) + return err + } + + objects, err := meta.ExtractList(objectsList) + if err != nil { + return err + } + + for _, runtimeObj := range objects { + obj := setPartOfLabel(runtimeObj.(client.Object)) + if err := ctx.ClusterAPI.NonCachingClient.Update(context.TODO(), obj); err != nil { + return err + } + logrus.Info(getObjectMigratedMessage(obj)) + } + + return nil +} + +func getFailedToCreateSelectorErrorMessage() string { + return "Failed to create selector for resources migration. Unable to perform resources migration." +} + +func getObjectMigratedMessage(obj client.Object) string { + return fmt.Sprintf("Added '%s=%s' label to %s object of %s kind", + deploy.KubernetesPartOfLabelKey, deploy.CheEclipseOrg, obj.GetName(), deploy.GetObjectType(obj)) +} diff --git a/pkg/deploy/openshift-oauth/openshiftoauth.go b/pkg/deploy/openshift-oauth/openshiftoauth.go index 9d47e48e61..83a7653ebd 100644 --- a/pkg/deploy/openshift-oauth/openshiftoauth.go +++ b/pkg/deploy/openshift-oauth/openshiftoauth.go @@ -95,7 +95,7 @@ func (oo *OpenShiftOAuth) enableOpenShiftOAuth(ctx *deploy.DeployContext) (recon } else { // Openshift 3 users := &userv1.UserList{} listOptions := &client.ListOptions{} - if err := ctx.ClusterAPI.NonCachedClient.List(context.TODO(), users, listOptions); err != nil { + if err := ctx.ClusterAPI.NonCachingClient.List(context.TODO(), users, listOptions); err != nil { logrus.Error(failedUnableToGetOpenshiftUsers + " Cause: " + err.Error()) } else { oauth = len(users.Items) >= 1 diff --git a/pkg/deploy/openshift-oauth/openshiftoauth_user.go b/pkg/deploy/openshift-oauth/openshiftoauth_user.go index 2ac0251ddd..c3b3737238 100644 --- a/pkg/deploy/openshift-oauth/openshiftoauth_user.go +++ b/pkg/deploy/openshift-oauth/openshiftoauth_user.go @@ -134,7 +134,7 @@ func (oou *OpenShiftOAuthUser) Create(ctx *deploy.DeployContext) (bool, error) { return false, err } - if err := appendIdentityProvider(oAuth, ctx.ClusterAPI.NonCachedClient); err != nil { + if err := appendIdentityProvider(oAuth, ctx.ClusterAPI.NonCachingClient); err != nil { return false, err } @@ -167,7 +167,7 @@ func (oou *OpenShiftOAuthUser) Delete(ctx *deploy.DeployContext) error { return err } - if err := deleteIdentityProvider(oAuth, ctx.ClusterAPI.NonCachedClient); err != nil { + if err := deleteIdentityProvider(oAuth, ctx.ClusterAPI.NonCachingClient); err != nil { return err } diff --git a/pkg/deploy/pluginregistry/pluginregistry_test.go b/pkg/deploy/pluginregistry/pluginregistry_test.go index 0a6aedeaa7..ba146848f8 100644 --- a/pkg/deploy/pluginregistry/pluginregistry_test.go +++ b/pkg/deploy/pluginregistry/pluginregistry_test.go @@ -44,9 +44,9 @@ func TestPluginRegistrySyncAll(t *testing.T) { deployContext := &deploy.DeployContext{ CheCluster: cheCluster, ClusterAPI: deploy.ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, } diff --git a/pkg/deploy/postgres/postgres_test.go b/pkg/deploy/postgres/postgres_test.go index 2a561c56c4..127b424e73 100644 --- a/pkg/deploy/postgres/postgres_test.go +++ b/pkg/deploy/postgres/postgres_test.go @@ -137,9 +137,9 @@ func TestSyncAllToCluster(t *testing.T) { }, }, ClusterAPI: deploy.ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, } diff --git a/pkg/deploy/pvc_test.go b/pkg/deploy/pvc_test.go index 36cfd95c0d..c55dff6814 100644 --- a/pkg/deploy/pvc_test.go +++ b/pkg/deploy/pvc_test.go @@ -37,9 +37,9 @@ func TestSyncPVCToCluster(t *testing.T) { }, }, ClusterAPI: ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, } diff --git a/pkg/deploy/role.go b/pkg/deploy/role.go index b062a3bc60..76234bc1c5 100644 --- a/pkg/deploy/role.go +++ b/pkg/deploy/role.go @@ -41,6 +41,8 @@ func SyncTLSRoleToCluster(deployContext *DeployContext) (bool, error) { }, Verbs: []string{ "create", + "get", + "patch", }, }, } diff --git a/pkg/deploy/role_test.go b/pkg/deploy/role_test.go index 2102353f3c..f1bd07deae 100644 --- a/pkg/deploy/role_test.go +++ b/pkg/deploy/role_test.go @@ -36,9 +36,9 @@ func TestSyncRoleToCluster(t *testing.T) { }, }, ClusterAPI: ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, } diff --git a/pkg/deploy/rolebinding_test.go b/pkg/deploy/rolebinding_test.go index 730e0d2833..b4cc3931ca 100644 --- a/pkg/deploy/rolebinding_test.go +++ b/pkg/deploy/rolebinding_test.go @@ -35,9 +35,9 @@ func TestSyncRoleBindingToCluster(t *testing.T) { }, }, ClusterAPI: ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, } diff --git a/pkg/deploy/route_test.go b/pkg/deploy/route_test.go index 1409da5ed7..78d1611102 100644 --- a/pkg/deploy/route_test.go +++ b/pkg/deploy/route_test.go @@ -68,6 +68,7 @@ func TestRouteSpec(t *testing.T) { "type": "default", "app.kubernetes.io/component": "test-component", "app.kubernetes.io/instance": DefaultCheFlavor(cheCluster), + "app.kubernetes.io/part-of": "che.eclipse.org", "app.kubernetes.io/managed-by": DefaultCheFlavor(cheCluster) + "-operator", "app.kubernetes.io/name": DefaultCheFlavor(cheCluster), }, @@ -110,6 +111,7 @@ func TestRouteSpec(t *testing.T) { "type": "default", "app.kubernetes.io/component": "test-component", "app.kubernetes.io/instance": DefaultCheFlavor(cheCluster), + "app.kubernetes.io/part-of": "che.eclipse.org", "app.kubernetes.io/managed-by": DefaultCheFlavor(cheCluster) + "-operator", "app.kubernetes.io/name": DefaultCheFlavor(cheCluster), }, diff --git a/pkg/deploy/sercet_test.go b/pkg/deploy/sercet_test.go index b60c140db5..7cd6ebcb32 100644 --- a/pkg/deploy/sercet_test.go +++ b/pkg/deploy/sercet_test.go @@ -149,9 +149,9 @@ func TestGetSecrets(t *testing.T) { }, }, ClusterAPI: ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, } @@ -178,9 +178,9 @@ func TestSyncSecretToCluster(t *testing.T) { }, }, ClusterAPI: ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, } diff --git a/pkg/deploy/server/server_deployment.go b/pkg/deploy/server/server_deployment.go index 999695c042..7d6c4a44fd 100644 --- a/pkg/deploy/server/server_deployment.go +++ b/pkg/deploy/server/server_deployment.go @@ -88,7 +88,7 @@ func (s Server) getDeploymentSpec() (*appsv1.Deployment, error) { ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ Key: "ca.crt", LocalObjectReference: corev1.LocalObjectReference{ - Name: "che-git-self-signed-cert", + Name: deploy.GitSelfSignedCertsConfigMapName, }, Optional: &optionalEnv, }, @@ -100,7 +100,7 @@ func (s Server) getDeploymentSpec() (*appsv1.Deployment, error) { ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ Key: "githost", LocalObjectReference: corev1.LocalObjectReference{ - Name: "che-git-self-signed-cert", + Name: deploy.GitSelfSignedCertsConfigMapName, }, Optional: &optionalEnv, }, diff --git a/pkg/deploy/server/server_test.go b/pkg/deploy/server/server_test.go index 3c0168bdda..b17e30d53c 100644 --- a/pkg/deploy/server/server_test.go +++ b/pkg/deploy/server/server_test.go @@ -50,9 +50,9 @@ func TestSyncService(t *testing.T) { }, }, ClusterAPI: deploy.ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, } @@ -97,9 +97,9 @@ func TestSyncAll(t *testing.T) { deployContext := &deploy.DeployContext{ CheCluster: cheCluster, ClusterAPI: deploy.ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, Proxy: &deploy.Proxy{}, } @@ -178,9 +178,9 @@ func TestSyncLegacyConfigMap(t *testing.T) { deployContext := &deploy.DeployContext{ CheCluster: cheCluster, ClusterAPI: deploy.ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, Proxy: &deploy.Proxy{}, } @@ -234,9 +234,9 @@ func TestUpdateAvailabilityStatus(t *testing.T) { deployContext := &deploy.DeployContext{ CheCluster: cheCluster, ClusterAPI: deploy.ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, } diff --git a/pkg/deploy/service_test.go b/pkg/deploy/service_test.go index 86b6f29150..6b1b9dcca5 100644 --- a/pkg/deploy/service_test.go +++ b/pkg/deploy/service_test.go @@ -35,9 +35,9 @@ func TestServiceToCluster(t *testing.T) { }, }, ClusterAPI: ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, } diff --git a/pkg/deploy/sync.go b/pkg/deploy/sync.go index dbaf437cfb..c06ee15809 100644 --- a/pkg/deploy/sync.go +++ b/pkg/deploy/sync.go @@ -111,7 +111,7 @@ func GetNamespacedObject(deployContext *DeployContext, name string, actual clien // Gets cluster scope object by name // Returns true if object exists otherwise returns false func GetClusterObject(deployContext *DeployContext, name string, actual client.Object) (bool, error) { - client := deployContext.ClusterAPI.NonCachedClient + client := deployContext.ClusterAPI.NonCachingClient key := types.NamespacedName{Name: name} return doGet(client, key, actual) } @@ -136,7 +136,7 @@ func CreateIfNotExists(deployContext *DeployContext, blueprint client.Object) (i return false, err } - logrus.Infof("Creating a new object: %s, name: %s", getObjectType(blueprint), blueprint.GetName()) + logrus.Infof("Creating a new object: %s, name: %s", GetObjectType(blueprint), blueprint.GetName()) err = setOwnerReferenceIfNeeded(deployContext, blueprint) if err != nil { @@ -157,7 +157,7 @@ func Create(deployContext *DeployContext, blueprint client.Object) (bool, error) client := getClientForObject(blueprint.GetNamespace(), deployContext) - logrus.Infof("Creating a new object: %s, name: %s", getObjectType(blueprint), blueprint.GetName()) + logrus.Infof("Creating a new object: %s, name: %s", GetObjectType(blueprint), blueprint.GetName()) err := setOwnerReferenceIfNeeded(deployContext, blueprint) if err != nil { @@ -181,7 +181,7 @@ func DeleteNamespacedObject(deployContext *DeployContext, name string, objectMet } func DeleteClusterObject(deployContext *DeployContext, name string, objectMeta client.Object) (bool, error) { - client := deployContext.ClusterAPI.NonCachedClient + client := deployContext.ClusterAPI.NonCachingClient key := types.NamespacedName{Name: name} return doDeleteByKey(client, deployContext.ClusterAPI.Scheme, key, objectMeta) } @@ -229,7 +229,7 @@ func Update(deployContext *DeployContext, actual client.Object, blueprint client client := getClientForObject(actualMeta.GetNamespace(), deployContext) if isUpdateUsingDeleteCreate(actual.GetObjectKind().GroupVersionKind().Kind) { - logrus.Infof("Recreating existing object: %s, name: %s", getObjectType(actualMeta), actualMeta.GetName()) + logrus.Infof("Recreating existing object: %s, name: %s", GetObjectType(actualMeta), actualMeta.GetName()) done, err := doDelete(client, actual) if !done { return false, err @@ -242,7 +242,7 @@ func Update(deployContext *DeployContext, actual client.Object, blueprint client return doCreate(client, blueprint, false) } else { - logrus.Infof("Updating existing object: %s, name: %s", getObjectType(actualMeta), actualMeta.GetName()) + logrus.Infof("Updating existing object: %s, name: %s", GetObjectType(actualMeta), actualMeta.GetName()) err := setOwnerReferenceIfNeeded(deployContext, blueprint) if err != nil { return false, err @@ -281,7 +281,7 @@ func doDeleteByKey(cli client.Client, scheme *runtime.Scheme, key client.ObjectK return false, err } - logrus.Infof("Deleting object: %s, name: %s", getObjectType(objectMeta), key.Name) + logrus.Infof("Deleting object: %s, name: %s", GetObjectType(objectMeta), key.Name) return doDelete(cli, actual) } @@ -334,10 +334,10 @@ func getClientForObject(objectNamespace string, deployContext *DeployContext) cl if deployContext.CheCluster.Namespace == objectNamespace { return deployContext.ClusterAPI.Client } - return deployContext.ClusterAPI.NonCachedClient + return deployContext.ClusterAPI.NonCachingClient } -func getObjectType(objectMeta metav1.Object) string { +func GetObjectType(objectMeta metav1.Object) string { objType := reflect.TypeOf(objectMeta).String() if reflect.TypeOf(objectMeta).Kind().String() == "ptr" { objType = objType[1:] diff --git a/pkg/deploy/sync_test.go b/pkg/deploy/sync_test.go index 2d32a637cb..ec102c473d 100644 --- a/pkg/deploy/sync_test.go +++ b/pkg/deploy/sync_test.go @@ -244,9 +244,9 @@ func initDeployContext() (client.Client, *DeployContext) { }, }, ClusterAPI: ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, } diff --git a/pkg/deploy/test_util.go b/pkg/deploy/test_util.go index c91a3f3f6a..d5faff39af 100644 --- a/pkg/deploy/test_util.go +++ b/pkg/deploy/test_util.go @@ -64,10 +64,10 @@ func GetTestDeployContext(cheCluster *orgv1.CheCluster, initObjs []runtime.Objec return &DeployContext{ CheCluster: cheCluster, ClusterAPI: ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme, - DiscoveryClient: fakeDiscovery, + Client: cli, + NonCachingClient: cli, + Scheme: scheme, + DiscoveryClient: fakeDiscovery, }, Proxy: &Proxy{}, } diff --git a/pkg/deploy/tls.go b/pkg/deploy/tls.go index 5c1ff3140c..9924e10b6d 100644 --- a/pkg/deploy/tls.go +++ b/pkg/deploy/tls.go @@ -17,6 +17,7 @@ import ( "crypto/x509" "encoding/pem" stderrors "errors" + "fmt" "net/http" "reflect" "strings" @@ -32,7 +33,7 @@ import ( "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/selection" "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" + k8sclient "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/reconcile" ) @@ -301,10 +302,25 @@ func GetEndpointTLSCrtBytes(deployContext *DeployContext, endpointURL string) (c func K8sHandleCheTLSSecrets(deployContext *DeployContext) (reconcile.Result, error) { cheTLSSecretName := deployContext.CheCluster.Spec.K8s.TlsSecretName + cheTLSSecretNamespacedName := types.NamespacedName{Namespace: deployContext.CheCluster.Namespace, Name: cheTLSSecretName} + CheTLSSelfSignedCertificateSecretNamespacedName := types.NamespacedName{Namespace: deployContext.CheCluster.Namespace, Name: CheTLSSelfSignedCertificateSecretName} + + job := &batchv1.Job{} + err := deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: CheTLSJobName, Namespace: deployContext.CheCluster.Namespace}, job) + var jobExists bool + if err != nil { + if !errors.IsNotFound(err) { + return reconcile.Result{}, err + } + jobExists = false + } else { + jobExists = true + } + // ===== Check Che server TLS certificate ===== // cheTLSSecret := &corev1.Secret{} - err := deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Namespace: deployContext.CheCluster.Namespace, Name: cheTLSSecretName}, cheTLSSecret) + err = deployContext.ClusterAPI.Client.Get(context.TODO(), cheTLSSecretNamespacedName, cheTLSSecret) if err != nil { if !errors.IsNotFound(err) { // Error reading secret info @@ -312,11 +328,22 @@ func K8sHandleCheTLSSecrets(deployContext *DeployContext) (reconcile.Result, err return reconcile.Result{RequeueAfter: time.Second}, err } + // Check if a job is already running for TLS secrets creation + if jobExists { + if job.Status.Succeeded == 0 && job.Status.Failed == 0 { + logrus.Infof("Waiting on job '%s' to be finished", CheTLSJobName) + return reconcile.Result{RequeueAfter: 2 * time.Second}, err + } else if job.Status.Succeeded > 0 { + // Secrets are ready, restart reconcilation loop + return reconcile.Result{}, nil + } + } + // Che TLS secret doesn't exist, generate a new one // Remove Che CA certificate secret if any cheCASelfSignedCertificateSecret := &corev1.Secret{} - err = deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Namespace: deployContext.CheCluster.Namespace, Name: CheTLSSelfSignedCertificateSecretName}, cheCASelfSignedCertificateSecret) + err = deployContext.ClusterAPI.Client.Get(context.TODO(), CheTLSSelfSignedCertificateSecretNamespacedName, cheCASelfSignedCertificateSecret) if err != nil { if !errors.IsNotFound(err) { // Error reading secret info @@ -349,44 +376,33 @@ func K8sHandleCheTLSSecrets(deployContext *DeployContext) (reconcile.Result, err } domains := deployContext.CheCluster.Spec.K8s.IngressDomain + ",*." + deployContext.CheCluster.Spec.K8s.IngressDomain - if deployContext.CheCluster.Spec.Server.CheHost != "" && strings.Index(deployContext.CheCluster.Spec.Server.CheHost, deployContext.CheCluster.Spec.K8s.IngressDomain) == -1 && deployContext.CheCluster.Spec.Server.CheHostTLSSecret == "" { + if deployContext.CheCluster.Spec.Server.CheHost != "" && !strings.Contains(deployContext.CheCluster.Spec.Server.CheHost, deployContext.CheCluster.Spec.K8s.IngressDomain) && deployContext.CheCluster.Spec.Server.CheHostTLSSecret == "" { domains += "," + deployContext.CheCluster.Spec.Server.CheHost } + + labels := "" + for labelName, labelValue := range GetLabels(deployContext.CheCluster, cheTLSSecretName) { + labels += fmt.Sprintf("%s=%s ", labelName, labelValue) + } + cheTLSSecretsCreationJobImage := DefaultCheTLSSecretsCreationJobImage() jobEnvVars := map[string]string{ "DOMAIN": domains, "CHE_NAMESPACE": deployContext.CheCluster.Namespace, "CHE_SERVER_TLS_SECRET_NAME": cheTLSSecretName, "CHE_CA_CERTIFICATE_SECRET_NAME": CheTLSSelfSignedCertificateSecretName, + "LABELS": labels, } - done, err = SyncJobToCluster(deployContext, CheTLSJobName, CheTLSJobComponentName, cheTLSSecretsCreationJobImage, CheTLSJobServiceAccountName, jobEnvVars) - if !done { - if err != nil { - logrus.Error(err) - } - return reconcile.Result{RequeueAfter: time.Second}, err - } - - job := &batchv1.Job{} - exists, err := GetNamespacedObject(deployContext, CheTLSJobName, job) - if !exists || job.Status.Succeeded == 0 { - logrus.Infof("Waiting on job '%s' to be finished", CheTLSJobName) - if err != nil { - logrus.Error(err) - } - return reconcile.Result{RequeueAfter: time.Second}, err + _, err = SyncJobToCluster(deployContext, CheTLSJobName, CheTLSJobComponentName, cheTLSSecretsCreationJobImage, CheTLSJobServiceAccountName, jobEnvVars) + if err != nil { + logrus.Error(err) } + return reconcile.Result{RequeueAfter: time.Second}, err } // cleanup job - job := &batchv1.Job{} - err = deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: CheTLSJobName, Namespace: deployContext.CheCluster.Namespace}, job) - if err != nil && !errors.IsNotFound(err) { - // Failed to get the job - return reconcile.Result{RequeueAfter: time.Second}, err - } - if err == nil { + if jobExists { // The job object is present if job.Status.Succeeded > 0 { logrus.Infof("Import public part of Eclipse Che self-signed CA certificate from \"%s\" secret into your browser.", CheTLSSelfSignedCertificateSecretName) @@ -429,7 +445,7 @@ func K8sHandleCheTLSSecrets(deployContext *DeployContext) (reconcile.Result, err // ===== Check Che CA certificate ===== // cheTLSSelfSignedCertificateSecret := &corev1.Secret{} - err = deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Namespace: deployContext.CheCluster.Namespace, Name: CheTLSSelfSignedCertificateSecretName}, cheTLSSelfSignedCertificateSecret) + err = deployContext.ClusterAPI.Client.Get(context.TODO(), CheTLSSelfSignedCertificateSecretNamespacedName, cheTLSSelfSignedCertificateSecret) if err != nil { if !errors.IsNotFound(err) { // Error reading Che self-signed secret info @@ -514,7 +530,7 @@ func deleteJob(deployContext *DeployContext, job *batchv1.Job) { func SyncAdditionalCACertsConfigMapToCluster(deployContext *DeployContext) (bool, error) { cr := deployContext.CheCluster // Get all source config maps, if any - caConfigMaps, err := GetCACertsConfigMaps(deployContext) + caConfigMaps, err := GetCACertsConfigMaps(deployContext.ClusterAPI.Client, deployContext.CheCluster.GetNamespace()) if err != nil { return false, err } @@ -586,16 +602,16 @@ func SyncAdditionalCACertsConfigMapToCluster(deployContext *DeployContext) (bool // GetCACertsConfigMaps returns list of config maps with additional CA certificates that should be trusted by Che // The selection is based on the specific label -func GetCACertsConfigMaps(deployContext *DeployContext) ([]corev1.ConfigMap, error) { +func GetCACertsConfigMaps(client k8sclient.Client, namespace string) ([]corev1.ConfigMap, error) { CACertsConfigMapList := &corev1.ConfigMapList{} caBundleLabelSelectorRequirement, _ := labels.NewRequirement(KubernetesComponentLabelKey, selection.Equals, []string{CheCACertsConfigMapLabelValue}) cheComponetLabelSelectorRequirement, _ := labels.NewRequirement(KubernetesPartOfLabelKey, selection.Equals, []string{CheEclipseOrg}) - listOptions := &client.ListOptions{ + listOptions := &k8sclient.ListOptions{ LabelSelector: labels.NewSelector().Add(*cheComponetLabelSelectorRequirement).Add(*caBundleLabelSelectorRequirement), - Namespace: deployContext.CheCluster.GetNamespace(), + Namespace: namespace, } - if err := deployContext.ClusterAPI.Client.List(context.TODO(), CACertsConfigMapList, listOptions); err != nil { + if err := client.List(context.TODO(), CACertsConfigMapList, listOptions); err != nil { return nil, err } diff --git a/pkg/deploy/tls_test.go b/pkg/deploy/tls_test.go index 5db595f994..fce7ab3c74 100644 --- a/pkg/deploy/tls_test.go +++ b/pkg/deploy/tls_test.go @@ -60,9 +60,9 @@ func TestSyncAdditionalCACertsConfigMapToCluster(t *testing.T) { }, }, ClusterAPI: ClusterAPI{ - Client: cli, - NonCachedClient: cli, - Scheme: scheme.Scheme, + Client: cli, + NonCachingClient: cli, + Scheme: scheme.Scheme, }, }