193 lines
6.0 KiB
Go
193 lines
6.0 KiB
Go
//
|
|
// Copyright (c) 2019-2021 Red Hat, Inc.
|
|
// This program and the accompanying materials are made
|
|
// available under the terms of the Eclipse Public License 2.0
|
|
// which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
//
|
|
// SPDX-License-Identifier: EPL-2.0
|
|
//
|
|
// Contributors:
|
|
// Red Hat, Inc. - initial API and implementation
|
|
//
|
|
|
|
package deploy
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/eclipse-che/che-operator/pkg/common/chetypes"
|
|
"github.com/eclipse-che/che-operator/pkg/common/constants"
|
|
"github.com/eclipse-che/che-operator/pkg/common/utils"
|
|
corev1 "k8s.io/api/core/v1"
|
|
|
|
"golang.org/x/net/http/httpproxy"
|
|
|
|
"net/http"
|
|
"net/url"
|
|
|
|
configv1 "github.com/openshift/api/config/v1"
|
|
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
func ReadClusterWideProxyConfiguration(clusterProxy *configv1.Proxy) (*chetypes.Proxy, error) {
|
|
proxy := &chetypes.Proxy{}
|
|
|
|
// Cluster components consume the status values to configure the proxy for their component.
|
|
proxy.HttpProxy = clusterProxy.Status.HTTPProxy
|
|
proxy.HttpsProxy = clusterProxy.Status.HTTPSProxy
|
|
if len(proxy.HttpsProxy) == 0 {
|
|
proxy.HttpsProxy = proxy.HttpProxy
|
|
}
|
|
proxy.NoProxy = clusterProxy.Status.NoProxy
|
|
httpProxy, err := url.Parse(proxy.HttpProxy)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
proxy.HttpHost = httpProxy.Hostname()
|
|
proxy.HttpPort = httpProxy.Port()
|
|
proxy.HttpUser = httpProxy.User.Username()
|
|
proxy.HttpPassword, _ = httpProxy.User.Password()
|
|
|
|
httpsProxy, err := url.Parse(proxy.HttpsProxy)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
proxy.HttpsHost = httpsProxy.Hostname()
|
|
proxy.HttpsPort = httpsProxy.Port()
|
|
proxy.HttpsUser = httpsProxy.User.Username()
|
|
proxy.HttpsPassword, _ = httpsProxy.User.Password()
|
|
proxy.TrustedCAMapName = clusterProxy.Spec.TrustedCA.Name
|
|
|
|
return proxy, nil
|
|
}
|
|
|
|
func ReadCheClusterProxyConfiguration(ctx *chetypes.DeployContext) (*chetypes.Proxy, error) {
|
|
if ctx.CheCluster.Spec.Components.CheServer.Proxy == nil {
|
|
return &chetypes.Proxy{}, nil
|
|
}
|
|
|
|
proxyParts := strings.Split(ctx.CheCluster.Spec.Components.CheServer.Proxy.Url, "://")
|
|
proxyProtocol := ""
|
|
proxyHost := ""
|
|
if len(proxyParts) == 1 {
|
|
proxyProtocol = ""
|
|
proxyHost = proxyParts[0]
|
|
} else {
|
|
proxyProtocol = proxyParts[0]
|
|
proxyHost = proxyParts[1]
|
|
}
|
|
|
|
proxyURL := proxyHost
|
|
if ctx.CheCluster.Spec.Components.CheServer.Proxy.Port != "" {
|
|
proxyURL = proxyURL + ":" + ctx.CheCluster.Spec.Components.CheServer.Proxy.Port
|
|
}
|
|
|
|
proxyUser := ""
|
|
proxyPassword := ""
|
|
|
|
proxyCredentialsSecretName := utils.GetValue(ctx.CheCluster.Spec.Components.CheServer.Proxy.CredentialsSecretName, constants.DefaultProxyCredentialsSecret)
|
|
proxyCredentialsSecret := &corev1.Secret{}
|
|
exists, err := GetNamespacedObject(ctx, proxyCredentialsSecretName, proxyCredentialsSecret)
|
|
if err != nil {
|
|
return nil, err
|
|
} else if exists {
|
|
proxyUser = string(proxyCredentialsSecret.Data["user"])
|
|
proxyPassword = string(proxyCredentialsSecret.Data["password"])
|
|
}
|
|
|
|
if len(proxyUser) > 1 && len(proxyPassword) > 1 {
|
|
proxyURL = proxyUser + ":" + proxyPassword + "@" + proxyURL
|
|
}
|
|
|
|
if proxyProtocol != "" {
|
|
proxyURL = proxyProtocol + "://" + proxyURL
|
|
}
|
|
|
|
return &chetypes.Proxy{
|
|
HttpProxy: proxyURL,
|
|
HttpUser: proxyUser,
|
|
HttpHost: proxyHost,
|
|
HttpPort: ctx.CheCluster.Spec.Components.CheServer.Proxy.Port,
|
|
HttpPassword: proxyPassword,
|
|
|
|
HttpsProxy: proxyURL,
|
|
HttpsUser: proxyUser,
|
|
HttpsHost: proxyHost,
|
|
HttpsPort: ctx.CheCluster.Spec.Components.CheServer.Proxy.Port,
|
|
HttpsPassword: proxyPassword,
|
|
|
|
NoProxy: strings.Join(ctx.CheCluster.Spec.Components.CheServer.Proxy.NonProxyHosts, ","),
|
|
}, nil
|
|
}
|
|
|
|
func MergeNonProxy(noProxy1 string, noProxy2 string) string {
|
|
if noProxy1 == "" {
|
|
return noProxy2
|
|
} else if noProxy2 == "" {
|
|
return noProxy1
|
|
}
|
|
|
|
return noProxy1 + "," + noProxy2
|
|
}
|
|
|
|
// GenerateProxyJavaOpts converts given proxy configuration into Java format.
|
|
func GenerateProxyJavaOpts(proxy *chetypes.Proxy, noProxy string) (javaOpts string, err error) {
|
|
if noProxy == "" {
|
|
noProxy = proxy.NoProxy
|
|
}
|
|
// Remove all spaces
|
|
noProxy = strings.Replace(noProxy, " ", "", -1)
|
|
// Replace , with |
|
|
noProxy = strings.Replace(noProxy, ",", "|", -1)
|
|
// Convert .domain wildcards to Java format *.domain
|
|
noProxy = strings.Replace(noProxy, "|.", "|*.", -1)
|
|
if strings.HasPrefix(noProxy, ".") {
|
|
noProxy = "*" + noProxy
|
|
}
|
|
|
|
proxyUserPassword := ""
|
|
if len(proxy.HttpUser) > 1 && len(proxy.HttpPassword) > 1 {
|
|
proxyUserPassword = " -Dhttp.proxyUser=" + proxy.HttpUser + " -Dhttp.proxyPassword=" + proxy.HttpPassword +
|
|
" -Dhttps.proxyUser=" + proxy.HttpsUser + " -Dhttps.proxyPassword=" + proxy.HttpsPassword +
|
|
" -Djdk.http.auth.tunneling.disabledSchemes= -Djdk.http.auth.proxying.disabledSchemes="
|
|
}
|
|
|
|
javaOpts =
|
|
" -Dhttp.proxyHost=" + removeProtocolPrefix(proxy.HttpHost) + " -Dhttp.proxyPort=" + proxy.HttpPort +
|
|
" -Dhttps.proxyHost=" + removeProtocolPrefix(proxy.HttpsHost) + " -Dhttps.proxyPort=" + proxy.HttpsPort +
|
|
" -Dhttp.nonProxyHosts='" + noProxy + "'" + proxyUserPassword
|
|
return javaOpts, nil
|
|
}
|
|
|
|
func removeProtocolPrefix(url string) string {
|
|
if strings.HasPrefix(url, "https://") {
|
|
return strings.TrimPrefix(url, "https://")
|
|
} else if strings.HasPrefix(url, "http://") {
|
|
return strings.TrimPrefix(url, "http://")
|
|
}
|
|
return url
|
|
}
|
|
|
|
// ConfigureProxy adds existing proxy configuration into provided transport object.
|
|
func ConfigureProxy(deployContext *chetypes.DeployContext, transport *http.Transport) {
|
|
config := httpproxy.Config{
|
|
HTTPProxy: deployContext.Proxy.HttpProxy,
|
|
HTTPSProxy: deployContext.Proxy.HttpsProxy,
|
|
NoProxy: deployContext.Proxy.NoProxy,
|
|
}
|
|
proxyFunc := config.ProxyFunc()
|
|
transport.Proxy = func(r *http.Request) (*url.URL, error) {
|
|
theProxyURL, err := proxyFunc(r.URL)
|
|
if err != nil {
|
|
logrus.Warnf("Error when trying to get the proxy to access TLS endpoint URL: %s - %s", r.URL, err)
|
|
}
|
|
if theProxyURL != nil {
|
|
logrus.Infof("Using proxy: %s to access TLS endpoint URL: %s", theProxyURL, r.URL)
|
|
} else {
|
|
logrus.Infof("Proxy isn't used to access TLS endpoint URL: %s", r.URL)
|
|
}
|
|
return theProxyURL, err
|
|
}
|
|
}
|