Port changes from 7.9.x to master (#201)
* Always add the devfile registry public URL env var (#192) This fixes the [CRW-710](https://issues.redhat.com/browse/CRW-710) blocker JIRA bug (blocking CRW 2.1 release) Signed-off-by: David Festal <dfestal@redhat.com> * Correctly propagate proxy settings in the operator and Keycloak (CRW-709) (#200) * Correctly propagate proxy settings in the operator and Keycloak .This fixes issue https://issues.redhat.com/browse/CRW-709 * Use the same Go release in PR checks as in the main Docker file to avoid a syntax arror in the PR check jobs Signed-off-by: David Festal <dfestal@redhat.com> * Refactoring Co-authored-by: David Festal <dfestal@redhat.com>pull/204/head
parent
016e7f11cd
commit
0952fa99a3
|
|
@ -20,7 +20,7 @@ Catch_Finish() {
|
|||
}
|
||||
|
||||
init() {
|
||||
GO_TOOLSET_VERSION="1.11.5-3"
|
||||
GO_TOOLSET_VERSION="1.12.12-4"
|
||||
SCRIPT=$(readlink -f "$0") # this script's absolute path
|
||||
SCRIPTPATH=$(dirname "$SCRIPT") # /path/to/e2e/ folder
|
||||
if [[ ${WORKSPACE} ]] && [[ -d ${WORKSPACE} ]]; then OPERATOR_REPO=${WORKSPACE}; else OPERATOR_REPO=$(dirname "$SCRIPTPATH"); fi
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
package che
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
|
@ -289,8 +290,8 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e
|
|||
logrus.Errorf("Error getting devfile-registry ConfigMap: %v", err)
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
if err == nil && !instance.IsAirGapMode() {
|
||||
logrus.Info("Found devfile-registry ConfigMap and not in airgap mode. Deleting.")
|
||||
if err == nil && instance.Spec.Server.ExternalDevfileRegistry {
|
||||
logrus.Info("Found devfile-registry ConfigMap and while using an external devfile registry. Deleting.")
|
||||
if err = r.client.Delete(context.TODO(), devfileRegistryConfigMap); err != nil {
|
||||
logrus.Errorf("Error deleting devfile-registry ConfigMap: %v", err)
|
||||
return reconcile.Result{}, err
|
||||
|
|
@ -871,37 +872,37 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e
|
|||
if devfileRegistryURL == "" {
|
||||
devfileRegistryURL = guessedDevfileRegistryURL
|
||||
}
|
||||
if instance.IsAirGapMode() {
|
||||
devFileRegistryConfigMap := &corev1.ConfigMap{}
|
||||
err = r.client.Get(context.TODO(), types.NamespacedName{Name: "devfile-registry", Namespace: instance.Namespace}, devFileRegistryConfigMap)
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
devFileRegistryConfigMap = deploy.CreateDevfileRegistryConfigMap(instance, devfileRegistryURL)
|
||||
err = controllerutil.SetControllerReference(instance, devFileRegistryConfigMap, r.scheme)
|
||||
if err != nil {
|
||||
logrus.Errorf("An error occurred: %v", err)
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
logrus.Info("Creating devfile registry airgap configmap")
|
||||
err = r.client.Create(context.TODO(), devFileRegistryConfigMap)
|
||||
if err != nil {
|
||||
logrus.Errorf("Error creating devfile registry configmap: %v", err)
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
return reconcile.Result{Requeue: true}, nil
|
||||
} else {
|
||||
logrus.Errorf("Could not get devfile-registry ConfigMap: %v", err)
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
} else {
|
||||
devFileRegistryConfigMap := &corev1.ConfigMap{}
|
||||
err = r.client.Get(context.TODO(), types.NamespacedName{Name: "devfile-registry", Namespace: instance.Namespace}, devFileRegistryConfigMap)
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
devFileRegistryConfigMap = deploy.CreateDevfileRegistryConfigMap(instance, devfileRegistryURL)
|
||||
err = controllerutil.SetControllerReference(instance, devFileRegistryConfigMap, r.scheme)
|
||||
if err != nil {
|
||||
logrus.Errorf("An error occurred: %v", err)
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
logrus.Info("Creating devfile registry airgap configmap")
|
||||
err = r.client.Create(context.TODO(), devFileRegistryConfigMap)
|
||||
if err != nil {
|
||||
logrus.Errorf("Error creating devfile registry configmap: %v", err)
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
return reconcile.Result{Requeue: true}, nil
|
||||
} else {
|
||||
logrus.Errorf("Could not get devfile-registry ConfigMap: %v", err)
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
} else {
|
||||
newDevFileRegistryConfigMap := deploy.CreateDevfileRegistryConfigMap(instance, devfileRegistryURL)
|
||||
if ! reflect.DeepEqual(devFileRegistryConfigMap.Data, newDevFileRegistryConfigMap.Data) {
|
||||
err = controllerutil.SetControllerReference(instance, devFileRegistryConfigMap, r.scheme)
|
||||
if err != nil {
|
||||
logrus.Errorf("An error occurred: %v", err)
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
logrus.Info("Updating devfile-registry ConfigMap")
|
||||
err = r.client.Update(context.TODO(), devFileRegistryConfigMap)
|
||||
err = r.client.Update(context.TODO(), newDevFileRegistryConfigMap)
|
||||
if err != nil {
|
||||
logrus.Errorf("Error updating devfile-registry ConfigMap: %v", err)
|
||||
return reconcile.Result{}, err
|
||||
|
|
|
|||
|
|
@ -130,6 +130,24 @@ func TestCheController(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatalf("reconcile: (%v)", err)
|
||||
}
|
||||
|
||||
// get devfile-registry configmap
|
||||
devfilecm := &corev1.ConfigMap{}
|
||||
if err := cl.Get(context.TODO(), types.NamespacedName{Name: "devfile-registry", Namespace: cheCR.Namespace}, devfilecm); err != nil {
|
||||
t.Errorf("ConfigMap %s not found: %s", devfilecm.Name, err)
|
||||
}
|
||||
|
||||
// Check the result of reconciliation to make sure it has the desired state.
|
||||
if ! res.Requeue {
|
||||
t.Error("Reconcile did not requeue request as expected")
|
||||
}
|
||||
|
||||
// reconcile again
|
||||
res, err = r.Reconcile(req)
|
||||
if err != nil {
|
||||
t.Fatalf("reconcile: (%v)", err)
|
||||
}
|
||||
|
||||
// Check the result of reconciliation to make sure it has the desired state.
|
||||
if res.Requeue {
|
||||
t.Error("Reconcile did not requeue request as expected")
|
||||
|
|
|
|||
|
|
@ -338,7 +338,7 @@ func (r *ReconcileChe) CreateTLSSecret(instance *orgv1.CheCluster, url string, n
|
|||
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)
|
||||
if err != nil {
|
||||
logrus.Errorf("Failed to extract crt. Failed to create a secret with a self signed crt: %s", err)
|
||||
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, crt)
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ import (
|
|||
"encoding/pem"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
orgv1 "github.com/eclipse/che-operator/pkg/apis/org/v1"
|
||||
|
|
@ -25,6 +27,7 @@ import (
|
|||
"github.com/eclipse/che-operator/pkg/util"
|
||||
routev1 "github.com/openshift/api/route/v1"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/http/httpproxy"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
|
@ -286,10 +289,10 @@ func (cl *k8s) GetDeploymentPod(name string, ns string) (podName string, err err
|
|||
// 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, url string) (certificate []byte, err error) {
|
||||
func (r *ReconcileChe) GetEndpointTlsCrt(instance *orgv1.CheCluster, endpointUrl string) (certificate []byte, err error) {
|
||||
testRoute := &routev1.Route{}
|
||||
var requestURL string
|
||||
if len(url) < 1 {
|
||||
if len(endpointUrl) < 1 {
|
||||
testRoute = deploy.NewTlsRoute(instance, "test", "test", 8080)
|
||||
logrus.Infof("Creating a test route %s to extract router crt", testRoute.Name)
|
||||
if err := r.CreateNewRoute(instance, testRoute); err != nil {
|
||||
|
|
@ -299,16 +302,26 @@ func (r *ReconcileChe) GetEndpointTlsCrt(instance *orgv1.CheCluster, url string)
|
|||
// sometimes timing conditions apply, and host isn't available right away
|
||||
if len(testRoute.Spec.Host) < 1 {
|
||||
time.Sleep(time.Duration(1) * time.Second)
|
||||
testRoute := r.GetEffectiveRoute(instance, "test")
|
||||
requestURL = "https://" + testRoute.Spec.Host
|
||||
testRoute = r.GetEffectiveRoute(instance, "test")
|
||||
}
|
||||
requestURL = "https://" + testRoute.Spec.Host
|
||||
|
||||
} else {
|
||||
requestURL = url
|
||||
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,
|
||||
}
|
||||
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
|
||||
client := &http.Client{}
|
||||
req, err := http.NewRequest("GET", requestURL, nil)
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
|
|
@ -329,7 +342,7 @@ func (r *ReconcileChe) GetEndpointTlsCrt(instance *orgv1.CheCluster, url string)
|
|||
certificate = append(certificate, crt...)
|
||||
}
|
||||
|
||||
if len(url) < 1 {
|
||||
if len(endpointUrl) < 1 {
|
||||
logrus.Infof("Deleting a test route %s to extract routes crt", testRoute.Name)
|
||||
if err := r.client.Delete(context.TODO(), testRoute); err != nil {
|
||||
logrus.Errorf("Failed to delete test route %s: %s", testRoute.Name, err)
|
||||
|
|
@ -337,3 +350,43 @@ func (r *ReconcileChe) GetEndpointTlsCrt(instance *orgv1.CheCluster, url string)
|
|||
}
|
||||
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
|
||||
}
|
||||
if len(instance.Spec.Server.ProxyUser) > 1 && len(instance.Spec.Server.ProxyPassword) > 1 {
|
||||
proxyURL = instance.Spec.Server.ProxyUser + ":" + instance.Spec.Server.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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ func GetConfigMapData(cr *orgv1.CheCluster) (cheEnv map[string]string) {
|
|||
cheWorkspaceHttpProxy := ""
|
||||
cheWorkspaceNoProxy := ""
|
||||
if len(cr.Spec.Server.ProxyURL) > 1 {
|
||||
cheWorkspaceHttpProxy, cheWorkspaceNoProxy = util.GenerateProxyEnvs(cr.Spec.Server.ProxyURL, cr.Spec.Server.ProxyPort, cr.Spec.Server.NonProxyHosts, proxyUser, proxyPassword)
|
||||
cheWorkspaceHttpProxy, cheWorkspaceNoProxy = util.GenerateProxyEnvs(cr.Spec.Server.ProxyURL, cr.Spec.Server.ProxyPort, nonProxyHosts, proxyUser, proxyPassword)
|
||||
}
|
||||
|
||||
ingressDomain := cr.Spec.K8s.IngressDomain
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@
|
|||
package deploy
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
orgv1 "github.com/eclipse/che-operator/pkg/apis/org/v1"
|
||||
"github.com/eclipse/che-operator/pkg/util"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
|
|
@ -59,7 +62,6 @@ func NewKeycloakDeployment(cr *orgv1.CheCluster, keycloakPostgresPassword string
|
|||
|
||||
addCertToTrustStoreCommand := addRouterCrt + " && " + addOpenShiftAPICrt + " && " + addMountedCrt + " && " + addMountedServiceCrt + " && " + importJavaCacerts
|
||||
|
||||
startCommand := "sed -i 's/WILDCARD/ANY/g' /opt/eap/bin/launch/keycloak-spi.sh && /opt/eap/bin/openshift-launch.sh -b 0.0.0.0"
|
||||
// upstream Keycloak has a bit different mechanism of adding jks
|
||||
changeConfigCommand := "echo Installing certificates into Keycloak && " +
|
||||
"echo -e \"embed-server --server-config=standalone.xml --std-out=echo \n" +
|
||||
|
|
@ -68,6 +70,50 @@ func NewKeycloakDeployment(cr *orgv1.CheCluster, keycloakPostgresPassword string
|
|||
"\"" + jbossDir + "/openshift.jks\", password => \"" + trustpass + "\", disabled => \"false\" },enabled=true) \n" +
|
||||
"stop-embedded-server\" > /scripts/add_openshift_certificate.cli && " +
|
||||
"/opt/jboss/keycloak/bin/jboss-cli.sh --file=/scripts/add_openshift_certificate.cli"
|
||||
|
||||
addProxyCliCommand := ""
|
||||
applyProxyCliCommand := ""
|
||||
proxyEnvVars := []corev1.EnvVar{}
|
||||
|
||||
if len(cr.Spec.Server.ProxyURL) > 1 {
|
||||
cheWorkspaceHttpProxy, cheWorkspaceNoProxy := util.GenerateProxyEnvs(cr.Spec.Server.ProxyURL, cr.Spec.Server.ProxyPort, cr.Spec.Server.NonProxyHosts, cr.Spec.Server.ProxyUser, cr.Spec.Server.ProxyPassword)
|
||||
|
||||
proxyEnvVars = []corev1.EnvVar{
|
||||
corev1.EnvVar{
|
||||
Name: "HTTP_PROXY",
|
||||
Value: cheWorkspaceHttpProxy,
|
||||
},
|
||||
corev1.EnvVar{
|
||||
Name: "HTTPS_PROXY",
|
||||
Value: cheWorkspaceHttpProxy,
|
||||
},
|
||||
corev1.EnvVar{
|
||||
Name: "NO_PROXY",
|
||||
Value: cheWorkspaceNoProxy,
|
||||
},
|
||||
}
|
||||
|
||||
cheWorkspaceNoProxy = strings.ReplaceAll(regexp.QuoteMeta(cheWorkspaceNoProxy), "\\", "\\\\\\")
|
||||
|
||||
jbossCli := "/opt/jboss/keycloak/bin/jboss-cli.sh"
|
||||
serverConfig := "standalone.xml"
|
||||
if cheFlavor == "codeready" {
|
||||
jbossCli = "/opt/eap/bin/jboss-cli.sh"
|
||||
serverConfig = "standalone-openshift.xml"
|
||||
}
|
||||
addProxyCliCommand = " && echo Configuring Proxy && " +
|
||||
"echo -e 'embed-server --server-config=" + serverConfig + " --std-out=echo \n" +
|
||||
"/subsystem=keycloak-server/spi=connectionsHttpClient/provider=default:write-attribute(name=properties.proxy-mappings,value=[\"" + cheWorkspaceNoProxy + ";NO_PROXY\",\".*;" + cheWorkspaceHttpProxy + "\"]) \n" +
|
||||
"stop-embedded-server' > " + jbossDir + "/setup-http-proxy.cli"
|
||||
|
||||
applyProxyCliCommand = " && " + jbossCli + " --file=" + jbossDir + "/setup-http-proxy.cli"
|
||||
if cheFlavor == "codeready" {
|
||||
applyProxyCliCommand = " && mkdir -p " + jbossDir + "/extensions && echo '#!/bin/bash\n" +
|
||||
"" + jbossDir + "/bin/jboss-cli.sh --file=" + jbossDir + "/setup-http-proxy.cli' > " + jbossDir + "/extensions/postconfigure.sh && " +
|
||||
"chmod a+x " + jbossDir + "/extensions/postconfigure.sh "
|
||||
}
|
||||
}
|
||||
|
||||
keycloakAdminUserName := util.GetValue(cr.Spec.Auth.IdentityProviderAdminUserName, DefaultKeycloakAdminUserName)
|
||||
keycloakEnv := []corev1.EnvVar{
|
||||
{
|
||||
|
|
@ -215,12 +261,18 @@ func NewKeycloakDeployment(cr *orgv1.CheCluster, keycloakPostgresPassword string
|
|||
},
|
||||
}
|
||||
}
|
||||
command := addCertToTrustStoreCommand + " && " + changeConfigCommand + " && /opt/jboss/docker-entrypoint.sh -b 0.0.0.0 -c standalone.xml"
|
||||
|
||||
for _, envvar := range proxyEnvVars {
|
||||
keycloakEnv = append(keycloakEnv, envvar)
|
||||
}
|
||||
|
||||
command := addCertToTrustStoreCommand + addProxyCliCommand + applyProxyCliCommand + " && " + changeConfigCommand +
|
||||
" && /opt/jboss/docker-entrypoint.sh -b 0.0.0.0 -c standalone.xml"
|
||||
command += " -Dkeycloak.profile.feature.token_exchange=enabled -Dkeycloak.profile.feature.admin_fine_grained_authz=enabled"
|
||||
if cheFlavor == "codeready" {
|
||||
command = addCertToTrustStoreCommand +
|
||||
" && echo \"feature.token_exchange=enabled\nfeature.admin_fine_grained_authz=enabled\" > /opt/eap/standalone/configuration/profile.properties && " +
|
||||
startCommand
|
||||
command = addCertToTrustStoreCommand + addProxyCliCommand + applyProxyCliCommand +
|
||||
" && echo \"feature.token_exchange=enabled\nfeature.admin_fine_grained_authz=enabled\" > /opt/eap/standalone/configuration/profile.properties" +
|
||||
" && sed -i 's/WILDCARD/ANY/g' /opt/eap/bin/launch/keycloak-spi.sh && /opt/eap/bin/openshift-launch.sh -b 0.0.0.0"
|
||||
}
|
||||
|
||||
return &appsv1.Deployment{
|
||||
|
|
|
|||
Loading…
Reference in New Issue