feat: Don't deploy CheManager - it no longer is a thing. (#868)

Remove the CRDs that we don't have to deploy. CheManager is not used
at all anymore and DevWorkspaceRouting is deployed at runtime while
enabling the devworkspaces. DWCO waits for the CRD to appear.

Don't deploy the DWCO metrics service anymore because the metrics
endpoint is switched off anyway.

Trivial - remove the unneeded serialized storage annotations on checluster
objects of different versions.

The cluster role must grant the operator the perms to update status
of the checluster resource.
pull/861/head
Lukas Krejci 2021-07-02 00:28:32 +02:00 committed by GitHub
parent 65e3cac0a8
commit 1f1a41f9b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 38 additions and 143 deletions

View File

@ -37,7 +37,7 @@ oc apply -f ${BASE_DIR}/deploy/crds/org.eclipse.che_chebackupserverconfiguration
oc apply -f ${BASE_DIR}/deploy/crds/org.eclipse.che_checlusterbackups_crd.yaml -n $NAMESPACE
oc apply -f ${BASE_DIR}/deploy/crds/org.eclipse.che_checlusterrestores_crd.yaml -n $NAMESPACE
# sometimes the operator cannot get CRD right away
sleep 2
sleep 5
cp -f ${BASE_DIR}/deploy/operator.yaml /tmp/operator.yaml
yq -riyY "( .spec.template.spec.containers[] | select(.name == \"che-operator\") | .image ) = \"${CHE_OPERATOR_IMAGE}\"" /tmp/operator.yaml

View File

@ -132,6 +132,7 @@ rules:
- org.eclipse.che
resources:
- checlusters
- checlusters/status
- checlusters/finalizers
verbs:
- '*'

View File

@ -86,13 +86,13 @@ metadata:
categories: Developer Tools
certified: "false"
containerImage: quay.io/eclipse/che-operator:next
createdAt: "2021-06-30T12:42:36Z"
createdAt: "2021-07-01T21:02:20Z"
description: A Kube-native development solution that delivers portable and collaborative
developer workspaces.
operatorframework.io/suggested-namespace: eclipse-che
repository: https://github.com/eclipse-che/che-operator
support: Eclipse Foundation
name: eclipse-che-preview-kubernetes.v7.33.0-244.nightly
name: eclipse-che-preview-kubernetes.v7.33.0-246.nightly
namespace: placeholder
spec:
apiservicedefinitions: {}
@ -318,6 +318,7 @@ spec:
- org.eclipse.che
resources:
- checlusters
- checlusters/status
- checlusters/finalizers
verbs:
- '*'
@ -1252,4 +1253,4 @@ spec:
maturity: stable
provider:
name: Eclipse Foundation
version: 7.33.0-244.nightly
version: 7.33.0-246.nightly

View File

@ -77,13 +77,13 @@ metadata:
categories: Developer Tools, OpenShift Optional
certified: "false"
containerImage: quay.io/eclipse/che-operator:next
createdAt: "2021-06-30T12:42:43Z"
createdAt: "2021-07-01T21:02:26Z"
description: A Kube-native development solution that delivers portable and collaborative
developer workspaces in OpenShift.
operatorframework.io/suggested-namespace: eclipse-che
repository: https://github.com/eclipse-che/che-operator
support: Eclipse Foundation
name: eclipse-che-preview-openshift.v7.33.0-244.nightly
name: eclipse-che-preview-openshift.v7.33.0-246.nightly
namespace: placeholder
spec:
apiservicedefinitions: {}
@ -365,6 +365,7 @@ spec:
- org.eclipse.che
resources:
- checlusters
- checlusters/status
- checlusters/finalizers
verbs:
- '*'
@ -1329,4 +1330,4 @@ spec:
maturity: stable
provider:
name: Eclipse Foundation
version: 7.33.0-244.nightly
version: 7.33.0-246.nightly

View File

@ -18,6 +18,7 @@ command -v operator-sdk >/dev/null 2>&1 || { echo "operator-sdk is not installed
ECLIPSE_CHE_NAMESPACE="eclipse-che"
ECLIPSE_CHE_CR="./deploy/crds/org_v1_che_cr.yaml"
ECLIPSE_CHE_CRD="./deploy/crds/org_v1_che_crd.yaml"
ECLIPSE_CHE_CRD_V1BETA1="./deploy/crds/org_v1_che_crd-v1beta1.yaml"
ECLIPSE_CHE_BACKUP_SERVER_CONFIGURATION_CRD="./deploy/crds/org.eclipse.che_chebackupserverconfigurations_crd.yaml"
ECLIPSE_CHE_BACKUP_CRD="./deploy/crds/org.eclipse.che_checlusterbackups_crd.yaml"
ECLIPSE_CHE_RESTORE_CRD="./deploy/crds/org.eclipse.che_checlusterrestores_crd.yaml"

View File

@ -60,6 +60,9 @@ func V1ToV2alpha1(v1 *v1.CheCluster, v2 *v2alpha1.CheCluster) error {
v1ToV2alpha1_WorkspaceDomainEndpointsTlsSecretName(v1, v2)
v1ToV2alpha1_K8sIngressAnnotations(v1, v2)
// we don't need to store the serialized v2 on a v2 object
delete(v2.Annotations, v2alpha1StorageAnnotation)
return nil
}
@ -97,6 +100,9 @@ func V2alpha1ToV1(v2 *v2alpha1.CheCluster, v1Obj *v1.CheCluster) error {
v2alpha1ToV1_WorkspaceDomainEndpointsTlsSecretName(v1Obj, v2)
v2alpha1ToV1_K8sIngressAnnotations(v1Obj, v2)
// we don't need to store the serialized v1 on a v1 object
delete(v1Obj.Annotations, v1StorageAnnotation)
return nil
}

View File

@ -666,6 +666,14 @@ func TestFullCircleV1(t *testing.T) {
if !reflect.DeepEqual(&v1Obj, &convertedV1) {
t.Errorf("V1 not equal to itself after the conversion through v2alpha1: %v", cmp.Diff(&v1Obj, &convertedV1))
}
if convertedV1.Annotations[v1StorageAnnotation] != "" {
t.Errorf("The v1 storage annotations should not be present on the v1 object")
}
if convertedV1.Annotations[v2alpha1StorageAnnotation] == "" {
t.Errorf("The v2alpha1 storage annotation should be present on the v1 object")
}
}
func TestFullCircleV2(t *testing.T) {
@ -711,6 +719,14 @@ func TestFullCircleV2(t *testing.T) {
if !reflect.DeepEqual(&v2Obj, &convertedV2) {
t.Errorf("V2alpha1 not equal to itself after the conversion through v1: %v", cmp.Diff(&v2Obj, &convertedV2))
}
if convertedV2.Annotations[v2alpha1StorageAnnotation] != "" {
t.Errorf("The v2alpha1 storage annotations should not be present on the v2alpha1 object")
}
if convertedV2.Annotations[v1StorageAnnotation] == "" {
t.Errorf("The v1 storage annotation should be present on the v2alpha1 object")
}
}
func onFakeOpenShift(f func()) {

View File

@ -30,9 +30,7 @@ import (
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/yaml"
@ -70,19 +68,6 @@ var (
DevWorkspaceConfigMapFile = DevWorkspaceTemplates + "/devworkspace-controller-configmap.ConfigMap.yaml"
DevWorkspaceDeploymentFile = DevWorkspaceTemplates + "/devworkspace-controller-manager.Deployment.yaml"
DevWorkspaceCheServiceAccountFile = DevWorkspaceCheTemplates + "/devworkspace-che-serviceaccount.ServiceAccount.yaml"
DevWorkspaceCheRoleFile = DevWorkspaceCheTemplates + "/devworkspace-che-leader-election-role.Role.yaml"
DevWorkspaceCheClusterRoleFile = DevWorkspaceCheTemplates + "/devworkspace-che-role.ClusterRole.yaml"
DevWorkspaceCheProxyClusterRoleFile = DevWorkspaceCheTemplates + "/devworkspace-che-proxy-role.ClusterRole.yaml"
DevWorkspaceCheMetricsReaderClusterRoleFile = DevWorkspaceCheTemplates + "/devworkspace-che-metrics-reader.ClusterRole.yaml"
DevWorkspaceCheRoleBindingFile = DevWorkspaceCheTemplates + "/devworkspace-che-leader-election-rolebinding.RoleBinding.yaml"
DevWorkspaceCheClusterRoleBindingFile = DevWorkspaceCheTemplates + "/devworkspace-che-rolebinding.ClusterRoleBinding.yaml"
DevWorkspaceCheProxyClusterRoleBindingFile = DevWorkspaceCheTemplates + "/devworkspace-che-proxy-rolebinding.ClusterRoleBinding.yaml"
DevWorkspaceCheManagersCRDFile = DevWorkspaceCheTemplates + "/chemanagers.che.eclipse.org.CustomResourceDefinition.yaml"
DevWorkspaceCheConfigMapFile = DevWorkspaceCheTemplates + "/devworkspace-che-configmap.ConfigMap.yaml"
DevWorkspaceCheDeploymentFile = DevWorkspaceCheTemplates + "/devworkspace-che-manager.Deployment.yaml"
DevWorkspaceCheMetricsServiceFile = DevWorkspaceCheTemplates + "/devworkspace-che-controller-manager-metrics-service.Service.yaml"
WebTerminalOperatorSubscriptionName = "web-terminal"
WebTerminalOperatorNamespace = "openshift-operators"
)
@ -112,12 +97,6 @@ var (
syncDwConfigMap,
syncDwDeployment,
}
syncDwCheItems = []func(*deploy.DeployContext) (bool, error){
syncDwCheCRD,
syncDwCheCR,
syncDwCheMetricsService,
}
)
func ReconcileDevWorkspace(deployContext *deploy.DeployContext) (bool, error) {
@ -131,6 +110,11 @@ func ReconcileDevWorkspace(deployContext *deploy.DeployContext) (bool, error) {
return true, nil
}
if !util.IsOpenShift && util.GetServerExposureStrategy(deployContext.CheCluster) == "single-host" {
logrus.Warn(`DevWorkspace Che operator can't be enabled in 'single-host' mode on a Kubernetes cluster. See https://github.com/eclipse/che/issues/19714 for more details. To enable DevWorkspace Che operator set 'spec.server.serverExposureStrategy' to 'multi-host'.`)
return true, nil
}
// check if DW exists on the cluster
devWorkspaceWebhookExists, err := deploy.Get(
deployContext,
@ -157,20 +141,6 @@ func ReconcileDevWorkspace(deployContext *deploy.DeployContext) (bool, error) {
}
}
if !util.IsOpenShift && util.GetServerExposureStrategy(deployContext.CheCluster) == "single-host" {
logrus.Warn(`DevWorkspace Che operator can't be enabled in 'single-host' mode on a Kubernetes cluster. See https://github.com/eclipse/che/issues/19714 for more details. To enable DevWorkspace Che operator set 'spec.server.serverExposureStrategy' to 'multi-host'.`)
return true, nil
}
for _, syncItem := range syncDwCheItems {
done, err := syncItem(deployContext)
if !util.IsTestMode() {
if !done {
return false, err
}
}
}
return true, nil
}
@ -292,65 +262,6 @@ func syncDwDeployment(deployContext *deploy.DeployContext) (bool, error) {
return syncObject(deployContext, obj2sync, DevWorkspaceNamespace)
}
func syncDwCheCRD(deployContext *deploy.DeployContext) (bool, error) {
return readAndSyncObject(deployContext, DevWorkspaceCheManagersCRDFile, &apiextensionsv1.CustomResourceDefinition{}, "")
}
func syncDwCheMetricsService(deployContext *deploy.DeployContext) (bool, error) {
return readAndSyncObject(deployContext, DevWorkspaceCheMetricsServiceFile, &corev1.Service{}, deployContext.CheCluster.Namespace)
}
func syncDwCheCR(deployContext *deploy.DeployContext) (bool, error) {
// We want to create a default CheManager instance to be able to configure the che-specific
// parts of the installation, but at the same time we don't want to add a dependency on
// devworkspace-che-operator. Note that this way of initializing will probably see changes
// once we figure out https://github.com/eclipse/che/issues/19220
// Wait until CRD for CheManager is created
if !util.HasK8SResourceObject(deployContext.ClusterAPI.DiscoveryClient, CheManagerResourcename) {
return false, nil
}
obj := &unstructured.Unstructured{}
obj.SetGroupVersionKind(schema.GroupVersionKind{Group: "che.eclipse.org", Version: "v1alpha1", Kind: "CheManager"})
err := deployContext.ClusterAPI.Client.Get(context.TODO(), client.ObjectKey{Name: "devworkspace-che", Namespace: deployContext.CheCluster.Namespace}, obj)
if err != nil {
if apierrors.IsNotFound(err) {
obj = nil
} else {
return false, err
}
}
if obj == nil {
obj := &unstructured.Unstructured{}
if !util.IsOpenShift {
obj.SetUnstructuredContent(map[string]interface{}{
"spec": map[string]interface{}{
"gatewayHost": deployContext.CheCluster.Spec.K8s.IngressDomain,
},
})
}
obj.SetGroupVersionKind(schema.GroupVersionKind{
Group: "che.eclipse.org",
Version: "v1alpha1",
Kind: "CheManager",
})
obj.SetName("devworkspace-che")
obj.SetNamespace(deployContext.CheCluster.Namespace)
err = deployContext.ClusterAPI.Client.Create(context.TODO(), obj)
if err != nil {
if apierrors.IsAlreadyExists(err) {
return false, nil
}
return false, err
}
}
return true, nil
}
func readAndSyncObject(deployContext *deploy.DeployContext, yamlFile string, obj interface{}, namespace string) (bool, error) {
obj2sync, err := readK8SObject(yamlFile, obj)
if err != nil {

View File

@ -12,21 +12,15 @@
package devworkspace
import (
"context"
orgv1 "github.com/eclipse-che/che-operator/pkg/apis/org/v1"
"github.com/eclipse-che/che-operator/pkg/deploy"
"github.com/eclipse-che/che-operator/pkg/util"
operatorsv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
fakeDiscovery "k8s.io/client-go/discovery/fake"
"sigs.k8s.io/controller-runtime/pkg/client"
"testing"
)
@ -132,42 +126,6 @@ func TestReconcileDevWorkspace(t *testing.T) {
if !done {
t.Fatalf("Dev Workspace operator has not been provisioned")
}
t.Run("defaultCheManagerDeployed", func(t *testing.T) {
obj := &unstructured.Unstructured{}
obj.SetGroupVersionKind(schema.GroupVersionKind{Group: "che.eclipse.org", Version: "v1alpha1", Kind: "CheManager"})
err := deployContext.ClusterAPI.Client.Get(context.TODO(), client.ObjectKey{Name: "devworkspace-che", Namespace: deployContext.CheCluster.Namespace}, obj)
if testCase.IsOpenShift {
if err != nil {
t.Fatalf("Should have found a CheManager with default config but got an error: %s", err)
}
if obj.GetName() != "devworkspace-che" {
t.Fatalf("Should have found a CheManager with default config but found: %s", obj.GetName())
}
} else {
if testCase.cheCluster.Spec.Server.ServerExposureStrategy == "single-host" {
if err == nil || !apierrors.IsNotFound(err) {
t.Fatalf("Should not have found a CheManager")
}
} else {
if err != nil {
t.Fatalf("Should have found a CheManager with default config but got an error: %s", err)
}
if obj.GetName() != "devworkspace-che" {
t.Fatalf("Should have found a CheManager with default config but found: %s", obj.GetName())
}
spec := obj.Object["spec"].(map[string]interface{})
gatewayHost := spec["gatewayHost"].(string)
if gatewayHost != deployContext.CheCluster.Spec.K8s.IngressDomain {
t.Fatalf("gatewayHost wasn't set correctly, expected: %s, actual: %s", deployContext.CheCluster.Spec.K8s.IngressDomain, gatewayHost)
}
}
}
})
})
}
}