Merge pull request #12089 from sleshchenko/selfSignedCerts

Add an ability to run Che with https endpoints with self-signed certificates
6.19.x
Sergii Leshchenko 2018-12-11 15:57:12 +02:00 committed by GitHub
commit 49280a495c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 635 additions and 80 deletions

View File

@ -192,13 +192,25 @@ else
echo "Exec Agent binary is downloaded remotely"
# Use curl
if [ ${CURL_INSTALLED} = true ]; then
if curl -o /dev/null --silent --head --fail $(echo ${AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g'); then
curl -o $(echo ${TARGET_AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g' | sed 's/file:\/\///g') -s $(echo ${AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g')
elif curl -o /dev/null --silent --head --fail $(echo ${AGENT_BINARIES_URI} | sed 's/-\${PREFIX}//g'); then
curl -o $(echo ${TARGET_AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g' | sed 's/file:\/\///g') -s $(echo ${AGENT_BINARIES_URI} | sed 's/-\${PREFIX}//g')
CA_ARG=""
if [ -f /tmp/che/secret/ca.crt ]; then
echo "Certificate File /tmp/che/secret/ca.crt will be used for binaries downloading"
CA_ARG="--cacert /tmp/che/secret/ca.crt"
fi
if curl ${CA_ARG} -o /dev/null --silent --head --fail $(echo ${AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g'); then
curl ${CA_ARG} -o $(echo ${TARGET_AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g' | sed 's/file:\/\///g') -s $(echo ${AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g')
elif curl ${CA_ARG} -o /dev/null --silent --head --fail $(echo ${AGENT_BINARIES_URI} | sed 's/-\${PREFIX}//g'); then
curl ${CA_ARG} -o $(echo ${TARGET_AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g' | sed 's/file:\/\///g') -s $(echo ${AGENT_BINARIES_URI} | sed 's/-\${PREFIX}//g')
fi
curl -s $(echo ${TARGET_AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g') | tar xzf - -C ${CHE_DIR}
else
CA_ARG=""
if [ -f /tmp/che/secret/ca.crt ]; then
echo "Certificate File /tmp/che/secret/ca.crt will be used for binaries downloading"
CA_ARG="--ca-certificate /tmp/che/secret/ca.crt"
fi
# replace https by http as wget may not be able to handle ssl
AGENT_BINARIES_URI=$(echo ${AGENT_BINARIES_URI} | sed 's/https/http/g')
@ -208,10 +220,10 @@ else
WGET_SPIDER="wget -s"
fi
LOCAL_DOWNLOAD=$(echo ${TARGET_AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g' | sed 's/file:\/\///g')
if ${WGET_SPIDER} -q $(echo ${AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g') >/dev/null; then
wget -qO ${LOCAL_DOWNLOAD} $(echo ${AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g')
elif ${WGET_SPIDER} -q $(echo ${AGENT_BINARIES_URI} | sed 's/-\${PREFIX}//g'); then
wget -qO- ${LOCAL_DOWNLOAD} $(echo ${AGENT_BINARIES_URI} | sed 's/-\${PREFIX}//g')
if ${WGET_SPIDER} ${CA_ARG} -q $(echo ${AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g') >/dev/null; then
wget ${CA_ARG} -qO ${LOCAL_DOWNLOAD} $(echo ${AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g')
elif ${WGET_SPIDER} ${CA_ARG} -q $(echo ${AGENT_BINARIES_URI} | sed 's/-\${PREFIX}//g'); then
wget ${CA_ARG} -qO- ${LOCAL_DOWNLOAD} $(echo ${AGENT_BINARIES_URI} | sed 's/-\${PREFIX}//g')
fi
tar xzf ${LOCAL_DOWNLOAD} -C ${CHE_DIR}
fi

View File

@ -186,13 +186,26 @@ else
echo "Exec Agent binary is downloaded remotely"
# Use curl
if [ ${CURL_INSTALLED} = true ]; then
if curl -o /dev/null --silent --head --fail $(echo ${AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g'); then
curl -o $(echo ${TARGET_AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g' | sed 's/file:\/\///g') -s $(echo ${AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g')
elif curl -o /dev/null --silent --head --fail $(echo ${AGENT_BINARIES_URI} | sed 's/-\${PREFIX}//g'); then
curl -o $(echo ${TARGET_AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g' | sed 's/file:\/\///g') -s $(echo ${AGENT_BINARIES_URI} | sed 's/-\${PREFIX}//g')
CA_ARG=""
if [ -f /tmp/che/secret/ca.crt ]; then
echo "Certificate File /tmp/che/secret/ca.crt will be used for binaries downloading"
CA_ARG="--cacert /tmp/che/secret/ca.crt"
fi
if curl ${CA_ARG} -o /dev/null --silent --head --fail $(echo ${AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g'); then
curl ${CA_ARG} -o $(echo ${TARGET_AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g' | sed 's/file:\/\///g') -s $(echo ${AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g')
elif curl ${CA_ARG} -o /dev/null --silent --head --fail $(echo ${AGENT_BINARIES_URI} | sed 's/-\${PREFIX}//g'); then
curl ${CA_ARG} -o $(echo ${TARGET_AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g' | sed 's/file:\/\///g') -s $(echo ${AGENT_BINARIES_URI} | sed 's/-\${PREFIX}//g')
fi
curl -s $(echo ${TARGET_AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g') | tar xzf - -C ${CHE_DIR}
else
CA_ARG=""
if [ -f /tmp/che/secret/ca.crt ]; then
echo "Certificate File /tmp/che/secret/ca.crt will be used for binaries downloading"
CA_ARG="--ca-certificate /tmp/che/secret/ca.crt"
fi
# replace https by http as wget may not be able to handle ssl
AGENT_BINARIES_URI=$(echo ${AGENT_BINARIES_URI} | sed 's/https/http/g')
@ -202,10 +215,10 @@ else
WGET_SPIDER="wget -s"
fi
LOCAL_DOWNLOAD=$(echo ${TARGET_AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g' | sed 's/file:\/\///g')
if ${WGET_SPIDER} -q $(echo ${AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g') >/dev/null; then
wget -qO ${LOCAL_DOWNLOAD} $(echo ${AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g')
elif ${WGET_SPIDER} -q $(echo ${AGENT_BINARIES_URI} | sed 's/-\${PREFIX}//g'); then
wget -qO- ${LOCAL_DOWNLOAD} $(echo ${AGENT_BINARIES_URI} | sed 's/-\${PREFIX}//g')
if ${WGET_SPIDER} ${CA_ARG} -q $(echo ${AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g') >/dev/null; then
wget ${CA_ARG} -qO ${LOCAL_DOWNLOAD} $(echo ${AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g')
elif ${WGET_SPIDER} ${CA_ARG} -q $(echo ${AGENT_BINARIES_URI} | sed 's/-\${PREFIX}//g'); then
wget ${CA_ARG} -qO- ${LOCAL_DOWNLOAD} $(echo ${AGENT_BINARIES_URI} | sed 's/-\${PREFIX}//g')
fi
tar xzf ${LOCAL_DOWNLOAD} -C ${CHE_DIR}
fi

View File

@ -10,7 +10,7 @@
version = "v3.1.0"
[[projects]]
digest = "1:9c9f33afa55018341587f251191382f8ddc7503826edcbbba7d421827b7616b9"
digest = "1:1f62c7f600ff6eb10f38bd414dd112b244ebadfd611bb50bedad3424743b66a9"
name = "github.com/eclipse/che-go-jsonrpc"
packages = [
".",
@ -19,8 +19,8 @@
"jsonrpcws",
]
pruneopts = "UT"
revision = "8449a748a2cdfa68f54d2d72e2b02f539f1cd2c5"
version = "0.1.0"
revision = "87cdb8da2597bc22a91f8dcff72999ac8fe5cd8c"
version = "0.2.0"
[[projects]]
digest = "1:b1888d094847a5198b91d76a299e45c2c8debe9f9b9eb9a6e7b1dc7ec2a27513"

View File

@ -1,6 +1,6 @@
[[constraint]]
name = "github.com/eclipse/che-go-jsonrpc"
version = "=0.1.0"
version = "=0.2.0"
[[constraint]]
name = "github.com/dgrijalva/jwt-go"

View File

@ -55,6 +55,9 @@ var (
// LogsEndpointReconnectPeriodSec how much time(seconds) is between logs endpoint reconnect attempts.
LogsEndpointReconnectPeriodSec int
// SelfSignedCertificateFilePath path to certificate file that should be used while connection establishing
SelfSignedCertificateFilePath string
)
func init() {
@ -127,6 +130,12 @@ func init() {
`Time(in seconds) between attempts to reconnect to push-logs-endpoint.
Bootstrapper tries to reconnect to push-logs-endpoint when previously established connection lost`,
)
flag.StringVar(
&SelfSignedCertificateFilePath,
"cacert",
"",
"Path to Certificate that should be used while connection establishing",
)
}
// Parse parses configuration.
@ -180,6 +189,9 @@ func Print() {
log.Printf(" Push endpoint: %s", PushStatusesEndpoint)
log.Printf(" Push logs endpoint: %s", PushLogsEndpoint)
log.Printf(" Auth enabled: %t", AuthEnabled)
if (SelfSignedCertificateFilePath != "") {
log.Printf(" Self signed certificate %s", SelfSignedCertificateFilePath)
}
log.Print(" Runtime ID:")
log.Printf(" Workspace: %s", RuntimeID.Workspace)
log.Printf(" Environment: %s", RuntimeID.Environment)

View File

@ -16,11 +16,14 @@ import (
"log"
"os"
"github.com/eclipse/che/agents/go-agents/bootstrapper/booter"
"github.com/eclipse/che/agents/go-agents/bootstrapper/cfg"
"crypto/tls"
"crypto/x509"
"github.com/eclipse/che-go-jsonrpc"
"github.com/eclipse/che-go-jsonrpc/jsonrpcws"
"github.com/eclipse/che/agents/go-agents/bootstrapper/booter"
"github.com/eclipse/che/agents/go-agents/bootstrapper/cfg"
"github.com/eclipse/che/agents/go-agents/core/process"
"io/ioutil"
)
func main() {
@ -29,6 +32,10 @@ func main() {
cfg.Parse()
cfg.Print()
if cfg.SelfSignedCertificateFilePath != "" {
configureCertPool(cfg.SelfSignedCertificateFilePath)
}
process.SetShellInterpreter("/bin/sh")
booter.Init(
@ -62,6 +69,30 @@ func main() {
}
}
func configureCertPool(customCertificateFilePath string) {
// Get the SystemCertPool, continue with an empty pool on error
rootCAs, _ := x509.SystemCertPool()
if rootCAs == nil {
rootCAs = x509.NewCertPool()
}
// Read in the cert file
certs, err := ioutil.ReadFile(customCertificateFilePath)
if err != nil {
log.Fatalf("Failed to read custom certificate %q. Error: %v", customCertificateFilePath, err)
}
// Append our cert to the system pool
if ok := rootCAs.AppendCertsFromPEM(certs); !ok {
log.Fatalf("Failed to append %q to RootCAs: %v", customCertificateFilePath, err)
}
// Trust the augmented cert pool in our client
jsonrpcws.DefaultDialer.TLSClientConfig = &tls.Config{
RootCAs: rootCAs,
}
}
func connectOrFail(endpoint string, token string) *jsonrpc.Tunnel {
tunnel, err := connect(endpoint, token)
if err != nil {

View File

@ -0,0 +1,32 @@
Websocket API
---
[JSON RPC 2.0](http://www.jsonrpc.org/specification) protocol is used for client-server
communication, but:
- `params` is always json object(never array)
- server to client notifications are treated as Events
the apis include some of the following fields:
```json
{
"jsonrpc" : "2.0",
"method": "...",
"id": "...",
"params": { },
"error" : { },
"result" : { }
}
```
these fields are part of the protocol so they are not documented.
##### Websocket messages order
The order is respected
```
Message fragments MUST be delivered to the recipient in the order sent by the sender.
```
Helpful Sources
* https://tools.ietf.org/html/rfc6455 (search the sentence above)
* http://stackoverflow.com/questions/11804721/can-websocket-messages-arrive-out-of-order
* http://stackoverflow.com/questions/14287224/processing-websockets-messages-in-order-of-receiving

View File

@ -41,13 +41,19 @@ import (
)
var (
defaultUpgrader = &websocket.Upgrader{
// default upgrader that is used for upgrading http connection to WebSocket
// may be changed by client if custom settings are needed
DefaultUpgrader = &websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
CheckOrigin: func(r *http.Request) bool {
return true
},
}
// default dialer that is used for WebSocket connection establishing
// may be changed by client if custom settings are needed
DefaultDialer = websocket.DefaultDialer
)
// Dial establishes a new client WebSocket connection.
@ -59,7 +65,7 @@ func Dial(url string, token string) (*NativeConnAdapter, error) {
headers = make(map[string][]string)
headers.Add("Authorization", token)
}
conn, _, err := websocket.DefaultDialer.Dial(url, headers)
conn, _, err := DefaultDialer.Dial(url, headers)
if err != nil {
return nil, err
}
@ -68,7 +74,7 @@ func Dial(url string, token string) (*NativeConnAdapter, error) {
// Upgrade upgrades http connection to WebSocket connection.
func Upgrade(w http.ResponseWriter, r *http.Request) (*NativeConnAdapter, error) {
conn, err := defaultUpgrader.Upgrade(w, r, nil)
conn, err := DefaultUpgrader.Upgrade(w, r, nil)
if err != nil {
return nil, err
}

View File

@ -137,8 +137,14 @@ WORKSPACE_MASTER_URI=$(echo $CHE_API | cut -d / -f 1-3)
## Evaluate variables now that prefix is defined
eval "DOWNLOAD_AGENT_BINARIES_URI=${DOWNLOAD_AGENT_BINARIES_URI}"
CA_ARG=""
if [ -f /tmp/che/secret/ca.crt ]; then
echo "Certificate File /tmp/che/secret/ca.crt will be used for binaries downloading"
CA_ARG="--cacert /tmp/che/secret/ca.crt"
fi
echo Downloading java LS
curl -sL ${DOWNLOAD_AGENT_BINARIES_URI} | tar xzf - -C ${LS_DIR}
curl ${CA_ARG} -sL ${DOWNLOAD_AGENT_BINARIES_URI} | tar xzf - -C ${LS_DIR}
echo writing start script to ${LS_LAUNCHER}
touch ${LS_LAUNCHER}

View File

@ -188,13 +188,25 @@ else
echo "Terminal Agent binary is downloaded remotely"
# Use curl
if [ ${CURL_INSTALLED} = true ]; then
if curl -o /dev/null --silent --head --fail $(echo ${AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g'); then
curl -o $(echo ${TARGET_AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g' | sed 's/file:\/\///g') -s $(echo ${AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g')
elif curl -o /dev/null --silent --head --fail $(echo ${AGENT_BINARIES_URI} | sed 's/-\${PREFIX}//g'); then
curl -o $(echo ${TARGET_AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g' | sed 's/file:\/\///g') -s $(echo ${AGENT_BINARIES_URI} | sed 's/-\${PREFIX}//g')
CA_ARG=""
if [ -f /tmp/che/secret/ca.crt ]; then
echo "Certificate File /tmp/che/secret/ca.crt will be used for binaries downloading"
CA_ARG="--cacert /tmp/che/secret/ca.crt"
fi
if curl ${CA_ARG} -o /dev/null --silent --head --fail $(echo ${AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g'); then
curl ${CA_ARG} -o $(echo ${TARGET_AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g' | sed 's/file:\/\///g') -s $(echo ${AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g')
elif curl ${CA_ARG} -o /dev/null --silent --head --fail $(echo ${AGENT_BINARIES_URI} | sed 's/-\${PREFIX}//g'); then
curl ${CA_ARG} -o $(echo ${TARGET_AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g' | sed 's/file:\/\///g') -s $(echo ${AGENT_BINARIES_URI} | sed 's/-\${PREFIX}//g')
fi
curl -s $(echo ${TARGET_AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g') | tar xzf - -C ${CHE_DIR}
else
CA_ARG=""
if [ -f /tmp/che/secret/ca.crt ]; then
echo "Certificate File /tmp/che/secret/ca.crt will be used for binaries downloading"
CA_ARG="--ca-certificate /tmp/che/secret/ca.crt"
fi
# replace https by http as wget may not be able to handle ssl
AGENT_BINARIES_URI=$(echo ${AGENT_BINARIES_URI} | sed 's/https/http/g')
@ -204,10 +216,10 @@ else
WGET_SPIDER="wget -s"
fi
LOCAL_DOWNLOAD=$(echo ${TARGET_AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g' | sed 's/file:\/\///g')
if ${WGET_SPIDER} -q $(echo ${AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g') >/dev/null; then
wget -qO ${LOCAL_DOWNLOAD} $(echo ${AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g')
elif ${WGET_SPIDER} -q $(echo ${AGENT_BINARIES_URI} | sed 's/-\${PREFIX}//g'); then
wget -qO- ${LOCAL_DOWNLOAD} $(echo ${AGENT_BINARIES_URI} | sed 's/-\${PREFIX}//g')
if ${WGET_SPIDER} ${CA_ARG} -q $(echo ${AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g') >/dev/null; then
wget ${CA_ARG} -qO ${LOCAL_DOWNLOAD} $(echo ${AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g')
elif ${WGET_SPIDER} ${CA_ARG} -q $(echo ${AGENT_BINARIES_URI} | sed 's/-\${PREFIX}//g'); then
wget ${CA_ARG} -qO- ${LOCAL_DOWNLOAD} $(echo ${AGENT_BINARIES_URI} | sed 's/-\${PREFIX}//g')
fi
tar xzf ${LOCAL_DOWNLOAD} -C ${CHE_DIR}
fi

View File

@ -181,13 +181,26 @@ else
echo "Terminal Agent binary is downloaded remotely"
# Use curl
if [ ${CURL_INSTALLED} = true ]; then
if curl -o /dev/null --silent --head --fail $(echo ${AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g'); then
curl -o $(echo ${TARGET_AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g' | sed 's/file:\/\///g') -s $(echo ${AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g')
elif curl -o /dev/null --silent --head --fail $(echo ${AGENT_BINARIES_URI} | sed 's/-\${PREFIX}//g'); then
curl -o $(echo ${TARGET_AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g' | sed 's/file:\/\///g') -s $(echo ${AGENT_BINARIES_URI} | sed 's/-\${PREFIX}//g')
CA_ARG=""
if [ -f /tmp/che/secret/ca.crt ]; then
echo "Certificate File /tmp/che/secret/ca.crt will be used for binaries downloading"
CA_ARG="--cacert /tmp/che/secret/ca.crt"
fi
if curl ${CA_ARG} -o /dev/null --silent --head --fail $(echo ${AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g'); then
curl ${CA_ARG} -o $(echo ${TARGET_AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g' | sed 's/file:\/\///g') -s $(echo ${AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g')
elif curl ${CA_ARG} -o /dev/null --silent --head --fail $(echo ${AGENT_BINARIES_URI} | sed 's/-\${PREFIX}//g'); then
curl ${CA_ARG} -o $(echo ${TARGET_AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g' | sed 's/file:\/\///g') -s $(echo ${AGENT_BINARIES_URI} | sed 's/-\${PREFIX}//g')
fi
curl -s $(echo ${TARGET_AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g') | tar xzf - -C ${CHE_DIR}
else
CA_ARG=""
if [ -f /tmp/che/secret/ca.crt ]; then
echo "Certificate File /tmp/che/secret/ca.crt will be used for binaries downloading"
CA_ARG="--ca-certificate /tmp/che/secret/ca.crt"
fi
# replace https by http as wget may not be able to handle ssl
AGENT_BINARIES_URI=$(echo ${AGENT_BINARIES_URI} | sed 's/https/http/g')
@ -197,10 +210,10 @@ else
WGET_SPIDER="wget -s"
fi
LOCAL_DOWNLOAD=$(echo ${TARGET_AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g' | sed 's/file:\/\///g')
if ${WGET_SPIDER} -q $(echo ${AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g') >/dev/null; then
wget -qO ${LOCAL_DOWNLOAD} $(echo ${AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g')
elif ${WGET_SPIDER} -q $(echo ${AGENT_BINARIES_URI} | sed 's/-\${PREFIX}//g'); then
wget -qO- ${LOCAL_DOWNLOAD} $(echo ${AGENT_BINARIES_URI} | sed 's/-\${PREFIX}//g')
if ${WGET_SPIDER} ${CA_ARG} -q $(echo ${AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g') >/dev/null; then
wget ${CA_ARG} -qO ${LOCAL_DOWNLOAD} $(echo ${AGENT_BINARIES_URI} | sed 's/\${PREFIX}/'${PREFIX}'/g')
elif ${WGET_SPIDER} ${CA_ARG} -q $(echo ${AGENT_BINARIES_URI} | sed 's/-\${PREFIX}//g'); then
wget ${CA_ARG} -qO- ${LOCAL_DOWNLOAD} $(echo ${AGENT_BINARIES_URI} | sed 's/-\${PREFIX}//g')
fi
tar xzf ${LOCAL_DOWNLOAD} -C ${CHE_DIR}
fi

View File

@ -39,6 +39,44 @@
JAVA_VERSION=$(java -version 2>&1 | head -n 1 | cut -d'"' -f2 | cut -d'.' -f1 | sed 's/[^0-9]*//g')
[ "$JAVA_VERSION" -ge 9 ] && JAVA_OPTS="$JAVA_OPTS --add-modules java.activation --add-modules java.xml.bind"
add_cert_to_truststore() {
SELF_SIGNED_CERT=/tmp/che/secret/ca.crt
if [ ! -f $SELF_SIGNED_CERT ]; then
return 0;
fi
mkdir -p $CHE_LOCAL_CONF_DIR/conf
WSAGENT_JAVA_TRUST_STORE=$CHE_LOCAL_CONF_DIR/conf/wsagent_cacerts
DEFAULT_JAVA_TRUST_STORE=$JAVA_HOME/jre/lib/security/cacerts
if [ -f $DEFAULT_JAVA_TRUST_STORE ]; then
cp $DEFAULT_JAVA_TRUST_STORE $WSAGENT_JAVA_TRUST_STORE
echo "Found a self-signed cert. Workspace Agent Java trust store will be based ${DEFAULT_JAVA_TRUST_STORE}"
else
DEFAULT_JAVA_TRUST_STORE=$JAVA_HOME/lib/security/cacerts
if [ -f $DEFAULT_JAVA_TRUST_STORE ]; then
cp $DEFAULT_JAVA_TRUST_STORE $WSAGENT_JAVA_TRUST_STORE
echo "Found a self-signed cert. Workspace Agent Java trust store will be based ${DEFAULT_JAVA_TRUST_STORE}"
fi
fi
DEFAULT_JAVA_TRUST_STORE_PASS="changeit"
JAVA_TRUST_STORE_PASS=${JAVA_TRUST_STORE_PASS:-${DEFAULT_JAVA_TRUST_STORE_PASS}}
# make sure that owner has permissions to write and other groups have permissions to read
chmod 644 $WSAGENT_JAVA_TRUST_STORE
echo yes | keytool -keystore $WSAGENT_JAVA_TRUST_STORE -importcert -alias HOSTDOMAIN -file $SELF_SIGNED_CERT -storepass $JAVA_TRUST_STORE_PASS > /dev/null
# allow only read by all groups
chmod 444 $WSAGENT_JAVA_TRUST_STORE
export JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStore=$WSAGENT_JAVA_TRUST_STORE -Djavax.net.ssl.trustStorePassword=changeit"
}
add_cert_to_truststore
export JAVA_OPTS="$JAVA_OPTS -Dche.logs.dir=${CHE_LOGS_DIR} -Dche.logs.level=${CHE_LOGS_LEVEL} -Djuli-logback.configurationFile=file:$CATALINA_HOME/conf/tomcat-logger.xml"
[ -z "${SERVER_PORT}" ] && SERVER_PORT=8080

View File

@ -20,6 +20,7 @@ import org.eclipse.che.commons.annotation.Traced;
import org.eclipse.che.commons.tracing.TracingTags;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment;
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.pvc.WorkspaceVolumesStrategy;
import org.eclipse.che.workspace.infrastructure.kubernetes.provision.CertificateProvisioner;
import org.eclipse.che.workspace.infrastructure.kubernetes.provision.ImagePullSecretProvisioner;
import org.eclipse.che.workspace.infrastructure.kubernetes.provision.IngressTlsProvisioner;
import org.eclipse.che.workspace.infrastructure.kubernetes.provision.InstallerServersPortProvisioner;
@ -54,21 +55,22 @@ public interface KubernetesEnvironmentProvisioner<T extends KubernetesEnvironmen
private static final Logger LOG =
LoggerFactory.getLogger(KubernetesEnvironmentProvisionerImpl.class);
private boolean pvcEnabled;
private WorkspaceVolumesStrategy volumesStrategy;
private UniqueNamesProvisioner<KubernetesEnvironment> uniqueNamesProvisioner;
private ServersConverter<KubernetesEnvironment> serversConverter;
private EnvVarsConverter envVarsConverter;
private RestartPolicyRewriter restartPolicyRewriter;
private RamLimitRequestProvisioner ramLimitProvisioner;
private InstallerServersPortProvisioner installerServersPortProvisioner;
private LogsVolumeMachineProvisioner logsVolumeMachineProvisioner;
private SecurityContextProvisioner securityContextProvisioner;
private PodTerminationGracePeriodProvisioner podTerminationGracePeriodProvisioner;
private IngressTlsProvisioner externalServerIngressTlsProvisioner;
private ImagePullSecretProvisioner imagePullSecretProvisioner;
private ProxySettingsProvisioner proxySettingsProvisioner;
private ServiceAccountProvisioner serviceAccountProvisioner;
private final boolean pvcEnabled;
private final WorkspaceVolumesStrategy volumesStrategy;
private final UniqueNamesProvisioner<KubernetesEnvironment> uniqueNamesProvisioner;
private final ServersConverter<KubernetesEnvironment> serversConverter;
private final EnvVarsConverter envVarsConverter;
private final RestartPolicyRewriter restartPolicyRewriter;
private final RamLimitRequestProvisioner ramLimitProvisioner;
private final InstallerServersPortProvisioner installerServersPortProvisioner;
private final LogsVolumeMachineProvisioner logsVolumeMachineProvisioner;
private final SecurityContextProvisioner securityContextProvisioner;
private final PodTerminationGracePeriodProvisioner podTerminationGracePeriodProvisioner;
private final IngressTlsProvisioner externalServerIngressTlsProvisioner;
private final ImagePullSecretProvisioner imagePullSecretProvisioner;
private final ProxySettingsProvisioner proxySettingsProvisioner;
private final ServiceAccountProvisioner serviceAccountProvisioner;
private final CertificateProvisioner certificateProvisioner;
@Inject
public KubernetesEnvironmentProvisionerImpl(
@ -86,7 +88,8 @@ public interface KubernetesEnvironmentProvisioner<T extends KubernetesEnvironmen
IngressTlsProvisioner externalServerIngressTlsProvisioner,
ImagePullSecretProvisioner imagePullSecretProvisioner,
ProxySettingsProvisioner proxySettingsProvisioner,
ServiceAccountProvisioner serviceAccountProvisioner) {
ServiceAccountProvisioner serviceAccountProvisioner,
CertificateProvisioner certificateProvisioner) {
this.pvcEnabled = pvcEnabled;
this.volumesStrategy = volumesStrategy;
this.uniqueNamesProvisioner = uniqueNamesProvisioner;
@ -102,6 +105,7 @@ public interface KubernetesEnvironmentProvisioner<T extends KubernetesEnvironmen
this.imagePullSecretProvisioner = imagePullSecretProvisioner;
this.proxySettingsProvisioner = proxySettingsProvisioner;
this.serviceAccountProvisioner = serviceAccountProvisioner;
this.certificateProvisioner = certificateProvisioner;
}
@Traced
@ -139,6 +143,7 @@ public interface KubernetesEnvironmentProvisioner<T extends KubernetesEnvironmen
imagePullSecretProvisioner.provision(k8sEnv, identity);
proxySettingsProvisioner.provision(k8sEnv, identity);
serviceAccountProvisioner.provision(k8sEnv, identity);
certificateProvisioner.provision(k8sEnv, identity);
LOG.debug("Provisioning Kubernetes environment done for workspace '{}'", workspaceId);
}
}

View File

@ -34,6 +34,7 @@ import org.eclipse.che.dto.server.DtoFactory;
import org.eclipse.che.workspace.infrastructure.kubernetes.StartSynchronizer;
import org.eclipse.che.workspace.infrastructure.kubernetes.model.KubernetesMachineImpl;
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.KubernetesNamespace;
import org.eclipse.che.workspace.infrastructure.kubernetes.provision.CertificateProvisioner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -43,6 +44,7 @@ import org.slf4j.LoggerFactory;
* @author Sergii Leshchenko
*/
public class KubernetesBootstrapper extends AbstractBootstrapper {
private static final int EXEC_TIMEOUT_MIN = 5;
private static final Logger LOG = LoggerFactory.getLogger(KubernetesBootstrapper.class);
@ -65,6 +67,7 @@ public class KubernetesBootstrapper extends AbstractBootstrapper {
private final EventService eventService;
private final KubernetesNamespace namespace;
private final StartSynchronizer startSynchronizer;
private final CertificateProvisioner certProvisioner;
@Inject
public KubernetesBootstrapper(
@ -79,7 +82,8 @@ public class KubernetesBootstrapper extends AbstractBootstrapper {
@Named("che.infra.kubernetes.bootstrapper.server_check_period_sec")
int serverCheckPeriodSeconds,
@Named("che.workspace.logs.root_dir") String logsRootPath,
EventService eventService) {
EventService eventService,
CertificateProvisioner certProvisioner) {
super(
kubernetesMachine.getName(),
runtimeIdentity,
@ -95,6 +99,7 @@ public class KubernetesBootstrapper extends AbstractBootstrapper {
this.bootstrapperLogsFolder = logsRootPath + "/bootstrapper";
this.eventService = eventService;
this.namespace = namespace;
this.certProvisioner = certProvisioner;
this.bootstrapperLogsFile = bootstrapperLogsFolder + "/bootstrapper.log";
this.startSynchronizer = startSynchronizer;
}
@ -134,6 +139,7 @@ public class KubernetesBootstrapper extends AbstractBootstrapper {
+ " -file "
+ BOOTSTRAPPER_DIR
+ CONFIG_FILE
+ (certProvisioner.isConfigured() ? " -cacert " + certProvisioner.getCertPath() : "")
// redirects command output and makes the bootstrapping process detached,
// to avoid the holding of the socket connection for exec watcher.
+ " > "
@ -161,14 +167,20 @@ public class KubernetesBootstrapper extends AbstractBootstrapper {
LOG.debug("Bootstrapping {}:{}. Downloading bootstrapper binary", runtimeIdentity, mName);
exec(
outputConsumer,
"curl",
// -f, --fail Fail silently (no output at all) on HTTP errors
// -s, --silent Silent mode
// -S, --show-error Show error even when -s is used
// -o, --output <file> Write to file instead of stdout
"-fsSo",
BOOTSTRAPPER_DIR + BOOTSTRAPPER_FILE,
bootstrapperBinaryUrl);
"sh",
"-c",
"curl"
+ (certProvisioner.isConfigured() ? " --cacert " + certProvisioner.getCertPath() : "")
+
// -f, --fail Fail silently (no output at all) on HTTP errors
// -s, --silent Silent mode
// -S, --show-error Show error even when -s is used
// -o, --output <file> Write to file instead of stdout
" -fsSo "
+ BOOTSTRAPPER_DIR
+ BOOTSTRAPPER_FILE
+ " "
+ bootstrapperBinaryUrl);
exec(outputConsumer, "chmod", "+x", BOOTSTRAPPER_DIR + BOOTSTRAPPER_FILE);
startSynchronizer.checkFailure();

View File

@ -0,0 +1,125 @@
/*
* Copyright (c) 2012-2018 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 org.eclipse.che.workspace.infrastructure.kubernetes.provision;
import static com.google.common.base.Strings.isNullOrEmpty;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Inject;
import io.fabric8.kubernetes.api.model.Container;
import io.fabric8.kubernetes.api.model.Pod;
import io.fabric8.kubernetes.api.model.SecretBuilder;
import io.fabric8.kubernetes.api.model.SecretVolumeSourceBuilder;
import io.fabric8.kubernetes.api.model.Volume;
import io.fabric8.kubernetes.api.model.VolumeBuilder;
import io.fabric8.kubernetes.api.model.VolumeMount;
import io.fabric8.kubernetes.api.model.VolumeMountBuilder;
import java.util.Optional;
import javax.inject.Named;
import javax.inject.Singleton;
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment;
/**
* Mount configured self-signed certificate as file in each workspace machines if configured.
*
* @author Sergii Leshchenko
*/
@Singleton
public class CertificateProvisioner implements ConfigurationProvisioner<KubernetesEnvironment> {
public static final String CHE_SELF_SIGNED_CERT_SECRET = "che-self-signed-cert";
public static final String CHE_SELF_SIGNED_CERT_VOLUME = "che-self-signed-cert";
public static final String CERT_MOUNT_PATH = "/tmp/che/secret/";
public static final String CA_CERT_FILE = "ca.crt";
@Inject(optional = true)
@Named("che.self_signed_cert")
private String certificate;
public CertificateProvisioner() {}
@VisibleForTesting
CertificateProvisioner(String certificate) {
this.certificate = certificate;
}
public boolean isConfigured() {
return !isNullOrEmpty(certificate);
}
public String getCertPath() {
return CERT_MOUNT_PATH + CA_CERT_FILE;
}
@Override
public void provision(KubernetesEnvironment k8sEnv, RuntimeIdentity identity)
throws InfrastructureException {
if (!isConfigured()) {
return;
}
k8sEnv
.getSecrets()
.put(
CHE_SELF_SIGNED_CERT_SECRET,
new SecretBuilder()
.withNewMetadata()
.withName(CHE_SELF_SIGNED_CERT_SECRET)
.endMetadata()
.withStringData(ImmutableMap.of(CA_CERT_FILE, certificate))
.build());
for (Pod pod : k8sEnv.getPods().values()) {
Optional<Volume> certVolume =
pod.getSpec()
.getVolumes()
.stream()
.filter(v -> v.getName().equals(CHE_SELF_SIGNED_CERT_VOLUME))
.findAny();
if (!certVolume.isPresent()) {
pod.getSpec().getVolumes().add(buildCertSecretVolume());
}
for (Container container : pod.getSpec().getContainers()) {
Optional<VolumeMount> certVolumeMount =
container
.getVolumeMounts()
.stream()
.filter(vm -> vm.getName().equals(CHE_SELF_SIGNED_CERT_VOLUME))
.findAny();
if (!certVolumeMount.isPresent()) {
container.getVolumeMounts().add(buildCertVolumeMount());
}
}
}
}
private VolumeMount buildCertVolumeMount() {
return new VolumeMountBuilder()
.withName(CHE_SELF_SIGNED_CERT_VOLUME)
.withNewReadOnly(true)
.withMountPath(CERT_MOUNT_PATH)
.build();
}
private Volume buildCertSecretVolume() {
return new VolumeBuilder()
.withName(CHE_SELF_SIGNED_CERT_VOLUME)
.withSecret(
new SecretVolumeSourceBuilder().withSecretName(CHE_SELF_SIGNED_CERT_SECRET).build())
.build();
}
}

View File

@ -18,6 +18,7 @@ import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
import org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesEnvironmentProvisioner.KubernetesEnvironmentProvisionerImpl;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment;
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.pvc.WorkspaceVolumesStrategy;
import org.eclipse.che.workspace.infrastructure.kubernetes.provision.CertificateProvisioner;
import org.eclipse.che.workspace.infrastructure.kubernetes.provision.ImagePullSecretProvisioner;
import org.eclipse.che.workspace.infrastructure.kubernetes.provision.IngressTlsProvisioner;
import org.eclipse.che.workspace.infrastructure.kubernetes.provision.InstallerServersPortProvisioner;
@ -62,6 +63,7 @@ public class KubernetesEnvironmentProvisionerTest {
@Mock private ImagePullSecretProvisioner imagePullSecretProvisioner;
@Mock private ProxySettingsProvisioner proxySettingsProvisioner;
@Mock private ServiceAccountProvisioner serviceAccountProvisioner;
@Mock private CertificateProvisioner certificateProvisioner;
private KubernetesEnvironmentProvisioner<KubernetesEnvironment> k8sInfraProvisioner;
@ -85,7 +87,8 @@ public class KubernetesEnvironmentProvisionerTest {
externalServerIngressTlsProvisioner,
imagePullSecretProvisioner,
proxySettingsProvisioner,
serviceAccountProvisioner);
serviceAccountProvisioner,
certificateProvisioner);
provisionOrder =
inOrder(
installerServersPortProvisioner,
@ -101,7 +104,8 @@ public class KubernetesEnvironmentProvisionerTest {
externalServerIngressTlsProvisioner,
imagePullSecretProvisioner,
proxySettingsProvisioner,
serviceAccountProvisioner);
serviceAccountProvisioner,
certificateProvisioner);
}
@Test
@ -128,6 +132,7 @@ public class KubernetesEnvironmentProvisionerTest {
provisionOrder.verify(imagePullSecretProvisioner).provision(eq(k8sEnv), eq(runtimeIdentity));
provisionOrder.verify(proxySettingsProvisioner).provision(eq(k8sEnv), eq(runtimeIdentity));
provisionOrder.verify(serviceAccountProvisioner).provision(eq(k8sEnv), eq(runtimeIdentity));
provisionOrder.verify(certificateProvisioner).provision(eq(k8sEnv), eq(runtimeIdentity));
provisionOrder.verifyNoMoreInteractions();
}
}

View File

@ -0,0 +1,174 @@
/*
* Copyright (c) 2012-2018 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 org.eclipse.che.workspace.infrastructure.kubernetes.provision;
import static org.eclipse.che.workspace.infrastructure.kubernetes.provision.CertificateProvisioner.CA_CERT_FILE;
import static org.eclipse.che.workspace.infrastructure.kubernetes.provision.CertificateProvisioner.CERT_MOUNT_PATH;
import static org.eclipse.che.workspace.infrastructure.kubernetes.provision.CertificateProvisioner.CHE_SELF_SIGNED_CERT_SECRET;
import static org.eclipse.che.workspace.infrastructure.kubernetes.provision.CertificateProvisioner.CHE_SELF_SIGNED_CERT_VOLUME;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import io.fabric8.kubernetes.api.model.Container;
import io.fabric8.kubernetes.api.model.ContainerBuilder;
import io.fabric8.kubernetes.api.model.Pod;
import io.fabric8.kubernetes.api.model.PodBuilder;
import io.fabric8.kubernetes.api.model.Secret;
import io.fabric8.kubernetes.api.model.SecretVolumeSource;
import io.fabric8.kubernetes.api.model.Volume;
import io.fabric8.kubernetes.api.model.VolumeMount;
import java.util.List;
import java.util.Map;
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment;
import org.mockito.Mock;
import org.mockito.testng.MockitoTestNGListener;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
/**
* Tests {@link CertificateProvisioner}.
*
* @author Sergii Leshchenko
*/
@Listeners(MockitoTestNGListener.class)
public class CertificateProvisionerTest {
public static final String CERT_CONTENT = "--BEGIN FJASBNDF END";
@Mock private RuntimeIdentity runtimeId;
private CertificateProvisioner provisioner;
private KubernetesEnvironment k8sEnv;
@BeforeMethod
public void setUp() {
provisioner = new CertificateProvisioner("--BEGIN FJASBNDF END");
k8sEnv = KubernetesEnvironment.builder().build();
}
@Test
public void shouldReturnFalseIfCertificateIsNotSpecifiedOnIsConfiguredInvoking() {
// given
provisioner = new CertificateProvisioner("");
// when
boolean configured = provisioner.isConfigured();
// then
assertFalse(configured);
}
@Test
public void shouldReturnTrueIfCertificateIsSpecifiedOnIsConfiguredInvoking() {
// given
provisioner = new CertificateProvisioner(CERT_CONTENT);
// when
boolean configured = provisioner.isConfigured();
// then
assertTrue(configured);
}
@Test
public void shouldReturnCertPathFile() {
// when
String certPath = provisioner.getCertPath();
// then
assertEquals(certPath, "/tmp/che/secret/ca.crt");
}
@Test
public void shouldAddSecretWithCertificateIntoEnvironment() throws Exception {
// when
provisioner.provision(k8sEnv, runtimeId);
// then
Map<String, Secret> secrets = k8sEnv.getSecrets();
assertEquals(secrets.size(), 1);
Secret certSecret = secrets.get(CHE_SELF_SIGNED_CERT_SECRET);
assertNotNull(certSecret);
assertEquals(certSecret.getMetadata().getName(), CHE_SELF_SIGNED_CERT_SECRET);
assertEquals(certSecret.getStringData().get(CA_CERT_FILE), CERT_CONTENT);
}
@Test
public void shouldAddVolumeAndVolumeMountsToPodsAndContainersInEnvironment() throws Exception {
// given
k8sEnv.getPods().put("pod", createPod());
k8sEnv.getPods().put("pod2", createPod());
// when
provisioner.provision(k8sEnv, runtimeId);
// then
for (Pod pod : k8sEnv.getPods().values()) {
verifyVolumeIsPresent(pod);
for (Container container : pod.getSpec().getContainers()) {
verifyVolumeMountIsPresent(container);
}
}
}
@Test
public void
shouldNotAddVolumeAndVolumeMountsToPodsAndContainersInEnvironmentIfCertIsNotConfigured()
throws Exception {
// given
provisioner = new CertificateProvisioner("");
k8sEnv.getPods().put("pod", createPod());
k8sEnv.getPods().put("pod2", createPod());
// when
provisioner.provision(k8sEnv, runtimeId);
// then
for (Pod pod : k8sEnv.getPods().values()) {
assertTrue(pod.getSpec().getVolumes().isEmpty());
for (Container container : pod.getSpec().getContainers()) {
assertTrue(container.getVolumeMounts().isEmpty());
}
}
}
private void verifyVolumeIsPresent(Pod pod) {
List<Volume> podVolumes = pod.getSpec().getVolumes();
assertEquals(podVolumes.size(), 1);
Volume certVolume = podVolumes.get(0);
assertEquals(certVolume.getName(), CHE_SELF_SIGNED_CERT_VOLUME);
SecretVolumeSource volumeSecret = certVolume.getSecret();
assertNotNull(volumeSecret);
assertEquals(volumeSecret.getSecretName(), CHE_SELF_SIGNED_CERT_SECRET);
}
private void verifyVolumeMountIsPresent(Container container) {
List<VolumeMount> volumeMounts = container.getVolumeMounts();
assertEquals(volumeMounts.size(), 1);
VolumeMount volumeMount = volumeMounts.get(0);
assertEquals(volumeMount.getName(), CHE_SELF_SIGNED_CERT_VOLUME);
assertTrue(volumeMount.getReadOnly());
assertEquals(volumeMount.getMountPath(), CERT_MOUNT_PATH);
}
private Pod createPod() {
return new PodBuilder()
.withNewMetadata()
.endMetadata()
.withNewSpec()
.withContainers(new ContainerBuilder().build(), new ContainerBuilder().build())
.endSpec()
.build();
}
}

View File

@ -20,6 +20,7 @@ import org.eclipse.che.commons.annotation.Traced;
import org.eclipse.che.commons.tracing.TracingTags;
import org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesEnvironmentProvisioner;
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.pvc.WorkspaceVolumesStrategy;
import org.eclipse.che.workspace.infrastructure.kubernetes.provision.CertificateProvisioner;
import org.eclipse.che.workspace.infrastructure.kubernetes.provision.ImagePullSecretProvisioner;
import org.eclipse.che.workspace.infrastructure.kubernetes.provision.InstallerServersPortProvisioner;
import org.eclipse.che.workspace.infrastructure.kubernetes.provision.LogsVolumeMachineProvisioner;
@ -64,6 +65,7 @@ public class OpenShiftEnvironmentProvisioner
private final ImagePullSecretProvisioner imagePullSecretProvisioner;
private final ProxySettingsProvisioner proxySettingsProvisioner;
private final ServiceAccountProvisioner serviceAccountProvisioner;
private final CertificateProvisioner certificateProvisioner;
@Inject
public OpenShiftEnvironmentProvisioner(
@ -80,7 +82,8 @@ public class OpenShiftEnvironmentProvisioner
PodTerminationGracePeriodProvisioner podTerminationGracePeriodProvisioner,
ImagePullSecretProvisioner imagePullSecretProvisioner,
ProxySettingsProvisioner proxySettingsProvisioner,
ServiceAccountProvisioner serviceAccountProvisioner) {
ServiceAccountProvisioner serviceAccountProvisioner,
CertificateProvisioner certificateProvisioner) {
this.pvcEnabled = pvcEnabled;
this.volumesStrategy = volumesStrategy;
this.uniqueNamesProvisioner = uniqueNamesProvisioner;
@ -95,6 +98,7 @@ public class OpenShiftEnvironmentProvisioner
this.imagePullSecretProvisioner = imagePullSecretProvisioner;
this.proxySettingsProvisioner = proxySettingsProvisioner;
this.serviceAccountProvisioner = serviceAccountProvisioner;
this.certificateProvisioner = certificateProvisioner;
}
@Override
@ -128,6 +132,7 @@ public class OpenShiftEnvironmentProvisioner
imagePullSecretProvisioner.provision(osEnv, identity);
proxySettingsProvisioner.provision(osEnv, identity);
serviceAccountProvisioner.provision(osEnv, identity);
certificateProvisioner.provision(osEnv, identity);
LOG.debug(
"Provisioning OpenShift environment done for workspace '{}'", identity.getWorkspaceId());
}

View File

@ -16,6 +16,7 @@ import static org.mockito.Mockito.inOrder;
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.pvc.WorkspaceVolumesStrategy;
import org.eclipse.che.workspace.infrastructure.kubernetes.provision.CertificateProvisioner;
import org.eclipse.che.workspace.infrastructure.kubernetes.provision.ImagePullSecretProvisioner;
import org.eclipse.che.workspace.infrastructure.kubernetes.provision.InstallerServersPortProvisioner;
import org.eclipse.che.workspace.infrastructure.kubernetes.provision.LogsVolumeMachineProvisioner;
@ -59,6 +60,7 @@ public class OpenShiftEnvironmentProvisionerTest {
@Mock private ImagePullSecretProvisioner imagePullSecretProvisioner;
@Mock private ProxySettingsProvisioner proxySettingsProvisioner;
@Mock private ServiceAccountProvisioner serviceAccountProvisioner;
@Mock private CertificateProvisioner certificateProvisioner;
private OpenShiftEnvironmentProvisioner osInfraProvisioner;
@ -81,7 +83,8 @@ public class OpenShiftEnvironmentProvisionerTest {
podTerminationGracePeriodProvisioner,
imagePullSecretProvisioner,
proxySettingsProvisioner,
serviceAccountProvisioner);
serviceAccountProvisioner,
certificateProvisioner);
provisionOrder =
inOrder(
installerServersPortProvisioner,
@ -96,7 +99,8 @@ public class OpenShiftEnvironmentProvisionerTest {
podTerminationGracePeriodProvisioner,
imagePullSecretProvisioner,
proxySettingsProvisioner,
serviceAccountProvisioner);
serviceAccountProvisioner,
certificateProvisioner);
}
@Test
@ -120,6 +124,7 @@ public class OpenShiftEnvironmentProvisionerTest {
provisionOrder.verify(imagePullSecretProvisioner).provision(eq(osEnv), eq(runtimeIdentity));
provisionOrder.verify(proxySettingsProvisioner).provision(eq(osEnv), eq(runtimeIdentity));
provisionOrder.verify(serviceAccountProvisioner).provision(eq(osEnv), eq(runtimeIdentity));
provisionOrder.verify(certificateProvisioner).provision(eq(osEnv), eq(runtimeIdentity));
provisionOrder.verifyNoMoreInteractions();
}
}

View File

@ -265,13 +265,25 @@ else
echo "Workspace Agent will be downloaded from Workspace Master"
AGENT_BINARIES_URI=${DOWNLOAD_AGENT_BINARIES_URI}
if [ ${CURL_INSTALLED} = true ]; then
curl -s ${AGENT_BINARIES_URI} | tar xzf - -C ${CHE_DIR}/ws-agent
CA_ARG=""
if [ -f /tmp/che/secret/ca.crt ]; then
echo "Certificate File /tmp/che/secret/ca.crt will be used for binaries downloading"
CA_ARG="--cacert /tmp/che/secret/ca.crt"
fi
curl -s ${CA_ARG} ${AGENT_BINARIES_URI} | tar xzf - -C ${CHE_DIR}/ws-agent
else
# replace https by http as wget may not be able to handle ssl
AGENT_BINARIES_URI=$(echo ${AGENT_BINARIES_URI} | sed 's/https/http/g')
CA_ARG=""
if [ -f /tmp/che/secret/ca.crt ]; then
echo "Certificate File /tmp/che/secret/ca.crt will be used for binaries downloading"
CA_ARG="--ca-certificate /tmp/che/secret/ca.crt"
fi
# use wget
wget -qO- ${AGENT_BINARIES_URI} | tar xzf - -C ${CHE_DIR}/ws-agent
wget ${CA_ARG} -qO- ${AGENT_BINARIES_URI} | tar xzf - -C ${CHE_DIR}/ws-agent
fi
fi

View File

@ -265,13 +265,25 @@ else
echo "Workspace Agent will be downloaded from Workspace Master"
AGENT_BINARIES_URI=${DOWNLOAD_AGENT_BINARIES_URI}
if [ ${CURL_INSTALLED} = true ]; then
curl -s ${AGENT_BINARIES_URI} | tar xzf - -C ${CHE_DIR}/ws-agent
CA_ARG=""
if [ -f /tmp/che/secret/ca.crt ]; then
echo "Certificate File /tmp/che/secret/ca.crt will be used for binaries downloading"
CA_ARG="--cacert /tmp/che/secret/ca.crt"
fi
curl -s ${CA_ARG} ${AGENT_BINARIES_URI} | tar xzf - -C ${CHE_DIR}/ws-agent
else
# replace https by http as wget may not be able to handle ssl
AGENT_BINARIES_URI=$(echo ${AGENT_BINARIES_URI} | sed 's/https/http/g')
CA_ARG=""
if [ -f /tmp/che/secret/ca.crt ]; then
echo "Certificate File /tmp/che/secret/ca.crt will be used for binaries downloading"
CA_ARG="--ca-certificate /tmp/che/secret/ca.crt"
fi
# use wget
wget -qO- ${AGENT_BINARIES_URI} | tar xzf - -C ${CHE_DIR}/ws-agent
wget ${CA_ARG} -qO- ${AGENT_BINARIES_URI} | tar xzf - -C ${CHE_DIR}/ws-agent
fi
fi

View File

@ -265,13 +265,25 @@ else
echo "Workspace Agent will be downloaded from Workspace Master"
AGENT_BINARIES_URI=${DOWNLOAD_AGENT_BINARIES_URI}
if [ ${CURL_INSTALLED} = true ]; then
curl -s ${AGENT_BINARIES_URI} | tar xzf - -C ${CHE_DIR}/ws-agent
CA_ARG=""
if [ -f /tmp/che/secret/ca.crt ]; then
echo "Certificate File /tmp/che/secret/ca.crt will be used for binaries downloading"
CA_ARG="--cacert /tmp/che/secret/ca.crt"
fi
curl -s ${CA_ARG} ${AGENT_BINARIES_URI} | tar xzf - -C ${CHE_DIR}/ws-agent
else
# replace https by http as wget may not be able to handle ssl
AGENT_BINARIES_URI=$(echo ${AGENT_BINARIES_URI} | sed 's/https/http/g')
CA_ARG=""
if [ -f /tmp/che/secret/ca.crt ]; then
echo "Certificate File /tmp/che/secret/ca.crt will be used for binaries downloading"
CA_ARG="--ca-certificate /tmp/che/secret/ca.crt"
fi
# use wget
wget -qO- ${AGENT_BINARIES_URI} | tar xzf - -C ${CHE_DIR}/ws-agent
wget ${CA_ARG} -qO- ${AGENT_BINARIES_URI} | tar xzf - -C ${CHE_DIR}/ws-agent
fi
fi

View File

@ -265,13 +265,26 @@ else
echo "Workspace Agent will be downloaded from Workspace Master"
AGENT_BINARIES_URI=${DOWNLOAD_AGENT_BINARIES_URI}
if [ ${CURL_INSTALLED} = true ]; then
curl -s ${AGENT_BINARIES_URI} | tar xzf - -C ${CHE_DIR}/ws-agent
CA_ARG=""
if [ -f /tmp/che/secret/ca.crt ]; then
echo "Certificate File /tmp/che/secret/ca.crt will be used for binaries downloading"
CA_ARG="--cacert /tmp/che/secret/ca.crt"
fi
curl -s ${CA_ARG} ${AGENT_BINARIES_URI} | tar xzf - -C ${CHE_DIR}/ws-agent
else
# replace https by http as wget may not be able to handle ssl
AGENT_BINARIES_URI=$(echo ${AGENT_BINARIES_URI} | sed 's/https/http/g')
CA_ARG=""
if [ -f /tmp/che/secret/ca.crt ]; then
echo "Certificate File /tmp/che/secret/ca.crt will be used for binaries downloading"
CA_ARG="--ca-certificate /tmp/che/secret/ca.crt"
fi
# use wget
wget -qO- ${AGENT_BINARIES_URI} | tar xzf - -C ${CHE_DIR}/ws-agent
wget ${CA_ARG} -qO- ${AGENT_BINARIES_URI} | tar xzf - -C ${CHE_DIR}/ws-agent
fi
fi