diff --git a/README.md b/README.md index 819520fe3d..49fdaa6308 100644 --- a/README.md +++ b/README.md @@ -83,16 +83,18 @@ Make sure your current user has cluster-admin privileges. ### TLS +TLS is enabled by default. +Turning it off is not recommended as it will cause malfunction of some components. + #### OpenShift -When using self-signed certificates make sure you set `server.selfSignedCert` to true -or create a secret called `self-signed-certificate` in a target namespace with ca.crt holding your OpenShift router crt body. -When `server.selfSignedCert` the operator will create a test TLS route, GET it, extract certificate chain, convert to a secret `self-signed-certificate`, -and Che/CRW server will automatically add it to Java trust store. +When the cluster is configured to use self-signed certificates for the router, the certificate will be automatically propogated to Che components as trusted. +If cluster router uses certificate signed by self-signed one, then parent/root CA certificate should be added into corresponding config map of additional trusted certificates (see `serverTrustStoreConfigMapName` option). #### K8S -When enabling TLS, make sure you create a secret with crt and key, and let the Operator know about it in `k8s.tlsSecretName` +By default self-signed certificates for Che will be generated automatically. +If it is needed to use own certificates, create `che-tls` secret (see `k8s.tlsSecretName` option) with `key.crt` and `tls.crt` fields. In case of self-signed certificate `self-signed-certificate` secret should be created with public part of CA certificate under `ca.crt` key in secret data. ## How to Configure diff --git a/deploy/crds/org_v1_che_cr.yaml b/deploy/crds/org_v1_che_cr.yaml index 96b9a0ff8f..980d6c864e 100644 --- a/deploy/crds/org_v1_che_cr.yaml +++ b/deploy/crds/org_v1_che_cr.yaml @@ -30,15 +30,12 @@ spec: # specifies a custom cluster role to user for the Che workspaces # Uses the default roles if left blank. cheWorkspaceClusterRole: '' - # when set to true the operator will attempt to get a secret in OpenShift router namespace - # to add it to Java trust store of Che server. Requires cluster-admin privileges for operator service account - selfSignedCert: false # Name of the config-map with public certificates to add to Java trust store of the Che server. serverTrustStoreConfigMapName: '' # 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. gitSelfSignedCert: false - # TLS mode for Che. Make sure you either have public cert, or set selfSignedCert to true + # TLS mode for Che. It is not recommended to turn this off. tlsSupport: true # protocol+hostname of a proxy server. Automatically added as JAVA_OPTS and https(s)_proxy # to Che server and workspaces containers diff --git a/deploy/crds/org_v1_che_crd.yaml b/deploy/crds/org_v1_che_crd.yaml index 5f06a7c026..2b88ce33d5 100644 --- a/deploy/crds/org_v1_che_crd.yaml +++ b/deploy/crds/org_v1_che_crd.yaml @@ -422,13 +422,9 @@ spec: a proxy is required (see also the `proxyURL` `proxySecret` fields). type: string selfSignedCert: - description: Enables the support of OpenShift clusters whose router - uses self-signed certificates. When enabled, the operator retrieves - the default self-signed certificate of OpenShift routes and adds - it to the Java trust store of the Che server. This is usually - required when activating the `tlsSupport` field on demo OpenShift - clusters that have not been setup with a valid certificate for - the routes. This is disabled by default. + 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. @@ -446,10 +442,9 @@ spec: its CA cert to be able to request it. This is disabled by default. type: string tlsSupport: - description: 'Instructs the operator to deploy Che in TLS mode, - ie with TLS routes or ingresses. This is disabled by default. - WARNING: Enabling TLS might require enabling the `selfSignedCert` - field also in some cases.' + 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 diff --git a/e2e/create.go b/e2e/create.go index 8bf2e83f22..ab29d87a1a 100644 --- a/e2e/create.go +++ b/e2e/create.go @@ -46,7 +46,7 @@ func createOperatorServiceAccountRole(operatorServiceAccountRole *rbac.Role) (er func createOperatorServiceAccountClusterRole(operatorServiceAccountClusterRole *rbac.ClusterRole) (err error) { operatorServiceAccountClusterRole, err = client.clientset.RbacV1().ClusterRoles().Create(operatorServiceAccountClusterRole) - if err != nil && ! errors.IsAlreadyExists(err) { + if err != nil && !errors.IsAlreadyExists(err) { logrus.Fatalf("Failed to create role %s: %s", operatorServiceAccountClusterRole.Name, err) return err } @@ -87,18 +87,16 @@ func deployOperator(deployment *appsv1.Deployment) (err error) { } -func newNamespace() (ns *corev1.Namespace){ +func newNamespace() (ns *corev1.Namespace) { return &corev1.Namespace{ - TypeMeta: metav1.TypeMeta{ - Kind: "Namespace", + Kind: "Namespace", APIVersion: corev1.SchemeGroupVersion.Version, }, ObjectMeta: metav1.ObjectMeta{ - Name:namespace, + Name: namespace, }, - } } @@ -110,7 +108,6 @@ func createNamespace(ns *corev1.Namespace) (err error) { return err } return nil - } func newCheCluster() (cr *orgv1.CheCluster) { @@ -121,10 +118,8 @@ func newCheCluster() (cr *orgv1.CheCluster) { TypeMeta: metav1.TypeMeta{ Kind: kind, }, - Spec:orgv1.CheClusterSpec{ - Server:orgv1.CheClusterSpecServer{ - SelfSignedCert: true, - }, + Spec: orgv1.CheClusterSpec{ + Server: orgv1.CheClusterSpecServer{}, }, } return cr diff --git a/olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/9.9.9-nightly.1592203276/eclipse-che-preview-kubernetes.crd.yaml b/olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/9.9.9-nightly.1592203276/eclipse-che-preview-kubernetes.crd.yaml new file mode 100644 index 0000000000..2b88ce33d5 --- /dev/null +++ b/olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/9.9.9-nightly.1592203276/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 `false`. + 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.1592203276/eclipse-che-preview-kubernetes.crd.yaml.diff b/olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/9.9.9-nightly.1592203276/eclipse-che-preview-kubernetes.crd.yaml.diff new file mode 100644 index 0000000000..3ef3403e60 --- /dev/null +++ b/olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/9.9.9-nightly.1592203276/eclipse-che-preview-kubernetes.crd.yaml.diff @@ -0,0 +1,33 @@ +--- /home/mmorhun/projects/go/src/github.com/eclipse/che-operator/olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/9.9.9-nightly.1591794793/eclipse-che-preview-kubernetes.crd.yaml 2020-06-15 09:11:07.460021934 +0300 ++++ /home/mmorhun/projects/go/src/github.com/eclipse/che-operator/olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/9.9.9-nightly.1592203276/eclipse-che-preview-kubernetes.crd.yaml 2020-06-15 09:41:17.221170801 +0300 +@@ -422,13 +422,9 @@ + a proxy is required (see also the `proxyURL` `proxySecret` fields). + type: string + selfSignedCert: +- description: Enables the support of OpenShift clusters whose router +- uses self-signed certificates. When enabled, the operator retrieves +- the default self-signed certificate of OpenShift routes and adds +- it to the Java trust store of the Che server. This is usually +- required when activating the `tlsSupport` field on demo OpenShift +- clusters that have not been setup with a valid certificate for +- the routes. This is disabled by default. ++ 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. +@@ -446,10 +442,9 @@ + its CA cert to be able to request it. This is disabled by default. + type: string + tlsSupport: +- description: 'Instructs the operator to deploy Che in TLS mode, +- ie with TLS routes or ingresses. This is disabled by default. +- WARNING: Enabling TLS might require enabling the `selfSignedCert` +- field also in some cases.' ++ 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 diff --git a/olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/9.9.9-nightly.1592203276/eclipse-che-preview-kubernetes.v9.9.9-nightly.1592203276.clusterserviceversion.yaml b/olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/9.9.9-nightly.1592203276/eclipse-che-preview-kubernetes.v9.9.9-nightly.1592203276.clusterserviceversion.yaml new file mode 100644 index 0000000000..189cf397d5 --- /dev/null +++ b/olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/9.9.9-nightly.1592203276/eclipse-che-preview-kubernetes.v9.9.9-nightly.1592203276.clusterserviceversion.yaml @@ -0,0 +1,398 @@ +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 + } + } + } + ] + capabilities: Seamless Upgrades + categories: Developer Tools + certified: "false" + containerImage: quay.io/eclipse/che-operator:nightly + createdAt: "2020-06-15T06:41:17Z" + 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.1592203276 + 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: 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 + 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: IMAGE_default_che_server + value: quay.io/eclipse/che-server:nightly + - name: IMAGE_default_plugin_registry + value: quay.io/eclipse/che-plugin-registry:nightly + - name: IMAGE_default_devfile_registry + value: quay.io/eclipse/che-devfile-registry:nightly + - name: IMAGE_default_che_tls_secrets_creation_job + value: quay.io/eclipse/che-tls-secret-creator:alpine-3029769 + - name: IMAGE_default_pvc_jobs + value: registry.access.redhat.com/ubi8-minimal:8.2-267 + - name: IMAGE_default_postgres + value: centos/postgresql-96-centos7:9.6 + - name: IMAGE_default_keycloak + value: quay.io/eclipse/che-keycloak:nightly + - name: IMAGE_default_che_workspace_plugin_broker_metadata + value: quay.io/eclipse/che-plugin-metadata-broker:v3.2.0 + - name: IMAGE_default_che_workspace_plugin_broker_artifacts + value: quay.io/eclipse/che-plugin-artifacts-broker:v3.2.0 + - name: IMAGE_default_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 + 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.1591794793 + version: 9.9.9-nightly.1592203276 diff --git a/olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/9.9.9-nightly.1592203276/eclipse-che-preview-kubernetes.v9.9.9-nightly.1592203276.clusterserviceversion.yaml.diff b/olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/9.9.9-nightly.1592203276/eclipse-che-preview-kubernetes.v9.9.9-nightly.1592203276.clusterserviceversion.yaml.diff new file mode 100644 index 0000000000..780a2f0517 --- /dev/null +++ b/olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/9.9.9-nightly.1592203276/eclipse-che-preview-kubernetes.v9.9.9-nightly.1592203276.clusterserviceversion.yaml.diff @@ -0,0 +1,25 @@ +--- /home/mmorhun/projects/go/src/github.com/eclipse/che-operator/olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/9.9.9-nightly.1591794793/eclipse-che-preview-kubernetes.v9.9.9-nightly.1591794793.clusterserviceversion.yaml 2020-06-15 09:11:07.460021934 +0300 ++++ /home/mmorhun/projects/go/src/github.com/eclipse/che-operator/olm/eclipse-che-preview-kubernetes/deploy/olm-catalog/eclipse-che-preview-kubernetes/9.9.9-nightly.1592203276/eclipse-che-preview-kubernetes.v9.9.9-nightly.1592203276.clusterserviceversion.yaml 2020-06-15 09:41:17.218170783 +0300 +@@ -49,12 +49,12 @@ + categories: Developer Tools + certified: "false" + containerImage: quay.io/eclipse/che-operator:nightly +- createdAt: "2020-06-10T13:13:13Z" ++ createdAt: "2020-06-15T06:41:17Z" + 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.1591794793 ++ name: eclipse-che-preview-kubernetes.v9.9.9-nightly.1592203276 + namespace: placeholder + spec: + apiservicedefinitions: {} +@@ -394,5 +394,5 @@ + maturity: stable + provider: + name: Eclipse Foundation +- replaces: eclipse-che-preview-kubernetes.v9.9.9-nightly.1591355178 +- version: 9.9.9-nightly.1591794793 ++ replaces: eclipse-che-preview-kubernetes.v9.9.9-nightly.1591794793 ++ version: 9.9.9-nightly.1592203276 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 ece3af5b3f..a3337137c9 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.1591794793 +- currentCSV: eclipse-che-preview-kubernetes.v9.9.9-nightly.1592203276 name: nightly - currentCSV: eclipse-che-preview-kubernetes.v7.14.2 name: stable diff --git a/olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/9.9.9-nightly.1592203277/eclipse-che-preview-openshift.crd.yaml b/olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/9.9.9-nightly.1592203277/eclipse-che-preview-openshift.crd.yaml new file mode 100644 index 0000000000..2b88ce33d5 --- /dev/null +++ b/olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/9.9.9-nightly.1592203277/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 `false`. + 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.1592203277/eclipse-che-preview-openshift.crd.yaml.diff b/olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/9.9.9-nightly.1592203277/eclipse-che-preview-openshift.crd.yaml.diff new file mode 100644 index 0000000000..6b8d7f10b3 --- /dev/null +++ b/olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/9.9.9-nightly.1592203277/eclipse-che-preview-openshift.crd.yaml.diff @@ -0,0 +1,33 @@ +--- /home/mmorhun/projects/go/src/github.com/eclipse/che-operator/olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/9.9.9-nightly.1591794794/eclipse-che-preview-openshift.crd.yaml 2020-06-15 09:11:07.462021947 +0300 ++++ /home/mmorhun/projects/go/src/github.com/eclipse/che-operator/olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/9.9.9-nightly.1592203277/eclipse-che-preview-openshift.crd.yaml 2020-06-15 09:41:17.400171852 +0300 +@@ -422,13 +422,9 @@ + a proxy is required (see also the `proxyURL` `proxySecret` fields). + type: string + selfSignedCert: +- description: Enables the support of OpenShift clusters whose router +- uses self-signed certificates. When enabled, the operator retrieves +- the default self-signed certificate of OpenShift routes and adds +- it to the Java trust store of the Che server. This is usually +- required when activating the `tlsSupport` field on demo OpenShift +- clusters that have not been setup with a valid certificate for +- the routes. This is disabled by default. ++ 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. +@@ -446,10 +442,9 @@ + its CA cert to be able to request it. This is disabled by default. + type: string + tlsSupport: +- description: 'Instructs the operator to deploy Che in TLS mode, +- ie with TLS routes or ingresses. This is disabled by default. +- WARNING: Enabling TLS might require enabling the `selfSignedCert` +- field also in some cases.' ++ 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 diff --git a/olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/9.9.9-nightly.1592203277/eclipse-che-preview-openshift.v9.9.9-nightly.1592203277.clusterserviceversion.yaml b/olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/9.9.9-nightly.1592203277/eclipse-che-preview-openshift.v9.9.9-nightly.1592203277.clusterserviceversion.yaml new file mode 100644 index 0000000000..c5280b7435 --- /dev/null +++ b/olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/9.9.9-nightly.1592203277/eclipse-che-preview-openshift.v9.9.9-nightly.1592203277.clusterserviceversion.yaml @@ -0,0 +1,442 @@ +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 + } + } + } + ] + capabilities: Seamless Upgrades + categories: Developer Tools, OpenShift Optional + certified: "false" + containerImage: quay.io/eclipse/che-operator:nightly + createdAt: "2020-06-15T06:41:17Z" + 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.1592203277 + 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: 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 + 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 + verbs: + - get + - 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: IMAGE_default_che_server + value: quay.io/eclipse/che-server:nightly + - name: IMAGE_default_plugin_registry + value: quay.io/eclipse/che-plugin-registry:nightly + - name: IMAGE_default_devfile_registry + value: quay.io/eclipse/che-devfile-registry:nightly + - name: IMAGE_default_pvc_jobs + value: registry.access.redhat.com/ubi8-minimal:8.2-267 + - name: IMAGE_default_postgres + value: centos/postgresql-96-centos7:9.6 + - name: IMAGE_default_keycloak + value: quay.io/eclipse/che-keycloak:nightly + - name: IMAGE_default_che_workspace_plugin_broker_metadata + value: quay.io/eclipse/che-plugin-metadata-broker:v3.2.0 + - name: IMAGE_default_che_workspace_plugin_broker_artifacts + value: quay.io/eclipse/che-plugin-artifacts-broker:v3.2.0 + - name: IMAGE_default_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 + 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.1591794794 + version: 9.9.9-nightly.1592203277 diff --git a/olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/9.9.9-nightly.1592203277/eclipse-che-preview-openshift.v9.9.9-nightly.1592203277.clusterserviceversion.yaml.diff b/olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/9.9.9-nightly.1592203277/eclipse-che-preview-openshift.v9.9.9-nightly.1592203277.clusterserviceversion.yaml.diff new file mode 100644 index 0000000000..eea3a723e3 --- /dev/null +++ b/olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/9.9.9-nightly.1592203277/eclipse-che-preview-openshift.v9.9.9-nightly.1592203277.clusterserviceversion.yaml.diff @@ -0,0 +1,25 @@ +--- /home/mmorhun/projects/go/src/github.com/eclipse/che-operator/olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/9.9.9-nightly.1591794794/eclipse-che-preview-openshift.v9.9.9-nightly.1591794794.clusterserviceversion.yaml 2020-06-15 09:11:07.463021953 +0300 ++++ /home/mmorhun/projects/go/src/github.com/eclipse/che-operator/olm/eclipse-che-preview-openshift/deploy/olm-catalog/eclipse-che-preview-openshift/9.9.9-nightly.1592203277/eclipse-che-preview-openshift.v9.9.9-nightly.1592203277.clusterserviceversion.yaml 2020-06-15 09:41:18.389177661 +0300 +@@ -46,12 +46,12 @@ + categories: Developer Tools, OpenShift Optional + certified: "false" + containerImage: quay.io/eclipse/che-operator:nightly +- createdAt: "2020-06-10T13:13:14Z" ++ createdAt: "2020-06-15T06:41:17Z" + 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.1591794794 ++ name: eclipse-che-preview-openshift.v9.9.9-nightly.1592203277 + namespace: placeholder + spec: + apiservicedefinitions: {} +@@ -438,5 +438,5 @@ + maturity: stable + provider: + name: Eclipse Foundation +- replaces: eclipse-che-preview-openshift.v9.9.9-nightly.1591355180 +- version: 9.9.9-nightly.1591794794 ++ replaces: eclipse-che-preview-openshift.v9.9.9-nightly.1591794794 ++ version: 9.9.9-nightly.1592203277 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 9e38f3438a..799f02c561 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.1591794794 +- currentCSV: eclipse-che-preview-openshift.v9.9.9-nightly.1592203277 name: nightly - currentCSV: eclipse-che-preview-openshift.v7.14.2 name: stable diff --git a/pkg/apis/org/v1/che_types.go b/pkg/apis/org/v1/che_types.go index c8d1450a69..fc7e7c1f5a 100644 --- a/pkg/apis/org/v1/che_types.go +++ b/pkg/apis/org/v1/che_types.go @@ -109,12 +109,9 @@ type CheClusterSpecServer struct { // It's NOT RECOMMENDED to configured true without OAuth configured. This property is also used by the OpenShift infra. // +optional AllowUserDefinedWorkspaceNamespaces bool `json:"allowUserDefinedWorkspaceNamespaces"` - // Enables the support of OpenShift clusters whose router uses self-signed certificates. - // When enabled, the operator retrieves the default self-signed certificate of OpenShift routes - // and adds it to the Java trust store of the Che server. - // This is usually required when activating the `tlsSupport` field on demo OpenShift clusters - // that have not been setup with a valid certificate for the routes. - // This is disabled by default. + // 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. // +optional SelfSignedCert bool `json:"selfSignedCert"` // Name of the config-map with public certificates @@ -130,9 +127,10 @@ type CheClusterSpecServer struct { // configuration for Git. // +optional GitSelfSignedCert bool `json:"gitSelfSignedCert"` - // Instructs the operator to deploy Che in TLS mode, ie with TLS routes or ingresses. - // This is disabled by default. - // WARNING: Enabling TLS might require enabling the `selfSignedCert` field also in some cases. + // Deprecated. + // Instructs the operator to deploy Che in TLS mode. + // This is enabled by default. + // Disabling TLS may cause malfunction of some Che components. // +optional TlsSupport bool `json:"tlsSupport"` // Public URL of the Devfile registry, that serves sample, ready-to-use devfiles. @@ -475,7 +473,7 @@ type CheCluster struct { // 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. - Spec CheClusterSpec `json:"spec,omitempty"` + Spec CheClusterSpec `json:"spec,omitempty"` // CheClusterStatus defines the observed state of Che installation Status CheClusterStatus `json:"status,omitempty"` diff --git a/pkg/apis/org/v1/zz_generated.openapi.go b/pkg/apis/org/v1/zz_generated.openapi.go index 75ce963726..f8e9e9091e 100644 --- a/pkg/apis/org/v1/zz_generated.openapi.go +++ b/pkg/apis/org/v1/zz_generated.openapi.go @@ -457,7 +457,7 @@ func schema_pkg_apis_org_v1_CheClusterSpecServer(ref common.ReferenceCallback) c }, "selfSignedCert": { SchemaProps: spec.SchemaProps{ - Description: "Enables the support of OpenShift clusters whose router uses self-signed certificates. When enabled, the operator retrieves the default self-signed certificate of OpenShift routes and adds it to the Java trust store of the Che server. This is usually required when activating the `tlsSupport` field on demo OpenShift clusters that have not been setup with a valid certificate for the routes. This is disabled by default.", + 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: []string{"boolean"}, Format: "", }, @@ -478,7 +478,7 @@ func schema_pkg_apis_org_v1_CheClusterSpecServer(ref common.ReferenceCallback) c }, "tlsSupport": { SchemaProps: spec.SchemaProps{ - Description: "Instructs the operator to deploy Che in TLS mode, ie with TLS routes or ingresses. This is disabled by default. WARNING: Enabling TLS might require enabling the `selfSignedCert` field also in some cases.", + 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: []string{"boolean"}, Format: "", }, diff --git a/pkg/controller/che/che_controller.go b/pkg/controller/che/che_controller.go index 1e4f7d5653..52306aec94 100644 --- a/pkg/controller/che/che_controller.go +++ b/pkg/controller/che/che_controller.go @@ -13,14 +13,9 @@ package che import ( "context" - "crypto/tls" - "encoding/pem" "fmt" - "net/http" - "net/url" "reflect" "strconv" - "strings" "time" orgv1 "github.com/eclipse/che-operator/pkg/apis/org/v1" @@ -32,7 +27,6 @@ import ( routev1 "github.com/openshift/api/route/v1" userv1 "github.com/openshift/api/user/v1" "github.com/sirupsen/logrus" - "golang.org/x/net/http/httpproxy" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" "k8s.io/api/extensions/v1beta1" @@ -313,22 +307,68 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e } } - // Handle Che TLS certificates on Kubernetes like infrastructures - if instance.Spec.Server.TlsSupport && instance.Spec.Server.SelfSignedCert && !isOpenShift { + cheFlavor := deploy.DefaultCheFlavor(instance) + cheDeploymentName := cheFlavor + + if !isOpenShift && instance.Spec.Server.TlsSupport { // Ensure TLS configuration is correct - if err := CheckAndUpdateTLSConfiguration(instance, clusterAPI); err != nil { + if err := deploy.CheckAndUpdateK8sTLSConfiguration(instance, clusterAPI); err != nil { instance, _ = r.GetCR(request) return reconcile.Result{Requeue: true, RequeueAfter: time.Second * 1}, err } + } + + // Detect whether self-signed certificate is used + selfSignedCertUsed, err := deploy.IsSelfSignedCertificateUsed(instance, clusterAPI) + if err != nil { + logrus.Errorf("Failed to detect if self-signed certificate used. Cause: %v", err) + return reconcile.Result{}, err + } + + if isOpenShift { + // create a secret with router tls cert when on OpenShift infra and router is configured with a self signed certificate + if selfSignedCertUsed || + // To use Openshift v4 OAuth, the OAuth endpoints are served from a namespace + // 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 { + return reconcile.Result{}, err + } + } - // Create TLS secrets if needed - result, err := HandleCheTLSSecrets(instance, clusterAPI) - if result.Requeue || result.RequeueAfter > 0 { + if !tests { + deployment := &appsv1.Deployment{} + err = r.client.Get(context.TODO(), types.NamespacedName{Name: cheDeploymentName, Namespace: instance.Namespace}, deployment) + if err != nil && instance.Status.CheClusterRunning != UnavailableStatus { + if err := r.SetCheUnavailableStatus(instance, request); err != nil { + return reconcile.Result{Requeue: true, RequeueAfter: time.Second * 1}, err + } + } + } + + if instance.Spec.Auth.OpenShiftoAuth { + // create a secret with OpenShift API crt to be added to keystore that RH SSO will consume + baseURL, err := util.GetClusterPublicHostname(isOpenShift4) if err != nil { - logrus.Error(err) + 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 { + return reconcile.Result{}, err + } } - if !tests { - return result, err + } + } else { + // Handle Che TLS certificates on Kubernetes infrastructure + if instance.Spec.Server.TlsSupport { + result, err := deploy.K8sHandleCheTLSSecrets(instance, clusterAPI) + if result.Requeue || result.RequeueAfter > 0 { + if err != nil { + logrus.Error(err) + } + if !tests { + return result, err + } } } } @@ -392,43 +432,6 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e return reconcile.Result{Requeue: true}, nil } - cheFlavor := deploy.DefaultCheFlavor(instance) - cheDeploymentName := cheFlavor - if isOpenShift { - // create a secret with router tls cert when on OpenShift infra and router is configured with a self signed certificate - if instance.Spec.Server.SelfSignedCert || - // To use Openshift v4 OAuth, the OAuth endpoints are served from a namespace - // 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 := r.CreateTLSSecret(instance, "", "self-signed-certificate", clusterAPI); err != nil { - return reconcile.Result{}, err - } - } - - if !tests { - deployment := &appsv1.Deployment{} - err = r.client.Get(context.TODO(), types.NamespacedName{Name: cheDeploymentName, Namespace: instance.Namespace}, deployment) - if err != nil && instance.Status.CheClusterRunning != UnavailableStatus { - if err := r.SetCheUnavailableStatus(instance, request); err != nil { - return reconcile.Result{Requeue: true, RequeueAfter: time.Second * 1}, err - } - } - } - - if instance.Spec.Auth.OpenShiftoAuth { - // create a secret with OpenShift API crt to be added to keystore that RH SSO will consume - baseURL, err := util.GetClusterPublicHostname(isOpenShift4) - 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 := r.CreateTLSSecret(instance, baseURL, "openshift-api-crt", clusterAPI); err != nil { - return reconcile.Result{}, err - } - } - } - } - if err := r.SetStatusDetails(instance, request, "", "", ""); err != nil { return reconcile.Result{}, err } @@ -530,7 +533,7 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e } } - if err := r.GenerateAndSaveFields(instance, request); err != nil { + if err := r.GenerateAndSaveFields(instance, request, clusterAPI); err != nil { instance, _ = r.GetCR(request) return reconcile.Result{Requeue: true, RequeueAfter: time.Second * 1}, err } @@ -1246,121 +1249,6 @@ func createConsoleLink(isOpenShift4 bool, protocol string, instance *orgv1.CheCl } } -// GetEndpointTlsCrt 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 (r *ReconcileChe) GetEndpointTlsCrt(instance *orgv1.CheCluster, endpointUrl string, clusterAPI deploy.ClusterAPI) (certificate []byte, err error) { - var requestURL string - var routeStatus deploy.RouteProvisioningStatus - - if len(endpointUrl) < 1 { - for wait := true; wait; { - routeStatus = deploy.SyncRouteToCluster(instance, "test", "test", 8080, clusterAPI) - if routeStatus.Err != nil { - return nil, routeStatus.Err - } - wait = !routeStatus.Continue || len(routeStatus.Route.Spec.Host) == 0 - time.Sleep(time.Duration(1) * time.Second) - } - - requestURL = "https://" + routeStatus.Route.Spec.Host - - } else { - requestURL = endpointUrl - } - - //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) - r.configureProxy(instance, transport) - } - - transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} - client := &http.Client{ - Transport: transport, - } - req, err := http.NewRequest("GET", requestURL, nil) - resp, err := client.Do(req) - if err != nil { - logrus.Errorf("An error occurred when reaching test TLS route: %s", err) - if r.tests { - fakeCrt := make([]byte, 5) - return fakeCrt, nil - } - return nil, err - } - - for i := range resp.TLS.PeerCertificates { - cert := resp.TLS.PeerCertificates[i].Raw - crt := pem.EncodeToMemory(&pem.Block{ - Type: "CERTIFICATE", - Bytes: cert, - }) - certificate = append(certificate, crt...) - } - - if routeStatus.Route != nil { - logrus.Infof("Deleting a test route %s to extract routes crt", routeStatus.Route.Name) - if err := r.client.Delete(context.TODO(), routeStatus.Route); err != nil { - logrus.Errorf("Failed to delete test route %s: %s", routeStatus.Route.Name, err) - } - } - return certificate, nil -} - -func (r *ReconcileChe) 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 - } -} - func hasConsolelinkObject() bool { resourceList, err := util.GetServerResources() if err != nil { diff --git a/pkg/controller/che/create.go b/pkg/controller/che/create.go index c4843cb165..f4dcc49f00 100644 --- a/pkg/controller/che/create.go +++ b/pkg/controller/che/create.go @@ -20,36 +20,11 @@ import ( "github.com/eclipse/che-operator/pkg/util" oauth "github.com/openshift/api/oauth/v1" "github.com/sirupsen/logrus" - corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/reconcile" ) -func (r *ReconcileChe) CreateNewSecret(instance *orgv1.CheCluster, secret *corev1.Secret) error { - if err := controllerutil.SetControllerReference(instance, secret, r.scheme); err != nil { - logrus.Errorf("An error occurred: %s", err) - return err - } - deploymentFound := &corev1.Secret{} - err := r.client.Get(context.TODO(), types.NamespacedName{Name: secret.Name, Namespace: secret.Namespace}, deploymentFound) - if err != nil && errors.IsNotFound(err) { - logrus.Infof("Creating a new object: %s, name: %s", secret.Kind, secret.Name) - err = r.client.Create(context.TODO(), secret) - if err != nil { - logrus.Errorf("Failed to create %s %s: %s", secret.Kind, secret.Name, err) - return err - } - return nil - } else if err != nil { - logrus.Errorf("An error occurred: %s", err) - - return err - } - return nil -} - func (r *ReconcileChe) CreateNewOauthClient(instance *orgv1.CheCluster, oAuthClient *oauth.OAuthClient) error { oAuthClientFound := &oauth.OAuthClient{} err := r.client.Get(context.TODO(), types.NamespacedName{Name: oAuthClient.Name, Namespace: oAuthClient.Namespace}, oAuthClientFound) @@ -123,40 +98,7 @@ func (r *ReconcileChe) CreateIdentityProviderItems(instance *orgv1.CheCluster, r return nil } -func (r *ReconcileChe) CreateSecret(instance *orgv1.CheCluster, m map[string][]byte, name string) (err error) { - secret := &corev1.Secret{} - if err := r.client.Get(context.TODO(), types.NamespacedName{Name: name, Namespace: instance.Namespace}, secret); err != nil && errors.IsNotFound(err) { - secret := deploy.NewSecret(instance, name, m) - if err := r.CreateNewSecret(instance, secret); err != nil { - return err - } - } - - return nil -} - -func (r *ReconcileChe) CreateTLSSecret(instance *orgv1.CheCluster, url string, name string, clusterAPI deploy.ClusterAPI) (err error) { - // create a secret with either router tls cert (or OpenShift API crt) when on OpenShift infra - // and router is configured with a self signed certificate - // this secret is used by CRW server to reach RH SSO TLS endpoint - secret := &corev1.Secret{} - if err := r.client.Get(context.TODO(), types.NamespacedName{Name: name, Namespace: instance.Namespace}, secret); err != nil && errors.IsNotFound(err) { - crt, err := r.GetEndpointTlsCrt(instance, url, clusterAPI) - if err != nil { - logrus.Errorf("Failed to extract crt for secret %s. Failed to create a secret with a self signed crt: %s", name, err) - return err - } else { - secret := deploy.NewSecret(instance, name, map[string][]byte{"ca.crt": crt}) - if err := r.CreateNewSecret(instance, secret); err != nil { - return err - } - } - } - - return nil -} - -func (r *ReconcileChe) GenerateAndSaveFields(instance *orgv1.CheCluster, request reconcile.Request) (err error) { +func (r *ReconcileChe) GenerateAndSaveFields(instance *orgv1.CheCluster, request reconcile.Request, clusterAPI deploy.ClusterAPI) (err error) { cheFlavor := deploy.DefaultCheFlavor(instance) if len(instance.Spec.Server.CheFlavor) < 1 { instance.Spec.Server.CheFlavor = cheFlavor @@ -170,7 +112,7 @@ func (r *ReconcileChe) GenerateAndSaveFields(instance *orgv1.CheCluster, request if len(instance.Spec.Database.ChePostgresSecret) < 1 { if len(instance.Spec.Database.ChePostgresUser) < 1 || len(instance.Spec.Database.ChePostgresPassword) < 1 { chePostgresSecret := deploy.DefaultChePostgresSecret() - r.CreateSecret(instance, map[string][]byte{"user": []byte(deploy.DefaultChePostgresUser), "password": []byte(util.GeneratePasswd(12))}, chePostgresSecret) + deploy.SyncSecretToCluster(instance, chePostgresSecret, map[string][]byte{"user": []byte(deploy.DefaultChePostgresUser), "password": []byte(util.GeneratePasswd(12))}, clusterAPI) instance.Spec.Database.ChePostgresSecret = chePostgresSecret if err := r.UpdateCheCRSpec(instance, "Postgres Secret", chePostgresSecret); err != nil { return err @@ -201,7 +143,7 @@ func (r *ReconcileChe) GenerateAndSaveFields(instance *orgv1.CheCluster, request if len(instance.Spec.Auth.IdentityProviderPostgresPassword) < 1 { identityPostgresSecret := deploy.DefaultCheIdentityPostgresSecret() - r.CreateSecret(instance, map[string][]byte{"password": []byte(keycloakPostgresPassword)}, identityPostgresSecret) + deploy.SyncSecretToCluster(instance, identityPostgresSecret, map[string][]byte{"password": []byte(keycloakPostgresPassword)}, clusterAPI) instance.Spec.Auth.IdentityProviderPostgresSecret = identityPostgresSecret if err := r.UpdateCheCRSpec(instance, "Identity Provider Postgres Secret", identityPostgresSecret); err != nil { return err @@ -223,7 +165,7 @@ func (r *ReconcileChe) GenerateAndSaveFields(instance *orgv1.CheCluster, request if len(instance.Spec.Auth.IdentityProviderAdminUserName) < 1 || len(instance.Spec.Auth.IdentityProviderPassword) < 1 { identityProviderSecret := deploy.DefaultCheIdentitySecret() - r.CreateSecret(instance, map[string][]byte{"user": []byte(keycloakAdminUserName), "password": []byte(keycloakAdminPassword)}, identityProviderSecret) + deploy.SyncSecretToCluster(instance, identityProviderSecret, map[string][]byte{"user": []byte(keycloakAdminUserName), "password": []byte(keycloakAdminPassword)}, clusterAPI) instance.Spec.Auth.IdentityProviderSecret = identityProviderSecret if err := r.UpdateCheCRSpec(instance, "Identity Provider Secret", identityProviderSecret); err != nil { return err diff --git a/pkg/controller/che/tls-secrets.go b/pkg/controller/che/tls-secrets.go deleted file mode 100644 index d4f3ce6b9f..0000000000 --- a/pkg/controller/che/tls-secrets.go +++ /dev/null @@ -1,264 +0,0 @@ -// -// 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" - "time" - - "github.com/eclipse/che-operator/pkg/util" - - orgv1 "github.com/eclipse/che-operator/pkg/apis/org/v1" - "github.com/eclipse/che-operator/pkg/deploy" - "github.com/sirupsen/logrus" - batchv1 "k8s.io/api/batch/v1" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - "sigs.k8s.io/controller-runtime/pkg/reconcile" -) - -const ( - CheTLSJobServiceAccountName = "che-tls-job-service-account" - CheTLSJobRoleName = "che-tls-job-role" - CheTLSJobRoleBindingName = "che-tls-job-role-binding" - CheTLSJobName = "che-tls-job" - CheTlsJobComponentName = "che-create-tls-secret-job" - CheTLSSelfSignedCertificateSecretName = "self-signed-certificate" -) - -// HandleCheTLSSecrets handles TLS secrets required for Che deployment -func HandleCheTLSSecrets(checluster *orgv1.CheCluster, clusterAPI deploy.ClusterAPI) (reconcile.Result, error) { - cheTLSSecretName := checluster.Spec.K8s.TlsSecretName - - // ===== Check Che TLS certificate ===== // - cheTLSSecret := &corev1.Secret{} - err := clusterAPI.Client.Get(context.TODO(), types.NamespacedName{Namespace: checluster.Namespace, Name: cheTLSSecretName}, cheTLSSecret) - if err != nil { - if !errors.IsNotFound(err) { - // Error reading secret info - logrus.Errorf("Error getting Che TLS secert \"%s\": %v", cheTLSSecretName, err) - return reconcile.Result{RequeueAfter: time.Second}, err - } - - // Che TLS secret doesn't exist, generate a new one - - // Remove Che CA certificate secret if any - cheCASelfSignedCertificateSecret := &corev1.Secret{} - err = clusterAPI.Client.Get(context.TODO(), types.NamespacedName{Namespace: checluster.Namespace, Name: CheTLSSelfSignedCertificateSecretName}, cheCASelfSignedCertificateSecret) - if err != nil { - if !errors.IsNotFound(err) { - // Error reading secret info - logrus.Errorf("Error getting Che self-signed certificate secert \"%s\": %v", CheTLSSelfSignedCertificateSecretName, err) - return reconcile.Result{RequeueAfter: time.Second}, err - } - // Che CA certificate doesn't exists (that's expected at this point), do nothing - } else { - // Remove Che CA secret because Che TLS secret is missing (they should be generated together). - if err = clusterAPI.Client.Delete(context.TODO(), cheCASelfSignedCertificateSecret); err != nil { - logrus.Errorf("Error deleting Che self-signed certificate secret \"%s\": %v", CheTLSSelfSignedCertificateSecretName, err) - return reconcile.Result{RequeueAfter: time.Second}, err - } - } - - // Prepare permissions for the certificate generation job - sa, err := deploy.SyncServiceAccountToCluster(checluster, CheTLSJobServiceAccountName, clusterAPI) - if sa == nil { - return reconcile.Result{RequeueAfter: time.Second}, err - } - - role, err := deploy.SyncRoleToCluster(checluster, CheTLSJobRoleName, []string{"secrets"}, []string{"create"}, clusterAPI) - if role == nil { - return reconcile.Result{RequeueAfter: time.Second}, err - } - - roleBiding, err := deploy.SyncRoleBindingToCluster(checluster, CheTLSJobRoleBindingName, CheTLSJobServiceAccountName, CheTLSJobRoleName, "Role", clusterAPI) - if roleBiding == nil { - return reconcile.Result{RequeueAfter: time.Second}, err - } - - cheTLSSecretsCreationJobImage := deploy.DefaultCheTLSSecretsCreationJobImage() - jobEnvVars := map[string]string{ - "DOMAIN": checluster.Spec.K8s.IngressDomain, - "CHE_NAMESPACE": checluster.Namespace, - "CHE_SERVER_TLS_SECRET_NAME": cheTLSSecretName, - "CHE_CA_CERTIFICATE_SECRET_NAME": CheTLSSelfSignedCertificateSecretName, - } - job, err := deploy.SyncJobToCluster(checluster, CheTLSJobName, CheTlsJobComponentName, cheTLSSecretsCreationJobImage, CheTLSJobServiceAccountName, jobEnvVars, clusterAPI) - if err != nil { - logrus.Error(err) - return reconcile.Result{RequeueAfter: time.Second}, err - } - if job == nil || job.Status.Succeeded == 0 { - logrus.Infof("Waiting on job '%s' to be finished", CheTLSJobName) - return reconcile.Result{RequeueAfter: time.Second}, err - } - } - - // cleanup job - job := &batchv1.Job{} - err = clusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: CheTLSJobName, Namespace: checluster.Namespace}, job) - if err != nil && !errors.IsNotFound(err) { - // Failed to get the job - return reconcile.Result{RequeueAfter: time.Second}, err - } - if err == nil { - // The job object is present - if job.Status.Succeeded > 0 { - logrus.Infof("Import public part of Eclipse Che self-signed CA certificvate from \"%s\" secret into your browser.", CheTLSSelfSignedCertificateSecretName) - deleteJob(job, checluster, clusterAPI) - } else if job.Status.Failed > 0 { - // The job failed, but the certificate is present, shouldn't happen - deleteJob(job, checluster, clusterAPI) - return reconcile.Result{}, nil - } - // Job hasn't reported finished status yet, wait more - return reconcile.Result{RequeueAfter: time.Second}, nil - } - - // Che TLS certificate exists, check for required data fields - if !isCheTLSSecretValid(cheTLSSecret) { - // The secret is invalid because required field(s) missing. - logrus.Infof("Che TLS secret \"%s\" is invalid. Recreating...", cheTLSSecretName) - // Delete old invalid secret - if err = clusterAPI.Client.Delete(context.TODO(), cheTLSSecret); err != nil { - logrus.Errorf("Error deleting Che TLS secret \"%s\": %v", cheTLSSecretName, err) - return reconcile.Result{RequeueAfter: time.Second}, err - } - // Recreate the secret - return reconcile.Result{RequeueAfter: time.Second}, err - } - - // Check owner reference - if cheTLSSecret.ObjectMeta.OwnerReferences == nil { - // Set owner Che cluster as Che TLS secret owner - if err := controllerutil.SetControllerReference(checluster, cheTLSSecret, clusterAPI.Scheme); err != nil { - logrus.Errorf("Failed to set owner for Che TLS secret \"%s\". Error: %s", cheTLSSecretName, err) - return reconcile.Result{RequeueAfter: time.Second}, err - } - if err := clusterAPI.Client.Update(context.TODO(), cheTLSSecret); err != nil { - logrus.Errorf("Failed to update owner for Che TLS secret \"%s\". Error: %s", cheTLSSecretName, err) - return reconcile.Result{RequeueAfter: time.Second}, err - } - } - - // ===== Check Che CA certificate ===== // - - cheTLSSelfSignedCertificateSecret := &corev1.Secret{} - err = clusterAPI.Client.Get(context.TODO(), types.NamespacedName{Namespace: checluster.Namespace, Name: CheTLSSelfSignedCertificateSecretName}, cheTLSSelfSignedCertificateSecret) - if err != nil { - if !errors.IsNotFound(err) { - // Error reading Che self-signed secret info - logrus.Errorf("Error getting Che self-signed certificate secert \"%s\": %v", CheTLSSelfSignedCertificateSecretName, err) - return reconcile.Result{RequeueAfter: time.Second}, err - } - // Che CA self-signed cetificate secret doesn't exist. - // Such situation could happen between reconcile loops, when CA cert is deleted. - // However the certificates should be created together, - // so it is mandatory to remove Che TLS secret now and recreate the pair. - cheTLSSecret = &corev1.Secret{} - err = clusterAPI.Client.Get(context.TODO(), types.NamespacedName{Namespace: checluster.Namespace, Name: cheTLSSecretName}, cheTLSSecret) - if err != nil { // No need to check for not found error as the secret already exists at this point - logrus.Errorf("Error getting Che TLS secert \"%s\": %v", cheTLSSecretName, err) - return reconcile.Result{RequeueAfter: time.Second}, err - } - if err = clusterAPI.Client.Delete(context.TODO(), cheTLSSecret); err != nil { - logrus.Errorf("Error deleting Che TLS secret \"%s\": %v", cheTLSSecretName, err) - return reconcile.Result{RequeueAfter: time.Second}, err - } - // Invalid secrets cleaned up, recreate them now - return reconcile.Result{RequeueAfter: time.Second}, err - } - - // Che CA self-signed certificate secret exists, check for required data fields - if !isCheCASecretValid(cheTLSSelfSignedCertificateSecret) { - logrus.Infof("Che self-signed certificate secret \"%s\" is invalid. Recrating...", CheTLSSelfSignedCertificateSecretName) - // Che CA self-signed certificate secret is invalid, delete it - if err = clusterAPI.Client.Delete(context.TODO(), cheTLSSelfSignedCertificateSecret); err != nil { - logrus.Errorf("Error deleting Che self-signed certificate secret \"%s\": %v", CheTLSSelfSignedCertificateSecretName, err) - return reconcile.Result{RequeueAfter: time.Second}, err - } - // Also delete Che TLS as the certificates should be created together - // Here it is not mandatory to check Che TLS secret existence as it is handled above - if err = clusterAPI.Client.Delete(context.TODO(), cheTLSSecret); err != nil { - logrus.Errorf("Error deleting Che TLS secret \"%s\": %v", cheTLSSecretName, err) - return reconcile.Result{RequeueAfter: time.Second}, err - } - // Regenerate Che TLS certicates and recreate secrets - return reconcile.Result{RequeueAfter: time.Second}, nil - } - - // Check owner reference - if cheTLSSelfSignedCertificateSecret.ObjectMeta.OwnerReferences == nil { - // Set owner Che cluster as Che TLS secret owner - if err := controllerutil.SetControllerReference(checluster, cheTLSSelfSignedCertificateSecret, clusterAPI.Scheme); err != nil { - logrus.Errorf("Failed to set owner for Che self-signed certificate secret \"%s\". Error: %s", CheTLSSelfSignedCertificateSecretName, err) - return reconcile.Result{RequeueAfter: time.Second}, err - } - if err := clusterAPI.Client.Update(context.TODO(), cheTLSSelfSignedCertificateSecret); err != nil { - logrus.Errorf("Failed to update owner for Che self-signed certificate secret \"%s\". Error: %s", CheTLSSelfSignedCertificateSecretName, err) - return reconcile.Result{RequeueAfter: time.Second}, err - } - } - - // Both secrets are ok, go further in reconcile loop - return reconcile.Result{}, nil -} - -func isCheTLSSecretValid(cheTLSSecret *corev1.Secret) bool { - if data, exists := cheTLSSecret.Data["tls.key"]; !exists || len(data) == 0 { - return false - } - if data, exists := cheTLSSecret.Data["tls.crt"]; !exists || len(data) == 0 { - return false - } - return true -} - -func isCheCASecretValid(cheCASelfSignedCertificateSecret *corev1.Secret) bool { - if data, exists := cheCASelfSignedCertificateSecret.Data["ca.crt"]; !exists || len(data) == 0 { - return false - } - return true -} - -// CheckAndUpdateTLSConfiguration validates TLS configuration and precreated objects if any -// If configuration is wrong it will guess most common use cases and will make changes in Che CR accordingly to the assumption. -func CheckAndUpdateTLSConfiguration(checluster *orgv1.CheCluster, clusterAPI deploy.ClusterAPI) error { - if checluster.Spec.K8s.TlsSecretName == "" { - checluster.Spec.K8s.TlsSecretName = "che-tls" - if err := deploy.UpdateCheCRSpec(checluster, "TlsSecretName", checluster.Spec.K8s.TlsSecretName, clusterAPI); err != nil { - return err - } - } - - return nil -} - -func deleteJob(job *batchv1.Job, checluster *orgv1.CheCluster, clusterAPI deploy.ClusterAPI) { - names := util.K8sclient.GetPodsByComponent(CheTlsJobComponentName, checluster.Namespace) - for _, podName := range names { - pod := &corev1.Pod{} - err := clusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: podName, Namespace: checluster.Namespace}, pod) - if err == nil { - // Delete pod (for some reasons pod isn't removed when job is removed) - if err = clusterAPI.Client.Delete(context.TODO(), pod); err != nil { - logrus.Errorf("Error deleting pod: '%s', error: %v", podName, err) - } - } - } - - if err := clusterAPI.Client.Delete(context.TODO(), job); err != nil { - logrus.Errorf("Error deleting job: '%s', error: %v", CheTLSJobName, err) - } -} diff --git a/pkg/deploy/deployment_che.go b/pkg/deploy/deployment_che.go index b7f96efdf3..ffb8f73085 100644 --- a/pkg/deploy/deployment_che.go +++ b/pkg/deploy/deployment_che.go @@ -49,6 +49,11 @@ func getSpecCheDeployment(checluster *orgv1.CheCluster, cmResourceVersion string return nil, err } + selfSignedCertUsed, err := IsSelfSignedCertificateUsed(checluster, clusterAPI) + if err != nil { + return nil, err + } + terminationGracePeriodSeconds := int64(30) cheFlavor := DefaultCheFlavor(checluster) labels := GetLabels(checluster, cheFlavor) @@ -84,14 +89,14 @@ func getSpecCheDeployment(checluster *orgv1.CheCluster, cmResourceVersion string Name: "CHE_GIT_SELF__SIGNED__CERT__HOST", Value: "", } - if checluster.Spec.Server.SelfSignedCert { + if selfSignedCertUsed { selfSignedCertEnv = corev1.EnvVar{ Name: "CHE_SELF__SIGNED__CERT", ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ Key: "ca.crt", LocalObjectReference: corev1.LocalObjectReference{ - Name: "self-signed-certificate", + Name: CheTLSSelfSignedCertificateSecretName, }, Optional: &optionalEnv, }, diff --git a/pkg/deploy/deployment_keycloak.go b/pkg/deploy/deployment_keycloak.go index 2d7cc2418d..a9c9a99bbc 100644 --- a/pkg/deploy/deployment_keycloak.go +++ b/pkg/deploy/deployment_keycloak.go @@ -254,7 +254,7 @@ func getSpecKeycloakDeployment(checluster *orgv1.CheCluster, clusterDeployment * SecretKeyRef: &corev1.SecretKeySelector{ Key: "ca.crt", LocalObjectReference: corev1.LocalObjectReference{ - Name: "self-signed-certificate", + Name: CheTLSSelfSignedCertificateSecretName, }, Optional: &optionalEnv, }, @@ -377,7 +377,7 @@ func getSpecKeycloakDeployment(checluster *orgv1.CheCluster, clusterDeployment * SecretKeyRef: &corev1.SecretKeySelector{ Key: "ca.crt", LocalObjectReference: corev1.LocalObjectReference{ - Name: "self-signed-certificate", + Name: CheTLSSelfSignedCertificateSecretName, }, Optional: &optionalEnv, }, diff --git a/pkg/deploy/route.go b/pkg/deploy/route.go index 21c07dfe45..b5b6a997d2 100644 --- a/pkg/deploy/route.go +++ b/pkg/deploy/route.go @@ -49,14 +49,14 @@ func SyncRouteToCluster( port int32, clusterAPI ClusterAPI) RouteProvisioningStatus { - specRoute, err := getSpecRoute(checluster, name, serviceName, port, clusterAPI) + specRoute, err := GetSpecRoute(checluster, name, serviceName, port, clusterAPI) if err != nil { return RouteProvisioningStatus{ ProvisioningStatus: ProvisioningStatus{Err: err}, } } - clusterRoute, err := getClusterRoute(specRoute.Name, specRoute.Namespace, clusterAPI.Client) + clusterRoute, err := GetClusterRoute(specRoute.Name, specRoute.Namespace, clusterAPI.Client) if err != nil { return RouteProvisioningStatus{ ProvisioningStatus: ProvisioningStatus{Err: err}, @@ -95,7 +95,8 @@ func SyncRouteToCluster( } } -func getClusterRoute(name string, namespace string, client runtimeClient.Client) (*routev1.Route, error) { +// GetClusterRoute returns existing route. +func GetClusterRoute(name string, namespace string, client runtimeClient.Client) (*routev1.Route, error) { route := &routev1.Route{} namespacedName := types.NamespacedName{ Namespace: namespace, @@ -111,7 +112,8 @@ func getClusterRoute(name string, namespace string, client runtimeClient.Client) return route, nil } -func getSpecRoute(checluster *orgv1.CheCluster, name string, serviceName string, port int32, clusterAPI ClusterAPI) (*routev1.Route, error) { +// GetSpecRoute returns default configuration of a route in Che namespace. +func GetSpecRoute(checluster *orgv1.CheCluster, name string, serviceName string, port int32, clusterAPI ClusterAPI) (*routev1.Route, error) { tlsSupport := checluster.Spec.Server.TlsSupport labels := GetLabels(checluster, DefaultCheFlavor(checluster)) weight := int32(100) diff --git a/pkg/deploy/secret.go b/pkg/deploy/secret.go index b61b1f1d1f..b3b9e3c2a5 100644 --- a/pkg/deploy/secret.go +++ b/pkg/deploy/secret.go @@ -12,12 +12,81 @@ package deploy import ( + "context" + "fmt" + orgv1 "github.com/eclipse/che-operator/pkg/apis/org/v1" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "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" ) -func NewSecret(cr *orgv1.CheCluster, name string, data map[string][]byte) *corev1.Secret { +var secretDiffOpts = cmp.Options{ + cmpopts.IgnoreFields(corev1.Secret{}, "TypeMeta", "ObjectMeta"), +} + +// SyncSecretToCluster applies secret into cluster +func SyncSecretToCluster( + checluster *orgv1.CheCluster, + name string, + data map[string][]byte, + clusterAPI ClusterAPI) (*corev1.Secret, error) { + + specSecret := GetSpecSecret(checluster, name, data) + + clusterSecret, err := GetClusterSecret(specSecret.Name, specSecret.Namespace, clusterAPI) + if err != nil { + return nil, err + } + + if clusterSecret == nil { + logrus.Infof("Creating a new object: %s, name %s", specSecret.Kind, specSecret.Name) + err := clusterAPI.Client.Create(context.TODO(), specSecret) + return specSecret, err + } + + diff := cmp.Diff(clusterSecret, specSecret, secretDiffOpts) + if len(diff) > 0 { + logrus.Infof("Updating existed object: %s, name: %s", clusterSecret.Kind, clusterSecret.Name) + fmt.Printf("Difference:\n%s", diff) + + err := clusterAPI.Client.Delete(context.TODO(), clusterSecret) + if err != nil { + return nil, err + } + + err = clusterAPI.Client.Create(context.TODO(), specSecret) + if err != nil { + return nil, err + } + } + + return clusterSecret, nil +} + +// GetClusterSecret retrieves given secret from cluster +func GetClusterSecret(name string, namespace string, clusterAPI ClusterAPI) (*corev1.Secret, error) { + secret := &corev1.Secret{} + namespacedName := types.NamespacedName{ + Namespace: namespace, + Name: name, + } + err := clusterAPI.Client.Get(context.TODO(), namespacedName, secret) + if err != nil { + if errors.IsNotFound(err) { + return nil, nil + } + return nil, err + } + return secret, nil +} + +// GetSpecSecret return default secret config for given data +func GetSpecSecret(cr *orgv1.CheCluster, name string, data map[string][]byte) *corev1.Secret { labels := GetLabels(cr, DefaultCheFlavor(cr)) return &corev1.Secret{ TypeMeta: metav1.TypeMeta{ @@ -32,3 +101,24 @@ func NewSecret(cr *orgv1.CheCluster, name string, data map[string][]byte) *corev Data: data, } } + +// 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) { + 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) + 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 + } + + secret, err = SyncSecretToCluster(checluster, name, map[string][]byte{"ca.crt": crtBytes}, clusterAPI) + if err != nil { + return err + } + } + + return nil +} diff --git a/pkg/deploy/tls.go b/pkg/deploy/tls.go new file mode 100644 index 0000000000..143aa257e4 --- /dev/null +++ b/pkg/deploy/tls.go @@ -0,0 +1,460 @@ +// +// Copyright (c) 2012-2019 Red Hat, Inc. +// This program and the accompanying materials are made +// available under the terms of the Eclipse Public License 2.0 +// which is available at https://www.eclipse.org/legal/epl-2.0/ +// +// SPDX-License-Identifier: EPL-2.0 +// +// Contributors: +// Red Hat, Inc. - initial API and implementation +// +package deploy + +import ( + "context" + "crypto/tls" + "crypto/x509" + "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" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + "sigs.k8s.io/controller-runtime/pkg/reconcile" +) + +// TLS related constants +const ( + CheTLSJobServiceAccountName = "che-tls-job-service-account" + CheTLSJobRoleName = "che-tls-job-role" + CheTLSJobRoleBindingName = "che-tls-job-role-binding" + CheTLSJobName = "che-tls-job" + CheTLSJobComponentName = "che-create-tls-secret-job" + CheTLSSelfSignedCertificateSecretName = "self-signed-certificate" + DefaultCheTLSSecretName = "che-tls" +) + +// IsSelfSignedCertificateUsed detects whether endpoints are/should be secured by self-signed certificate. +func IsSelfSignedCertificateUsed(checluster *orgv1.CheCluster, clusterAPI ClusterAPI) (bool, error) { + if util.IsTestMode() { + return true, nil + } + + cheTLSSelfSignedCertificateSecret := &corev1.Secret{} + err := clusterAPI.Client.Get(context.TODO(), types.NamespacedName{Namespace: checluster.Namespace, Name: CheTLSSelfSignedCertificateSecretName}, cheTLSSelfSignedCertificateSecret) + if err == nil { + // "self signed-certificate" secret found + return true, nil + } + if !errors.IsNotFound(err) { + // Failed to get secret, return error to restart reconcile loop. + return false, err + } + + if util.IsOpenShift { + // Get router TLS certificates chain + peerCertificates, err := GetEndpointTLSCrtChain(checluster, "", clusterAPI) + if err != nil { + return false, err + } + + // Check the chain if ti contains self-signed CA certificate + for _, cert := range peerCertificates { + if cert.Subject.String() == cert.Issuer.String() { + // Self-signed CA certificate is found in the chain + return true, nil + } + } + // The chain doesn't contain self-signed certificate + return false, nil + } + + // For Kubernetes, check che-tls secret. + + cheTLSSecretName := checluster.Spec.K8s.TlsSecretName + if len(cheTLSSecretName) < 1 { + cheTLSSecretName = DefaultCheTLSSecretName + } + + cheTLSSecret := &corev1.Secret{} + err = clusterAPI.Client.Get(context.TODO(), types.NamespacedName{Namespace: checluster.Namespace, Name: cheTLSSecretName}, cheTLSSecret) + if err != nil { + if !errors.IsNotFound(err) { + // Failed to get secret, return error to restart reconcile loop. + return false, err + } + + // Both secrets (che-tls and self-signed-certificate) are missing which means that we should generate them (i.e. use self-signed certificate). + return true, nil + } + // TLS secret found, consider it as commonly trusted. + return false, nil +} + +// 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) { + if util.IsTestMode() { + return nil, stderrors.New("Not allowed for tests") + } + + var requestURL string + if len(endpointURL) < 1 { + // Create test route to get certificates chain. + // Note, it is not possible to use SyncRouteToCluster here as it may cause infinite reconcile loop. + routeSpec, err := GetSpecRoute(instance, "test", "test", 8080, clusterAPI) + if err != nil { + return nil, err + } + // Remove controller reference to prevent queueing new reconcile loop + routeSpec.SetOwnerReferences(nil) + // Create route manually + if err := clusterAPI.Client.Create(context.TODO(), routeSpec); err != nil { + logrus.Errorf("Failed to create test route 'test': %s", err) + return nil, err + } + + // Schedule test route cleanup after the job done. + defer func() { + if err := clusterAPI.Client.Delete(context.TODO(), routeSpec); err != nil { + logrus.Errorf("Failed to delete test route %s: %s", routeSpec.Name, err) + } + }() + + // Wait till route is ready + var route *routev1.Route + for wait := true; wait; { + time.Sleep(time.Duration(1) * time.Second) + route, err = GetClusterRoute(routeSpec.Name, routeSpec.Namespace, clusterAPI.Client) + if err != nil { + return nil, err + } + wait = len(route.Spec.Host) == 0 + } + + requestURL = "https://" + route.Spec.Host + } else { + requestURL = endpointURL + } + + // 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) + } + transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} + client := &http.Client{ + Transport: transport, + } + + req, err := http.NewRequest("GET", requestURL, nil) + resp, err := client.Do(req) + if err != nil { + logrus.Errorf("An error occurred when reaching test TLS route: %s", err) + return nil, err + } + + return resp.TLS.PeerCertificates, nil +} + +// 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) + if err != nil { + if util.IsTestMode() { + fakeCrt := make([]byte, 5) + return fakeCrt, nil + } + return nil, err + } + + for i := range peerCertificates { + cert := peerCertificates[i].Raw + crt := pem.EncodeToMemory(&pem.Block{ + Type: "CERTIFICATE", + Bytes: cert, + }) + certificates = append(certificates, crt...) + } + + 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 + + // ===== Check Che server TLS certificate ===== // + + cheTLSSecret := &corev1.Secret{} + err := clusterAPI.Client.Get(context.TODO(), types.NamespacedName{Namespace: checluster.Namespace, Name: cheTLSSecretName}, cheTLSSecret) + if err != nil { + if !errors.IsNotFound(err) { + // Error reading secret info + logrus.Errorf("Error getting Che TLS secert \"%s\": %v", cheTLSSecretName, err) + return reconcile.Result{RequeueAfter: time.Second}, err + } + + // Che TLS secret doesn't exist, generate a new one + + // Remove Che CA certificate secret if any + cheCASelfSignedCertificateSecret := &corev1.Secret{} + err = clusterAPI.Client.Get(context.TODO(), types.NamespacedName{Namespace: checluster.Namespace, Name: CheTLSSelfSignedCertificateSecretName}, cheCASelfSignedCertificateSecret) + if err != nil { + if !errors.IsNotFound(err) { + // Error reading secret info + logrus.Errorf("Error getting Che self-signed certificate secert \"%s\": %v", CheTLSSelfSignedCertificateSecretName, err) + return reconcile.Result{RequeueAfter: time.Second}, err + } + // Che CA certificate doesn't exists (that's expected at this point), do nothing + } else { + // Remove Che CA secret because Che TLS secret is missing (they should be generated together). + if err = clusterAPI.Client.Delete(context.TODO(), cheCASelfSignedCertificateSecret); err != nil { + logrus.Errorf("Error deleting Che self-signed certificate secret \"%s\": %v", CheTLSSelfSignedCertificateSecretName, err) + return reconcile.Result{RequeueAfter: time.Second}, err + } + } + + // Prepare permissions for the certificate generation job + sa, err := SyncServiceAccountToCluster(checluster, CheTLSJobServiceAccountName, clusterAPI) + if sa == nil { + return reconcile.Result{RequeueAfter: time.Second}, err + } + + role, err := SyncRoleToCluster(checluster, CheTLSJobRoleName, []string{"secrets"}, []string{"create"}, clusterAPI) + if role == nil { + return reconcile.Result{RequeueAfter: time.Second}, err + } + + roleBiding, err := SyncRoleBindingToCluster(checluster, CheTLSJobRoleBindingName, CheTLSJobServiceAccountName, CheTLSJobRoleName, "Role", clusterAPI) + if roleBiding == nil { + return reconcile.Result{RequeueAfter: time.Second}, err + } + + cheTLSSecretsCreationJobImage := DefaultCheTLSSecretsCreationJobImage() + jobEnvVars := map[string]string{ + "DOMAIN": checluster.Spec.K8s.IngressDomain, + "CHE_NAMESPACE": checluster.Namespace, + "CHE_SERVER_TLS_SECRET_NAME": cheTLSSecretName, + "CHE_CA_CERTIFICATE_SECRET_NAME": CheTLSSelfSignedCertificateSecretName, + } + job, err := SyncJobToCluster(checluster, CheTLSJobName, CheTLSJobComponentName, cheTLSSecretsCreationJobImage, CheTLSJobServiceAccountName, jobEnvVars, clusterAPI) + if err != nil { + logrus.Error(err) + return reconcile.Result{RequeueAfter: time.Second}, err + } + if job == nil || job.Status.Succeeded == 0 { + logrus.Infof("Waiting on job '%s' to be finished", CheTLSJobName) + return reconcile.Result{RequeueAfter: time.Second}, err + } + } + + // cleanup job + job := &batchv1.Job{} + err = clusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: CheTLSJobName, Namespace: checluster.Namespace}, job) + if err != nil && !errors.IsNotFound(err) { + // Failed to get the job + return reconcile.Result{RequeueAfter: time.Second}, err + } + if err == nil { + // The job object is present + if job.Status.Succeeded > 0 { + logrus.Infof("Import public part of Eclipse Che self-signed CA certificvate from \"%s\" secret into your browser.", CheTLSSelfSignedCertificateSecretName) + deleteJob(job, checluster, clusterAPI) + } else if job.Status.Failed > 0 { + // The job failed, but the certificate is present, shouldn't happen + deleteJob(job, checluster, clusterAPI) + return reconcile.Result{}, nil + } + // Job hasn't reported finished status yet, wait more + return reconcile.Result{RequeueAfter: time.Second}, nil + } + + // Che TLS certificate exists, check for required data fields + if !isCheTLSSecretValid(cheTLSSecret) { + // The secret is invalid because required field(s) missing. + logrus.Infof("Che TLS secret \"%s\" is invalid. Recreating...", cheTLSSecretName) + // Delete old invalid secret + if err = clusterAPI.Client.Delete(context.TODO(), cheTLSSecret); err != nil { + logrus.Errorf("Error deleting Che TLS secret \"%s\": %v", cheTLSSecretName, err) + return reconcile.Result{RequeueAfter: time.Second}, err + } + // Recreate the secret + return reconcile.Result{RequeueAfter: time.Second}, err + } + + // Check owner reference + if cheTLSSecret.ObjectMeta.OwnerReferences == nil { + // Set owner Che cluster as Che TLS secret owner + if err := controllerutil.SetControllerReference(checluster, cheTLSSecret, clusterAPI.Scheme); err != nil { + logrus.Errorf("Failed to set owner for Che TLS secret \"%s\". Error: %s", cheTLSSecretName, err) + return reconcile.Result{RequeueAfter: time.Second}, err + } + if err := clusterAPI.Client.Update(context.TODO(), cheTLSSecret); err != nil { + logrus.Errorf("Failed to update owner for Che TLS secret \"%s\". Error: %s", cheTLSSecretName, err) + return reconcile.Result{RequeueAfter: time.Second}, err + } + } + + // ===== Check Che CA certificate ===== // + + cheTLSSelfSignedCertificateSecret := &corev1.Secret{} + err = clusterAPI.Client.Get(context.TODO(), types.NamespacedName{Namespace: checluster.Namespace, Name: CheTLSSelfSignedCertificateSecretName}, cheTLSSelfSignedCertificateSecret) + if err != nil { + if !errors.IsNotFound(err) { + // Error reading Che self-signed secret info + logrus.Errorf("Error getting Che self-signed certificate secert \"%s\": %v", CheTLSSelfSignedCertificateSecretName, err) + return reconcile.Result{RequeueAfter: time.Second}, err + } + // Che CA self-signed cetificate secret doesn't exist. + // This means that commonly trusted certificate is used. + } else { + // Che CA self-signed certificate secret exists, check for required data fields + if !isCheCASecretValid(cheTLSSelfSignedCertificateSecret) { + logrus.Infof("Che self-signed certificate secret \"%s\" is invalid. Recrating...", CheTLSSelfSignedCertificateSecretName) + // Che CA self-signed certificate secret is invalid, delete it + if err = clusterAPI.Client.Delete(context.TODO(), cheTLSSelfSignedCertificateSecret); err != nil { + logrus.Errorf("Error deleting Che self-signed certificate secret \"%s\": %v", CheTLSSelfSignedCertificateSecretName, err) + return reconcile.Result{RequeueAfter: time.Second}, err + } + // Also delete Che TLS as the certificates should be created together + // Here it is not mandatory to check Che TLS secret existence as it is handled above + if err = clusterAPI.Client.Delete(context.TODO(), cheTLSSecret); err != nil { + logrus.Errorf("Error deleting Che TLS secret \"%s\": %v", cheTLSSecretName, err) + return reconcile.Result{RequeueAfter: time.Second}, err + } + // Regenerate Che TLS certicates and recreate secrets + return reconcile.Result{RequeueAfter: time.Second}, nil + } + + // Check owner reference + if cheTLSSelfSignedCertificateSecret.ObjectMeta.OwnerReferences == nil { + // Set owner Che cluster as Che TLS secret owner + if err := controllerutil.SetControllerReference(checluster, cheTLSSelfSignedCertificateSecret, clusterAPI.Scheme); err != nil { + logrus.Errorf("Failed to set owner for Che self-signed certificate secret \"%s\". Error: %s", CheTLSSelfSignedCertificateSecretName, err) + return reconcile.Result{RequeueAfter: time.Second}, err + } + if err := clusterAPI.Client.Update(context.TODO(), cheTLSSelfSignedCertificateSecret); err != nil { + logrus.Errorf("Failed to update owner for Che self-signed certificate secret \"%s\". Error: %s", CheTLSSelfSignedCertificateSecretName, err) + return reconcile.Result{RequeueAfter: time.Second}, err + } + } + } + + // TLS configuration is ok, go further in reconcile loop + return reconcile.Result{}, nil +} + +// CheckAndUpdateK8sTLSConfiguration validates Che TLS configuration on Kubernetes infra. +// If configuration is wrong it will guess most common use cases and will make changes in Che CR accordingly to the assumption. +func CheckAndUpdateK8sTLSConfiguration(checluster *orgv1.CheCluster, clusterAPI ClusterAPI) error { + if checluster.Spec.K8s.TlsSecretName == "" { + checluster.Spec.K8s.TlsSecretName = DefaultCheTLSSecretName + if err := UpdateCheCRSpec(checluster, "TlsSecretName", checluster.Spec.K8s.TlsSecretName, clusterAPI); err != nil { + return err + } + } + + return nil +} + +func isCheTLSSecretValid(cheTLSSecret *corev1.Secret) bool { + if data, exists := cheTLSSecret.Data["tls.key"]; !exists || len(data) == 0 { + return false + } + if data, exists := cheTLSSecret.Data["tls.crt"]; !exists || len(data) == 0 { + return false + } + return true +} + +func isCheCASecretValid(cheCASelfSignedCertificateSecret *corev1.Secret) bool { + if data, exists := cheCASelfSignedCertificateSecret.Data["ca.crt"]; !exists || len(data) == 0 { + return false + } + return true +} + +func deleteJob(job *batchv1.Job, checluster *orgv1.CheCluster, clusterAPI ClusterAPI) { + names := util.K8sclient.GetPodsByComponent(CheTLSJobComponentName, checluster.Namespace) + for _, podName := range names { + pod := &corev1.Pod{} + err := clusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: podName, Namespace: checluster.Namespace}, pod) + if err == nil { + // Delete pod (for some reasons pod isn't removed when job is removed) + if err = clusterAPI.Client.Delete(context.TODO(), pod); err != nil { + logrus.Errorf("Error deleting pod: '%s', error: %v", podName, err) + } + } + } + + if err := clusterAPI.Client.Delete(context.TODO(), job); err != nil { + logrus.Errorf("Error deleting job: '%s', error: %v", CheTLSJobName, err) + } +}