diff --git a/.ci/cico_updates_openshift.sh b/.ci/cico_updates_openshift.sh index 8f322688a..1b2aadafb 100755 --- a/.ci/cico_updates_openshift.sh +++ b/.ci/cico_updates_openshift.sh @@ -38,11 +38,11 @@ runTests() { sleep 10s createWorkspaceDevWorkspaceController - waitWorkspaceStartedDevWorkspaceController + waitAllPodsRunning ${DEVWORKSPACE_CONTROLLER_TEST_NAMESPACE} sleep 10s createWorkspaceDevWorkspaceCheOperator - waitWorkspaceStartedDevWorkspaceController + waitAllPodsRunning ${DEVWORKSPACE_CHE_OPERATOR_TEST_NAMESPACE} } initDefaults diff --git a/.ci/oci-multi-host.sh b/.ci/oci-multi-host.sh index 5c92ac7dc..9bd976a17 100755 --- a/.ci/oci-multi-host.sh +++ b/.ci/oci-multi-host.sh @@ -47,15 +47,14 @@ runTests() { # Dev Workspace controller tests enableDevWorkspaceEngine waitDevWorkspaceControllerStarted - waitEclipseCheDeployed "next" - sleep 10s - createWorkspaceDevWorkspaceController - waitWorkspaceStartedDevWorkspaceController + sleep 10s + createWorkspaceDevWorkspaceController + waitAllPodsRunning ${DEVWORKSPACE_CONTROLLER_TEST_NAMESPACE} - sleep 10s - createWorkspaceDevWorkspaceCheOperator - waitWorkspaceStartedDevWorkspaceController + sleep 10s + createWorkspaceDevWorkspaceCheOperator + waitAllPodsRunning ${DEVWORKSPACE_CHE_OPERATOR_TEST_NAMESPACE} } diff --git a/.ci/oci-single-host.sh b/.ci/oci-single-host.sh index 96a2ef162..ec0caaa3e 100755 --- a/.ci/oci-single-host.sh +++ b/.ci/oci-single-host.sh @@ -34,28 +34,27 @@ overrideDefaults() { } runTests() { - # create namespace - oc create namespace eclipse-che || true + # create namespace + oc create namespace eclipse-che || true - # Deploy Eclipse Che applying CR - applyOlmCR - waitEclipseCheDeployed "next" - provisionOAuth - startNewWorkspace - waitWorkspaceStart + # Deploy Eclipse Che applying CR + applyOlmCR + waitEclipseCheDeployed "next" + provisionOAuth + startNewWorkspace + waitWorkspaceStart - # Dev Workspace controller tests - enableDevWorkspaceEngine - waitDevWorkspaceControllerStarted - waitEclipseCheDeployed "next" + # Dev Workspace controller tests + enableDevWorkspaceEngine + waitDevWorkspaceControllerStarted - sleep 10s - createWorkspaceDevWorkspaceController - waitWorkspaceStartedDevWorkspaceController + sleep 10s + createWorkspaceDevWorkspaceController + waitAllPodsRunning ${DEVWORKSPACE_CONTROLLER_TEST_NAMESPACE} - sleep 10s - createWorkspaceDevWorkspaceCheOperator - waitWorkspaceStartedDevWorkspaceController + sleep 10s + createWorkspaceDevWorkspaceCheOperator + waitAllPodsRunning ${DEVWORKSPACE_CHE_OPERATOR_TEST_NAMESPACE} } initDefaults diff --git a/.github/bin/check-resources.sh b/.github/bin/check-resources.sh index a416b2b72..c818cf297 100755 --- a/.github/bin/check-resources.sh +++ b/.github/bin/check-resources.sh @@ -77,16 +77,13 @@ checkCRDs() { checkNightlyOlmBundle() { # files to check - local CSV_FILE_KUBERNETES="bundle/nightly/eclipse-che-preview-kubernetes/manifests/che-operator.clusterserviceversion.yaml" - local CSV_FILE_OPENSHIFT="bundle/nightly/eclipse-che-preview-openshift/manifests/che-operator.clusterserviceversion.yaml" - local CRD_FILE_KUBERNETES="bundle/nightly/eclipse-che-preview-kubernetes/manifests/org_v1_che_crd.yaml" - local CRD_FILE_OPENSHIFT="bundle/nightly/eclipse-che-preview-openshift/manifests/org_v1_che_crd.yaml" + local CSV_KUBERNETES="bundle/nightly/eclipse-che-preview-kubernetes/manifests" + local CSV_OPENSHIFT="bundle/nightly/eclipse-che-preview-openshift/manifests" changedFiles=($(cd ${ROOT_PROJECT_DIR}; git diff --name-only)) - if [[ " ${changedFiles[*]} " =~ $CSV_FILE_OPENSHIFT ]] || [[ " ${changedFiles[*]} " =~ $CSV_FILE_OPENSHIFT ]] || \ - [[ " ${changedFiles[*]} " =~ $CRD_FILE_KUBERNETES ]] || [[ " ${changedFiles[*]} " =~ $CRD_FILE_OPENSHIFT ]]; then + if [[ " ${changedFiles[*]} " =~ $CSV_KUBERNETES ]] || [[ " ${changedFiles[*]} " =~ $CSV_OPENSHIFT ]]; then echo "[ERROR] Nighlty bundle is not up to date: ${BASH_REMATCH}" - echo "[ERROR] Run 'make update-resources -s' to regenerate CSV/CRD files." + echo "[ERROR] Run 'make update-resources -s' to regenerate nightly bundle files." exit 1 else echo "[INFO] Nightly bundles are up to date." @@ -109,22 +106,22 @@ checkDockerfile() { checkOperatorYaml() { # files to check - local OperatorYaml="config/manager/manager.yaml" + local managerYaml="config/manager/manager.yaml" changedFiles=($(cd ${ROOT_PROJECT_DIR}; git diff --name-only)) - if [[ " ${changedFiles[*]} " =~ $OperatorYaml ]]; then - echo "[ERROR] $OperatorYaml is not up to date" - echo "[ERROR] Run 'make update-resources -s' to update $OperatorYaml" + if [[ " ${changedFiles[*]} " =~ $managerYaml ]]; then + echo "[ERROR] $managerYaml is not up to date" + echo "[ERROR] Run 'make update-resources -s' to update $managerYaml" exit 1 else - echo "[INFO] $OperatorYaml is up to date." + echo "[INFO] $managerYaml is up to date." fi } checkRoles() { # files to check - local RoleYaml="deploy/role.yaml" - local ClusterRoleYaml="deploy/cluster_role.yaml" + local RoleYaml="config/rbac/role.yaml" + local ClusterRoleYaml="config/rbac/cluster_role.yaml" changedFiles=( $(git diff --name-only) diff --git a/.github/bin/common.sh b/.github/bin/common.sh index 94f9954c6..546748347 100755 --- a/.github/bin/common.sh +++ b/.github/bin/common.sh @@ -37,6 +37,8 @@ initDefaults() { export OPENSHIFT_NIGHTLY_CSV_FILE="${OPERATOR_REPO}/bundle/nightly/eclipse-che-preview-openshift/manifests/che-operator.clusterserviceversion.yaml" export DEV_WORKSPACE_CONTROLLER_VERSION="main" export DEV_WORKSPACE_ENABLE="false" + export DEVWORKSPACE_CONTROLLER_TEST_NAMESPACE=devworkspace-controller-test + export DEVWORKSPACE_CHE_OPERATOR_TEST_NAMESPACE=devworkspace-cheoperator-test # turn off telemetry mkdir -p ${HOME}/.config/chectl @@ -282,8 +284,8 @@ updateEclipseChe() { chectl server:update --chenamespace=${NAMESPACE} -y --che-operator-image=${image} --templates=${templates} } +# Create and start a workspace startNewWorkspace() { - # Create and start a workspace sleep 5s login chectl workspace:create --start --chenamespace=${NAMESPACE} --devfile="${DEFAULT_DEVFILE}" @@ -466,46 +468,66 @@ waitDevWorkspaceControllerStarted() { done echo "[ERROR] Failed to deploy Dev Workspace controller" + OPERATOR_POD=$(oc get pods -o json -n ${NAMESPACE} | jq -r '.items[] | select(.metadata.name | test("che-operator-")).metadata.name') - oc logs ${OPERATOR_POD} -n ${NAMESPACE} + oc logs ${OPERATOR_POD} -c che-operator -n ${NAMESPACE} + oc logs ${OPERATOR_POD} -c devworkspace-che-operator -n ${NAMESPACE} exit 1 } createWorkspaceDevWorkspaceController () { + oc create namespace $DEVWORKSPACE_CONTROLLER_TEST_NAMESPACE + sleep 10s + echo -e "[INFO] Waiting for webhook-server to be running" CURRENT_TIME=$(date +%s) ENDTIME=$(($CURRENT_TIME + 180)) while [ $(date +%s) -lt $ENDTIME ]; do - if oc apply -f https://raw.githubusercontent.com/che-incubator/devworkspace-che-operator/main/samples/flattened_theia-nodejs.yaml -n ${NAMESPACE}; then + if oc apply -f https://raw.githubusercontent.com/che-incubator/devworkspace-che-operator/main/samples/flattened_theia-nodejs.yaml -n ${DEVWORKSPACE_CONTROLLER_TEST_NAMESPACE}; then break fi sleep 10 done } -waitWorkspaceStartedDevWorkspaceController() { +waitAllPodsRunning() { + echo "[INFO] Wait for running all pods" + local namespace=$1 + n=0 while [ $n -le 24 ] do - pods=$(oc get pods -n ${NAMESPACE}) + pods=$(oc get pods -n ${namespace}) if [[ $pods =~ .*Running.* ]]; then - echo "[INFO] Workspace started succesfully" return fi + kubectl get pods -n ${namespace} sleep 5 n=$(( n+1 )) done - echo "Failed to start a workspace" + echo "Failed to run pods in ${namespace}" exit 1 } createWorkspaceDevWorkspaceCheOperator() { - oc apply -f https://raw.githubusercontent.com/che-incubator/devworkspace-che-operator/main/samples/flattened_theia-nodejs.yaml -n ${NAMESPACE} + oc create namespace ${DEVWORKSPACE_CHE_OPERATOR_TEST_NAMESPACE} + sleep 10s + oc apply -f https://raw.githubusercontent.com/che-incubator/devworkspace-che-operator/main/samples/flattened_theia-nodejs.yaml -n ${DEVWORKSPACE_CHE_OPERATOR_TEST_NAMESPACE} } enableDevWorkspaceEngine() { + kubectl patch checluster/eclipse-che -n ${NAMESPACE} --type=merge -p "{\"spec\":{\"server\":{\"customCheProperties\": {\"CHE_INFRA_KUBERNETES_ENABLE__UNSUPPORTED__K8S\": \"true\"}}}}" kubectl patch checluster/eclipse-che -n ${NAMESPACE} --type=merge -p '{"spec":{"devWorkspace":{"enable": true}}}' } + +deployCertManager() { + kubectl apply -f https://raw.githubusercontent.com/che-incubator/chectl/main/installers/cert-manager.yml + sleep 10s + + kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=cert-manager -n cert-manager --timeout=60s + kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=webhook -n cert-manager --timeout=60s + kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=cainjector -n cert-manager --timeout=60s +} diff --git a/.github/bin/minikube/test-olm.sh b/.github/bin/minikube/test-olm.sh index 19e60e2d0..a1da4d0e6 100755 --- a/.github/bin/minikube/test-olm.sh +++ b/.github/bin/minikube/test-olm.sh @@ -28,6 +28,24 @@ runTest() { source "${OPERATOR_REPO}"/olm/testCatalogSource.sh "kubernetes" "nightly" "${NAMESPACE}" startNewWorkspace waitWorkspaceStart + + # stop workspace to free some resources + stopExistedWorkspace + waitExistedWorkspaceStop + + deployCertManager + + # Dev Workspace controller tests + enableDevWorkspaceEngine + waitDevWorkspaceControllerStarted + + sleep 10s + createWorkspaceDevWorkspaceController + waitAllPodsRunning ${DEVWORKSPACE_CONTROLLER_TEST_NAMESPACE} + + sleep 10s + createWorkspaceDevWorkspaceCheOperator + waitAllPodsRunning ${DEVWORKSPACE_CHE_OPERATOR_TEST_NAMESPACE} } initDefaults diff --git a/.github/bin/minikube/test-operator-singlehost-gateway.sh b/.github/bin/minikube/test-operator-singlehost-gateway.sh index 9e6376af0..ea18353f7 100755 --- a/.github/bin/minikube/test-operator-singlehost-gateway.sh +++ b/.github/bin/minikube/test-operator-singlehost-gateway.sh @@ -37,6 +37,24 @@ runTest() { deployEclipseCheWithTemplates "operator" "minikube" ${OPERATOR_IMAGE} ${TEMPLATES} startNewWorkspace waitWorkspaceStart + + # stop workspace to free some resources + stopExistedWorkspace + waitExistedWorkspaceStop + + deployCertManager + + # Dev Workspace controller tests + enableDevWorkspaceEngine + waitDevWorkspaceControllerStarted + + sleep 10s + createWorkspaceDevWorkspaceController + waitAllPodsRunning ${DEVWORKSPACE_CONTROLLER_TEST_NAMESPACE} + + sleep 10s + createWorkspaceDevWorkspaceCheOperator + waitAllPodsRunning ${DEVWORKSPACE_CHE_OPERATOR_TEST_NAMESPACE} } initDefaults diff --git a/.github/bin/minikube/test-operator-singlehost-native.sh b/.github/bin/minikube/test-operator-singlehost-native.sh index d1b43e549..3d2abca57 100755 --- a/.github/bin/minikube/test-operator-singlehost-native.sh +++ b/.github/bin/minikube/test-operator-singlehost-native.sh @@ -36,6 +36,24 @@ runTest() { deployEclipseCheWithTemplates "operator" "minikube" ${OPERATOR_IMAGE} ${TEMPLATES} startNewWorkspace waitWorkspaceStart + + # stop workspace to free some resources + stopExistedWorkspace + waitExistedWorkspaceStop + + deployCertManager + + # Dev Workspace controller tests + enableDevWorkspaceEngine + waitDevWorkspaceControllerStarted + + sleep 10s + createWorkspaceDevWorkspaceController + waitAllPodsRunning ${DEVWORKSPACE_CONTROLLER_TEST_NAMESPACE} + + sleep 10s + createWorkspaceDevWorkspaceCheOperator + waitAllPodsRunning ${DEVWORKSPACE_CHE_OPERATOR_TEST_NAMESPACE} } initDefaults diff --git a/Makefile b/Makefile index dc6885a52..ecd5a2026 100644 --- a/Makefile +++ b/Makefile @@ -535,6 +535,7 @@ bundle: generate manifests kustomize ## Generate bundle manifests and metadata, sed -ri "s/(.*:\s?)$(RELEASE)([^-])?$$/\1$(TAG)\2/" "$${NEW_CSV}" fi + # Remove roles for kubernetes bundle YAML_CONTENT=$$(cat "$${NEW_CSV}") if [ $${platform} = "kubernetes" ]; then clusterPermLength=$$(echo "$${YAML_CONTENT}" | yq -r ".spec.install.spec.clusterPermissions[0].rules | length") @@ -546,9 +547,12 @@ bundle: generate manifests kustomize ## Generate bundle manifests and metadata, while [ "$${j}" -lt "$${apiGroupLength}" ]; do apiGroup=$$(echo "$${YAML_CONTENT}" | yq -r '.spec.install.spec.clusterPermissions[0].rules['$${i}'].apiGroups['$${j}']') case $${apiGroup} in *openshift.io) - YAML_CONTENT=$$(echo "$${YAML_CONTENT}" | yq -rY 'del(.spec.install.spec.clusterPermissions[0].rules['$${i}'])' ) - j=$$((j-1)) - i=$$((i-1)) + # Permissions needed for DevWorkspace + if [ "$${apiGroup}" != "route.openshift.io" ] && [ "$${apiGroup}" != oauth.openshift.io ]; then + YAML_CONTENT=$$(echo "$${YAML_CONTENT}" | yq -rY 'del(.spec.install.spec.clusterPermissions[0].rules['$${i}'])' ) + j=$$((j-1)) + i=$$((i-1)) + fi break ;; esac; @@ -581,6 +585,32 @@ bundle: generate manifests kustomize ## Generate bundle manifests and metadata, fi echo "$${YAML_CONTENT}" > "$${NEW_CSV}" + # Remove roles for openshift bundle + YAML_CONTENT=$$(cat "$${NEW_CSV}") + if [ $${platform} = "openshift" ]; then + clusterPermLength=$$(echo "$${YAML_CONTENT}" | yq -r ".spec.install.spec.clusterPermissions[0].rules | length") + i=0 + while [ "$${i}" -lt "$${clusterPermLength}" ]; do + apiGroupLength=$$(echo "$${YAML_CONTENT}" | yq -r '.spec.install.spec.clusterPermissions[0].rules['$${i}'].apiGroups | length') + if [ "$${apiGroupLength}" -gt 0 ]; then + j=0 + while [ "$${j}" -lt "$${apiGroupLength}" ]; do + apiGroup=$$(echo "$${YAML_CONTENT}" | yq -r '.spec.install.spec.clusterPermissions[0].rules['$${i}'].apiGroups['$${j}']') + case $${apiGroup} in cert-manager.io) + YAML_CONTENT=$$(echo "$${YAML_CONTENT}" | yq -rY 'del(.spec.install.spec.clusterPermissions[0].rules['$${i}'])' ) + j=$$((j-1)) + i=$$((i-1)) + break + ;; + esac; + j=$$((i+1)) + done + fi + i=$$((i+1)) + done + fi + echo "$${YAML_CONTENT}" > "$${NEW_CSV}" + if [ $${platform} = "openshift" ]; then # Removes che-tls-secret-creator index=0 diff --git a/bundle/nightly/eclipse-che-preview-kubernetes/manifests/che-operator.clusterserviceversion.yaml b/bundle/nightly/eclipse-che-preview-kubernetes/manifests/che-operator.clusterserviceversion.yaml index 92fd81cc3..37d0866e2 100644 --- a/bundle/nightly/eclipse-che-preview-kubernetes/manifests/che-operator.clusterserviceversion.yaml +++ b/bundle/nightly/eclipse-che-preview-kubernetes/manifests/che-operator.clusterserviceversion.yaml @@ -83,7 +83,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.34.0-266.nightly + name: eclipse-che-preview-kubernetes.v7.34.0-267.nightly namespace: placeholder spec: apiservicedefinitions: {} @@ -288,6 +288,18 @@ spec: - nodes verbs: - get + - apiGroups: + - oauth.openshift.io + resources: + - oauthclients + verbs: + - create + - get + - delete + - list + - patch + - update + - watch - apiGroups: - rbac.authorization.k8s.io resources: @@ -422,6 +434,14 @@ spec: - create - delete - list + - apiGroups: + - route.openshift.io + resources: + - routes + verbs: + - list + - create + - delete - apiGroups: - "" resources: @@ -470,6 +490,16 @@ spec: - get - list - watch + - apiGroups: + - cert-manager.io + resources: + - issuers + - certificates + verbs: + - create + - get + - list + - update - apiGroups: - workspace.devfile.io resources: @@ -671,6 +701,19 @@ spec: verbs: - create - get + - apiGroups: + - oauth.openshift.io + resources: + - oauthclients + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch - apiGroups: - rbac.authorization.k8s.io resources: @@ -684,6 +727,18 @@ spec: - list - update - watch + - apiGroups: + - route.openshift.io + resources: + - routes + verbs: + - '*' + - apiGroups: + - route.openshift.io + resources: + - routes/custom-host + verbs: + - create - apiGroups: - workspace.devfile.io resources: @@ -833,6 +888,19 @@ spec: verbs: - create - get + - apiGroups: + - oauth.openshift.io + resources: + - oauthclients + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch - apiGroups: - rbac.authorization.k8s.io resources: @@ -846,6 +914,18 @@ spec: - list - update - watch + - apiGroups: + - route.openshift.io + resources: + - routes + verbs: + - '*' + - apiGroups: + - route.openshift.io + resources: + - routes/custom-host + verbs: + - create - nonResourceURLs: - /metrics verbs: @@ -1219,4 +1299,4 @@ spec: maturity: stable provider: name: Eclipse Foundation - version: 7.34.0-266.nightly + version: 7.34.0-267.nightly diff --git a/bundle/nightly/eclipse-che-preview-openshift/manifests/che-operator.clusterserviceversion.yaml b/bundle/nightly/eclipse-che-preview-openshift/manifests/che-operator.clusterserviceversion.yaml index 81749e2e6..b6ce4099c 100644 --- a/bundle/nightly/eclipse-che-preview-openshift/manifests/che-operator.clusterserviceversion.yaml +++ b/bundle/nightly/eclipse-che-preview-openshift/manifests/che-operator.clusterserviceversion.yaml @@ -74,7 +74,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.34.0-266.nightly + name: eclipse-che-preview-openshift.v7.34.0-267.nightly namespace: placeholder spec: apiservicedefinitions: {} @@ -1362,4 +1362,4 @@ spec: maturity: stable provider: name: Eclipse Foundation - version: 7.34.0-266.nightly + version: 7.34.0-267.nightly diff --git a/config/rbac/cluster_role.yaml b/config/rbac/cluster_role.yaml index 03024ffd3..a34d3b063 100644 --- a/config/rbac/cluster_role.yaml +++ b/config/rbac/cluster_role.yaml @@ -300,6 +300,16 @@ rules: - get - list - watch + - apiGroups: + - cert-manager.io + resources: + - issuers + - certificates + verbs: + - create + - get + - list + - update ### CHE-OPERATOR ROLES ONLY: END # devworkspace-controller-view-workspaces.ClusterRole.yaml - apiGroups: diff --git a/pkg/deploy/dev-workspace/dev_workspace.go b/pkg/deploy/dev-workspace/dev_workspace.go index 910e8cfba..7e58bbbef 100644 --- a/pkg/deploy/dev-workspace/dev_workspace.go +++ b/pkg/deploy/dev-workspace/dev_workspace.go @@ -30,6 +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/types" "sigs.k8s.io/controller-runtime/pkg/client" @@ -69,6 +70,8 @@ var ( DevWorkspaceConfigMapFile = DevWorkspaceTemplates + "/devworkspace-controller-configmap.ConfigMap.yaml" DevWorkspaceServiceFile = DevWorkspaceTemplates + "/devworkspace-controller-manager-service.Service.yaml" DevWorkspaceDeploymentFile = DevWorkspaceTemplates + "/devworkspace-controller-manager.Deployment.yaml" + DevWorkspaceIssuerFile = DevWorkspaceTemplates + "/devworkspace-controller-selfsigned-issuer.Issuer.yaml" + DevWorkspaceCertificateFile = DevWorkspaceTemplates + "/devworkspace-controller-serving-cert.Certificate.yaml" WebTerminalOperatorSubscriptionName = "web-terminal" WebTerminalOperatorNamespace = "openshift-operators" @@ -94,6 +97,8 @@ var ( syncDwRoleBinding, syncDwClusterRoleBinding, syncDwProxyClusterRoleBinding, + syncDwIssuer, + syncDwCertificate, syncDwCRD, syncDwTemplatesCRD, syncDwWorkspaceRoutingCRD, @@ -113,8 +118,8 @@ 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'.`) + if !util.IsOpenShift && util.GetCheServerCustomCheProperty(deployContext.CheCluster, "CHE_INFRA_KUBERNETES_ENABLE__UNSUPPORTED__K8S") != "true" { + logrus.Warn(`DevWorkspace Che operator can't be enabled on a Kubernetes cluster without explicitly enabled k8s API on che-server. To enable DevWorkspace Che operator set 'spec.server.customCheProperties[CHE_INFRA_KUBERNETES_ENABLE__UNSUPPORTED__K8S]' to 'true'.`) return true, nil } @@ -238,6 +243,32 @@ func syncDwCRD(deployContext *deploy.DeployContext) (bool, error) { return readAndSyncObject(deployContext, DevWorkspaceCRDFile, &apiextensionsv1.CustomResourceDefinition{}, "") } +func syncDwIssuer(deployContext *deploy.DeployContext) (bool, error) { + if !util.IsOpenShift { + // We're using unstructured to not require a direct dependency on the cert-manager + // This will cause a failure if cert-manager is not installed, which we're ok with + // Also, our Sync functionality requires the scheme to have the type we want to persist registered. + // In case of cert-manager objects, we don't want that because we would have to depend + // on cert manager, which would require us to also update operator-sdk version because cert-manager + // uses extension/v1 objects. So, we have to go the unstructured way here... + return readAndSyncUnstructured(deployContext, DevWorkspaceIssuerFile) + } + return true, nil +} + +func syncDwCertificate(deployContext *deploy.DeployContext) (bool, error) { + if !util.IsOpenShift { + // We're using unstructured to not require a direct dependency on the cert-manager + // This will cause a failure if cert-manager is not installed, which we're ok with + // Also, our Sync functionality requires the scheme to have the type we want to persist registered. + // In case of cert-manager objects, we don't want that because we would have to depend + // on cert manager, which would require us to also update operator-sdk version because cert-manager + // uses extension/v1 objects. So, we have to go the unstructured way here... + return readAndSyncUnstructured(deployContext, DevWorkspaceCertificateFile) + } + return true, nil +} + func syncDwConfigMap(deployContext *deploy.DeployContext) (bool, error) { obj2sync, err := readK8SObject(DevWorkspaceConfigMapFile, &corev1.ConfigMap{}) if err != nil { @@ -278,6 +309,42 @@ func readAndSyncObject(deployContext *deploy.DeployContext, yamlFile string, obj return syncObject(deployContext, obj2sync, namespace) } +func readAndSyncUnstructured(deployContext *deploy.DeployContext, yamlFile string) (bool, error) { + obj := &unstructured.Unstructured{} + obj2sync, err := readK8SObject(yamlFile, obj) + if err != nil { + return false, err + } + + return createUnstructured(deployContext, obj2sync.obj.(*unstructured.Unstructured)) +} + +func createUnstructured(deployContext *deploy.DeployContext, obj *unstructured.Unstructured) (bool, error) { + check := &unstructured.Unstructured{} + check.SetGroupVersionKind(obj.GroupVersionKind()) + + err := deployContext.ClusterAPI.Client.Get(context.TODO(), client.ObjectKey{Name: obj.GetName(), Namespace: obj.GetNamespace()}, obj) + if err != nil { + if apierrors.IsNotFound(err) { + check = nil + } else { + return false, err + } + } + + if check == nil { + 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 syncObject(deployContext *deploy.DeployContext, obj2sync *Object2Sync, namespace string) (bool, error) { obj2sync.obj.SetNamespace(namespace) diff --git a/pkg/util/util.go b/pkg/util/util.go index 689cbf611..071c4599b 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -477,6 +477,14 @@ func GetWorkspaceNamespaceDefault(cr *orgv1.CheCluster) string { return GetValue(cr.Spec.Server.WorkspaceNamespaceDefault, workspaceNamespaceDefault) } +// GetCheServerCustomCheProperty - returns value of che-server's custom property. +func GetCheServerCustomCheProperty(cr *orgv1.CheCluster, key string) string { + if cr.Spec.Server.CustomCheProperties != nil { + return cr.Spec.Server.CustomCheProperties[key] + } + return "" +} + // IsDeleteOAuthInitialUser - returns true when initial Openshfit oAuth user must be deleted. func IsDeleteOAuthInitialUser(cr *orgv1.CheCluster) bool { return cr.Spec.Auth.InitialOpenShiftOAuthUser != nil && !*cr.Spec.Auth.InitialOpenShiftOAuthUser && cr.Status.OpenShiftOAuthUserCredentialsSecret != ""