From 110149a5c7b158ec14659ca61f5c3153a9e8b80a Mon Sep 17 00:00:00 2001 From: Anatolii Bazko Date: Wed, 8 Jul 2020 16:08:20 +0300 Subject: [PATCH] Respect openshift cluster wide proxy (#272) * Respect OpenShift cluster wide proxy Signed-off-by: Anatoliy Bazko --- .vscode/launch.json | 3 +- deploy/cluster_role.yaml | 3 + deploy/operator-local.yaml | 2 + deploy/operator.yaml | 2 + .../eclipse-che-preview-kubernetes.crd.yaml | 548 ++++++++++++++++++ ...lipse-che-preview-kubernetes.crd.yaml.diff | 0 ...htly.1594209360.clusterserviceversion.yaml | 403 +++++++++++++ ...1594209360.clusterserviceversion.yaml.diff | 34 ++ ...clipse-che-preview-kubernetes.package.yaml | 2 +- .../eclipse-che-preview-openshift.crd.yaml | 548 ++++++++++++++++++ ...clipse-che-preview-openshift.crd.yaml.diff | 0 ...htly.1594209361.clusterserviceversion.yaml | 450 ++++++++++++++ ...1594209361.clusterserviceversion.yaml.diff | 46 ++ ...eclipse-che-preview-openshift.package.yaml | 2 +- pkg/controller/che/che_controller.go | 52 +- pkg/controller/che/create.go | 8 +- pkg/controller/che/proxy.go | 60 ++ pkg/deploy/che_configmap.go | 130 +---- pkg/deploy/che_configmap_test.go | 8 +- pkg/deploy/configmap.go | 98 ++++ pkg/deploy/configmap_cert.go | 55 ++ pkg/deploy/data_types.go | 17 + pkg/deploy/defaults.go | 4 + pkg/deploy/deployment_che.go | 8 +- pkg/deploy/deployment_keycloak.go | 34 +- pkg/deploy/proxy.go | 171 ++++++ pkg/deploy/proxy_test.go | 261 +++++++++ pkg/deploy/registry_configmap.go | 1 - pkg/deploy/secret.go | 4 +- pkg/deploy/tls.go | 70 +-- pkg/util/util.go | 56 -- pkg/util/util_test.go | 63 -- 32 files changed, 2800 insertions(+), 343 deletions(-) create mode 100644 olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/9.9.9-nightly.1594209360/eclipse-che-preview-kubernetes.crd.yaml create mode 100644 olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/9.9.9-nightly.1594209360/eclipse-che-preview-kubernetes.crd.yaml.diff create mode 100644 olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/9.9.9-nightly.1594209360/eclipse-che-preview-kubernetes.v9.9.9-nightly.1594209360.clusterserviceversion.yaml create mode 100644 olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/9.9.9-nightly.1594209360/eclipse-che-preview-kubernetes.v9.9.9-nightly.1594209360.clusterserviceversion.yaml.diff create mode 100644 olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/9.9.9-nightly.1594209361/eclipse-che-preview-openshift.crd.yaml create mode 100644 olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/9.9.9-nightly.1594209361/eclipse-che-preview-openshift.crd.yaml.diff create mode 100644 olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/9.9.9-nightly.1594209361/eclipse-che-preview-openshift.v9.9.9-nightly.1594209361.clusterserviceversion.yaml create mode 100644 olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/9.9.9-nightly.1594209361/eclipse-che-preview-openshift.v9.9.9-nightly.1594209361.clusterserviceversion.yaml.diff create mode 100644 pkg/controller/che/proxy.go create mode 100644 pkg/deploy/configmap.go create mode 100644 pkg/deploy/configmap_cert.go create mode 100644 pkg/deploy/proxy.go create mode 100644 pkg/deploy/proxy_test.go diff --git a/.vscode/launch.json b/.vscode/launch.json index 86ceadf439..e2198c536a 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -50,7 +50,8 @@ "CONSOLE_LINK_IMAGE": "/dashboard/assets/branding/loader.svg", "CHE_IDENTITY_SECRET": "che-identity-secret", "CHE_IDENTITY_POSTGRES_SECRET": "che-identity-postgres-secret", - "CHE_POSTGRES_SECRET": "che-postgres-secret" + "CHE_POSTGRES_SECRET": "che-postgres-secret", + "CHE_SERVER_TRUST_STORE_CONFIGMAP_NAME": "ca-certs" }, "cwd": "${workspaceFolder}", "args": [ diff --git a/deploy/cluster_role.yaml b/deploy/cluster_role.yaml index afd2126c1c..a4d0b01c7d 100644 --- a/deploy/cluster_role.yaml +++ b/deploy/cluster_role.yaml @@ -30,8 +30,11 @@ rules: resources: - infrastructures - oauths + - proxies verbs: - get + - list + - watch - apiGroups: - user.openshift.io resources: diff --git a/deploy/operator-local.yaml b/deploy/operator-local.yaml index 5f6a4caeff..6d2d673e86 100644 --- a/deploy/operator-local.yaml +++ b/deploy/operator-local.yaml @@ -81,3 +81,5 @@ spec: value: che-identity-postgres-secret - name: CHE_POSTGRES_SECRET value: che-postgres-secret + - name: CHE_SERVER_TRUST_STORE_CONFIGMAP_NAME + value: ca-certs diff --git a/deploy/operator.yaml b/deploy/operator.yaml index 61450b6c9f..2507964f9a 100644 --- a/deploy/operator.yaml +++ b/deploy/operator.yaml @@ -80,6 +80,8 @@ spec: value: che-identity-postgres-secret - name: CHE_POSTGRES_SECRET value: che-postgres-secret + - name: CHE_SERVER_TRUST_STORE_CONFIGMAP_NAME + value: ca-certs restartPolicy: Always serviceAccountName: che-operator terminationGracePeriodSeconds: 5 diff --git a/olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/9.9.9-nightly.1594209360/eclipse-che-preview-kubernetes.crd.yaml b/olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/9.9.9-nightly.1594209360/eclipse-che-preview-kubernetes.crd.yaml new file mode 100644 index 0000000000..12e325dc1f --- /dev/null +++ b/olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/9.9.9-nightly.1594209360/eclipse-che-preview-kubernetes.crd.yaml @@ -0,0 +1,548 @@ +# +# Copyright (c) 2012-2020 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 +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: checlusters.org.eclipse.che +spec: + group: org.eclipse.che + names: + kind: CheCluster + listKind: CheClusterList + plural: checlusters + singular: checluster + scope: Namespaced + subresources: + status: {} + validation: + openAPIV3Schema: + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Desired configuration of the Che installation. Based on these + settings, the operator automatically creates and maintains several config + maps that will contain the appropriate environment variables the various + components of the Che installation. These generated config maps should + NOT be updated manually. + properties: + auth: + description: Configuration settings related to the Authentication used + by the Che installation. + properties: + externalIdentityProvider: + description: 'Instructs the operator on whether or not to deploy + a dedicated Identity Provider (Keycloak or RH SSO instance). By + default a dedicated Identity Provider server is deployed as part + of the Che installation. But if `externalIdentityProvider` is + `true`, then no dedicated identity provider will be deployed by + the operator and you might need to provide details about the external + identity provider you want to use. See also all the other fields + starting with: `identityProvider`.' + type: boolean + identityProviderAdminUserName: + description: Overrides the name of the Identity Provider admin user. + Defaults to `admin`. + type: string + identityProviderClientId: + description: Name of a Identity provider (Keycloak / RH SSO) `client-id` + that should be used for Che. This is useful to override it ONLY + if you use an external Identity Provider (see the `externalIdentityProvider` + field). If omitted or left blank, it will be set to the value + of the `flavour` field suffixed with `-public`. + type: string + identityProviderImage: + description: Overrides the container image used in the Identity + Provider (Keycloak / RH SSO) deployment. This includes the image + tag. Omit it or leave it empty to use the defaut container image + provided by the operator. + type: string + identityProviderImagePullPolicy: + description: Overrides the image pull policy used in the Identity + Provider (Keycloak / RH SSO) deployment. Default value is `Always` + for `nightly` or `latest` images, and `IfNotPresent` in other + cases. + type: string + identityProviderPassword: + description: Overrides the password of Keycloak admin user. This + is useful to override it ONLY if you use an external Identity + Provider (see the `externalIdentityProvider` field). If omitted + or left blank, it will be set to an auto-generated password. + type: string + identityProviderPostgresPassword: + description: Password for The Identity Provider (Keycloak / RH SSO) + to connect to the database. This is useful to override it ONLY + if you use an external Identity Provider (see the `externalIdentityProvider` + field). If omitted or left blank, it will be set to an auto-generated + password. + type: string + identityProviderPostgresSecret: + description: 'The secret that contains `password` for The Identity + Provider (Keycloak / RH SSO) to connect to the database. If the + secret is defined then `identityProviderPostgresPassword` will + be ignored. If the value is omitted or left blank then there are + two scenarios: 1. `identityProviderPostgresPassword` is defined, + then it will be used to connect to the database. 2. `identityProviderPostgresPassword` + is not defined, then a new secret with the name `che-identity-postgres-secret` + will be created with an auto-generated value for `password`.' + type: string + identityProviderRealm: + description: Name of a Identity provider (Keycloak / RH SSO) realm + that should be used for Che. This is useful to override it ONLY + if you use an external Identity Provider (see the `externalIdentityProvider` + field). If omitted or left blank, it will be set to the value + of the `flavour` field. + type: string + identityProviderSecret: + description: 'The secret that contains `user` and `password` for + Identity Provider. If the secret is defined then `identityProviderAdminUserName` + and `identityProviderPassword` are ignored. If the value is omitted + or left blank then there are two scenarios: 1. `identityProviderAdminUserName` + and `identityProviderPassword` are defined, then they will be + used. 2. `identityProviderAdminUserName` or `identityProviderPassword` + are not defined, then a new secret with the name `che-identity-secret` + will be created with default value `admin` for `user` and with + an auto-generated value for `password`.' + type: string + identityProviderURL: + description: Public URL of the Identity Provider server (Keycloak + / RH SSO server). You should set it ONLY if you use an external + Identity Provider (see the `externalIdentityProvider` field). + By default this will be automatically calculated and set by the + operator. + type: string + oAuthClientName: + description: Name of the OpenShift `OAuthClient` resource used to + setup identity federation on the OpenShift side. Auto-generated + if left blank. See also the `OpenShiftoAuth` field. + type: string + oAuthSecret: + description: Name of the secret set in the OpenShift `OAuthClient` + resource used to setup identity federation on the OpenShift side. + Auto-generated if left blank. See also the `OAuthClientName` field. + type: string + openShiftoAuth: + description: 'Enables the integration of the identity provider (Keycloak + / RHSSO) with OpenShift OAuth. Enabled by default on OpenShift. + This will allow users to directly login with their Openshift user + through the Openshift login, and have their workspaces created + under personal OpenShift namespaces. WARNING: the `kubeadmin` + user is NOT supported, and logging through it will NOT allow accessing + the Che Dashboard.' + type: boolean + updateAdminPassword: + description: Forces the default `admin` Che user to update password + on first login. Defaults to `false`. + type: boolean + type: object + database: + description: Configuration settings related to the database used by + the Che installation. + properties: + chePostgresDb: + description: Postgres database name that the Che server uses to + connect to the DB. Defaults to `dbche`. + type: string + chePostgresHostName: + description: Postgres Database hostname that the Che server uses + to connect to. Defaults to postgres. This value should be overridden + ONLY when using an external database (see field `externalDb`). + In the default case it will be automatically set by the operator. + type: string + chePostgresPassword: + description: Postgres password that the Che server should use to + connect to the DB. If omitted or left blank, it will be set to + an auto-generated value. + type: string + chePostgresPort: + description: Postgres Database port that the Che server uses to + connect to. Defaults to 5432. This value should be overridden + ONLY when using an external database (see field `externalDb`). + In the default case it will be automatically set by the operator. + type: string + chePostgresSecret: + description: 'The secret that contains Postgres `user` and `password` + that the Che server should use to connect to the DB. If the secret + is defined then `chePostgresUser` and `chePostgresPassword` are + ignored. If the value is omitted or left blank then there are + two scenarios: 1. `chePostgresUser` and `chePostgresPassword` + are defined, then they will be used to connect to the DB. 2. `chePostgresUser` + or `chePostgresPassword` are not defined, then a new secret with + the name `che-postgres-secret` will be created with default value + of `pgche` for `user` and with an auto-generated value for `password`.' + type: string + chePostgresUser: + description: Postgres user that the Che server should use to connect + to the DB. Defaults to `pgche`. + type: string + externalDb: + description: 'Instructs the operator on whether or not to deploy + a dedicated database. By default a dedicated Postgres database + is deployed as part of the Che installation. But if `externalDb` + is `true`, then no dedicated database will be deployed by the + operator and you might need to provide connection details to the + external DB you want to use. See also all the fields starting + with: `chePostgres`.' + type: boolean + postgresImage: + description: Overrides the container image used in the Postgres + database deployment. This includes the image tag. Omit it or leave + it empty to use the defaut container image provided by the operator. + type: string + postgresImagePullPolicy: + description: Overrides the image pull policy used in the Postgres + database deployment. Default value is `Always` for `nightly` or + `latest` images, and `IfNotPresent` in other cases. + type: string + type: object + k8s: + description: Configuration settings specific to Che installations made + on upstream Kubernetes. + properties: + ingressClass: + description: 'Ingress class that will define the which controler + will manage ingresses. Defaults to `nginx`. NB: This drives the + `is kubernetes.io/ingress.class` annotation on Che-related ingresses.' + type: string + ingressDomain: + description: 'Global ingress domain for a K8S cluster. This MUST + be explicitly specified: there are no defaults.' + type: string + ingressStrategy: + description: Strategy for ingress creation. This can be `multi-host` + (host is explicitly provided in ingress), `single-host` (host + is provided, path-based rules) and `default-host.*`(no host is + provided, path-based rules). Defaults to `"multi-host` + type: string + securityContextFsGroup: + description: FSGroup the Che pod and Workspace pods containers should + run in. Defaults to `1724`. + type: string + securityContextRunAsUser: + description: ID of the user the Che pod and Workspace pods containers + should run as. Default to `1724`. + type: string + tlsSecretName: + description: Name of a secret that will be used to setup ingress + TLS termination if TLS is enabled. See also the `tlsSupport` field. + type: string + type: object + metrics: + description: Configuration settings related to the metrics collection + used by the Che installation. + properties: + enable: + description: Enables `metrics` Che server endpoint. Default to `true`. + type: boolean + type: object + server: + description: General configuration settings related to the Che server + and the plugin and devfile registries + properties: + airGapContainerRegistryHostname: + description: Optional hostname (or url) to an alternate container + registry to pull images from. This value overrides the container + registry hostname defined in all the default container images + involved in a Che deployment. This is particularly useful to install + Che in an air-gapped environment. + type: string + airGapContainerRegistryOrganization: + description: Optional repository name of an alternate container + registry to pull images from. This value overrides the container + registry organization defined in all the default container images + involved in a Che deployment. This is particularly useful to install + Che in an air-gapped environment. + type: string + allowUserDefinedWorkspaceNamespaces: + description: Defines if a user is able to specify Kubernetes namespace + (or OpenShift project) different from the default. It's NOT RECOMMENDED + to configured true without OAuth configured. This property is + also used by the OpenShift infra. + type: boolean + cheDebug: + description: Enables the debug mode for Che server. Defaults to + `false`. + type: string + cheFlavor: + description: Flavor of the installation. This is either `che` for + upstream Che installations, or `codeready` for CodeReady Workspaces + installation. In most cases the default value should not be overriden. + type: string + cheHost: + description: Public hostname of the installed Che server. This will + be automatically set by the operator. In most cases the default + value set by the operator should not be overriden. + type: string + cheImage: + description: Overrides the container image used in Che deployment. + This does NOT include the container image tag. Omit it or leave + it empty to use the defaut container image provided by the operator. + type: string + cheImagePullPolicy: + description: Overrides the image pull policy used in Che deployment. + Default value is `Always` for `nightly` or `latest` images, and + `IfNotPresent` in other cases. + type: string + cheImageTag: + description: Overrides the tag of the container image used in Che + deployment. Omit it or leave it empty to use the defaut image + tag provided by the operator. + type: string + cheLogLevel: + description: 'Log level for the Che server: `INFO` or `DEBUG`. Defaults + to `INFO`.' + type: string + cheWorkspaceClusterRole: + description: Custom cluster role bound to the user for the Che workspaces. + The default roles are used if this is omitted or left blank. + type: string + customCheProperties: + additionalProperties: + type: string + description: Map of additional environment variables that will be + applied in the generated `che` config map to be used by the Che + server, in addition to the values already generated from other + fields of the `CheCluster` custom resource (CR). If `customCheProperties` + contains a property that would be normally generated in `che` + config map from other CR fields, then the value defined in the + `customCheProperties` will be used instead. + type: object + devfileRegistryImage: + description: Overrides the container image used in the Devfile registry + deployment. This includes the image tag. Omit it or leave it empty + to use the defaut container image provided by the operator. + type: string + devfileRegistryMemoryLimit: + description: Overrides the memory limit used in the Devfile registry + deployment. Defaults to 256Mi. + type: string + devfileRegistryMemoryRequest: + description: Overrides the memory request used in the Devfile registry + deployment. Defaults to 16Mi. + type: string + devfileRegistryPullPolicy: + description: Overrides the image pull policy used in the Devfile + registry deployment. Default value is `Always` for `nightly` or + `latest` images, and `IfNotPresent` in other cases. + type: string + devfileRegistryUrl: + description: Public URL of the Devfile registry, that serves sample, + ready-to-use devfiles. You should set it ONLY if you use an external + devfile registry (see the `externalDevfileRegistry` field). By + default this will be automatically calculated by the operator. + type: string + externalDevfileRegistry: + description: Instructs the operator on whether or not to deploy + a dedicated Devfile registry server. By default a dedicated devfile + registry server is started. But if `externalDevfileRegistry` is + `true`, then no such dedicated server will be started by the operator + and you will have to manually set the `devfileRegistryUrl` field + type: boolean + externalPluginRegistry: + description: Instructs the operator on whether or not to deploy + a dedicated Plugin registry server. By default a dedicated plugin + registry server is started. But if `externalPluginRegistry` is + `true`, then no such dedicated server will be started by the operator + and you will have to manually set the `pluginRegistryUrl` field. + type: boolean + gitSelfSignedCert: + description: If enabled, then the certificate from `che-git-self-signed-cert` + config map will be propagated to the Che components and provide + particular configuration for Git. + type: boolean + nonProxyHosts: + description: List of hosts that should not use the configured proxy. + Use `|`` as delimiter, eg `localhost|my.host.com|123.42.12.32` + Only use when configuring a proxy is required (see also the `proxyURL` + field). + type: string + pluginRegistryImage: + description: Overrides the container image used in the Plugin registry + deployment. This includes the image tag. Omit it or leave it empty + to use the defaut container image provided by the operator. + type: string + pluginRegistryMemoryLimit: + description: Overrides the memory limit used in the Plugin registry + deployment. Defaults to 256Mi. + type: string + pluginRegistryMemoryRequest: + description: Overrides the memory request used in the Plugin registry + deployment. Defaults to 16Mi. + type: string + pluginRegistryPullPolicy: + description: Overrides the image pull policy used in the Plugin + registry deployment. Default value is `Always` for `nightly` or + `latest` images, and `IfNotPresent` in other cases. + type: string + pluginRegistryUrl: + description: Public URL of the Plugin registry, that serves sample + ready-to-use devfiles. You should set it ONLY if you use an external + devfile registry (see the `externalPluginRegistry` field). By + default this will be automatically calculated by the operator. + type: string + proxyPassword: + description: Password of the proxy server Only use when proxy configuration + is required (see also the `proxyUser` and `proxySecret` fields). + type: string + proxyPort: + description: Port of the proxy server. Only use when configuring + a proxy is required (see also the `proxyURL` field). + type: string + proxySecret: + description: The secret that contains `user` and `password` for + a proxy server. If the secret is defined then `proxyUser` and + `proxyPassword` are ignored + type: string + proxyURL: + description: URL (protocol+hostname) of the proxy server. This drives + the appropriate changes in the `JAVA_OPTS` and `https(s)_proxy` + variables in the Che server and workspaces containers. Only use + when configuring a proxy is required. + type: string + proxyUser: + description: User name of the proxy server. Only use when configuring + a proxy is required (see also the `proxyURL` `proxySecret` fields). + type: string + selfSignedCert: + description: Deprecated. The value of this flag is ignored. Che + operator will automatically detect if router certificate is self-signed. + If so it will be propagated to Che server and some other components. + type: boolean + serverMemoryLimit: + description: Overrides the memory limit used in the Che server deployment. + Defaults to 1Gi. + type: string + serverMemoryRequest: + description: Overrides the memory request used in the Che server + deployment. Defaults to 512Mi. + type: string + serverTrustStoreConfigMapName: + description: Name of the config-map with public certificates to + add to Java trust store of the Che server. This is usually required + when adding the OpenShift OAuth provider which has https endpoint + signed with self-signed cert. So, Che server must be aware of + its CA cert to be able to request it. This is disabled by default. + type: string + tlsSupport: + description: Deprecated. Instructs the operator to deploy Che in + TLS mode. This is enabled by default. Disabling TLS may cause + malfunction of some Che components. + type: boolean + workspaceNamespaceDefault: + description: 'Defines Kubernetes default namespace in which user''s + workspaces are created if user does not override it. It''s possible + to use , and placeholders (e.g.: + che-workspace-). In that case, new namespace will be + created for each user (or workspace). Is used by OpenShift infra + as well to specify Project' + type: string + type: object + storage: + description: Configuration settings related to the persistent storage + used by the Che installation. + properties: + postgresPVCStorageClassName: + description: Storage class for the Persistent Volume Claim dedicated + to the Postgres database. If omitted or left blank, default storage + class is used. + type: string + preCreateSubPaths: + description: Instructs the Che server to launch a special pod to + pre-create a subpath in the Persistent Volumes. Defaults to `false`, + however it might need to enable it according to the configuration + of your K8S cluster. + type: boolean + pvcClaimSize: + description: Size of the persistent volume claim for workspaces. + Defaults to `1Gi` + type: string + pvcJobsImage: + description: Overrides the container image used to create sub-paths + in the Persistent Volumes. This includes the image tag. Omit it + or leave it empty to use the defaut container image provided by + the operator. See also the `preCreateSubPaths` field. + type: string + pvcStrategy: + description: Persistent volume claim strategy for the Che server. + This Can be:`common` (all workspaces PVCs in one volume), `per-workspace` + (one PVC per workspace for all declared volumes) and `unique` + (one PVC per declared volume). Defaults to `common`. + type: string + workspacePVCStorageClassName: + description: Storage class for the Persistent Volume Claims dedicated + to the Che workspaces. If omitted or left blank, default storage + class is used. + type: string + type: object + type: object + status: + description: CheClusterStatus defines the observed state of Che installation + properties: + cheClusterRunning: + description: Status of a Che installation. Can be `Available`, `Unavailable`, + or `Available, Rolling Update in Progress` + type: string + cheURL: + description: Public URL to the Che server + type: string + cheVersion: + description: Current installed Che version + type: string + dbProvisioned: + description: Indicates if or not a Postgres instance has been correctly + provisioned + type: boolean + devfileRegistryURL: + description: Public URL to the Devfile registry + type: string + helpLink: + description: A URL that can point to some URL where to find help related + to the current Operator status. + type: string + keycloakProvisioned: + description: Indicates whether an Identity Provider instance (Keycloak + / RH SSO) has been provisioned with realm, client and user + type: boolean + keycloakURL: + description: Public URL to the Identity Provider server (Keycloak / + RH SSO). + type: string + message: + description: A human readable message indicating details about why the + pod is in this condition. + type: string + openShiftoAuthProvisioned: + description: Indicates whether an Identity Provider instance (Keycloak + / RH SSO) has been configured to integrate with the OpenShift OAuth. + type: boolean + pluginRegistryURL: + description: Public URL to the Plugin registry + type: string + reason: + description: A brief CamelCase message indicating details about why + the pod is in this state. + type: string + type: object + version: v1 + versions: + - name: v1 + served: true + storage: true diff --git a/olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/9.9.9-nightly.1594209360/eclipse-che-preview-kubernetes.crd.yaml.diff b/olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/9.9.9-nightly.1594209360/eclipse-che-preview-kubernetes.crd.yaml.diff new file mode 100644 index 0000000000..e69de29bb2 diff --git a/olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/9.9.9-nightly.1594209360/eclipse-che-preview-kubernetes.v9.9.9-nightly.1594209360.clusterserviceversion.yaml b/olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/9.9.9-nightly.1594209360/eclipse-che-preview-kubernetes.v9.9.9-nightly.1594209360.clusterserviceversion.yaml new file mode 100644 index 0000000000..b7abcb71cf --- /dev/null +++ b/olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/9.9.9-nightly.1594209360/eclipse-che-preview-kubernetes.v9.9.9-nightly.1594209360.clusterserviceversion.yaml @@ -0,0 +1,403 @@ +apiVersion: operators.coreos.com/v1alpha1 +kind: ClusterServiceVersion +metadata: + annotations: + alm-examples: |- + [ + { + "apiVersion": "org.eclipse.che/v1", + "kind": "CheCluster", + "metadata": { + "name": "eclipse-che" + }, + "spec": { + "k8s": { + "ingressDomain": "", + "tlsSecretName": "" + }, + "server": { + "cheImageTag": "nightly", + "devfileRegistryImage": "quay.io/eclipse/che-devfile-registry:nightly", + "pluginRegistryImage": "quay.io/eclipse/che-plugin-registry:nightly", + "tlsSupport": true, + "selfSignedCert": false + }, + "database": { + "externalDb": false, + "chePostgresHostName": "", + "chePostgresPort": "", + "chePostgresUser": "", + "chePostgresPassword": "", + "chePostgresDb": "" + }, + "auth": { + "identityProviderImage": "quay.io/eclipse/che-keycloak:nightly", + "externalIdentityProvider": false, + "identityProviderURL": "", + "identityProviderRealm": "", + "identityProviderClientId": "" + }, + "storage": { + "pvcStrategy": "per-workspace", + "pvcClaimSize": "1Gi", + "preCreateSubPaths": true + }, + "metrics": { + "enable": true + } + } + } + ] + capabilities: Seamless Upgrades + categories: Developer Tools + certified: "false" + containerImage: quay.io/eclipse/che-operator:nightly + createdAt: "2020-07-08T11:56:01Z" + description: A Kube-native development solution that delivers portable and collaborative + developer workspaces. + repository: https://github.com/eclipse/che-operator + support: Eclipse Foundation + name: eclipse-che-preview-kubernetes.v9.9.9-nightly.1594209360 + namespace: placeholder +spec: + apiservicedefinitions: {} + customresourcedefinitions: + owned: + - description: Eclipse Che cluster with DB and Auth Server + displayName: Eclipse Che Cluster + kind: CheCluster + name: checlusters.org.eclipse.che + specDescriptors: + - description: TLS routes + displayName: TLS Mode + path: server.tlsSupport + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + statusDescriptors: + - description: Ingress to access Eclipse Che + displayName: Eclipse Che URL + path: cheURL + x-descriptors: + - urn:alm:descriptor:org.w3:link + - description: Ingress to access Keycloak Admin Console + displayName: Keycloak Admin Console URL + path: keycloakURL + x-descriptors: + - urn:alm:descriptor:org.w3:link + - description: Eclipse Che server version + displayName: Eclipse Che version + path: cheVersion + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:label + - description: The current status of the application + displayName: Status + path: cheClusterRunning + x-descriptors: + - urn:alm:descriptor:io.kubernetes.phase + - description: Reason of the current status + displayName: Reason + path: reason + x-descriptors: + - urn:alm:descriptor:text + - description: Message explaining the current status + displayName: Message + path: message + x-descriptors: + - urn:alm:descriptor:text + - description: Link providing help related to the current status + displayName: Help link + path: helpLink + x-descriptors: + - urn:alm:descriptor:org.w3:link + version: v1 + description: | + A collaborative Kubernetes-native development solution that delivers Kubernetes workspaces and in-browser IDE for rapid cloud application development. + This operator installs PostgreSQL, Keycloak, Registries and the Eclipse Che server, as well as configures all these services. + ## Prerequisites + - Operator Lifecycle Manager (OLM) needs to be installed. + - Kubernetes Platform. For OpenShift, the installation is directly made from OperatorHub UI in the admin console. + + OLM installation can be checked by running the command: + ``` + $ kubectl get pods --all-namespaces | grep olm + olm catalog-operator-7b8cd7f8bf-2v7zj 1/1 Running 0 10m + olm olm-operator-5c5c798cd5-s6ll5 1/1 Running 0 10m + olm olm-operators-fm5wc 1/1 Running 0 10m + olm operatorhubio-catalog-d78km 1/1 Running 0 10m + olm packageserver-5c5f64947b-trghp 1/1 Running 0 9m56s + olm packageserver-5c5f64947b-zqvxg 1/1 Running 0 9m56s + ``` + + ## How to Install + Install `Eclipse Che Operator` by following instructions in top right button `Install`. + + A new pod che-operator is created in `my-eclipse-che` namespace + + ``` + $ kubectl get pods --all-namespaces | grep my-eclipse-che + my-eclipse-che che-operator-554c564476-fl98z 1/1 Running 0 13s + ``` + + The operator is now providing new Custom Resources Definitions: `checluster.org.eclipse.che` + + Create a new Eclipse Che instance by creating a new CheCluster resource: + + On the bottom of this page, there is a section `Custom Resource Definitions` with `Eclipse Che Cluster` name. + + Click on `View YAML Example` *Link* and copy the content to a new file named `my-eclipse-che.yaml` + **Important!** Make sure you provide **K8s.ingressDomain** which is a global ingress domain of your k8s cluster, for example, `gcp.my-ide.cloud` + Create the new CheCluster by creating the resource in the `my-eclipse-che` namespace : + ``` + $ kubectl create -f my-eclipse-che.yaml -n my-eclipse-che + ``` + ***important:*** The operator is only tracking resources in its own namespace. If CheCluster is not created in this namespace it's ignored. + The operator will now create pods for Eclipse Che. The deployment status can be tracked by looking at the Operator logs by using the command: + ``` + $ kubectl logs -n my-eclipse-che che-operator-554c564476-fl98z + ``` + ***important:*** pod name is different on each installation + + When all Eclipse Che containers are running, the Eclipse Che URL is printed + + + Eclipse Che URL can be tracked by searching for available trace: + ``` + $ kubectl logs -f -n my-eclipse-che che-operator-7b6b4bcb9c-m4m2m | grep "Eclipse Che is now available" + time="2019-08-01T13:31:05Z" level=info msg="Eclipse Che is now available at: http://che-my-eclipse-che.gcp.my-ide.cloud" + ``` + When Eclipse Che is ready, the Eclipse Che URL is displayed in CheCluster resource in `status` section + ``` + $ kubectl describe checluster/eclipse-che -n my-eclipse-che + ``` + + ``` + Status: + Che Cluster Running: Available + Che URL: http://che-my-eclipse-che.gcp.my-ide.cloud + Che Version: 7.0.0 + ... + ``` + + By opening this URL in a web browser, Eclipse Che is ready to use. + ## Defaults + By default, the operator deploys Eclipse Che with: + * Bundled PostgreSQL and Keycloak + * Per-Workspace PVC strategy + * Auto-generated passwords + * HTTP mode (non-secure ingresses) + ## Installation Options + Eclipse Che operator installation options include: + * Connection to external database and Keycloak + * Configuration of default passwords and object names + * TLS mode + * PVC strategy (once shared PVC for all workspaces, PVC per workspace, or PVC per volume) + * Authentication options + ### External Database and Keycloak + To instruct the operator to skip deploying PostgreSQL and Keycloak and connect to an existing DB and Keycloak instead: + * set respective fields to `true` in a custom resource spec + * provide the operator with connection and authentication details: + ``` + externalDb: true + chePostgresHostname: 'yourPostgresHost' + chePostgresPort: '5432' + chePostgresUser: 'myuser' + chePostgresPassword: 'mypass' + chePostgresDb: 'mydb' + externalIdentityProvider: true + identityProviderURL: 'https://my-keycloak.com' + identityProviderRealm: 'myrealm' + identityProviderClientId: 'myClient' + ``` + ### TLS Mode + To activate TLS mode, set the respective field in the CR spec to `true` (in the `server` block): + ``` + tlsSupport: true + ``` + You will also need to provide name of tls secret that will be used for Eclipse Che and workspaces ingresses: + ``` + tlsSecretName: 'my-ingress-tls-secret' + ``` + displayName: Eclipse Che + icon: + - base64data: iVBORw0KGgoAAAANSUhEUgAAANMAAAD0CAYAAAABrhNXAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QA/wD/AP+gvaeTAAAaNklEQVR42u3de3QU9dkH8O/zm91EQK0U77dqVdTW++1V20KigUSQahLjsSSbtp4eeqqVLHILCcoiyQZEIbF61B6PVQJ6XiOkr6TlYiABr603wHotar1bBUWUYDY787x/JIGoSchmZ+c3M/t8/iS7M8+M5+vs7szz/IiZIYRIntJdgBB+IWESwiYSJiFsImESwiYSJiFsImESwiaBvv5ARLprEwB4ddaJTBQF8w/JsKbQmI0v665JAL3dUqK+7jNJmPTiNWOHWYhNB1AOILPrn+MA369MazaNe+Iz3TWmMwmTB3AEyrwwu4SIbwVwWB+v+hxEt6gg7qLs1rjumtORhMnlePUlF5hk1RFw4QDf8rrFmBLMa12tu/Z0I2FyKV53yVGWyTVgLgGQ8IknoImMQBnlNL+t+1jShYTJZXjlhKFW8KsbQJgNYP8ktxYDcI8yh95E41bt1H1sfidhcpH4mtETCHQHgONs3vTHAEXUMy33UQSW7uP0KwmTC/DqS84xyaol4Bcp3tULiqiMxrY8pfuY/UjCpBG3ZB1sxfgmgK4HYDi1WwI9SnGaTuPXv6v7HPiJhEkDfv7coPX5AdeB+RaADtRURRtAC9UB7Qvo4md26z4nfiBhcljH6qwcRbgDwKm6a+nyATNVGrkt9USQrtAkSJgcwquyT2ZlLWLQON219FofsMEghGls6ybdtXiVhCnFuOnnw62gEQHoOvTz3KM7sAVSy5RS0yln3X91V+M1EqYU4ZasgBWjawGuAnCI7noStAOM+coaUkvjVrXrLsYrJEwp0LHmkksUrFoAp+uuJSnMbzLR1EBua5PuUrxAwmSj7tYIBhfprsVOBDQTU5jyWl7RXYubSZhs0KM1YiaA/XTXkyIdAN+tMmgOZbfu0F2MG0mYksAMMtdkh4h4AYDDddfj0FF3tnrsOOROurrB1F2Nm0iYBolXjT7fVFRHwEW6a9FkkyIK09iWDboLcQsJU4KSbY3wGwKaCNZkyt34ju5adJMwDRA/fdEQa2fmZBAqARygux536Wr1+CY+m6546ivd1Wg7CxKmfUtha4TP8EeAmpuurR4Spn7w46PONi2qJdAo3bV4CROeM1iFKXf907prcfS4JUzfx82XjrDM+M0Ot0b4TWerB8yplLvxfd3FOHLAEqYeJ2NPawTmAviB7np8YheA21QG5lN26ze6i0klCVOXjtVZOUpxHZh+orsWn3qfmWYH8lqW6C4kVdI+TLwq+2Q2+HZmjNddSzogoIUsI0yXrduiuxa7pW2YuOnnw62MwEwwTwEoQ3c96aWr1SMen+qnKbRpF6a901GthQAdqrueNPcFGAvUzkMW09UNMd3FJCutwtSxenS2ItQCdIbuWsS3vMFENwbGtvxddyHJSIsw8ZpRx1hkVIM5pLsW0TcCmsk0ymjculd11zIYvg5TmrRG+E1nq4cK3kxjmr/UXUwifBkmZpD5+OiriHEbQMfqrkcMynYQ5nmp1cN3YepsjUAtgS7WXYuwA7+oGGHK2/CE7kr2WalfwsRrxxxpcWwOgN8BJEuJ+gwBTWThBrqs9T+6a+mL58PEjxRlWAd99gcw5kFaI3yO20D0JxVEFWW3fq27mu9V5+UwdbVG1AE4XnctwlEfMlOF26bQejJMvDbrLJNRS8Bo3bUIfRj8T0NRGY1pfVZ3LYDHwsSrc39o0TdzpDVC7OWeKbSeCFOP1ogIgIO0FCHcrrPVwxxSo2sKrevD1LVqRC2Anzq+c+FFW5m4IjB2Q4PTO3ZtmLj50pFsmrczcLnTJ0V4HzHWESFMua3/cmqfrgsTt2QdZHWgHIwwgEynToTwpTjA96sMqqTs1m2p3plrwiStESJ1uqbQBnEXZbfGU7YXN4SpY1VWllKoBXBmqg5UCACvW4wpwbzW1anYuNYw8d+zjrYCFJXpqMJJBDSRESijnOa37dyuljDxyglDrYyvZkBaI4Q2XVNozaE30bhVO23ZopNhktYI4UIfAxSxYwqtY2HitVnndT0C9DOHT5YQA/GCIiqjsS1PDXYDKQ8Tr/7FERapCKQ1Qrhf5xTaOE2n8evfTfjNqQrT3tYIvgWgA3WfJSEGjtsAWpjoFNqUhKmzNQK1AP1Y92kRIgkfMFPlQFs9bA0TPz7qVLbUIgbydJ8FIezChFbDojDltWzu93V2hElaI4T/dbV6cHAa5a79tNdXJBMmbskKWDG6FszVIBys+3CFcMAOMOYra0jtd1s9Bh2mjrXZlyrmWgCn6T46IRzH/CYTTQ3ktjbt/acEw8RrR53EbFQzuEj38QihGwHNxBSmvJZXEgqT9Xj2bWC+QVaNEKInjoFQpca0zvvuXwJ9vwdT5XlUIXpiC6T+Vyn1597+Gkh0c0KkIwb+YUCV0diWfwBAbx/oJExC9G/AN3MlTEL0qudE2ZYBTZSVMAnxHQQ0Udz4Y6IPwEqYhNiDX1SdU2OfHMy7pU1CCMY2EMLqy0MvGGyQALkyifTWuXKhNfQmyku+nV3CJNISAc2krMk0ZuNrdm1TwiTSzRtMdKORgtXeJUwiXXwBwtzO4ZQtKRlOKWESftc5Ntm0ZtO4Jz5L5Y4kTMK3CLyerMAUumzdFif2J2HyBu58GkwmPg3QW8w01chr/T8ndyr/cVyPX1QKoxTUBcwY9D2QNLELwFyVgdMCeS2OBgmQK5N7MbZBoUrtOPROurrBBABmjDIfH30VgRaC8SPdJboIg2ip6uAZNL71E11F9N0cuDbbNStbp5nOG4n9zMXuMb99BoAhugvWiQnPGSaX0WUbnnF0vwl12kqYHEdAE5kqTOPWvzWQ16f5yiIfMlPFQOfc2U3C5F5vMHhKIHfDqsG8mddmj7Y6B96cpftAHLAbhDvU7o5quuKpr3QVIWFynx43EpNb5W7vaox8K4DDdB9YKhDQRLAmU+7Gd3TXImFyj5TdSOSWrP2tGKYBKIdf1glmvKRIhSl3/UbdpewpScKkH4HXk+Iwjdn4cir345MxbdtBmKd2HLLnF023kDDptZWJKwJjNzQ4udOO1Vk5ilAL4Ke6T0AiZQN8t1LBm2lM85e6i+mNhEmPXQBuS3TJEjvx8+cGre0H/tYLo617DnrUXUt/JEzOcsWNxG8V5OZFF3oZQexmEiaHMPifhoWw0zcSB1zf46NOZVMtZkKu7lrQPRx/5yGL6eqGmO5iBkrClHpabyQmqnOhOqoDcLzze9/3si1u1ltu5EFXe+wGYYHKwCmBvJYlXggSAARyN6xUXx5yCghhAI7dAGVCq2J1jjG2pdSLQeqLXJmSREATWbiBLmv9j+5aksFrxxxpcWwOUru49/vMNNsrV+7+yMc8OzFeUuAyytvwhO5SbD2stVnnmcx1BLrYxq0OahFmN5Mw2cO1NxLtwgwyHx99FTFuA+jYZDZFoEdJGdNoTPN7uo/LThKm5Lj+RqLdeM3YYRZi0wHMBLBfQu8FnjeIwjS25Sndx5GScyNhGhwCmsk0ymjculd116IDrxl1jEVGNZhDA3j5xwBF1DMt91EElu7aU3ZOJEwJe4OJbgykYMaaF3WsHp3d+WgSnfH9v3IMwD39NTX6iYRp4L4AY4HXbiQ6YW+rh7UQoEOBrl80jUAZ5TS/rbs+x86DhGmf4gD/WRmBmyln3XbdxbhZ56NJ7dMtqMeDuevX667H8eOXMPWNgBayjLBTM9aEt/WWG5lO1H0jMa9lie5ChLelc5h6tEa0+OJGotArHcPUeSMR5lTK3fi+7mKEf6RVmJjwnMEqTLnrn9Zdi/CfNHlqnD8C6PfG060XSpBEqvj9ytQ1Yy2udcaaSA++DdOeGWtj9c9YE/4RiUTUlreCpQAe+O7f/BimTQqqzE0z1oQ/FBTXnL9lK2oBvhg+D5PvWyOEHr+8ZsGRgUB8DsC/Qz+/M/ghTGnXGiGcUVS0aEg8s30ywawE6IB9vd7TYdo7Y63V1TPWhPcUhqommPxNHSUwbMabYeqasWZ4ZMaa8I4rJ1afpRTqmGlUou/1Wpg6Z6xZQ2tp3Kp23cUI/ygqivzQysiYw4RBD+j0SJh6zFjL889oKKHfpEn3Bre3bbvOBEUAHJTMtlwfJia0GpYKU27LZt21CH8pLK3J2bZrey2IbFnUwM1hep+ZZgdypTVC2Cu/NDpSMW5niy+3c/FSF4ap54w1aY0Q9rnyN5GDjHiwnC2EOQULwbkpTF0z1gK+m7Em9IpEImrz1mAJxelWTuESpa4Ik99nrAl98kPR0Vu2oo6AM1O9L81h4o8ANdfw+Yw14byC4gVHA2YUjBLAzm9GfdMSprhF2PThwZvf3Tli/NU33vOhjhqEP02YFBkabAvOAMwZAIY4uW/Hw/TCB4fgL8+fgv9+NeRMAM8Vhmoip5/Qfl8kEpErk0gCU35o/lXUxgsB/EhHBY6N+vrgy/3xwPMnY/NHI3r78/NghFcsq5DvTCJhV06sOVcprgPwM6f2ubx+1vc+Oqb8yvR1ewANL5+I1a8fA4v7/Oh6HghPFJZEH1VKTWtYUi6/5ol9KiipPgJAZF+tEU5J2ZXJtAgtbx2FhzediJ3fZCTy1jaAFx4Y6Jj/wAMRuc8kvqeoKJJhZQb/YIFuIeBAHTX0dmVKSZpf/mQEZvztItz77E8SDRIADAVozs54xr/zS6pLAXbklxjhDYWhqglmZsZrDKrVFaS+2Hpl+njnUDy86UQ88+7hthXIQCugwo1Ly+XZvDRW+KvoKWxgMYA83bUAKfzO9E2HgZWvHYfGl49Hh2XvxY6ALMB6saA4uoxVcFpj/XR5ajyN9GiNuA7a74v2L6krEwN44p0jUf/CSOzYnfDHucHYwaD53wwfVrvqT5Oln8nHsrIigRHHZF7LbFUDdLDuer7L1u9M/972A1Su+h/86cnTnAoSABxE4PlDvvh6S35x9HKndiqcdVVx9aUjjs54kZnvdWOQ+pLwZXN72354+KWTsPGdw8H6fhsYSYSVBcXRZgqo8PIHy2UGhA8UldScaIGjFlCku5bBGHCY2k2Fx145Hn995TjE4oPq6rUfIYdN66XC4ujdZjA2568PRHboLkkkLhRaOGwXx6ab4HKkoDXCKfv8zsRMePa9w1D/wkh8tiuhBbcdPhJ8Tsy3qPaT7mxouFrm5nkCU35JNESgBQDs+wnYAb19Z+o3TG9tPxAPPn8yXvt0uO7aE8CvEWHK8vrKNborEX27cmLVBUoZdQBfqLuWwUjop/G7nj4NG946AuzM0+s2olOZsbowFG1SMCc31N8ks8ZdpKi06ijTVDUglPjthnyfYWp960jdtSWFGZebMMYWFkfv6cg0Zj92/0xZBUOj7umopsWzQdhfdz2poP3hwBTLYMLkQMx8vTBUMykSifj9eF2pMFQ1wcz45lUCzwf8GSTA/2HqdiQz37tla8azV5VUXay7mHRRUFJ9Tn5JdCOzegyE43TXk2qufjwjBc63oJ6UVo/Uyi+NjlAmbmbgehrkdFQvSrcwAQAxUGRa1riCkurbpNXDPt3TUdnCXCb8QHc9TkuXj3m9GQbQnJ1mxpudrR4iGYWlNTmftW3fxKBaIP2CBKTnlenbGMcQ6MGCUPQ3RBxevqRyi+6SvKSoZN7JJoxFbPE4X/3OPQgSpm6MbGZ6SVo9Bmb8xJrh+ylrpgmaAsCxJ53dTML0bQqEkOKOy/NLahYE2tsXNzREYrqLcpM901HBCxl0qO563CSdvzP1iYHhBJ5vZma8XFBSPV53PW5RMLE6e8vWjJcI9CAACdJ3yJWpfyMBaioojjYbQFnDsopXdRekwxXXVB1jGKoahJDuWtxMwjQQhBwT2FRYHL1bxdTNDQ3labEQdXdrBEAzAbi4ZcAd5GPewAWZMNnMtN4qLKkuKyp6xMc3I5nyQzVFu7jjVYDmQII0IBKmxI1gUK2ZufW5gonzE15E2O0KimvOLyiZ/yQxPwLgWN31eIl8zBu8s6GsDX5p9fjlNQuODATic9wyHdWLJExJ6mr1uLSwpPqOjoxAtddaPbqnozLMeQAdoLseL5P/A9ljCINmBmLma16aQts1HfX1rkeAJEhJkiuTvY4i0IMFJTV/ZBUta1xS8YzugnqTH1pwKlnmYmbk6q7FTyRMqXE+WXiqoDi61AgGZjQ8MOMT3QUBPaajsnk9KH1aI5wiYUodAiFkxuMFuls9Jk26N7h99+e/NdmqBuCZoY5eI9+ZUm9Y16oeL+eHahwfrlhYWpOzbdf2l7w2HdWL5MrknBOJ+ZGCkuh6Ujwl1a0ehRPnnQTDWMQWX+65AVMeJWFy3iVs0QsFJdX3G0Ga3fCXis/s3PiVv4kcZMSD5QwKg707HdWLJEx6BACaZHWgyK5Wjz2tEXG6lYHDdB9gOpLvTBp1t3rEMzO3FIai4wa7nfxQdPTLWzNe6GqNkCBpIlcmFyDwycz4W0FxtJmVMbmxfuZrA3lfQfGCowEzCkYJQ74Z6SZhchNCDrG5ubA4encbYjetWhbZ2dvLJkyKDA22BWcA5gwAQ3SXLTrJxzz3CTJh8hAK9tLq0dkaEWzL6G6NkCC5SJ+rYBSGahJeIFqkxIsKCMctalOK6wD8THdBIoULRIuUOscCNijFDPkk4WoSJm8gyA8Mrif/pxPCJhImIWwiYRLCJhImIWwiYRLCJhImIWwiYRLCJhImIWwiYRLCJhImIWwiYRLCJhImIWzSd5iIbgcgS1AK8W2xrmx8T59hWlE/axpZ5mkENOiuXghXYDSToc5ZUT9rWm9/7rM5kGjvE/9XFVdfahHVAjhN9/EIocGbAN+4Ymnl37r/obfcDChMAJCVFQmMOCbzWmarWiaDijSxg0HzexvFllSYuu0Z/k64DtJcKPzJAmMZq+C0xvrpn/b2AlvC1K3wV9FT2MBiAHm6j1wIuzDQCqhw49Lyzf2+zs4wdSsMVU1gVrUAfqz7RAgxaIT3mXl249LKJQN5eW+5Sfo+0/L62SuN9tipBA4zsDPZ7QnhsDaA5x5oxEYONEh9SfrK1FNBSfURACIAySLDwu2YgEeVUtMalpS/l/CbU/ExrzdXTqw5V2a8CRd7HozwimUVTw12A46FqWt3lB+afxUxLwTwIyfPlBB9+JiIIqef0H5fJBKxktmQw2HqtHcuNslcbKFLjBj39De/PVFawtRtz4oNhBLIQEXhECI0waSy5Q/NetvO7WoNU7f8UHQ0MeoAnJmSHQgBAITXmWlK49JZq1Ox+ZT8NJ6oxvqKDWecGDuHwb8G8F+n9y98jvA5gcOfvx87PVVB6nPXTl+ZevrW+quQ9VdFUuIA399hZlaufHjatlTvzBUf83qTXxodqRi3M+Nyx3YqfIOBdSAON9ZX/suxfbo1TN0KS2ty2ORaEH7q+M6FB9G/mVDZWD/L8Z47V3xn6s/yJbOaDx424mwi+j3AKb9UC8/6GuC5u4cPO11HkPriqitTTz1aPa4HYCS9QeEHFhjL4hZPf+zhSq0/Xrn+Y15v8kMLTiXLXAxCru5ahEaEf8KyylYsm/2s7lIAj4apW1erRx2A43XXIhz1IYMrGpdW1APkmnWWXf+dqT9drR6nEDgM4Cvd9YiUayPwAqM9dkpna4R7gtQXz1yZevrlNQuODATic6TVw5+I0GQadMNfH5j1H9219MXTH/N6UxiqOo/ZqAP4Yt21CFu8qIDwo0srntBdyL74Lkxdh9Xd6nEbgGN1VyMGg7cRUKXaT7qzoeFqU3c1A6rYn2HqFAotHLaLY9MBmglgP931iAHpIMbddrZGOMXXYep2xTVVxxiGqgYhpLsW0Q9GMytjcmP9zNd0lzKo8tMhTN0KJlZnQ1EtgDN01yL2YtAbivjG5fUVf9ddS1LH4eWfxhO14qHKljNOjJ3d1erxadIbFEkh4AsGlQfa28/wepD6PEa/Xpl66tHqMQVAhu560owFxjIjA1Mb/lLxme5i7JJWH/N6k18aHUkWLQJ4vO5a0gKhhYjDy5dUbtFdit3SPkzdCktrciyL6wj4ie5afOo9Bt+U7FBHN0ur70z9Wb5kVvMhQ0ec1fVo0pe66/GRXQDPPTAQO9nPQepLWl6ZesovjY5QJm6WVo+kMBhLjWBgRsMDMz7RXYwjBywf8/pWWFpzNltWLUCjdNfiMc+xQlnjkopndBfiJAnTAEirx4B9xOBZbmuNcIqEaYCKihYNiWe2TyZwJYADdNfjMrsJfEdHRqD6sftnpm0rjIQpQUWlVUeZpqqRKbSdiNCkYE5uqL/pHd216CZhGqSC4przAa4D4SLdtWjyEiwVXvFQ+UbdhbiFhCkpTPkl0RCBFgA4XHc1DtlO4Hleao1wioTJBmnS6tFBjLtVTN3c0FAu9+F6IWGy0ZW/nneCYRo1DBTprsVWjGYKqPDyB8tf0V2Km0mYUiA/VHMJMS+G91s93mTG1MZlFU26C/ECeZwoBRrrZ63v0erhxaeidzCofPfw/c+QICVHrkw2Gj+xZvh+yprpkVYPC4xlrILTGuunS79XguRjnkOKSuadbMJYBGCc7lp6w0AroMKNS8s3667FqyRMDissrclhy7oDoFN119LlAwZXpusjQHaS70wOW75kVvPBQw8+0wWtHm1drREneWU6qhfJlckhmlo9mIBH2bKmr3ho9ru6z4GfyMc8FygoqT6HQbUE/CKV+yHCC2yhbMWyiqd0H7MfSZhcpDBUNYEtdQcIx9m86Y+JKHL6Ce33RSIRS/dx+pWEyWUmTIoMDbRl3kDg2QD2T3JzMWLc48XpqF4kYXKpZFs9iNAEk8qWPzTrbd3Hki4kTC535cSqC5Qy6gC+cEBvILzOTFMal85arbv2dCNh8oQBtHoQPifmW7Z/0HFXa2skrrvidCRh8pAerR7lADK7/jkO8P0dZmblyoenyWr0GkmYPKhw4ryTYBiL2EKQlTHFq6tG+E1CYRJCJEYeJxLCJhImIWwiYRLCJhImIWwiYRLCJv8P9sXhC7xE4kIAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTktMDQtMTNUMDg6MTY6MDgrMDI6MDCcYZVaAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE5LTA0LTEzVDA4OjE2OjA4KzAyOjAw7Twt5gAAAABJRU5ErkJggg== + mediatype: image/png + install: + spec: + deployments: + - name: che-operator + spec: + replicas: 1 + selector: + matchLabels: + app: che-operator + strategy: {} + template: + metadata: + labels: + app: che-operator + spec: + containers: + - command: + - /usr/local/bin/che-operator + env: + - name: WATCH_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.annotations['olm.targetNamespaces'] + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: OPERATOR_NAME + value: che-operator + - name: CHE_VERSION + value: nightly + - name: RELATED_IMAGE_che_server + value: quay.io/eclipse/che-server:nightly + - name: RELATED_IMAGE_plugin_registry + value: quay.io/eclipse/che-plugin-registry:nightly + - name: RELATED_IMAGE_devfile_registry + value: quay.io/eclipse/che-devfile-registry:nightly + - name: RELATED_IMAGE_che_tls_secrets_creation_job + value: quay.io/eclipse/che-tls-secret-creator:alpine-3029769 + - name: RELATED_IMAGE_pvc_jobs + value: registry.access.redhat.com/ubi8-minimal:8.2-301.1592810506 + - name: RELATED_IMAGE_postgres + value: centos/postgresql-96-centos7:9.6 + - name: RELATED_IMAGE_keycloak + value: quay.io/eclipse/che-keycloak:nightly + - name: RELATED_IMAGE_che_workspace_plugin_broker_metadata + value: quay.io/eclipse/che-plugin-metadata-broker:v3.2.0 + - name: RELATED_IMAGE_che_workspace_plugin_broker_artifacts + value: quay.io/eclipse/che-plugin-artifacts-broker:v3.2.0 + - name: RELATED_IMAGE_che_server_secure_exposer_jwt_proxy_image + value: quay.io/eclipse/che-jwtproxy:fd94e60 + - name: CHE_FLAVOR + value: che + - name: CONSOLE_LINK_NAME + value: che + - name: CONSOLE_LINK_DISPLAY_NAME + value: Eclipse Che + - name: CONSOLE_LINK_SECTION + value: Red Hat Applications + - name: CONSOLE_LINK_IMAGE + value: /dashboard/assets/branding/loader.svg + - name: CHE_IDENTITY_SECRET + value: che-identity-secret + - name: CHE_IDENTITY_POSTGRES_SECRET + value: che-identity-postgres-secret + - name: CHE_POSTGRES_SECRET + value: che-postgres-secret + - name: CHE_SERVER_TRUST_STORE_CONFIGMAP_NAME + value: ca-certs + image: quay.io/eclipse/che-operator:nightly + imagePullPolicy: Always + name: che-operator + ports: + - containerPort: 60000 + name: metrics + resources: {} + restartPolicy: Always + serviceAccountName: che-operator + terminationGracePeriodSeconds: 5 + permissions: + - rules: + - apiGroups: + - extensions + resources: + - ingresses + verbs: + - '*' + - apiGroups: + - batch + resources: + - jobs + verbs: + - '*' + - apiGroups: + - rbac.authorization.k8s.io + resources: + - roles + - rolebindings + verbs: + - '*' + - apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterroles + - clusterrolebindings + verbs: + - '*' + - apiGroups: + - "" + resources: + - pods + - services + - serviceaccounts + - endpoints + - persistentvolumeclaims + - events + - configmaps + - secrets + - pods/exec + - pods/log + verbs: + - '*' + - apiGroups: + - "" + resources: + - namespaces + verbs: + - get + - apiGroups: + - apps + resources: + - deployments + verbs: + - '*' + - apiGroups: + - monitoring.coreos.com + resources: + - servicemonitors + verbs: + - get + - create + - apiGroups: + - org.eclipse.che + resources: + - '*' + verbs: + - '*' + serviceAccountName: che-operator + strategy: deployment + installModes: + - supported: true + type: OwnNamespace + - supported: true + type: SingleNamespace + - supported: true + type: MultiNamespace + - supported: false + type: AllNamespaces + keywords: + - eclipse che + - workspaces + - devtools + - developer + - ide + - java + links: + - name: Product Page + url: http://www.eclipse.org/che + - name: Documentation + url: https://www.eclipse.org/che/docs + - name: Operator GitHub Repo + url: https://github.com/eclipse/che-operator + maintainers: + - email: dfestal@redhat.com + name: David Festal + maturity: stable + provider: + name: Eclipse Foundation + replaces: eclipse-che-preview-kubernetes.v9.9.9-nightly.1594133420 + version: 9.9.9-nightly.1594209360 diff --git a/olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/9.9.9-nightly.1594209360/eclipse-che-preview-kubernetes.v9.9.9-nightly.1594209360.clusterserviceversion.yaml.diff b/olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/9.9.9-nightly.1594209360/eclipse-che-preview-kubernetes.v9.9.9-nightly.1594209360.clusterserviceversion.yaml.diff new file mode 100644 index 0000000000..0fd7c0c539 --- /dev/null +++ b/olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/9.9.9-nightly.1594209360/eclipse-che-preview-kubernetes.v9.9.9-nightly.1594209360.clusterserviceversion.yaml.diff @@ -0,0 +1,34 @@ +--- /home/tolusha/gocode/src/github.com/eclipse/che-operator/olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/9.9.9-nightly.1594133420/eclipse-che-preview-kubernetes.v9.9.9-nightly.1594133420.clusterserviceversion.yaml 2020-07-08 14:55:47.702990053 +0300 ++++ /home/tolusha/gocode/src/github.com/eclipse/che-operator/olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/9.9.9-nightly.1594209360/eclipse-che-preview-kubernetes.v9.9.9-nightly.1594209360.clusterserviceversion.yaml 2020-07-08 14:56:01.247006488 +0300 +@@ -52,12 +52,12 @@ + categories: Developer Tools + certified: "false" + containerImage: quay.io/eclipse/che-operator:nightly +- createdAt: "2020-07-07T14:50:21Z" ++ createdAt: "2020-07-08T11:56:01Z" + description: A Kube-native development solution that delivers portable and collaborative + developer workspaces. + repository: https://github.com/eclipse/che-operator + support: Eclipse Foundation +- name: eclipse-che-preview-kubernetes.v9.9.9-nightly.1594133420 ++ name: eclipse-che-preview-kubernetes.v9.9.9-nightly.1594209360 + namespace: placeholder + spec: + apiservicedefinitions: {} +@@ -288,6 +288,8 @@ + value: che-identity-postgres-secret + - name: CHE_POSTGRES_SECRET + value: che-postgres-secret ++ - name: CHE_SERVER_TRUST_STORE_CONFIGMAP_NAME ++ value: ca-certs + image: quay.io/eclipse/che-operator:nightly + imagePullPolicy: Always + name: che-operator +@@ -397,5 +399,5 @@ + maturity: stable + provider: + name: Eclipse Foundation +- replaces: eclipse-che-preview-kubernetes.v9.9.9-nightly.1594019197 +- version: 9.9.9-nightly.1594133420 ++ replaces: eclipse-che-preview-kubernetes.v9.9.9-nightly.1594133420 ++ version: 9.9.9-nightly.1594209360 diff --git a/olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/eclipse-che-preview-kubernetes.package.yaml b/olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/eclipse-che-preview-kubernetes.package.yaml index 690fa616f1..be351c67ce 100644 --- a/olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/eclipse-che-preview-kubernetes.package.yaml +++ b/olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/eclipse-che-preview-kubernetes.package.yaml @@ -1,5 +1,5 @@ channels: -- currentCSV: eclipse-che-preview-kubernetes.v9.9.9-nightly.1594133420 +- currentCSV: eclipse-che-preview-kubernetes.v9.9.9-nightly.1594209360 name: nightly - currentCSV: eclipse-che-preview-kubernetes.v7.15.1 name: stable diff --git a/olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/9.9.9-nightly.1594209361/eclipse-che-preview-openshift.crd.yaml b/olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/9.9.9-nightly.1594209361/eclipse-che-preview-openshift.crd.yaml new file mode 100644 index 0000000000..12e325dc1f --- /dev/null +++ b/olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/9.9.9-nightly.1594209361/eclipse-che-preview-openshift.crd.yaml @@ -0,0 +1,548 @@ +# +# Copyright (c) 2012-2020 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 +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: checlusters.org.eclipse.che +spec: + group: org.eclipse.che + names: + kind: CheCluster + listKind: CheClusterList + plural: checlusters + singular: checluster + scope: Namespaced + subresources: + status: {} + validation: + openAPIV3Schema: + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Desired configuration of the Che installation. Based on these + settings, the operator automatically creates and maintains several config + maps that will contain the appropriate environment variables the various + components of the Che installation. These generated config maps should + NOT be updated manually. + properties: + auth: + description: Configuration settings related to the Authentication used + by the Che installation. + properties: + externalIdentityProvider: + description: 'Instructs the operator on whether or not to deploy + a dedicated Identity Provider (Keycloak or RH SSO instance). By + default a dedicated Identity Provider server is deployed as part + of the Che installation. But if `externalIdentityProvider` is + `true`, then no dedicated identity provider will be deployed by + the operator and you might need to provide details about the external + identity provider you want to use. See also all the other fields + starting with: `identityProvider`.' + type: boolean + identityProviderAdminUserName: + description: Overrides the name of the Identity Provider admin user. + Defaults to `admin`. + type: string + identityProviderClientId: + description: Name of a Identity provider (Keycloak / RH SSO) `client-id` + that should be used for Che. This is useful to override it ONLY + if you use an external Identity Provider (see the `externalIdentityProvider` + field). If omitted or left blank, it will be set to the value + of the `flavour` field suffixed with `-public`. + type: string + identityProviderImage: + description: Overrides the container image used in the Identity + Provider (Keycloak / RH SSO) deployment. This includes the image + tag. Omit it or leave it empty to use the defaut container image + provided by the operator. + type: string + identityProviderImagePullPolicy: + description: Overrides the image pull policy used in the Identity + Provider (Keycloak / RH SSO) deployment. Default value is `Always` + for `nightly` or `latest` images, and `IfNotPresent` in other + cases. + type: string + identityProviderPassword: + description: Overrides the password of Keycloak admin user. This + is useful to override it ONLY if you use an external Identity + Provider (see the `externalIdentityProvider` field). If omitted + or left blank, it will be set to an auto-generated password. + type: string + identityProviderPostgresPassword: + description: Password for The Identity Provider (Keycloak / RH SSO) + to connect to the database. This is useful to override it ONLY + if you use an external Identity Provider (see the `externalIdentityProvider` + field). If omitted or left blank, it will be set to an auto-generated + password. + type: string + identityProviderPostgresSecret: + description: 'The secret that contains `password` for The Identity + Provider (Keycloak / RH SSO) to connect to the database. If the + secret is defined then `identityProviderPostgresPassword` will + be ignored. If the value is omitted or left blank then there are + two scenarios: 1. `identityProviderPostgresPassword` is defined, + then it will be used to connect to the database. 2. `identityProviderPostgresPassword` + is not defined, then a new secret with the name `che-identity-postgres-secret` + will be created with an auto-generated value for `password`.' + type: string + identityProviderRealm: + description: Name of a Identity provider (Keycloak / RH SSO) realm + that should be used for Che. This is useful to override it ONLY + if you use an external Identity Provider (see the `externalIdentityProvider` + field). If omitted or left blank, it will be set to the value + of the `flavour` field. + type: string + identityProviderSecret: + description: 'The secret that contains `user` and `password` for + Identity Provider. If the secret is defined then `identityProviderAdminUserName` + and `identityProviderPassword` are ignored. If the value is omitted + or left blank then there are two scenarios: 1. `identityProviderAdminUserName` + and `identityProviderPassword` are defined, then they will be + used. 2. `identityProviderAdminUserName` or `identityProviderPassword` + are not defined, then a new secret with the name `che-identity-secret` + will be created with default value `admin` for `user` and with + an auto-generated value for `password`.' + type: string + identityProviderURL: + description: Public URL of the Identity Provider server (Keycloak + / RH SSO server). You should set it ONLY if you use an external + Identity Provider (see the `externalIdentityProvider` field). + By default this will be automatically calculated and set by the + operator. + type: string + oAuthClientName: + description: Name of the OpenShift `OAuthClient` resource used to + setup identity federation on the OpenShift side. Auto-generated + if left blank. See also the `OpenShiftoAuth` field. + type: string + oAuthSecret: + description: Name of the secret set in the OpenShift `OAuthClient` + resource used to setup identity federation on the OpenShift side. + Auto-generated if left blank. See also the `OAuthClientName` field. + type: string + openShiftoAuth: + description: 'Enables the integration of the identity provider (Keycloak + / RHSSO) with OpenShift OAuth. Enabled by default on OpenShift. + This will allow users to directly login with their Openshift user + through the Openshift login, and have their workspaces created + under personal OpenShift namespaces. WARNING: the `kubeadmin` + user is NOT supported, and logging through it will NOT allow accessing + the Che Dashboard.' + type: boolean + updateAdminPassword: + description: Forces the default `admin` Che user to update password + on first login. Defaults to `false`. + type: boolean + type: object + database: + description: Configuration settings related to the database used by + the Che installation. + properties: + chePostgresDb: + description: Postgres database name that the Che server uses to + connect to the DB. Defaults to `dbche`. + type: string + chePostgresHostName: + description: Postgres Database hostname that the Che server uses + to connect to. Defaults to postgres. This value should be overridden + ONLY when using an external database (see field `externalDb`). + In the default case it will be automatically set by the operator. + type: string + chePostgresPassword: + description: Postgres password that the Che server should use to + connect to the DB. If omitted or left blank, it will be set to + an auto-generated value. + type: string + chePostgresPort: + description: Postgres Database port that the Che server uses to + connect to. Defaults to 5432. This value should be overridden + ONLY when using an external database (see field `externalDb`). + In the default case it will be automatically set by the operator. + type: string + chePostgresSecret: + description: 'The secret that contains Postgres `user` and `password` + that the Che server should use to connect to the DB. If the secret + is defined then `chePostgresUser` and `chePostgresPassword` are + ignored. If the value is omitted or left blank then there are + two scenarios: 1. `chePostgresUser` and `chePostgresPassword` + are defined, then they will be used to connect to the DB. 2. `chePostgresUser` + or `chePostgresPassword` are not defined, then a new secret with + the name `che-postgres-secret` will be created with default value + of `pgche` for `user` and with an auto-generated value for `password`.' + type: string + chePostgresUser: + description: Postgres user that the Che server should use to connect + to the DB. Defaults to `pgche`. + type: string + externalDb: + description: 'Instructs the operator on whether or not to deploy + a dedicated database. By default a dedicated Postgres database + is deployed as part of the Che installation. But if `externalDb` + is `true`, then no dedicated database will be deployed by the + operator and you might need to provide connection details to the + external DB you want to use. See also all the fields starting + with: `chePostgres`.' + type: boolean + postgresImage: + description: Overrides the container image used in the Postgres + database deployment. This includes the image tag. Omit it or leave + it empty to use the defaut container image provided by the operator. + type: string + postgresImagePullPolicy: + description: Overrides the image pull policy used in the Postgres + database deployment. Default value is `Always` for `nightly` or + `latest` images, and `IfNotPresent` in other cases. + type: string + type: object + k8s: + description: Configuration settings specific to Che installations made + on upstream Kubernetes. + properties: + ingressClass: + description: 'Ingress class that will define the which controler + will manage ingresses. Defaults to `nginx`. NB: This drives the + `is kubernetes.io/ingress.class` annotation on Che-related ingresses.' + type: string + ingressDomain: + description: 'Global ingress domain for a K8S cluster. This MUST + be explicitly specified: there are no defaults.' + type: string + ingressStrategy: + description: Strategy for ingress creation. This can be `multi-host` + (host is explicitly provided in ingress), `single-host` (host + is provided, path-based rules) and `default-host.*`(no host is + provided, path-based rules). Defaults to `"multi-host` + type: string + securityContextFsGroup: + description: FSGroup the Che pod and Workspace pods containers should + run in. Defaults to `1724`. + type: string + securityContextRunAsUser: + description: ID of the user the Che pod and Workspace pods containers + should run as. Default to `1724`. + type: string + tlsSecretName: + description: Name of a secret that will be used to setup ingress + TLS termination if TLS is enabled. See also the `tlsSupport` field. + type: string + type: object + metrics: + description: Configuration settings related to the metrics collection + used by the Che installation. + properties: + enable: + description: Enables `metrics` Che server endpoint. Default to `true`. + type: boolean + type: object + server: + description: General configuration settings related to the Che server + and the plugin and devfile registries + properties: + airGapContainerRegistryHostname: + description: Optional hostname (or url) to an alternate container + registry to pull images from. This value overrides the container + registry hostname defined in all the default container images + involved in a Che deployment. This is particularly useful to install + Che in an air-gapped environment. + type: string + airGapContainerRegistryOrganization: + description: Optional repository name of an alternate container + registry to pull images from. This value overrides the container + registry organization defined in all the default container images + involved in a Che deployment. This is particularly useful to install + Che in an air-gapped environment. + type: string + allowUserDefinedWorkspaceNamespaces: + description: Defines if a user is able to specify Kubernetes namespace + (or OpenShift project) different from the default. It's NOT RECOMMENDED + to configured true without OAuth configured. This property is + also used by the OpenShift infra. + type: boolean + cheDebug: + description: Enables the debug mode for Che server. Defaults to + `false`. + type: string + cheFlavor: + description: Flavor of the installation. This is either `che` for + upstream Che installations, or `codeready` for CodeReady Workspaces + installation. In most cases the default value should not be overriden. + type: string + cheHost: + description: Public hostname of the installed Che server. This will + be automatically set by the operator. In most cases the default + value set by the operator should not be overriden. + type: string + cheImage: + description: Overrides the container image used in Che deployment. + This does NOT include the container image tag. Omit it or leave + it empty to use the defaut container image provided by the operator. + type: string + cheImagePullPolicy: + description: Overrides the image pull policy used in Che deployment. + Default value is `Always` for `nightly` or `latest` images, and + `IfNotPresent` in other cases. + type: string + cheImageTag: + description: Overrides the tag of the container image used in Che + deployment. Omit it or leave it empty to use the defaut image + tag provided by the operator. + type: string + cheLogLevel: + description: 'Log level for the Che server: `INFO` or `DEBUG`. Defaults + to `INFO`.' + type: string + cheWorkspaceClusterRole: + description: Custom cluster role bound to the user for the Che workspaces. + The default roles are used if this is omitted or left blank. + type: string + customCheProperties: + additionalProperties: + type: string + description: Map of additional environment variables that will be + applied in the generated `che` config map to be used by the Che + server, in addition to the values already generated from other + fields of the `CheCluster` custom resource (CR). If `customCheProperties` + contains a property that would be normally generated in `che` + config map from other CR fields, then the value defined in the + `customCheProperties` will be used instead. + type: object + devfileRegistryImage: + description: Overrides the container image used in the Devfile registry + deployment. This includes the image tag. Omit it or leave it empty + to use the defaut container image provided by the operator. + type: string + devfileRegistryMemoryLimit: + description: Overrides the memory limit used in the Devfile registry + deployment. Defaults to 256Mi. + type: string + devfileRegistryMemoryRequest: + description: Overrides the memory request used in the Devfile registry + deployment. Defaults to 16Mi. + type: string + devfileRegistryPullPolicy: + description: Overrides the image pull policy used in the Devfile + registry deployment. Default value is `Always` for `nightly` or + `latest` images, and `IfNotPresent` in other cases. + type: string + devfileRegistryUrl: + description: Public URL of the Devfile registry, that serves sample, + ready-to-use devfiles. You should set it ONLY if you use an external + devfile registry (see the `externalDevfileRegistry` field). By + default this will be automatically calculated by the operator. + type: string + externalDevfileRegistry: + description: Instructs the operator on whether or not to deploy + a dedicated Devfile registry server. By default a dedicated devfile + registry server is started. But if `externalDevfileRegistry` is + `true`, then no such dedicated server will be started by the operator + and you will have to manually set the `devfileRegistryUrl` field + type: boolean + externalPluginRegistry: + description: Instructs the operator on whether or not to deploy + a dedicated Plugin registry server. By default a dedicated plugin + registry server is started. But if `externalPluginRegistry` is + `true`, then no such dedicated server will be started by the operator + and you will have to manually set the `pluginRegistryUrl` field. + type: boolean + gitSelfSignedCert: + description: If enabled, then the certificate from `che-git-self-signed-cert` + config map will be propagated to the Che components and provide + particular configuration for Git. + type: boolean + nonProxyHosts: + description: List of hosts that should not use the configured proxy. + Use `|`` as delimiter, eg `localhost|my.host.com|123.42.12.32` + Only use when configuring a proxy is required (see also the `proxyURL` + field). + type: string + pluginRegistryImage: + description: Overrides the container image used in the Plugin registry + deployment. This includes the image tag. Omit it or leave it empty + to use the defaut container image provided by the operator. + type: string + pluginRegistryMemoryLimit: + description: Overrides the memory limit used in the Plugin registry + deployment. Defaults to 256Mi. + type: string + pluginRegistryMemoryRequest: + description: Overrides the memory request used in the Plugin registry + deployment. Defaults to 16Mi. + type: string + pluginRegistryPullPolicy: + description: Overrides the image pull policy used in the Plugin + registry deployment. Default value is `Always` for `nightly` or + `latest` images, and `IfNotPresent` in other cases. + type: string + pluginRegistryUrl: + description: Public URL of the Plugin registry, that serves sample + ready-to-use devfiles. You should set it ONLY if you use an external + devfile registry (see the `externalPluginRegistry` field). By + default this will be automatically calculated by the operator. + type: string + proxyPassword: + description: Password of the proxy server Only use when proxy configuration + is required (see also the `proxyUser` and `proxySecret` fields). + type: string + proxyPort: + description: Port of the proxy server. Only use when configuring + a proxy is required (see also the `proxyURL` field). + type: string + proxySecret: + description: The secret that contains `user` and `password` for + a proxy server. If the secret is defined then `proxyUser` and + `proxyPassword` are ignored + type: string + proxyURL: + description: URL (protocol+hostname) of the proxy server. This drives + the appropriate changes in the `JAVA_OPTS` and `https(s)_proxy` + variables in the Che server and workspaces containers. Only use + when configuring a proxy is required. + type: string + proxyUser: + description: User name of the proxy server. Only use when configuring + a proxy is required (see also the `proxyURL` `proxySecret` fields). + type: string + selfSignedCert: + description: Deprecated. The value of this flag is ignored. Che + operator will automatically detect if router certificate is self-signed. + If so it will be propagated to Che server and some other components. + type: boolean + serverMemoryLimit: + description: Overrides the memory limit used in the Che server deployment. + Defaults to 1Gi. + type: string + serverMemoryRequest: + description: Overrides the memory request used in the Che server + deployment. Defaults to 512Mi. + type: string + serverTrustStoreConfigMapName: + description: Name of the config-map with public certificates to + add to Java trust store of the Che server. This is usually required + when adding the OpenShift OAuth provider which has https endpoint + signed with self-signed cert. So, Che server must be aware of + its CA cert to be able to request it. This is disabled by default. + type: string + tlsSupport: + description: Deprecated. Instructs the operator to deploy Che in + TLS mode. This is enabled by default. Disabling TLS may cause + malfunction of some Che components. + type: boolean + workspaceNamespaceDefault: + description: 'Defines Kubernetes default namespace in which user''s + workspaces are created if user does not override it. It''s possible + to use , and placeholders (e.g.: + che-workspace-). In that case, new namespace will be + created for each user (or workspace). Is used by OpenShift infra + as well to specify Project' + type: string + type: object + storage: + description: Configuration settings related to the persistent storage + used by the Che installation. + properties: + postgresPVCStorageClassName: + description: Storage class for the Persistent Volume Claim dedicated + to the Postgres database. If omitted or left blank, default storage + class is used. + type: string + preCreateSubPaths: + description: Instructs the Che server to launch a special pod to + pre-create a subpath in the Persistent Volumes. Defaults to `false`, + however it might need to enable it according to the configuration + of your K8S cluster. + type: boolean + pvcClaimSize: + description: Size of the persistent volume claim for workspaces. + Defaults to `1Gi` + type: string + pvcJobsImage: + description: Overrides the container image used to create sub-paths + in the Persistent Volumes. This includes the image tag. Omit it + or leave it empty to use the defaut container image provided by + the operator. See also the `preCreateSubPaths` field. + type: string + pvcStrategy: + description: Persistent volume claim strategy for the Che server. + This Can be:`common` (all workspaces PVCs in one volume), `per-workspace` + (one PVC per workspace for all declared volumes) and `unique` + (one PVC per declared volume). Defaults to `common`. + type: string + workspacePVCStorageClassName: + description: Storage class for the Persistent Volume Claims dedicated + to the Che workspaces. If omitted or left blank, default storage + class is used. + type: string + type: object + type: object + status: + description: CheClusterStatus defines the observed state of Che installation + properties: + cheClusterRunning: + description: Status of a Che installation. Can be `Available`, `Unavailable`, + or `Available, Rolling Update in Progress` + type: string + cheURL: + description: Public URL to the Che server + type: string + cheVersion: + description: Current installed Che version + type: string + dbProvisioned: + description: Indicates if or not a Postgres instance has been correctly + provisioned + type: boolean + devfileRegistryURL: + description: Public URL to the Devfile registry + type: string + helpLink: + description: A URL that can point to some URL where to find help related + to the current Operator status. + type: string + keycloakProvisioned: + description: Indicates whether an Identity Provider instance (Keycloak + / RH SSO) has been provisioned with realm, client and user + type: boolean + keycloakURL: + description: Public URL to the Identity Provider server (Keycloak / + RH SSO). + type: string + message: + description: A human readable message indicating details about why the + pod is in this condition. + type: string + openShiftoAuthProvisioned: + description: Indicates whether an Identity Provider instance (Keycloak + / RH SSO) has been configured to integrate with the OpenShift OAuth. + type: boolean + pluginRegistryURL: + description: Public URL to the Plugin registry + type: string + reason: + description: A brief CamelCase message indicating details about why + the pod is in this state. + type: string + type: object + version: v1 + versions: + - name: v1 + served: true + storage: true diff --git a/olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/9.9.9-nightly.1594209361/eclipse-che-preview-openshift.crd.yaml.diff b/olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/9.9.9-nightly.1594209361/eclipse-che-preview-openshift.crd.yaml.diff new file mode 100644 index 0000000000..e69de29bb2 diff --git a/olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/9.9.9-nightly.1594209361/eclipse-che-preview-openshift.v9.9.9-nightly.1594209361.clusterserviceversion.yaml b/olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/9.9.9-nightly.1594209361/eclipse-che-preview-openshift.v9.9.9-nightly.1594209361.clusterserviceversion.yaml new file mode 100644 index 0000000000..7c156ddc84 --- /dev/null +++ b/olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/9.9.9-nightly.1594209361/eclipse-che-preview-openshift.v9.9.9-nightly.1594209361.clusterserviceversion.yaml @@ -0,0 +1,450 @@ +apiVersion: operators.coreos.com/v1alpha1 +kind: ClusterServiceVersion +metadata: + annotations: + alm-examples: |- + [ + { + "apiVersion": "org.eclipse.che/v1", + "kind": "CheCluster", + "metadata": { + "name": "eclipse-che" + }, + "spec": { + "server": { + "cheImageTag": "nightly", + "devfileRegistryImage": "quay.io/eclipse/che-devfile-registry:nightly", + "pluginRegistryImage": "quay.io/eclipse/che-plugin-registry:nightly", + "tlsSupport": true, + "selfSignedCert": false + }, + "database": { + "externalDb": false, + "chePostgresHostName": "", + "chePostgresPort": "", + "chePostgresUser": "", + "chePostgresPassword": "", + "chePostgresDb": "" + }, + "auth": { + "openShiftoAuth": true, + "identityProviderImage": "quay.io/eclipse/che-keycloak:nightly", + "externalIdentityProvider": false, + "identityProviderURL": "", + "identityProviderRealm": "", + "identityProviderClientId": "" + }, + "storage": { + "pvcStrategy": "per-workspace", + "pvcClaimSize": "1Gi", + "preCreateSubPaths": true + }, + "metrics": { + "enable": true + } + } + } + ] + capabilities: Seamless Upgrades + categories: Developer Tools, OpenShift Optional + certified: "false" + containerImage: quay.io/eclipse/che-operator:nightly + createdAt: "2020-07-08T11:56:01Z" + description: A Kube-native development solution that delivers portable and collaborative + developer workspaces in OpenShift. + repository: https://github.com/eclipse/che-operator + support: Eclipse Foundation + name: eclipse-che-preview-openshift.v9.9.9-nightly.1594209361 + namespace: placeholder +spec: + apiservicedefinitions: {} + customresourcedefinitions: + owned: + - description: Eclipse Che cluster with DB and Auth Server + displayName: Eclipse Che Cluster + kind: CheCluster + name: checlusters.org.eclipse.che + specDescriptors: + - description: Log in to Eclipse Che with OpenShift credentials + displayName: OpenShift oAuth + path: auth.openShiftoAuth + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: TLS routes + displayName: TLS Mode + path: server.tlsSupport + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + statusDescriptors: + - description: Route to access Eclipse Che + displayName: Eclipse Che URL + path: cheURL + x-descriptors: + - urn:alm:descriptor:org.w3:link + - description: Route to access Keycloak Admin Console + displayName: Keycloak Admin Console URL + path: keycloakURL + x-descriptors: + - urn:alm:descriptor:org.w3:link + - description: Eclipse Che server version + displayName: Eclipse Che version + path: cheVersion + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:label + - description: The current status of the application + displayName: Status + path: cheClusterRunning + x-descriptors: + - urn:alm:descriptor:io.kubernetes.phase + - description: Reason of the current status + displayName: Reason + path: reason + x-descriptors: + - urn:alm:descriptor:text + - description: Message explaining the current status + displayName: Message + path: message + x-descriptors: + - urn:alm:descriptor:text + - description: Link providing help related to the current status + displayName: Help link + path: helpLink + x-descriptors: + - urn:alm:descriptor:org.w3:link + version: v1 + description: | + A collaborative Kubernetes-native development solution that delivers OpenShift workspaces and in-browser IDE for rapid cloud application development. + This operator installs PostgreSQL, Keycloak, and the Eclipse Che server, as well as configures all three services. + + ## How to Install + + Press the **Install** button, choose the upgrade strategy, and wait for the **Installed** Operator status. + + When the operator is installed, create a new CR of Kind CheCluster (click the **Create New** button). + The CR spec contains all defaults (see below). + + You can start using Eclipse Che when the CR status is set to **Available**, and you see a URL to Eclipse Che. + + ## Defaults + + By default, the operator deploys Eclipse Che with: + + * Bundled PostgreSQL and Keycloak + + * Per-Workspace PVC strategy + + * Auto-generated passwords + + * HTTP mode (non-secure routes) + + * Regular login extended with OpenShift OAuth authentication + + ## Installation Options + + Eclipse Che operator installation options include: + + * Connection to external database and Keycloak + + * Configuration of default passwords and object names + + * TLS mode + + * PVC strategy (once shared PVC for all workspaces, PVC per workspace, or PVC per volume) + + * Authentication options + + ### External Database and Keycloak + + To instruct the operator to skip deploying PostgreSQL and Keycloak and connect to an existing DB and Keycloak instead: + + * set respective fields to `true` in a custom resource spec + + * provide the operator with connection and authentication details: + + + + `externalDb: true` + + + `chePostgresHostname: 'yourPostgresHost'` + + + `chePostgresPort: '5432'` + + + `chePostgresUser: 'myuser'` + + + `chePostgresPassword: 'mypass'` + + + `chePostgresDb: 'mydb'` + + + `externalIdentityProvider: true` + + + `identityProviderURL: 'https://my-keycloak.com'` + + + `identityProviderRealm: 'myrealm'` + + + `identityProviderClientId: 'myClient'` + + + ### TLS Mode + + To activate TLS mode, set the respective field in the CR spec to `true` (in the `server` block): + + + ``` + tlsSupport: true + ``` + + #### Self-signed Certificates + + To use Eclipse Che with TLS enabled, but the OpenShift router does not use certificates signed by a public authority, you can use self-signed certificates, which the operator can fetch for you: + + + ``` + selfSignedCert: true + ``` + + + You can also manually create a secret: + + + + ``` + oc create secret generic self-signed-certificate --from-file=/path/to/certificate/ca.crt -n=$codeReadyNamespace + ``` + displayName: Eclipse Che + icon: + - base64data: iVBORw0KGgoAAAANSUhEUgAAANMAAAD0CAYAAAABrhNXAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QA/wD/AP+gvaeTAAAaNklEQVR42u3de3QU9dkH8O/zm91EQK0U77dqVdTW++1V20KigUSQahLjsSSbtp4eeqqVLHILCcoiyQZEIbF61B6PVQJ6XiOkr6TlYiABr603wHotar1bBUWUYDY787x/JIGoSchmZ+c3M/t8/iS7M8+M5+vs7szz/IiZIYRIntJdgBB+IWESwiYSJiFsImESwiYSJiFsImESwiaBvv5ARLprEwB4ddaJTBQF8w/JsKbQmI0v665JAL3dUqK+7jNJmPTiNWOHWYhNB1AOILPrn+MA369MazaNe+Iz3TWmMwmTB3AEyrwwu4SIbwVwWB+v+hxEt6gg7qLs1rjumtORhMnlePUlF5hk1RFw4QDf8rrFmBLMa12tu/Z0I2FyKV53yVGWyTVgLgGQ8IknoImMQBnlNL+t+1jShYTJZXjlhKFW8KsbQJgNYP8ktxYDcI8yh95E41bt1H1sfidhcpH4mtETCHQHgONs3vTHAEXUMy33UQSW7uP0KwmTC/DqS84xyaol4Bcp3tULiqiMxrY8pfuY/UjCpBG3ZB1sxfgmgK4HYDi1WwI9SnGaTuPXv6v7HPiJhEkDfv7coPX5AdeB+RaADtRURRtAC9UB7Qvo4md26z4nfiBhcljH6qwcRbgDwKm6a+nyATNVGrkt9USQrtAkSJgcwquyT2ZlLWLQON219FofsMEghGls6ybdtXiVhCnFuOnnw62gEQHoOvTz3KM7sAVSy5RS0yln3X91V+M1EqYU4ZasgBWjawGuAnCI7noStAOM+coaUkvjVrXrLsYrJEwp0LHmkksUrFoAp+uuJSnMbzLR1EBua5PuUrxAwmSj7tYIBhfprsVOBDQTU5jyWl7RXYubSZhs0KM1YiaA/XTXkyIdAN+tMmgOZbfu0F2MG0mYksAMMtdkh4h4AYDDddfj0FF3tnrsOOROurrB1F2Nm0iYBolXjT7fVFRHwEW6a9FkkyIK09iWDboLcQsJU4KSbY3wGwKaCNZkyt34ju5adJMwDRA/fdEQa2fmZBAqARygux536Wr1+CY+m6546ivd1Wg7CxKmfUtha4TP8EeAmpuurR4Spn7w46PONi2qJdAo3bV4CROeM1iFKXf907prcfS4JUzfx82XjrDM+M0Ot0b4TWerB8yplLvxfd3FOHLAEqYeJ2NPawTmAviB7np8YheA21QG5lN26ze6i0klCVOXjtVZOUpxHZh+orsWn3qfmWYH8lqW6C4kVdI+TLwq+2Q2+HZmjNddSzogoIUsI0yXrduiuxa7pW2YuOnnw62MwEwwTwEoQ3c96aWr1SMen+qnKbRpF6a901GthQAdqrueNPcFGAvUzkMW09UNMd3FJCutwtSxenS2ItQCdIbuWsS3vMFENwbGtvxddyHJSIsw8ZpRx1hkVIM5pLsW0TcCmsk0ymjculd11zIYvg5TmrRG+E1nq4cK3kxjmr/UXUwifBkmZpD5+OiriHEbQMfqrkcMynYQ5nmp1cN3YepsjUAtgS7WXYuwA7+oGGHK2/CE7kr2WalfwsRrxxxpcWwOgN8BJEuJ+gwBTWThBrqs9T+6a+mL58PEjxRlWAd99gcw5kFaI3yO20D0JxVEFWW3fq27mu9V5+UwdbVG1AE4XnctwlEfMlOF26bQejJMvDbrLJNRS8Bo3bUIfRj8T0NRGY1pfVZ3LYDHwsSrc39o0TdzpDVC7OWeKbSeCFOP1ogIgIO0FCHcrrPVwxxSo2sKrevD1LVqRC2Anzq+c+FFW5m4IjB2Q4PTO3ZtmLj50pFsmrczcLnTJ0V4HzHWESFMua3/cmqfrgsTt2QdZHWgHIwwgEynToTwpTjA96sMqqTs1m2p3plrwiStESJ1uqbQBnEXZbfGU7YXN4SpY1VWllKoBXBmqg5UCACvW4wpwbzW1anYuNYw8d+zjrYCFJXpqMJJBDSRESijnOa37dyuljDxyglDrYyvZkBaI4Q2XVNozaE30bhVO23ZopNhktYI4UIfAxSxYwqtY2HitVnndT0C9DOHT5YQA/GCIiqjsS1PDXYDKQ8Tr/7FERapCKQ1Qrhf5xTaOE2n8evfTfjNqQrT3tYIvgWgA3WfJSEGjtsAWpjoFNqUhKmzNQK1AP1Y92kRIgkfMFPlQFs9bA0TPz7qVLbUIgbydJ8FIezChFbDojDltWzu93V2hElaI4T/dbV6cHAa5a79tNdXJBMmbskKWDG6FszVIBys+3CFcMAOMOYra0jtd1s9Bh2mjrXZlyrmWgCn6T46IRzH/CYTTQ3ktjbt/acEw8RrR53EbFQzuEj38QihGwHNxBSmvJZXEgqT9Xj2bWC+QVaNEKInjoFQpca0zvvuXwJ9vwdT5XlUIXpiC6T+Vyn1597+Gkh0c0KkIwb+YUCV0diWfwBAbx/oJExC9G/AN3MlTEL0qudE2ZYBTZSVMAnxHQQ0Udz4Y6IPwEqYhNiDX1SdU2OfHMy7pU1CCMY2EMLqy0MvGGyQALkyifTWuXKhNfQmyku+nV3CJNISAc2krMk0ZuNrdm1TwiTSzRtMdKORgtXeJUwiXXwBwtzO4ZQtKRlOKWESftc5Ntm0ZtO4Jz5L5Y4kTMK3CLyerMAUumzdFif2J2HyBu58GkwmPg3QW8w01chr/T8ndyr/cVyPX1QKoxTUBcwY9D2QNLELwFyVgdMCeS2OBgmQK5N7MbZBoUrtOPROurrBBABmjDIfH30VgRaC8SPdJboIg2ip6uAZNL71E11F9N0cuDbbNStbp5nOG4n9zMXuMb99BoAhugvWiQnPGSaX0WUbnnF0vwl12kqYHEdAE5kqTOPWvzWQ16f5yiIfMlPFQOfc2U3C5F5vMHhKIHfDqsG8mddmj7Y6B96cpftAHLAbhDvU7o5quuKpr3QVIWFynx43EpNb5W7vaox8K4DDdB9YKhDQRLAmU+7Gd3TXImFyj5TdSOSWrP2tGKYBKIdf1glmvKRIhSl3/UbdpewpScKkH4HXk+Iwjdn4cir345MxbdtBmKd2HLLnF023kDDptZWJKwJjNzQ4udOO1Vk5ilAL4Ke6T0AiZQN8t1LBm2lM85e6i+mNhEmPXQBuS3TJEjvx8+cGre0H/tYLo617DnrUXUt/JEzOcsWNxG8V5OZFF3oZQexmEiaHMPifhoWw0zcSB1zf46NOZVMtZkKu7lrQPRx/5yGL6eqGmO5iBkrClHpabyQmqnOhOqoDcLzze9/3si1u1ltu5EFXe+wGYYHKwCmBvJYlXggSAARyN6xUXx5yCghhAI7dAGVCq2J1jjG2pdSLQeqLXJmSREATWbiBLmv9j+5aksFrxxxpcWwOUru49/vMNNsrV+7+yMc8OzFeUuAyytvwhO5SbD2stVnnmcx1BLrYxq0OahFmN5Mw2cO1NxLtwgwyHx99FTFuA+jYZDZFoEdJGdNoTPN7uo/LThKm5Lj+RqLdeM3YYRZi0wHMBLBfQu8FnjeIwjS25Sndx5GScyNhGhwCmsk0ymjculd116IDrxl1jEVGNZhDA3j5xwBF1DMt91EElu7aU3ZOJEwJe4OJbgykYMaaF3WsHp3d+WgSnfH9v3IMwD39NTX6iYRp4L4AY4HXbiQ6YW+rh7UQoEOBrl80jUAZ5TS/rbs+x86DhGmf4gD/WRmBmyln3XbdxbhZ56NJ7dMtqMeDuevX667H8eOXMPWNgBayjLBTM9aEt/WWG5lO1H0jMa9lie5ChLelc5h6tEa0+OJGotArHcPUeSMR5lTK3fi+7mKEf6RVmJjwnMEqTLnrn9Zdi/CfNHlqnD8C6PfG060XSpBEqvj9ytQ1Yy2udcaaSA++DdOeGWtj9c9YE/4RiUTUlreCpQAe+O7f/BimTQqqzE0z1oQ/FBTXnL9lK2oBvhg+D5PvWyOEHr+8ZsGRgUB8DsC/Qz+/M/ghTGnXGiGcUVS0aEg8s30ywawE6IB9vd7TYdo7Y63V1TPWhPcUhqommPxNHSUwbMabYeqasWZ4ZMaa8I4rJ1afpRTqmGlUou/1Wpg6Z6xZQ2tp3Kp23cUI/ygqivzQysiYw4RBD+j0SJh6zFjL889oKKHfpEn3Bre3bbvOBEUAHJTMtlwfJia0GpYKU27LZt21CH8pLK3J2bZrey2IbFnUwM1hep+ZZgdypTVC2Cu/NDpSMW5niy+3c/FSF4ap54w1aY0Q9rnyN5GDjHiwnC2EOQULwbkpTF0z1gK+m7Em9IpEImrz1mAJxelWTuESpa4Ik99nrAl98kPR0Vu2oo6AM1O9L81h4o8ANdfw+Yw14byC4gVHA2YUjBLAzm9GfdMSprhF2PThwZvf3Tli/NU33vOhjhqEP02YFBkabAvOAMwZAIY4uW/Hw/TCB4fgL8+fgv9+NeRMAM8Vhmoip5/Qfl8kEpErk0gCU35o/lXUxgsB/EhHBY6N+vrgy/3xwPMnY/NHI3r78/NghFcsq5DvTCJhV06sOVcprgPwM6f2ubx+1vc+Oqb8yvR1ewANL5+I1a8fA4v7/Oh6HghPFJZEH1VKTWtYUi6/5ol9KiipPgJAZF+tEU5J2ZXJtAgtbx2FhzediJ3fZCTy1jaAFx4Y6Jj/wAMRuc8kvqeoKJJhZQb/YIFuIeBAHTX0dmVKSZpf/mQEZvztItz77E8SDRIADAVozs54xr/zS6pLAXbklxjhDYWhqglmZsZrDKrVFaS+2Hpl+njnUDy86UQ88+7hthXIQCugwo1Ly+XZvDRW+KvoKWxgMYA83bUAKfzO9E2HgZWvHYfGl49Hh2XvxY6ALMB6saA4uoxVcFpj/XR5ajyN9GiNuA7a74v2L6krEwN44p0jUf/CSOzYnfDHucHYwaD53wwfVrvqT5Oln8nHsrIigRHHZF7LbFUDdLDuer7L1u9M/972A1Su+h/86cnTnAoSABxE4PlDvvh6S35x9HKndiqcdVVx9aUjjs54kZnvdWOQ+pLwZXN72354+KWTsPGdw8H6fhsYSYSVBcXRZgqo8PIHy2UGhA8UldScaIGjFlCku5bBGHCY2k2Fx145Hn995TjE4oPq6rUfIYdN66XC4ujdZjA2568PRHboLkkkLhRaOGwXx6ab4HKkoDXCKfv8zsRMePa9w1D/wkh8tiuhBbcdPhJ8Tsy3qPaT7mxouFrm5nkCU35JNESgBQDs+wnYAb19Z+o3TG9tPxAPPn8yXvt0uO7aE8CvEWHK8vrKNborEX27cmLVBUoZdQBfqLuWwUjop/G7nj4NG946AuzM0+s2olOZsbowFG1SMCc31N8ks8ZdpKi06ijTVDUglPjthnyfYWp960jdtSWFGZebMMYWFkfv6cg0Zj92/0xZBUOj7umopsWzQdhfdz2poP3hwBTLYMLkQMx8vTBUMykSifj9eF2pMFQ1wcz45lUCzwf8GSTA/2HqdiQz37tla8azV5VUXay7mHRRUFJ9Tn5JdCOzegyE43TXk2qufjwjBc63oJ6UVo/Uyi+NjlAmbmbgehrkdFQvSrcwAQAxUGRa1riCkurbpNXDPt3TUdnCXCb8QHc9TkuXj3m9GQbQnJ1mxpudrR4iGYWlNTmftW3fxKBaIP2CBKTnlenbGMcQ6MGCUPQ3RBxevqRyi+6SvKSoZN7JJoxFbPE4X/3OPQgSpm6MbGZ6SVo9Bmb8xJrh+ylrpgmaAsCxJ53dTML0bQqEkOKOy/NLahYE2tsXNzREYrqLcpM901HBCxl0qO563CSdvzP1iYHhBJ5vZma8XFBSPV53PW5RMLE6e8vWjJcI9CAACdJ3yJWpfyMBaioojjYbQFnDsopXdRekwxXXVB1jGKoahJDuWtxMwjQQhBwT2FRYHL1bxdTNDQ3labEQdXdrBEAzAbi4ZcAd5GPewAWZMNnMtN4qLKkuKyp6xMc3I5nyQzVFu7jjVYDmQII0IBKmxI1gUK2ZufW5gonzE15E2O0KimvOLyiZ/yQxPwLgWN31eIl8zBu8s6GsDX5p9fjlNQuODATic9wyHdWLJExJ6mr1uLSwpPqOjoxAtddaPbqnozLMeQAdoLseL5P/A9ljCINmBmLma16aQts1HfX1rkeAJEhJkiuTvY4i0IMFJTV/ZBUta1xS8YzugnqTH1pwKlnmYmbk6q7FTyRMqXE+WXiqoDi61AgGZjQ8MOMT3QUBPaajsnk9KH1aI5wiYUodAiFkxuMFuls9Jk26N7h99+e/NdmqBuCZoY5eI9+ZUm9Y16oeL+eHahwfrlhYWpOzbdf2l7w2HdWL5MrknBOJ+ZGCkuh6Ujwl1a0ehRPnnQTDWMQWX+65AVMeJWFy3iVs0QsFJdX3G0Ga3fCXis/s3PiVv4kcZMSD5QwKg707HdWLJEx6BACaZHWgyK5Wjz2tEXG6lYHDdB9gOpLvTBp1t3rEMzO3FIai4wa7nfxQdPTLWzNe6GqNkCBpIlcmFyDwycz4W0FxtJmVMbmxfuZrA3lfQfGCowEzCkYJQ74Z6SZhchNCDrG5ubA4encbYjetWhbZ2dvLJkyKDA22BWcA5gwAQ3SXLTrJxzz3CTJh8hAK9tLq0dkaEWzL6G6NkCC5SJ+rYBSGahJeIFqkxIsKCMctalOK6wD8THdBIoULRIuUOscCNijFDPkk4WoSJm8gyA8Mrif/pxPCJhImIWwiYRLCJhImIWwiYRLCJhImIWwiYRLCJhImIWwiYRLCJhImIWwiYRLCJhImIWzSd5iIbgcgS1AK8W2xrmx8T59hWlE/axpZ5mkENOiuXghXYDSToc5ZUT9rWm9/7rM5kGjvE/9XFVdfahHVAjhN9/EIocGbAN+4Ymnl37r/obfcDChMAJCVFQmMOCbzWmarWiaDijSxg0HzexvFllSYuu0Z/k64DtJcKPzJAmMZq+C0xvrpn/b2AlvC1K3wV9FT2MBiAHm6j1wIuzDQCqhw49Lyzf2+zs4wdSsMVU1gVrUAfqz7RAgxaIT3mXl249LKJQN5eW+5Sfo+0/L62SuN9tipBA4zsDPZ7QnhsDaA5x5oxEYONEh9SfrK1FNBSfURACIAySLDwu2YgEeVUtMalpS/l/CbU/ExrzdXTqw5V2a8CRd7HozwimUVTw12A46FqWt3lB+afxUxLwTwIyfPlBB9+JiIIqef0H5fJBKxktmQw2HqtHcuNslcbKFLjBj39De/PVFawtRtz4oNhBLIQEXhECI0waSy5Q/NetvO7WoNU7f8UHQ0MeoAnJmSHQgBAITXmWlK49JZq1Ox+ZT8NJ6oxvqKDWecGDuHwb8G8F+n9y98jvA5gcOfvx87PVVB6nPXTl+ZevrW+quQ9VdFUuIA399hZlaufHjatlTvzBUf83qTXxodqRi3M+Nyx3YqfIOBdSAON9ZX/suxfbo1TN0KS2ty2ORaEH7q+M6FB9G/mVDZWD/L8Z47V3xn6s/yJbOaDx424mwi+j3AKb9UC8/6GuC5u4cPO11HkPriqitTTz1aPa4HYCS9QeEHFhjL4hZPf+zhSq0/Xrn+Y15v8kMLTiXLXAxCru5ahEaEf8KyylYsm/2s7lIAj4apW1erRx2A43XXIhz1IYMrGpdW1APkmnWWXf+dqT9drR6nEDgM4Cvd9YiUayPwAqM9dkpna4R7gtQXz1yZevrlNQuODATic6TVw5+I0GQadMNfH5j1H9219MXTH/N6UxiqOo/ZqAP4Yt21CFu8qIDwo0srntBdyL74Lkxdh9Xd6nEbgGN1VyMGg7cRUKXaT7qzoeFqU3c1A6rYn2HqFAotHLaLY9MBmglgP931iAHpIMbddrZGOMXXYep2xTVVxxiGqgYhpLsW0Q9GMytjcmP9zNd0lzKo8tMhTN0KJlZnQ1EtgDN01yL2YtAbivjG5fUVf9ddS1LH4eWfxhO14qHKljNOjJ3d1erxadIbFEkh4AsGlQfa28/wepD6PEa/Xpl66tHqMQVAhu560owFxjIjA1Mb/lLxme5i7JJWH/N6k18aHUkWLQJ4vO5a0gKhhYjDy5dUbtFdit3SPkzdCktrciyL6wj4ie5afOo9Bt+U7FBHN0ur70z9Wb5kVvMhQ0ec1fVo0pe66/GRXQDPPTAQO9nPQepLWl6ZesovjY5QJm6WVo+kMBhLjWBgRsMDMz7RXYwjBywf8/pWWFpzNltWLUCjdNfiMc+xQlnjkopndBfiJAnTAEirx4B9xOBZbmuNcIqEaYCKihYNiWe2TyZwJYADdNfjMrsJfEdHRqD6sftnpm0rjIQpQUWlVUeZpqqRKbSdiNCkYE5uqL/pHd216CZhGqSC4przAa4D4SLdtWjyEiwVXvFQ+UbdhbiFhCkpTPkl0RCBFgA4XHc1DtlO4Hleao1wioTJBmnS6tFBjLtVTN3c0FAu9+F6IWGy0ZW/nneCYRo1DBTprsVWjGYKqPDyB8tf0V2Km0mYUiA/VHMJMS+G91s93mTG1MZlFU26C/ECeZwoBRrrZ63v0erhxaeidzCofPfw/c+QICVHrkw2Gj+xZvh+yprpkVYPC4xlrILTGuunS79XguRjnkOKSuadbMJYBGCc7lp6w0AroMKNS8s3667FqyRMDissrclhy7oDoFN119LlAwZXpusjQHaS70wOW75kVvPBQw8+0wWtHm1drREneWU6qhfJlckhmlo9mIBH2bKmr3ho9ru6z4GfyMc8FygoqT6HQbUE/CKV+yHCC2yhbMWyiqd0H7MfSZhcpDBUNYEtdQcIx9m86Y+JKHL6Ce33RSIRS/dx+pWEyWUmTIoMDbRl3kDg2QD2T3JzMWLc48XpqF4kYXKpZFs9iNAEk8qWPzTrbd3Hki4kTC535cSqC5Qy6gC+cEBvILzOTFMal85arbv2dCNh8oQBtHoQPifmW7Z/0HFXa2skrrvidCRh8pAerR7lADK7/jkO8P0dZmblyoenyWr0GkmYPKhw4ryTYBiL2EKQlTHFq6tG+E1CYRJCJEYeJxLCJhImIWwiYRLCJhImIWwiYRLCJv8P9sXhC7xE4kIAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTktMDQtMTNUMDg6MTY6MDgrMDI6MDCcYZVaAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE5LTA0LTEzVDA4OjE2OjA4KzAyOjAw7Twt5gAAAABJRU5ErkJggg== + mediatype: image/png + install: + spec: + clusterPermissions: + - rules: + - apiGroups: + - oauth.openshift.io + resources: + - oauthclients + verbs: + - create + - get + - delete + - list + - patch + - update + - watch + - apiGroups: + - config.openshift.io + resources: + - infrastructures + - oauths + - proxies + verbs: + - get + - list + - watch + - apiGroups: + - user.openshift.io + resources: + - users + verbs: + - list + - apiGroups: + - console.openshift.io + resources: + - consolelinks + verbs: + - get + - list + - create + - update + - patch + - delete + serviceAccountName: che-operator + deployments: + - name: che-operator + spec: + replicas: 1 + selector: + matchLabels: + app: che-operator + strategy: {} + template: + metadata: + labels: + app: che-operator + spec: + containers: + - command: + - /usr/local/bin/che-operator + env: + - name: WATCH_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.annotations['olm.targetNamespaces'] + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: OPERATOR_NAME + value: che-operator + - name: CHE_VERSION + value: nightly + - name: RELATED_IMAGE_che_server + value: quay.io/eclipse/che-server:nightly + - name: RELATED_IMAGE_plugin_registry + value: quay.io/eclipse/che-plugin-registry:nightly + - name: RELATED_IMAGE_devfile_registry + value: quay.io/eclipse/che-devfile-registry:nightly + - name: RELATED_IMAGE_pvc_jobs + value: registry.access.redhat.com/ubi8-minimal:8.2-301.1592810506 + - name: RELATED_IMAGE_postgres + value: centos/postgresql-96-centos7:9.6 + - name: RELATED_IMAGE_keycloak + value: quay.io/eclipse/che-keycloak:nightly + - name: RELATED_IMAGE_che_workspace_plugin_broker_metadata + value: quay.io/eclipse/che-plugin-metadata-broker:v3.2.0 + - name: RELATED_IMAGE_che_workspace_plugin_broker_artifacts + value: quay.io/eclipse/che-plugin-artifacts-broker:v3.2.0 + - name: RELATED_IMAGE_che_server_secure_exposer_jwt_proxy_image + value: quay.io/eclipse/che-jwtproxy:fd94e60 + - name: CHE_FLAVOR + value: che + - name: CONSOLE_LINK_NAME + value: che + - name: CONSOLE_LINK_DISPLAY_NAME + value: Eclipse Che + - name: CONSOLE_LINK_SECTION + value: Red Hat Applications + - name: CONSOLE_LINK_IMAGE + value: /dashboard/assets/branding/loader.svg + - name: CHE_IDENTITY_SECRET + value: che-identity-secret + - name: CHE_IDENTITY_POSTGRES_SECRET + value: che-identity-postgres-secret + - name: CHE_POSTGRES_SECRET + value: che-postgres-secret + - name: CHE_SERVER_TRUST_STORE_CONFIGMAP_NAME + value: ca-certs + image: quay.io/eclipse/che-operator:nightly + imagePullPolicy: Always + name: che-operator + ports: + - containerPort: 60000 + name: metrics + resources: {} + restartPolicy: Always + serviceAccountName: che-operator + terminationGracePeriodSeconds: 5 + permissions: + - rules: + - apiGroups: + - extensions + resources: + - ingresses + verbs: + - '*' + - apiGroups: + - batch + resources: + - jobs + verbs: + - '*' + - apiGroups: + - route.openshift.io + resources: + - routes + verbs: + - '*' + - apiGroups: + - rbac.authorization.k8s.io + resources: + - roles + - rolebindings + verbs: + - '*' + - apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterroles + - clusterrolebindings + verbs: + - '*' + - apiGroups: + - "" + resources: + - pods + - services + - serviceaccounts + - endpoints + - persistentvolumeclaims + - events + - configmaps + - secrets + - pods/exec + - pods/log + verbs: + - '*' + - apiGroups: + - "" + resources: + - namespaces + verbs: + - get + - apiGroups: + - apps + resources: + - deployments + verbs: + - '*' + - apiGroups: + - monitoring.coreos.com + resources: + - servicemonitors + verbs: + - get + - create + - apiGroups: + - org.eclipse.che + resources: + - '*' + verbs: + - '*' + serviceAccountName: che-operator + strategy: deployment + installModes: + - supported: true + type: OwnNamespace + - supported: true + type: SingleNamespace + - supported: true + type: MultiNamespace + - supported: false + type: AllNamespaces + keywords: + - workspaces + - devtools + - developer + - ide + - java + links: + - name: Product Page + url: http://www.eclipse.org/che + - name: Documentation + url: https://www.eclipse.org/che/docs + - name: Operator GitHub Repo + url: https://github.com/eclipse/che-operator + maintainers: + - email: dfestal@redhat.com + name: David Festal + maturity: stable + provider: + name: Eclipse Foundation + replaces: eclipse-che-preview-openshift.v9.9.9-nightly.1594133421 + version: 9.9.9-nightly.1594209361 diff --git a/olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/9.9.9-nightly.1594209361/eclipse-che-preview-openshift.v9.9.9-nightly.1594209361.clusterserviceversion.yaml.diff b/olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/9.9.9-nightly.1594209361/eclipse-che-preview-openshift.v9.9.9-nightly.1594209361.clusterserviceversion.yaml.diff new file mode 100644 index 0000000000..5f371aa9d2 --- /dev/null +++ b/olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/9.9.9-nightly.1594209361/eclipse-che-preview-openshift.v9.9.9-nightly.1594209361.clusterserviceversion.yaml.diff @@ -0,0 +1,46 @@ +--- /home/tolusha/gocode/src/github.com/eclipse/che-operator/olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/9.9.9-nightly.1594133421/eclipse-che-preview-openshift.v9.9.9-nightly.1594133421.clusterserviceversion.yaml 2020-07-08 14:55:47.710990063 +0300 ++++ /home/tolusha/gocode/src/github.com/eclipse/che-operator/olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/9.9.9-nightly.1594209361/eclipse-che-preview-openshift.v9.9.9-nightly.1594209361.clusterserviceversion.yaml 2020-07-08 14:56:02.467007934 +0300 +@@ -49,12 +49,12 @@ + categories: Developer Tools, OpenShift Optional + certified: "false" + containerImage: quay.io/eclipse/che-operator:nightly +- createdAt: "2020-07-07T14:50:21Z" ++ createdAt: "2020-07-08T11:56:01Z" + description: A Kube-native development solution that delivers portable and collaborative + developer workspaces in OpenShift. + repository: https://github.com/eclipse/che-operator + support: Eclipse Foundation +- name: eclipse-che-preview-openshift.v9.9.9-nightly.1594133421 ++ name: eclipse-che-preview-openshift.v9.9.9-nightly.1594209361 + namespace: placeholder + spec: + apiservicedefinitions: {} +@@ -244,8 +244,11 @@ + resources: + - infrastructures + - oauths ++ - proxies + verbs: + - get ++ - list ++ - watch + - apiGroups: + - user.openshift.io + resources: +@@ -327,6 +330,8 @@ + value: che-identity-postgres-secret + - name: CHE_POSTGRES_SECRET + value: che-postgres-secret ++ - name: CHE_SERVER_TRUST_STORE_CONFIGMAP_NAME ++ value: ca-certs + image: quay.io/eclipse/che-operator:nightly + imagePullPolicy: Always + name: che-operator +@@ -441,5 +446,5 @@ + maturity: stable + provider: + name: Eclipse Foundation +- replaces: eclipse-che-preview-openshift.v9.9.9-nightly.1594019198 +- version: 9.9.9-nightly.1594133421 ++ replaces: eclipse-che-preview-openshift.v9.9.9-nightly.1594133421 ++ version: 9.9.9-nightly.1594209361 diff --git a/olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/eclipse-che-preview-openshift.package.yaml b/olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/eclipse-che-preview-openshift.package.yaml index 9c051b9c4b..919dc6b4f8 100644 --- a/olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/eclipse-che-preview-openshift.package.yaml +++ b/olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/eclipse-che-preview-openshift.package.yaml @@ -1,5 +1,5 @@ channels: -- currentCSV: eclipse-che-preview-openshift.v9.9.9-nightly.1594133421 +- currentCSV: eclipse-che-preview-openshift.v9.9.9-nightly.1594209361 name: nightly - currentCSV: eclipse-che-preview-openshift.v7.15.1 name: stable diff --git a/pkg/controller/che/che_controller.go b/pkg/controller/che/che_controller.go index 52306aec94..054ae46d6e 100644 --- a/pkg/controller/che/che_controller.go +++ b/pkg/controller/che/che_controller.go @@ -21,6 +21,7 @@ import ( orgv1 "github.com/eclipse/che-operator/pkg/apis/org/v1" "github.com/eclipse/che-operator/pkg/deploy" "github.com/eclipse/che-operator/pkg/util" + configv1 "github.com/openshift/api/config/v1" oauthv1 "github.com/openshift/api/config/v1" consolev1 "github.com/openshift/api/console/v1" oauth "github.com/openshift/api/oauth/v1" @@ -96,6 +97,9 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error { if err := oauthv1.AddToScheme(mgr.GetScheme()); err != nil { logrus.Errorf("Failed to add OpenShift OAuth to scheme: %s", err) } + if err := configv1.AddToScheme(mgr.GetScheme()); err != nil { + logrus.Errorf("Failed to add OpenShift Config to scheme: %s", err) + } if hasConsolelinkObject() { if err := consolev1.AddToScheme(mgr.GetScheme()); err != nil { logrus.Errorf("Failed to add OpenShift ConsoleLink to scheme: %s", err) @@ -307,6 +311,26 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e } } + // Read proxy configuration + proxy, err := r.getProxyConfiguration(instance) + if err != nil { + logrus.Errorf("Error on reading proxy configuration: %v", err) + return reconcile.Result{}, err + } + + if proxy.TrustedCAMapName != "" { + provisioned, err := r.putOpenShiftCertsIntoConfigMap(instance, proxy, clusterAPI) + if !provisioned { + configMapName := instance.Spec.Server.ServerTrustStoreConfigMapName + if err != nil { + logrus.Errorf("Error on provisioning config map '%s': %v", configMapName, err) + } else { + logrus.Infof("Waiting on provisioning config map '%s'", configMapName) + } + return reconcile.Result{}, err + } + } + cheFlavor := deploy.DefaultCheFlavor(instance) cheDeploymentName := cheFlavor @@ -319,7 +343,7 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e } // Detect whether self-signed certificate is used - selfSignedCertUsed, err := deploy.IsSelfSignedCertificateUsed(instance, clusterAPI) + selfSignedCertUsed, err := deploy.IsSelfSignedCertificateUsed(instance, proxy, clusterAPI) if err != nil { logrus.Errorf("Failed to detect if self-signed certificate used. Cause: %v", err) return reconcile.Result{}, err @@ -332,7 +356,7 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e // and NOT from the Openshift API Master URL (as in v3) // So we also need the self-signed certificate to access them (same as the Che server) (isOpenShift4 && instance.Spec.Auth.OpenShiftoAuth && !instance.Spec.Server.TlsSupport) { - if err := deploy.CreateTLSSecretFromRoute(instance, "", deploy.CheTLSSelfSignedCertificateSecretName, clusterAPI); err != nil { + if err := deploy.CreateTLSSecretFromRoute(instance, "", deploy.CheTLSSelfSignedCertificateSecretName, proxy, clusterAPI); err != nil { return reconcile.Result{}, err } } @@ -353,7 +377,7 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e if err != nil { logrus.Errorf("Failed to get OpenShift cluster public hostname. A secret with API crt will not be created and consumed by RH-SSO/Keycloak") } else { - if err := deploy.CreateTLSSecretFromRoute(instance, baseURL, "openshift-api-crt", clusterAPI); err != nil { + if err := deploy.CreateTLSSecretFromRoute(instance, baseURL, "openshift-api-crt", proxy, clusterAPI); err != nil { return reconcile.Result{}, err } } @@ -793,7 +817,7 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e } } - deploymentStatus := deploy.SyncKeycloakDeploymentToCluster(instance, clusterAPI) + deploymentStatus := deploy.SyncKeycloakDeploymentToCluster(instance, proxy, clusterAPI) if !tests { if !deploymentStatus.Continue { logrus.Info("Waiting on deployment 'keycloak' to be ready") @@ -992,7 +1016,7 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e logrus.Errorf("An error occurred: %v", err) return reconcile.Result{}, err } - logrus.Info(" Updating plugin-registry ConfigMap") + logrus.Info("Updating plugin-registry ConfigMap") err = r.client.Update(context.TODO(), pluginRegistryConfigMap) if err != nil { logrus.Errorf("Error updating plugin-registry ConfigMap: %v", err) @@ -1088,16 +1112,14 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e // create Che ConfigMap which is synced with CR and is not supposed to be manually edited // controller will reconcile this CM with CR spec - cheEnv := deploy.GetConfigMapData(instance) - configMapStatus := deploy.SyncConfigMapToCluster(instance, cheEnv, clusterAPI) + cheConfigMap, err := deploy.SyncCheConfigMapToCluster(instance, proxy, clusterAPI) if !tests { - if !configMapStatus.Continue { - logrus.Infof("Waiting on config map '%s' to be created", cheFlavor) - if configMapStatus.Err != nil { - logrus.Error(configMapStatus.Err) + if cheConfigMap == nil { + logrus.Infof("Waiting on config map '%s' to be created", deploy.CheConfigMapName) + if err != nil { + logrus.Error(err) } - - return reconcile.Result{Requeue: configMapStatus.Requeue}, configMapStatus.Err + return reconcile.Result{}, err } } @@ -1107,11 +1129,11 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e if tests { cmResourceVersion = r.GetEffectiveConfigMap(instance, deploy.CheConfigMapName).ResourceVersion } else { - cmResourceVersion = configMapStatus.ConfigMap.ResourceVersion + cmResourceVersion = cheConfigMap.ResourceVersion } // Create a new che deployment - deploymentStatus := deploy.SyncCheDeploymentToCluster(instance, cmResourceVersion, clusterAPI) + deploymentStatus := deploy.SyncCheDeploymentToCluster(instance, cmResourceVersion, proxy, clusterAPI) if !tests { if !deploymentStatus.Continue { logrus.Infof("Waiting on deployment '%s' to be ready", cheFlavor) diff --git a/pkg/controller/che/create.go b/pkg/controller/che/create.go index f4dcc49f00..b8b487faf4 100644 --- a/pkg/controller/che/create.go +++ b/pkg/controller/che/create.go @@ -135,9 +135,7 @@ func (r *ReconcileChe) GenerateAndSaveFields(instance *orgv1.CheCluster, request if len(instance.Spec.Auth.IdentityProviderPostgresSecret) < 1 { keycloakPostgresPassword := util.GeneratePasswd(12) keycloakDeployment, err := r.GetEffectiveDeployment(instance, "keycloak") - if err != nil { - logrus.Info("Disregard the error. No existing Identity provider deployment found. Generating passwd") - } else { + if err == nil { keycloakPostgresPassword = util.GetDeploymentEnv(keycloakDeployment, "DB_PASSWORD") } @@ -156,9 +154,7 @@ func (r *ReconcileChe) GenerateAndSaveFields(instance *orgv1.CheCluster, request keycloakAdminPassword := util.GetValue(instance.Spec.Auth.IdentityProviderPassword, util.GeneratePasswd(12)) keycloakDeployment, err := r.GetEffectiveDeployment(instance, "keycloak") - if err != nil { - logrus.Info("Disregard the error. No existing Identity provider deployment found. Generating admin username and password") - } else { + if err == nil { keycloakAdminUserName = util.GetDeploymentEnv(keycloakDeployment, "SSO_ADMIN_USERNAME") keycloakAdminPassword = util.GetDeploymentEnv(keycloakDeployment, "SSO_ADMIN_PASSWORD") } diff --git a/pkg/controller/che/proxy.go b/pkg/controller/che/proxy.go new file mode 100644 index 0000000000..14a6c20788 --- /dev/null +++ b/pkg/controller/che/proxy.go @@ -0,0 +1,60 @@ +// +// Copyright (c) 2020 Red Hat, Inc. +// This program and the accompanying materials are made +// available under the terms of the Eclipse Public License 2.0 +// which is available at https://www.eclipse.org/legal/epl-2.0/ +// +// SPDX-License-Identifier: EPL-2.0 +// +// Contributors: +// Red Hat, Inc. - initial API and implementation +// +package che + +import ( + "context" + + orgv1 "github.com/eclipse/che-operator/pkg/apis/org/v1" + "github.com/eclipse/che-operator/pkg/deploy" + "github.com/eclipse/che-operator/pkg/util" + configv1 "github.com/openshift/api/config/v1" + "k8s.io/apimachinery/pkg/types" +) + +func (r *ReconcileChe) getProxyConfiguration(checluster *orgv1.CheCluster) (*deploy.Proxy, error) { + proxy, err := deploy.ReadCheClusterProxyConfiguration(checluster) + if err != nil { + return nil, err + } + + if util.IsOpenShift4 { + clusterProxy := &configv1.Proxy{} + if err := r.client.Get(context.TODO(), types.NamespacedName{Name: "cluster"}, clusterProxy); err != nil { + return nil, err + } + + // If proxy configuration exists in CR then cluster wide proxy configuration is ignored + // otherwise cluster wide proxy configuration is used and non proxy hosts + // are merted with defined ones in CR + if proxy.HttpProxy == "" && clusterProxy.Status.HTTPProxy != "" { + proxy, err = deploy.ReadClusterWideProxyConfiguration(clusterProxy, proxy.NoProxy) + if err != nil { + return nil, err + } + } + } + + return proxy, nil +} + +func (r *ReconcileChe) putOpenShiftCertsIntoConfigMap(checluster *orgv1.CheCluster, proxy *deploy.Proxy, clusterAPI deploy.ClusterAPI) (bool, error) { + if checluster.Spec.Server.ServerTrustStoreConfigMapName == "" { + checluster.Spec.Server.ServerTrustStoreConfigMapName = deploy.DefaultServerTrustStoreConfigMapName() + if err := r.UpdateCheCRSpec(checluster, "truststore configmap", deploy.DefaultServerTrustStoreConfigMapName()); err != nil { + return false, err + } + } + + certConfigMap, err := deploy.SyncTrustStoreConfigMapToCluster(checluster, clusterAPI) + return certConfigMap != nil, err +} diff --git a/pkg/deploy/che_configmap.go b/pkg/deploy/che_configmap.go index 62a0068bc0..baf925e1af 100644 --- a/pkg/deploy/che_configmap.go +++ b/pkg/deploy/che_configmap.go @@ -12,7 +12,6 @@ package deploy import ( - "context" "encoding/json" "fmt" "os" @@ -20,14 +19,8 @@ import ( orgv1 "github.com/eclipse/che-operator/pkg/apis/org/v1" "github.com/eclipse/che-operator/pkg/util" - "github.com/google/go-cmp/cmp" "github.com/sirupsen/logrus" corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - runtimeClient "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" ) const ( @@ -83,54 +76,19 @@ type CheConfigMap struct { CheJGroupsKubernetesLabels string `json:"KUBERNETES_LABELS,omitempty"` } -type ConfigMapProvisioningStatus struct { - ProvisioningStatus - ConfigMap *corev1.ConfigMap -} - -func SyncConfigMapToCluster(checluster *orgv1.CheCluster, cheEnv map[string]string, clusterAPI ClusterAPI) ConfigMapProvisioningStatus { - specConfigMap, err := GetSpecConfigMap(checluster, cheEnv, clusterAPI) - if err != nil { - return ConfigMapProvisioningStatus{ - ProvisioningStatus: ProvisioningStatus{Err: err}, - } - } - - clusterConfigMap, err := getClusterConfigMap(specConfigMap.Name, specConfigMap.Namespace, clusterAPI.Client) +func SyncCheConfigMapToCluster(checluster *orgv1.CheCluster, proxy *Proxy, clusterAPI ClusterAPI) (*corev1.ConfigMap, error) { + data := GetCheConfigMapData(checluster, proxy) + specConfigMap, err := GetSpecConfigMap(checluster, CheConfigMapName, data, clusterAPI) if err != nil { - return ConfigMapProvisioningStatus{ - ProvisioningStatus: ProvisioningStatus{Err: err}, - } - } - - if clusterConfigMap == nil { - logrus.Infof("Creating a new object: %s, name %s", specConfigMap.Kind, specConfigMap.Name) - err := clusterAPI.Client.Create(context.TODO(), specConfigMap) - return ConfigMapProvisioningStatus{ - ProvisioningStatus: ProvisioningStatus{Requeue: true, Err: err}, - } - } - - diff := cmp.Diff(clusterConfigMap.Data, specConfigMap.Data) - if len(diff) > 0 { - logrus.Infof("Updating existed object: %s, name: %s", specConfigMap.Kind, specConfigMap.Name) - fmt.Printf("Difference:\n%s", diff) - clusterConfigMap.Data = specConfigMap.Data - err := clusterAPI.Client.Update(context.TODO(), clusterConfigMap) - return ConfigMapProvisioningStatus{ - ProvisioningStatus: ProvisioningStatus{Requeue: true, Err: err}, - } + return nil, err } - return ConfigMapProvisioningStatus{ - ProvisioningStatus: ProvisioningStatus{Continue: true}, - ConfigMap: clusterConfigMap, - } + return SyncConfigMapToCluster(checluster, specConfigMap, clusterAPI) } // GetConfigMapData gets env values from CR spec and returns a map with key:value // which is used in CheCluster ConfigMap to configure CheCluster master behavior -func GetConfigMapData(cr *orgv1.CheCluster) (cheEnv map[string]string) { +func GetCheConfigMapData(cr *orgv1.CheCluster, proxy *Proxy) (cheEnv map[string]string) { cheHost := cr.Spec.Server.CheHost keycloakURL := cr.Spec.Auth.IdentityProviderURL isOpenShift, isOpenshift4, err := util.DetectOpenShift() @@ -165,29 +123,18 @@ func GetConfigMapData(cr *orgv1.CheCluster) (cheEnv map[string]string) { wsprotocol = "wss" tls = "true" } - proxyJavaOpts := "" - proxyUser := cr.Spec.Server.ProxyUser - proxyPassword := cr.Spec.Server.ProxyPassword - proxySecret := cr.Spec.Server.ProxySecret - nonProxyHosts := cr.Spec.Server.NonProxyHosts - if len(nonProxyHosts) < 1 && len(cr.Spec.Server.ProxyURL) > 1 { - nonProxyHosts = os.Getenv("KUBERNETES_SERVICE_HOST") - } else { - nonProxyHosts = nonProxyHosts + "|" + os.Getenv("KUBERNETES_SERVICE_HOST") - } - if len(cr.Spec.Server.ProxyURL) > 1 { - proxyJavaOpts, err = util.GenerateProxyJavaOpts(cr.Spec.Server.ProxyURL, cr.Spec.Server.ProxyPort, nonProxyHosts, proxyUser, proxyPassword, proxySecret, cr.Namespace) - if err != nil { - logrus.Errorf("Failed to generate java proxy options: %v", err) + proxyJavaOpts := "" + cheWorkspaceNoProxy := proxy.NoProxy + if proxy.HttpProxy != "" { + if proxy.NoProxy == "" { + cheWorkspaceNoProxy = os.Getenv("KUBERNETES_SERVICE_HOST") + } else { + cheWorkspaceNoProxy = cheWorkspaceNoProxy + "," + os.Getenv("KUBERNETES_SERVICE_HOST") } - } - cheWorkspaceHttpProxy := "" - cheWorkspaceNoProxy := "" - if len(cr.Spec.Server.ProxyURL) > 1 { - cheWorkspaceHttpProxy, cheWorkspaceNoProxy, err = util.GenerateProxyEnvs(cr.Spec.Server.ProxyURL, cr.Spec.Server.ProxyPort, nonProxyHosts, proxyUser, proxyPassword, proxySecret, cr.Namespace) + proxyJavaOpts, err = GenerateProxyJavaOpts(proxy, cheWorkspaceNoProxy) if err != nil { - logrus.Errorf("Failed to generate proxy env variables: %v", err) + logrus.Errorf("Failed to generate java proxy options: %v", err) } } @@ -220,7 +167,7 @@ func GetConfigMapData(cr *orgv1.CheCluster) (cheEnv map[string]string) { cheLogLevel := util.GetValue(cr.Spec.Server.CheLogLevel, DefaultCheLogLevel) cheDebug := util.GetValue(cr.Spec.Server.CheDebug, DefaultCheDebug) cheMetrics := strconv.FormatBool(cr.Spec.Metrics.Enable) - cheLabels := util.MapToKeyValuePairs(GetLabels(cr, cheFlavor)) + cheLabels := util.MapToKeyValuePairs(GetLabels(cr, DefaultCheFlavor(cr))) cheMultiUser := GetCheMultiUser(cr) data := &CheConfigMap{ @@ -248,8 +195,8 @@ func GetConfigMapData(cr *orgv1.CheCluster) (cheEnv map[string]string) { WorkspaceJavaOpts: DefaultWorkspaceJavaOpts + " " + proxyJavaOpts, WorkspaceMavenOpts: DefaultWorkspaceJavaOpts + " " + proxyJavaOpts, WorkspaceProxyJavaOpts: proxyJavaOpts, - WorkspaceHttpProxy: cheWorkspaceHttpProxy, - WorkspaceHttpsProxy: cheWorkspaceHttpProxy, + WorkspaceHttpProxy: proxy.HttpProxy, + WorkspaceHttpsProxy: proxy.HttpsProxy, WorkspaceNoProxy: cheWorkspaceNoProxy, PluginRegistryUrl: pluginRegistryUrl, DevfileRegistryUrl: devfileRegistryUrl, @@ -295,44 +242,3 @@ func GetConfigMapData(cr *orgv1.CheCluster) (cheEnv map[string]string) { addMap(cheEnv, cr.Spec.Server.CustomCheProperties) return cheEnv } - -func GetSpecConfigMap(checluster *orgv1.CheCluster, cheEnv map[string]string, clusterAPI ClusterAPI) (*corev1.ConfigMap, error) { - labels := GetLabels(checluster, DefaultCheFlavor(checluster)) - configMap := &corev1.ConfigMap{ - TypeMeta: metav1.TypeMeta{ - Kind: "ConfigMap", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: CheConfigMapName, - Namespace: checluster.Namespace, - Labels: labels, - }, - Data: cheEnv, - } - - if !util.IsTestMode() { - err := controllerutil.SetControllerReference(checluster, configMap, clusterAPI.Scheme) - if err != nil { - return nil, err - } - } - - return configMap, nil -} - -func getClusterConfigMap(name string, namespace string, client runtimeClient.Client) (*corev1.ConfigMap, error) { - configMap := &corev1.ConfigMap{} - namespacedName := types.NamespacedName{ - Namespace: namespace, - Name: name, - } - err := client.Get(context.TODO(), namespacedName, configMap) - if err != nil { - if errors.IsNotFound(err) { - return nil, nil - } - return nil, err - } - return configMap, nil -} diff --git a/pkg/deploy/che_configmap_test.go b/pkg/deploy/che_configmap_test.go index 9c0786d5ab..b4dce3d4c9 100644 --- a/pkg/deploy/che_configmap_test.go +++ b/pkg/deploy/che_configmap_test.go @@ -28,8 +28,8 @@ func TestNewCheConfigMap(t *testing.T) { cr.Spec.Server.CheHost = "myhostname.com" cr.Spec.Server.TlsSupport = true cr.Spec.Auth.OpenShiftoAuth = true - cheEnv := GetConfigMapData(cr) - testCm, _ := GetSpecConfigMap(cr, cheEnv, ClusterAPI{}) + cheEnv := GetCheConfigMapData(cr, &Proxy{}) + testCm, _ := GetSpecConfigMap(cr, CheConfigMapName, cheEnv, ClusterAPI{}) identityProvider := testCm.Data["CHE_INFRA_OPENSHIFT_OAUTH__IDENTITY__PROVIDER"] _, isOpenshiftv4, _ := util.DetectOpenShift() protocol := strings.Split(testCm.Data["CHE_API"], "://")[0] @@ -53,8 +53,8 @@ func TestConfigMapOverride(t *testing.T) { "CHE_WORKSPACE_NO_PROXY": "myproxy.myhostname.com", } cr.Spec.Auth.OpenShiftoAuth = true - cheEnv := GetConfigMapData(cr) - testCm, _ := GetSpecConfigMap(cr, cheEnv, ClusterAPI{}) + cheEnv := GetCheConfigMapData(cr, &Proxy{}) + testCm, _ := GetSpecConfigMap(cr, CheConfigMapName, cheEnv, ClusterAPI{}) if testCm.Data["CHE_WORKSPACE_NO_PROXY"] != "myproxy.myhostname.com" { t.Errorf("Test failed. Expected myproxy.myhostname.com but was %s", testCm.Data["CHE_WORKSPACE_NO_PROXY"]) } diff --git a/pkg/deploy/configmap.go b/pkg/deploy/configmap.go new file mode 100644 index 0000000000..fca4bc174d --- /dev/null +++ b/pkg/deploy/configmap.go @@ -0,0 +1,98 @@ +// +// Copyright (c) 2020 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 deploy + +import ( + "context" + "fmt" + + orgv1 "github.com/eclipse/che-operator/pkg/apis/org/v1" + "github.com/eclipse/che-operator/pkg/util" + "github.com/google/go-cmp/cmp" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + runtimeClient "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" +) + +func SyncConfigMapToCluster(checluster *orgv1.CheCluster, specConfigMap *corev1.ConfigMap, clusterAPI ClusterAPI) (*corev1.ConfigMap, error) { + clusterConfigMap, err := getClusterConfigMap(specConfigMap.Name, specConfigMap.Namespace, clusterAPI.Client) + if err != nil { + return nil, err + } + + if clusterConfigMap == nil { + logrus.Infof("Creating a new object: %s, name %s", specConfigMap.Kind, specConfigMap.Name) + err := clusterAPI.Client.Create(context.TODO(), specConfigMap) + return nil, err + } + + diff := cmp.Diff(clusterConfigMap.Data, specConfigMap.Data) + if len(diff) > 0 { + logrus.Infof("Updating existed object: %s, name: %s", specConfigMap.Kind, specConfigMap.Name) + fmt.Printf("Difference:\n%s", diff) + clusterConfigMap.Data = specConfigMap.Data + err := clusterAPI.Client.Update(context.TODO(), clusterConfigMap) + return nil, err + } + + return clusterConfigMap, nil +} + +func GetSpecConfigMap( + checluster *orgv1.CheCluster, + name string, + data map[string]string, + clusterAPI ClusterAPI) (*corev1.ConfigMap, error) { + + labels := GetLabels(checluster, DefaultCheFlavor(checluster)) + configMap := &corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + Kind: "ConfigMap", + APIVersion: "v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: checluster.Namespace, + Labels: labels, + }, + Data: data, + } + + if !util.IsTestMode() { + err := controllerutil.SetControllerReference(checluster, configMap, clusterAPI.Scheme) + if err != nil { + return nil, err + } + } + + return configMap, nil +} + +func getClusterConfigMap(name string, namespace string, client runtimeClient.Client) (*corev1.ConfigMap, error) { + configMap := &corev1.ConfigMap{} + namespacedName := types.NamespacedName{ + Namespace: namespace, + Name: name, + } + err := client.Get(context.TODO(), namespacedName, configMap) + if err != nil { + if errors.IsNotFound(err) { + return nil, nil + } + return nil, err + } + return configMap, nil +} diff --git a/pkg/deploy/configmap_cert.go b/pkg/deploy/configmap_cert.go new file mode 100644 index 0000000000..12d7cd57a4 --- /dev/null +++ b/pkg/deploy/configmap_cert.go @@ -0,0 +1,55 @@ +// +// Copyright (c) 2020 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 deploy + +import ( + "context" + + orgv1 "github.com/eclipse/che-operator/pkg/apis/org/v1" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" +) + +const ( + injector = "config.openshift.io/inject-trusted-cabundle" +) + +func SyncTrustStoreConfigMapToCluster(checluster *orgv1.CheCluster, clusterAPI ClusterAPI) (*corev1.ConfigMap, error) { + name := checluster.Spec.Server.ServerTrustStoreConfigMapName + specConfigMap, err := GetSpecConfigMap(checluster, name, map[string]string{}, clusterAPI) + if err != nil { + return nil, err + } + + // OpenShift will automatically injects all certs into the configmap + specConfigMap.ObjectMeta.Labels[injector] = "true" + + clusterConfigMap, err := getClusterConfigMap(specConfigMap.Name, specConfigMap.Namespace, clusterAPI.Client) + if err != nil { + return nil, err + } + + if clusterConfigMap == nil { + logrus.Infof("Creating a new object: %s, name %s", specConfigMap.Kind, specConfigMap.Name) + err := clusterAPI.Client.Create(context.TODO(), specConfigMap) + return nil, err + } + + if clusterConfigMap.ObjectMeta.Labels[injector] != "true" { + clusterConfigMap.ObjectMeta.Labels[injector] = "true" + logrus.Infof("Updating existed object: %s, name: %s", specConfigMap.Kind, specConfigMap.Name) + err := clusterAPI.Client.Update(context.TODO(), clusterConfigMap) + return nil, err + } + + return clusterConfigMap, nil +} diff --git a/pkg/deploy/data_types.go b/pkg/deploy/data_types.go index 5df7f86806..a449526e42 100644 --- a/pkg/deploy/data_types.go +++ b/pkg/deploy/data_types.go @@ -27,3 +27,20 @@ type ClusterAPI struct { Client client.Client Scheme *runtime.Scheme } + +type Proxy struct { + HttpProxy string + HttpUser string + HttpPassword string + HttpHost string + HttpPort string + + HttpsProxy string + HttpsUser string + HttpsPassword string + HttpsHost string + HttpsPort string + + NoProxy string + TrustedCAMapName string +} diff --git a/pkg/deploy/defaults.go b/pkg/deploy/defaults.go index 4e94d6ec6c..f9df749257 100644 --- a/pkg/deploy/defaults.go +++ b/pkg/deploy/defaults.go @@ -177,6 +177,10 @@ func MigratingToCRW2_0(cr *orgv1.CheCluster) bool { return false } +func DefaultServerTrustStoreConfigMapName() string { + return getDefaultFromEnv("CHE_SERVER_TRUST_STORE_CONFIGMAP_NAME") +} + func DefaultCheFlavor(cr *orgv1.CheCluster) string { return util.GetValue(cr.Spec.Server.CheFlavor, getDefaultFromEnv("CHE_FLAVOR")) } diff --git a/pkg/deploy/deployment_che.go b/pkg/deploy/deployment_che.go index ffb8f73085..38cdae74a3 100644 --- a/pkg/deploy/deployment_che.go +++ b/pkg/deploy/deployment_che.go @@ -25,7 +25,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" ) -func SyncCheDeploymentToCluster(checluster *orgv1.CheCluster, cmResourceVersion string, clusterAPI ClusterAPI) DeploymentProvisioningStatus { +func SyncCheDeploymentToCluster(checluster *orgv1.CheCluster, cmResourceVersion string, proxy *Proxy, clusterAPI ClusterAPI) DeploymentProvisioningStatus { clusterDeployment, err := getClusterDeployment(DefaultCheFlavor(checluster), checluster.Namespace, clusterAPI.Client) if err != nil { return DeploymentProvisioningStatus{ @@ -33,7 +33,7 @@ func SyncCheDeploymentToCluster(checluster *orgv1.CheCluster, cmResourceVersion } } - specDeployment, err := getSpecCheDeployment(checluster, cmResourceVersion, clusterAPI) + specDeployment, err := getSpecCheDeployment(checluster, cmResourceVersion, proxy, clusterAPI) if err != nil { return DeploymentProvisioningStatus{ ProvisioningStatus: ProvisioningStatus{Err: err}, @@ -43,13 +43,13 @@ func SyncCheDeploymentToCluster(checluster *orgv1.CheCluster, cmResourceVersion return SyncDeploymentToCluster(checluster, specDeployment, clusterDeployment, nil, nil, clusterAPI) } -func getSpecCheDeployment(checluster *orgv1.CheCluster, cmResourceVersion string, clusterAPI ClusterAPI) (*appsv1.Deployment, error) { +func getSpecCheDeployment(checluster *orgv1.CheCluster, cmResourceVersion string, proxy *Proxy, clusterAPI ClusterAPI) (*appsv1.Deployment, error) { isOpenShift, _, err := util.DetectOpenShift() if err != nil { return nil, err } - selfSignedCertUsed, err := IsSelfSignedCertificateUsed(checluster, clusterAPI) + selfSignedCertUsed, err := IsSelfSignedCertificateUsed(checluster, proxy, clusterAPI) if err != nil { return nil, err } diff --git a/pkg/deploy/deployment_keycloak.go b/pkg/deploy/deployment_keycloak.go index a9c9a99bbc..d32e40911c 100644 --- a/pkg/deploy/deployment_keycloak.go +++ b/pkg/deploy/deployment_keycloak.go @@ -56,7 +56,7 @@ var ( } ) -func SyncKeycloakDeploymentToCluster(checluster *orgv1.CheCluster, clusterAPI ClusterAPI) DeploymentProvisioningStatus { +func SyncKeycloakDeploymentToCluster(checluster *orgv1.CheCluster, proxy *Proxy, clusterAPI ClusterAPI) DeploymentProvisioningStatus { clusterDeployment, err := getClusterDeployment(KeycloakDeploymentName, checluster.Namespace, clusterAPI.Client) if err != nil { return DeploymentProvisioningStatus{ @@ -64,7 +64,7 @@ func SyncKeycloakDeploymentToCluster(checluster *orgv1.CheCluster, clusterAPI Cl } } - specDeployment, err := getSpecKeycloakDeployment(checluster, clusterDeployment, clusterAPI) + specDeployment, err := getSpecKeycloakDeployment(checluster, clusterDeployment, proxy, clusterAPI) if err != nil { return DeploymentProvisioningStatus{ ProvisioningStatus: ProvisioningStatus{Err: err}, @@ -74,7 +74,11 @@ func SyncKeycloakDeploymentToCluster(checluster *orgv1.CheCluster, clusterAPI Cl return SyncDeploymentToCluster(checluster, specDeployment, clusterDeployment, keycloakCustomDiffOpts, keycloakAdditionalDeploymentMerge, clusterAPI) } -func getSpecKeycloakDeployment(checluster *orgv1.CheCluster, clusterDeployment *appsv1.Deployment, clusterAPI ClusterAPI) (*appsv1.Deployment, error) { +func getSpecKeycloakDeployment( + checluster *orgv1.CheCluster, + clusterDeployment *appsv1.Deployment, + proxy *Proxy, + clusterAPI ClusterAPI) (*appsv1.Deployment, error) { optionalEnv := true labels := GetLabels(checluster, KeycloakDeploymentName) cheFlavor := DefaultCheFlavor(checluster) @@ -164,29 +168,29 @@ func getSpecKeycloakDeployment(checluster *orgv1.CheCluster, clusterDeployment * applyProxyCliCommand := "" proxyEnvVars := []corev1.EnvVar{} - if len(checluster.Spec.Server.ProxyURL) > 1 { - proxySecret := checluster.Spec.Server.ProxySecret - cheWorkspaceHttpProxy, cheWorkspaceNoProxy, err := util.GenerateProxyEnvs(checluster.Spec.Server.ProxyURL, checluster.Spec.Server.ProxyPort, checluster.Spec.Server.NonProxyHosts, checluster.Spec.Server.ProxyUser, checluster.Spec.Server.ProxyPassword, proxySecret, checluster.Namespace) - if err != nil { - logrus.Errorf("Failed to read '%s' secret: %v", proxySecret, err) - } - + if proxy.HttpProxy != "" { proxyEnvVars = []corev1.EnvVar{ corev1.EnvVar{ Name: "HTTP_PROXY", - Value: cheWorkspaceHttpProxy, + Value: proxy.HttpProxy, }, corev1.EnvVar{ Name: "HTTPS_PROXY", - Value: cheWorkspaceHttpProxy, + Value: proxy.HttpsProxy, }, corev1.EnvVar{ Name: "NO_PROXY", - Value: cheWorkspaceNoProxy, + Value: proxy.NoProxy, }, } - cheWorkspaceNoProxy = strings.ReplaceAll(regexp.QuoteMeta(cheWorkspaceNoProxy), "\\", "\\\\\\") + quotedNoProxy := "" + for _, noProxyHost := range strings.Split(proxy.NoProxy, ",") { + if len(quotedNoProxy) != 0 { + quotedNoProxy += "," + } + quotedNoProxy += "\"" + strings.ReplaceAll(regexp.QuoteMeta(noProxyHost), "\\", "\\\\\\") + ";NO_PROXY\"" + } jbossCli := "/opt/jboss/keycloak/bin/jboss-cli.sh" serverConfig := "standalone.xml" @@ -196,7 +200,7 @@ func getSpecKeycloakDeployment(checluster *orgv1.CheCluster, clusterDeployment * } addProxyCliCommand = " && echo Configuring Proxy && " + "echo -e 'embed-server --server-config=" + serverConfig + " --std-out=echo \n" + - "/subsystem=keycloak-server/spi=connectionsHttpClient/provider=default:write-attribute(name=properties.proxy-mappings,value=[\"" + cheWorkspaceNoProxy + ";NO_PROXY\",\".*;" + cheWorkspaceHttpProxy + "\"]) \n" + + "/subsystem=keycloak-server/spi=connectionsHttpClient/provider=default:write-attribute(name=properties.proxy-mappings,value=[" + quotedNoProxy + ",\".*;" + proxy.HttpProxy + "\"]) \n" + "stop-embedded-server' > " + jbossDir + "/setup-http-proxy.cli" applyProxyCliCommand = " && " + jbossCli + " --file=" + jbossDir + "/setup-http-proxy.cli" diff --git a/pkg/deploy/proxy.go b/pkg/deploy/proxy.go new file mode 100644 index 0000000000..137fdceb5e --- /dev/null +++ b/pkg/deploy/proxy.go @@ -0,0 +1,171 @@ +// +// Copyright (c) 2020 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 deploy + +import ( + "strings" + + "github.com/eclipse/che-operator/pkg/util" + + "golang.org/x/net/http/httpproxy" + + "net/http" + "net/url" + + orgv1 "github.com/eclipse/che-operator/pkg/apis/org/v1" + configv1 "github.com/openshift/api/config/v1" + + "github.com/sirupsen/logrus" +) + +func ReadClusterWideProxyConfiguration(clusterProxy *configv1.Proxy, noProxy string) (*Proxy, error) { + proxy := &Proxy{} + + // Cluster components consume the status values to configure the proxy for their component. + proxy.HttpProxy = clusterProxy.Status.HTTPProxy + proxy.HttpsProxy = clusterProxy.Status.HTTPSProxy + if len(proxy.HttpsProxy) == 0 { + proxy.HttpsProxy = proxy.HttpProxy + } + proxy.NoProxy = clusterProxy.Status.NoProxy + if proxy.NoProxy == "" { + proxy.NoProxy = noProxy + } else if noProxy != "" { + proxy.NoProxy += "," + noProxy + } + + httpProxy, err := url.Parse(proxy.HttpProxy) + if err != nil { + return nil, err + } + proxy.HttpHost = httpProxy.Hostname() + proxy.HttpPort = httpProxy.Port() + proxy.HttpUser = httpProxy.User.Username() + proxy.HttpPassword, _ = httpProxy.User.Password() + + httpsProxy, err := url.Parse(proxy.HttpsProxy) + if err != nil { + return nil, err + } + proxy.HttpsHost = httpsProxy.Hostname() + proxy.HttpsPort = httpsProxy.Port() + proxy.HttpsUser = httpsProxy.User.Username() + proxy.HttpsPassword, _ = httpsProxy.User.Password() + proxy.TrustedCAMapName = clusterProxy.Spec.TrustedCA.Name + + return proxy, nil +} + +func ReadCheClusterProxyConfiguration(checluster *orgv1.CheCluster) (*Proxy, error) { + proxyParts := strings.Split(checluster.Spec.Server.ProxyURL, "://") + proxyProtocol := "" + proxyHost := "" + if len(proxyParts) == 1 { + proxyProtocol = "" + proxyHost = proxyParts[0] + } else { + proxyProtocol = proxyParts[0] + proxyHost = proxyParts[1] + } + + proxyURL := proxyHost + if checluster.Spec.Server.ProxyPort != "" { + proxyURL = proxyURL + ":" + checluster.Spec.Server.ProxyPort + } + + proxyUser := checluster.Spec.Server.ProxyUser + proxyPassword := checluster.Spec.Server.ProxyPassword + proxySecret := checluster.Spec.Server.ProxySecret + if len(proxySecret) > 0 { + user, password, err := util.K8sclient.ReadSecret(proxySecret, checluster.Namespace) + if err == nil { + proxyUser = user + proxyPassword = password + } else { + return nil, err + } + } + + if len(proxyUser) > 1 && len(proxyPassword) > 1 { + proxyURL = proxyUser + ":" + proxyPassword + "@" + proxyURL + } + + if proxyProtocol != "" { + proxyURL = proxyProtocol + "://" + proxyURL + } + + return &Proxy{ + HttpProxy: proxyURL, + HttpUser: proxyUser, + HttpHost: proxyHost, + HttpPort: checluster.Spec.Server.ProxyPort, + HttpPassword: proxyPassword, + + HttpsProxy: proxyURL, + HttpsUser: proxyUser, + HttpsHost: proxyHost, + HttpsPort: checluster.Spec.Server.ProxyPort, + HttpsPassword: proxyPassword, + + NoProxy: strings.Replace(checluster.Spec.Server.NonProxyHosts, "|", ",", -1), + }, nil +} + +func GenerateProxyJavaOpts(proxy *Proxy, noProxy string) (javaOpts string, err error) { + if noProxy == "" { + noProxy = proxy.NoProxy + } + noProxy = strings.Replace(noProxy, ",", "|", -1) + + proxyUserPassword := "" + if len(proxy.HttpUser) > 1 && len(proxy.HttpPassword) > 1 { + proxyUserPassword = " -Dhttp.proxyUser=" + proxy.HttpUser + " -Dhttp.proxyPassword=" + proxy.HttpPassword + + " -Dhttps.proxyUser=" + proxy.HttpsUser + " -Dhttps.proxyPassword=" + proxy.HttpsPassword + } + + javaOpts = + " -Dhttp.proxyHost=" + removeProtocolPrefix(proxy.HttpHost) + " -Dhttp.proxyPort=" + proxy.HttpPort + + " -Dhttps.proxyHost=" + removeProtocolPrefix(proxy.HttpsHost) + " -Dhttps.proxyPort=" + proxy.HttpsPort + + " -Dhttp.nonProxyHosts='" + noProxy + "'" + proxyUserPassword + return javaOpts, nil +} + +func removeProtocolPrefix(url string) string { + if strings.HasPrefix(url, "https://") { + return strings.TrimPrefix(url, "https://") + } else if strings.HasPrefix(url, "http://") { + return strings.TrimPrefix(url, "http://") + } + return url +} + +func ConfigureProxy(instance *orgv1.CheCluster, transport *http.Transport, proxy *Proxy) { + config := httpproxy.Config{ + HTTPProxy: proxy.HttpProxy, + HTTPSProxy: proxy.HttpsProxy, + NoProxy: proxy.NoProxy, + } + proxyFunc := config.ProxyFunc() + transport.Proxy = func(r *http.Request) (*url.URL, error) { + theProxyUrl, err := proxyFunc(r.URL) + if err != nil { + logrus.Warnf("Error when trying to get the proxy to access TLS endpoint URL: %s - %s", r.URL, err) + } + if theProxyUrl != nil { + logrus.Infof("Using proxy: %s to access TLS endpoint URL: %s", theProxyUrl, r.URL) + } else { + logrus.Infof("Proxy isn't used to access TLS endpoint URL: %s", r.URL) + } + return theProxyUrl, err + } +} diff --git a/pkg/deploy/proxy_test.go b/pkg/deploy/proxy_test.go new file mode 100644 index 0000000000..02d329a703 --- /dev/null +++ b/pkg/deploy/proxy_test.go @@ -0,0 +1,261 @@ +// +// Copyright (c) 2020 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 deploy + +import ( + "os" + "reflect" + "testing" + + orgv1 "github.com/eclipse/che-operator/pkg/apis/org/v1" + configv1 "github.com/openshift/api/config/v1" + "github.com/sirupsen/logrus" +) + +const ( + expectedProxyURLWithUsernamePassword = "https://user:password@myproxy.com:1234" + expectedProxyURLWithoutUsernamePassword = "https://myproxy.com:1234" + expectedNoProxy = "localhost,myhost.com" +) + +func TestGenerateProxyJavaOpts(t *testing.T) { + proxy := &Proxy{ + HttpProxy: "https://user:password@myproxy.com:1234", + HttpUser: "user", + HttpPassword: "password", + HttpHost: "myproxy.com", + HttpPort: "1234", + + HttpsProxy: "https://user:password@myproxy.com:1234", + HttpsUser: "user", + HttpsPassword: "password", + HttpsHost: "myproxy.com", + HttpsPort: "1234", + + NoProxy: "localhost,myhost.com", + } + + if err := os.Setenv("KUBERNETES_SERVICE_HOST", "172.30.0.1"); err != nil { + logrus.Errorf("Failed to set env %s", err) + } + + javaOpts, _ := GenerateProxyJavaOpts(proxy, "") + expectedJavaOpts := " -Dhttp.proxyHost=myproxy.com -Dhttp.proxyPort=1234 -Dhttps.proxyHost=myproxy.com " + + "-Dhttps.proxyPort=1234 -Dhttp.nonProxyHosts='localhost|myhost.com' -Dhttp.proxyUser=user " + + "-Dhttp.proxyPassword=password -Dhttps.proxyUser=user -Dhttps.proxyPassword=password" + if !reflect.DeepEqual(javaOpts, expectedJavaOpts) { + t.Errorf("Test failed. Expected '%s' but got '%s'", expectedJavaOpts, javaOpts) + + } + + proxy = &Proxy{ + HttpProxy: "http://user:password@myproxy.com:1234", + HttpHost: "myproxy.com", + HttpPort: "1234", + + HttpsProxy: "https://user:password@myproxy.com:1234", + HttpsHost: "myproxy.com", + HttpsPort: "1234", + + NoProxy: "localhost,myhost.com", + } + javaOpts, _ = GenerateProxyJavaOpts(proxy, "test-no-proxy.com") + expectedJavaOptsWithoutUsernamePassword := " -Dhttp.proxyHost=myproxy.com -Dhttp.proxyPort=1234 -Dhttps.proxyHost=myproxy.com " + + "-Dhttps.proxyPort=1234 -Dhttp.nonProxyHosts='test-no-proxy.com'" + + if !reflect.DeepEqual(javaOpts, expectedJavaOptsWithoutUsernamePassword) { + t.Errorf("Test failed. Expected '%s' but got '%s'", expectedJavaOptsWithoutUsernamePassword, javaOpts) + } +} + +func TestReadCheClusterProxyConfiguration(t *testing.T) { + checluster := &orgv1.CheCluster{ + Spec: orgv1.CheClusterSpec{ + Server: orgv1.CheClusterSpecServer{ + ProxyPassword: "password", + ProxyUser: "user", + ProxyPort: "1234", + ProxyURL: "https://myproxy.com", + NonProxyHosts: "host1|host2", + }, + }, + } + expectedProxy := &Proxy{ + HttpProxy: "https://user:password@myproxy.com:1234", + HttpUser: "user", + HttpPassword: "password", + HttpHost: "myproxy.com", + HttpPort: "1234", + + HttpsProxy: "https://user:password@myproxy.com:1234", + HttpsUser: "user", + HttpsPassword: "password", + HttpsHost: "myproxy.com", + HttpsPort: "1234", + + NoProxy: "host1,host2", + } + + actualProxy, _ := ReadCheClusterProxyConfiguration(checluster) + + if !reflect.DeepEqual(actualProxy, expectedProxy) { + t.Errorf("Test failed. Expected '%v', but got '%v'", expectedProxy, actualProxy) + } +} + +func TestReadCheClusterProxyConfigurationNoUser(t *testing.T) { + checluster := &orgv1.CheCluster{ + Spec: orgv1.CheClusterSpec{ + Server: orgv1.CheClusterSpecServer{ + ProxyPort: "1234", + ProxyURL: "https://myproxy.com", + NonProxyHosts: "host1|host2", + }, + }, + } + expectedProxy := &Proxy{ + HttpProxy: "https://myproxy.com:1234", + HttpHost: "myproxy.com", + HttpPort: "1234", + + HttpsProxy: "https://myproxy.com:1234", + HttpsHost: "myproxy.com", + HttpsPort: "1234", + + NoProxy: "host1,host2", + } + + actualProxy, _ := ReadCheClusterProxyConfiguration(checluster) + + if !reflect.DeepEqual(actualProxy, expectedProxy) { + t.Errorf("Test failed. Expected '%v', but got '%v'", expectedProxy, actualProxy) + } +} + +func TestReadCheClusterProxyConfigurationNoPort(t *testing.T) { + checluster := &orgv1.CheCluster{ + Spec: orgv1.CheClusterSpec{ + Server: orgv1.CheClusterSpecServer{ + ProxyPassword: "password", + ProxyUser: "user", + ProxyURL: "https://myproxy.com", + NonProxyHosts: "host1|host2", + }, + }, + } + expectedProxy := &Proxy{ + HttpProxy: "https://user:password@myproxy.com", + HttpUser: "user", + HttpPassword: "password", + HttpHost: "myproxy.com", + + HttpsProxy: "https://user:password@myproxy.com", + HttpsUser: "user", + HttpsPassword: "password", + HttpsHost: "myproxy.com", + + NoProxy: "host1,host2", + } + + actualProxy, _ := ReadCheClusterProxyConfiguration(checluster) + + if !reflect.DeepEqual(actualProxy, expectedProxy) { + t.Errorf("Test failed. Expected '%v', but got '%v'", expectedProxy, actualProxy) + } +} + +func TestReadClusterWideProxyConfiguration(t *testing.T) { + clusterProxy := &configv1.Proxy{ + Status: configv1.ProxyStatus{ + HTTPProxy: "http://user1:password1@myproxy1.com:1234", + HTTPSProxy: "https://user2:password2@myproxy2.com:2345", + NoProxy: "host1,host2", + }, + } + + expectedProxy := &Proxy{ + HttpProxy: "http://user1:password1@myproxy1.com:1234", + HttpUser: "user1", + HttpPassword: "password1", + HttpHost: "myproxy1.com", + HttpPort: "1234", + + HttpsProxy: "https://user2:password2@myproxy2.com:2345", + HttpsUser: "user2", + HttpsPassword: "password2", + HttpsHost: "myproxy2.com", + HttpsPort: "2345", + + NoProxy: "host1,host2", + } + + actualProxy, _ := ReadClusterWideProxyConfiguration(clusterProxy, "") + + if !reflect.DeepEqual(actualProxy, expectedProxy) { + t.Errorf("Test failed. Expected '%v', but got '%v'", expectedProxy, actualProxy) + } +} + +func TestReadClusterWideProxyConfigurationNoUser(t *testing.T) { + clusterProxy := &configv1.Proxy{ + Status: configv1.ProxyStatus{ + HTTPProxy: "http://myproxy.com:1234", + NoProxy: "host1,host2", + }, + } + + expectedProxy := &Proxy{ + HttpProxy: "http://myproxy.com:1234", + HttpHost: "myproxy.com", + HttpPort: "1234", + + HttpsProxy: "http://myproxy.com:1234", + NoProxy: "host1,host2", + HttpsHost: "myproxy.com", + HttpsPort: "1234", + } + + actualProxy, _ := ReadClusterWideProxyConfiguration(clusterProxy, "") + + if !reflect.DeepEqual(actualProxy, expectedProxy) { + t.Errorf("Test failed. Expected '%v', but got '%v'", expectedProxy, actualProxy) + } +} + +func TestReadClusterWideProxyConfigurationNoPort(t *testing.T) { + clusterProxy := &configv1.Proxy{ + Status: configv1.ProxyStatus{ + HTTPProxy: "http://user:password@myproxy.com", + NoProxy: "host1,host2", + }, + } + + expectedProxy := &Proxy{ + HttpProxy: "http://user:password@myproxy.com", + HttpUser: "user", + HttpPassword: "password", + HttpHost: "myproxy.com", + + HttpsProxy: "http://user:password@myproxy.com", + HttpsUser: "user", + HttpsPassword: "password", + HttpsHost: "myproxy.com", + + NoProxy: "host1,host2,host3", + } + + actualProxy, _ := ReadClusterWideProxyConfiguration(clusterProxy, "host3") + + if !reflect.DeepEqual(actualProxy, expectedProxy) { + t.Errorf("Test failed. Expected '%v', but got '%v'", expectedProxy, actualProxy) + } +} diff --git a/pkg/deploy/registry_configmap.go b/pkg/deploy/registry_configmap.go index 7cc9974a65..5c137b4850 100644 --- a/pkg/deploy/registry_configmap.go +++ b/pkg/deploy/registry_configmap.go @@ -50,7 +50,6 @@ func CreateDevfileRegistryConfigMap(cr *orgv1.CheCluster, endpoint string) *core func CreatePluginRegistryConfigMap(cr *orgv1.CheCluster) *corev1.ConfigMap { labels := GetLabels(cr, DefaultCheFlavor(cr)) - fmt.Println("Cr namespace " + cr.Namespace) return &corev1.ConfigMap{ TypeMeta: metav1.TypeMeta{ Kind: "ConfigMap", diff --git a/pkg/deploy/secret.go b/pkg/deploy/secret.go index b3b9e3c2a5..3592b0ac64 100644 --- a/pkg/deploy/secret.go +++ b/pkg/deploy/secret.go @@ -105,10 +105,10 @@ func GetSpecSecret(cr *orgv1.CheCluster, name string, data map[string][]byte) *c // CreateTLSSecretFromRoute creates TLS secret with given name which contains certificates obtained from give url. // If the url is empty string, then router certificate will be obtained. // Works only on Openshift family infrastructures. -func CreateTLSSecretFromRoute(checluster *orgv1.CheCluster, url string, name string, clusterAPI ClusterAPI) (err error) { +func CreateTLSSecretFromRoute(checluster *orgv1.CheCluster, url string, name string, proxy *Proxy, clusterAPI ClusterAPI) (err error) { secret := &corev1.Secret{} if err := clusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: name, Namespace: checluster.Namespace}, secret); err != nil && errors.IsNotFound(err) { - crtBytes, err := GetEndpointTLSCrtBytes(checluster, url, clusterAPI) + crtBytes, err := GetEndpointTLSCrtBytes(checluster, url, proxy, clusterAPI) if err != nil { logrus.Errorf("Failed to extract certificate for secret %s. Failed to create a secret with a self signed crt: %s", name, err) return err diff --git a/pkg/deploy/tls.go b/pkg/deploy/tls.go index 143aa257e4..5ef9a5ec80 100644 --- a/pkg/deploy/tls.go +++ b/pkg/deploy/tls.go @@ -18,15 +18,12 @@ import ( "encoding/pem" stderrors "errors" "net/http" - "net/url" - "strings" "time" orgv1 "github.com/eclipse/che-operator/pkg/apis/org/v1" "github.com/eclipse/che-operator/pkg/util" routev1 "github.com/openshift/api/route/v1" "github.com/sirupsen/logrus" - "golang.org/x/net/http/httpproxy" batchv1 "k8s.io/api/batch/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" @@ -47,7 +44,7 @@ const ( ) // IsSelfSignedCertificateUsed detects whether endpoints are/should be secured by self-signed certificate. -func IsSelfSignedCertificateUsed(checluster *orgv1.CheCluster, clusterAPI ClusterAPI) (bool, error) { +func IsSelfSignedCertificateUsed(checluster *orgv1.CheCluster, proxy *Proxy, clusterAPI ClusterAPI) (bool, error) { if util.IsTestMode() { return true, nil } @@ -65,7 +62,7 @@ func IsSelfSignedCertificateUsed(checluster *orgv1.CheCluster, clusterAPI Cluste if util.IsOpenShift { // Get router TLS certificates chain - peerCertificates, err := GetEndpointTLSCrtChain(checluster, "", clusterAPI) + peerCertificates, err := GetEndpointTLSCrtChain(checluster, "", proxy, clusterAPI) if err != nil { return false, err } @@ -105,7 +102,7 @@ func IsSelfSignedCertificateUsed(checluster *orgv1.CheCluster, clusterAPI Cluste // GetEndpointTLSCrtChain retrieves TLS certificates chain from given endpoint. // If endpoint is not specified, then a test route will be created and used to get router certificates. -func GetEndpointTLSCrtChain(instance *orgv1.CheCluster, endpointURL string, clusterAPI ClusterAPI) ([]*x509.Certificate, error) { +func GetEndpointTLSCrtChain(instance *orgv1.CheCluster, endpointURL string, proxy *Proxy, clusterAPI ClusterAPI) ([]*x509.Certificate, error) { if util.IsTestMode() { return nil, stderrors.New("Not allowed for tests") } @@ -151,9 +148,9 @@ func GetEndpointTLSCrtChain(instance *orgv1.CheCluster, endpointURL string, clus // Adding the proxy settings to the Transport object transport := &http.Transport{} - if instance.Spec.Server.ProxyURL != "" { - logrus.Infof("Configuring proxy with %s to extract crt from the following URL: %s", instance.Spec.Server.ProxyURL, requestURL) - configureProxy(instance, transport) + if proxy.HttpProxy != "" { + logrus.Infof("Configuring proxy with %s to extract crt from the following URL: %s", proxy.HttpProxy, requestURL) + ConfigureProxy(instance, transport, proxy) } transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} client := &http.Client{ @@ -173,8 +170,8 @@ func GetEndpointTLSCrtChain(instance *orgv1.CheCluster, endpointURL string, clus // GetEndpointTLSCrtBytes creates a test TLS route and gets it to extract certificate chain // There's an easier way which is to read tls secret in default (3.11) or openshift-ingress (4.0) namespace // which however requires extra privileges for operator service account -func GetEndpointTLSCrtBytes(instance *orgv1.CheCluster, endpointURL string, clusterAPI ClusterAPI) (certificates []byte, err error) { - peerCertificates, err := GetEndpointTLSCrtChain(instance, endpointURL, clusterAPI) +func GetEndpointTLSCrtBytes(instance *orgv1.CheCluster, endpointURL string, proxy *Proxy, clusterAPI ClusterAPI) (certificates []byte, err error) { + peerCertificates, err := GetEndpointTLSCrtChain(instance, endpointURL, proxy, clusterAPI) if err != nil { if util.IsTestMode() { fakeCrt := make([]byte, 5) @@ -195,57 +192,6 @@ func GetEndpointTLSCrtBytes(instance *orgv1.CheCluster, endpointURL string, clus return certificates, nil } -func configureProxy(instance *orgv1.CheCluster, transport *http.Transport) { - proxyParts := strings.Split(instance.Spec.Server.ProxyURL, "://") - proxyProtocol := "" - proxyHost := "" - if len(proxyParts) == 1 { - proxyProtocol = "" - proxyHost = proxyParts[0] - } else { - proxyProtocol = proxyParts[0] - proxyHost = proxyParts[1] - - } - - proxyURL := proxyHost - if instance.Spec.Server.ProxyPort != "" { - proxyURL = proxyURL + ":" + instance.Spec.Server.ProxyPort - } - - proxyUser := instance.Spec.Server.ProxyUser - proxyPassword := instance.Spec.Server.ProxyPassword - proxySecret := instance.Spec.Server.ProxySecret - user, password, err := util.K8sclient.ReadSecret(proxySecret, instance.Namespace) - if err == nil { - proxyUser = user - proxyPassword = password - } else { - logrus.Errorf("Failed to read '%s' secret: %s", proxySecret, err) - } - if len(proxyUser) > 1 && len(proxyPassword) > 1 { - proxyURL = proxyUser + ":" + proxyPassword + "@" + proxyURL - } - - if proxyProtocol != "" { - proxyURL = proxyProtocol + "://" + proxyURL - } - config := httpproxy.Config{ - HTTPProxy: proxyURL, - HTTPSProxy: proxyURL, - NoProxy: strings.Replace(instance.Spec.Server.NonProxyHosts, "|", ",", -1), - } - proxyFunc := config.ProxyFunc() - transport.Proxy = func(r *http.Request) (*url.URL, error) { - theProxyURL, err := proxyFunc(r.URL) - if err != nil { - logrus.Warnf("Error when trying to get the proxy to access TLS endpoint URL: %s - %s", r.URL, err) - } - logrus.Infof("Using proxy: %s to access TLS endpoint URL: %s", theProxyURL, r.URL) - return theProxyURL, err - } -} - // K8sHandleCheTLSSecrets handles TLS secrets required for Che deployment on Kubernetes infrastructure. func K8sHandleCheTLSSecrets(checluster *orgv1.CheCluster, clusterAPI ClusterAPI) (reconcile.Result, error) { cheTLSSecretName := checluster.Spec.K8s.TlsSecretName diff --git a/pkg/util/util.go b/pkg/util/util.go index edf6296837..e8e00f51f2 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -243,62 +243,6 @@ func getClusterPublicHostnameForOpenshiftV4() (hostname string, err error) { return hostname, nil } -func GenerateProxyJavaOpts(proxyURL string, proxyPort string, nonProxyHosts string, proxyUser string, proxyPassword string, proxySecret string, namespace string) (javaOpts string, err error) { - if len(proxySecret) > 0 { - user, password, err := k8sclient.ReadSecret(proxySecret, namespace) - if err == nil { - proxyUser = user - proxyPassword = password - } else { - return "", err - } - } - - var proxyHost string - if strings.HasPrefix(proxyURL, "https://") { - proxyHost = strings.TrimPrefix(proxyURL, "https://") - } else if strings.HasPrefix(proxyURL, "http://") { - proxyHost = strings.TrimPrefix(proxyURL, "http://") - } else { - proxyHost = proxyURL - } - - proxyUserPassword := "" - if len(proxyUser) > 1 && len(proxyPassword) > 1 { - proxyUserPassword = - " -Dhttp.proxyUser=" + proxyUser + " -Dhttp.proxyPassword=" + proxyPassword + - " -Dhttps.proxyUser=" + proxyUser + " -Dhttps.proxyPassword=" + proxyPassword - } - javaOpts = - " -Dhttp.proxyHost=" + proxyHost + " -Dhttp.proxyPort=" + proxyPort + - " -Dhttps.proxyHost=" + proxyHost + " -Dhttps.proxyPort=" + proxyPort + - " -Dhttp.nonProxyHosts='" + nonProxyHosts + "'" + proxyUserPassword - return javaOpts, nil -} - -func GenerateProxyEnvs(proxyHost string, proxyPort string, nonProxyHosts string, proxyUser string, proxyPassword string, proxySecret string, namespace string) (proxyUrl string, noProxy string, err error) { - if len(proxySecret) > 0 { - user, password, err := k8sclient.ReadSecret(proxySecret, namespace) - if err == nil { - proxyUser = user - proxyPassword = password - } else { - return "", "", err - } - } - - proxyUrl = proxyHost + ":" + proxyPort - if len(proxyUser) > 1 && len(proxyPassword) > 1 { - protocol := strings.Split(proxyHost, "://")[0] - host := strings.Split(proxyHost, "://")[1] - proxyUrl = protocol + "://" + proxyUser + ":" + proxyPassword + "@" + host + ":" + proxyPort - } - - noProxy = strings.Replace(nonProxyHosts, "|", ",", -1) - - return proxyUrl, noProxy, nil -} - func GetDeploymentEnv(deployment *appsv1.Deployment, key string) (value string) { env := deployment.Spec.Template.Spec.Containers[0].Env for i := range env { diff --git a/pkg/util/util_test.go b/pkg/util/util_test.go index b8c574cc8d..989b230ea7 100644 --- a/pkg/util/util_test.go +++ b/pkg/util/util_test.go @@ -12,73 +12,10 @@ package util import ( - "os" "reflect" "testing" - - "github.com/sirupsen/logrus" -) - -const ( - proxyHost = "https://myproxy.com" - proxyPort = "1234" - nonProxyHosts = "localhost|myhost.com" - proxyUser = "user" - proxyPassword = "password" - expectedProxyURLWithUsernamePassword = "https://user:password@myproxy.com:1234" - expectedProxyURLWithoutUsernamePassword = "https://myproxy.com:1234" - expectedNoProxy = "localhost,myhost.com" ) -func TestGenerateProxyEnvs(t *testing.T) { - - proxyUrl, noProxy, _ := GenerateProxyEnvs(proxyHost, proxyPort, nonProxyHosts, proxyUser, proxyPassword, "", "") - - if !reflect.DeepEqual(proxyUrl, expectedProxyURLWithUsernamePassword) { - t.Errorf("Test failed. Expected %s but got %s", expectedProxyURLWithUsernamePassword, proxyUrl) - } - - if !reflect.DeepEqual(noProxy, expectedNoProxy) { - t.Errorf("Test failed. Expected %s but got %s", expectedNoProxy, noProxy) - - } - - proxyUrl, _, _ = GenerateProxyEnvs(proxyHost, proxyPort, nonProxyHosts, "", proxyPassword, "", "") - if !reflect.DeepEqual(proxyUrl, expectedProxyURLWithoutUsernamePassword) { - t.Errorf("Test failed. Expected %s but got %s", expectedProxyURLWithoutUsernamePassword, proxyUrl) - } - -} - -func TestGenerateProxyJavaOpts(t *testing.T) { - if err := os.Setenv("KUBERNETES_SERVICE_HOST", "172.30.0.1"); err != nil { - logrus.Errorf("Failed to set env %s", err) - } - - javaOpts, _ := GenerateProxyJavaOpts(proxyHost, proxyPort, nonProxyHosts, proxyUser, proxyPassword, "", "") - expectedJavaOpts := " -Dhttp.proxyHost=myproxy.com -Dhttp.proxyPort=1234 -Dhttps.proxyHost=myproxy.com " + - "-Dhttps.proxyPort=1234 -Dhttp.nonProxyHosts='localhost|myhost.com' -Dhttp.proxyUser=user " + - "-Dhttp.proxyPassword=password -Dhttps.proxyUser=user -Dhttps.proxyPassword=password" - if !reflect.DeepEqual(javaOpts, expectedJavaOpts) { - t.Errorf("Test failed. Expected '%s' but got '%s'", expectedJavaOpts, javaOpts) - } - - javaOpts, _ = GenerateProxyJavaOpts(proxyHost, proxyPort, nonProxyHosts, "", proxyPassword, "", "") - expectedJavaOptsWithoutUsernamePassword := " -Dhttp.proxyHost=myproxy.com -Dhttp.proxyPort=1234 -Dhttps.proxyHost=myproxy.com " + - "-Dhttps.proxyPort=1234 -Dhttp.nonProxyHosts='localhost|myhost.com'" - if !reflect.DeepEqual(javaOpts, expectedJavaOptsWithoutUsernamePassword) { - t.Errorf("Test failed. Expected '%s' but got '%s'", expectedJavaOptsWithoutUsernamePassword, javaOpts) - } - - javaOpts, _ = GenerateProxyJavaOpts("http://myproxy.com", proxyPort, nonProxyHosts, "", proxyPassword, "", "") - expectedJavaOptsWithoutUsernamePassword = " -Dhttp.proxyHost=myproxy.com -Dhttp.proxyPort=1234 -Dhttps.proxyHost=myproxy.com " + - "-Dhttps.proxyPort=1234 -Dhttp.nonProxyHosts='localhost|myhost.com'" - if !reflect.DeepEqual(javaOpts, expectedJavaOptsWithoutUsernamePassword) { - t.Errorf("Test failed. Expected '%s' but got '%s'", expectedJavaOptsWithoutUsernamePassword, javaOpts) - } - -} - func TestGeneratePasswd(t *testing.T) { chars := 12 passwd := GeneratePasswd(chars)