Skip to content

Commit 2523505

Browse files
authored
Merge pull request #812 from oracle/OWLS-70638
WIP: Get the external operator REST certificate and private key from a Kubernetes secret
2 parents 1b981bc + 64a8973 commit 2523505

File tree

9 files changed

+162
-41
lines changed

9 files changed

+162
-41
lines changed

kubernetes/charts/weblogic-operator/templates/_operator-cm.tpl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1-
# Copyright 2018 Oracle Corporation and/or its affiliates. All rights reserved.
1+
# Copyright 2018, 2019, Oracle Corporation and/or its affiliates. All rights reserved.
22
# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl.
33

44
{{- define "operator.operatorConfigMap" }}
55
---
66
apiVersion: "v1"
77
data:
88
{{- if .externalRestEnabled }}
9+
{{- if (hasKey . "externalCertificateSecret") }}
10+
externalCertificateSecret: {{ .externalCertificateSecret | quote }}
11+
{{- else }}
912
externalOperatorCert: {{ .externalOperatorCert | quote }}
13+
{{- end }}
1014
{{- end }}
1115
serviceaccount: {{ .serviceAccount | quote }}
1216
targetNamespaces: {{ .domainNamespaces | uniq | sortAlpha | join "," | quote }}

kubernetes/charts/weblogic-operator/templates/_operator-secret.tpl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
# Copyright 2018 Oracle Corporation and/or its affiliates. All rights reserved.
1+
# Copyright 2018, 2019, Oracle Corporation and/or its affiliates. All rights reserved.
22
# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl.
33

44
{{- define "operator.operatorSecrets" }}
55
---
66
apiVersion: "v1"
77
kind: "Secret"
88
data:
9-
{{- if .externalRestEnabled }}
9+
{{- if (and .externalRestEnabled (hasKey . "externalOperatorKey")) }}
1010
externalOperatorKey: {{ .externalOperatorKey | quote }}
1111
{{- end }}
1212
metadata:

kubernetes/charts/weblogic-operator/templates/_utils.tpl

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright 2018 Oracle Corporation and/or its affiliates. All rights reserved.
1+
# Copyright 2018, 2019, Oracle Corporation and/or its affiliates. All rights reserved.
22
# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl.
33

44
{{/*
@@ -426,3 +426,35 @@ TBD - does helm provide a clone method we can use instead?
426426
{{- define "utils.cloneDictionary" -}}
427427
{{- include "utils.mergeDictionaries" (list .) -}}
428428
{{- end -}}
429+
430+
{{/*
431+
Verify that a list of values (exclude) can not be defined if another value (key) is already defined
432+
*/}}
433+
{{- define "utils.mutexValue" -}}
434+
{{- $scope := index . 0 -}}
435+
{{- $key := index . 1 -}}
436+
{{- $exclude := index . 2 -}}
437+
{{- $type := index . 3 -}}
438+
{{- $parent := $scope.validationScope -}}
439+
{{- $args := . -}}
440+
{{- $status := dict -}}
441+
{{- if hasKey $parent $key -}}
442+
{{- range $value := $exclude -}}
443+
{{- if hasKey $parent $value -}}
444+
{{- $errorMsg := cat $value "can not be present when" $key "is defined" " " -}}
445+
{{- include "utils.recordValidationError" (list $scope $errorMsg) -}}
446+
{{- $ignore := set $status "error" true -}}
447+
{{- end -}}
448+
{{- end -}}
449+
{{- end -}}
450+
{{- if not (hasKey $status "error") -}}
451+
true
452+
{{- end -}}
453+
{{- end -}}
454+
455+
{{/*
456+
Verify that a list of strings can not be defined if another string is already defined
457+
*/}}
458+
{{- define "utils.mutexString" -}}
459+
{{- include "utils.mutexValue" (append . "string") -}}
460+
{{- end -}}

kubernetes/charts/weblogic-operator/templates/_validate-inputs.tpl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright 2018 Oracle Corporation and/or its affiliates. All rights reserved.
1+
# Copyright 2018, 2019, Oracle Corporation and/or its affiliates. All rights reserved.
22
# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl.
33

44
{{- define "operator.validateInputs" -}}
@@ -12,11 +12,14 @@
1212
{{- $ignore := include "utils.verifyEnum" (list $scope "imagePullPolicy" (list "Always" "IfNotPresent" "Never")) -}}
1313
{{- $ignore := include "utils.verifyOptionalDictionaryList" (list $scope "imagePullSecrets") -}}
1414
{{- $ignore := include "utils.verifyEnum" (list $scope "javaLoggingLevel" (list "SEVERE" "WARNING" "INFO" "CONFIG" "FINE" "FINER" "FINEST")) -}}
15+
{{- $ignore := include "utils.mutexString" (list $scope "externalCertificateSecret" (list "externalOperatorKey" "externalOperatorCert")) -}}
1516
{{- if include "utils.verifyBoolean" (list $scope "externalRestEnabled") -}}
1617
{{- if $scope.externalRestEnabled -}}
1718
{{- $ignore := include "utils.verifyInteger" (list $scope "externalRestHttpsPort") -}}
18-
{{- $ignore := include "utils.verifyString" (list $scope "externalOperatorCert") -}}
19-
{{- $ignore := include "utils.verifyString" (list $scope "externalOperatorKey") -}}
19+
{{/* The following condition is for backward compatibility only */}}
20+
{{- if (or (not (hasKey $scope "externalOperatorCert")) (not (hasKey $scope "externalOperatorKey"))) -}}
21+
{{- $ignore := include "utils.verifyString" (list $scope "externalCertificateSecret") -}}
22+
{{- end -}}
2023
{{- end -}}
2124
{{- end -}}
2225
{{- if include "utils.verifyBoolean" (list $scope "remoteDebugNodePortEnabled") -}}

kubernetes/charts/weblogic-operator/values.yaml

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright 2018 Oracle Corporation and/or its affiliates. All rights reserved.
1+
# Copyright 2018, 2019, Oracle Corporation and/or its affiliates. All rights reserved.
22
# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl.
33

44
# serviceAccount specifies the name of the service account in the operator's namespace that the
@@ -52,17 +52,12 @@ externalRestEnabled: false
5252
# Otherwise, it is ignored.
5353
externalRestHttpsPort: 31001
5454

55-
# The customer supplied certificate to use for the external operator REST https interface.
56-
# The value must be a string containing a base64 encoded PEM certificate.
57-
# This parameter is required if 'externalRestEnabled' is true.
58-
# Otherwise, it is ignored.
59-
#externalOperatorCert:
60-
61-
# The customer supplied private key to use for the external operator REST https interface.
62-
# The value must be a string containing a base64 encoded PEM key.
63-
# This parameter is required if 'externalRestEnabled' is true.
64-
# Otherwise, it is ignored.
65-
#externalOperatorKey:
55+
# The name of the secret used to store the certificate and private key to use for the external operator REST https interface.
56+
# The secret has to be created in the same namespace of the welbogic operator.
57+
# This parameter is required if 'externalRestEnabled' is true. Otherwise, it is ignored.
58+
# As example, a self-sigend certificate can be created and stored in weblogic-operator-certificate using the
59+
# following sample script kubernetes/samples/scripts/rest/generate-external-rest-identity.sh
60+
#externalCertificateSecret:
6661

6762
# remoteDebugNodePortEnabled specifies whether or not the operator will start a Java remote debug server
6863
# on the provided port and suspend execution until a remote debugger has attached.

kubernetes/samples/scripts/rest/generate-external-rest-identity.sh

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,26 @@
11
#!/usr/bin/env bash
2-
# Copyright 2017, 2018, Oracle Corporation and/or its affiliates. All rights reserved.
2+
# Copyright 2017, 2019, Oracle Corporation and/or its affiliates. All rights reserved.
33
# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl.
44
#
55
# When the customer enables the operator's external REST api (by setting
66
# externalRestEnabled to true when installing the operator helm chart), the customer needs
7-
# to provide the certificate and private key for api's SSL identity too (by setting
8-
# externalOperatorCert and externalOperatorKey to the base64 encoded PEM of the cert and
9-
# key when installing the operator helm chart).
7+
# to provide the certificate and private key for api's SSL identity too (by creating a
8+
# tls secret befor the installation of the operator helm chart).
109
#
1110
# This sample script generates a self-signed certificate and private key that can be used
1211
# for the operator's external REST api when experimenting with the operator. They should
1312
# not be used in a production environment.
1413
#
1514
# The sytax of the script is:
16-
# kubernetes/samples/scripts/generate-external-rest-identity.sh <subject alternative names>
15+
# kubernetes/samples/scripts/rest/generate-external-rest-identity.sh <subject alternative names>
1716
#
1817
# <subject alternative names> lists the subject alternative names to put into the generated
1918
# self-signed certificate for the external WebLogic Operator REST https interface,
2019
# for example:
2120
# DNS:myhost,DNS:localhost,IP:127.0.0.1
2221
#
23-
# The script prints out the base64 encoded pem of the generated certificate and private key
24-
# in the same format that the operator helm chart's values.yaml requires.
22+
# The script creates the weblogic-operator-certificate secret in the weblogic-operator namespace with
23+
# the self-signed certificate and private key
2524
#
2625
# Example usage:
2726
# generate-external-rest-identity.sh IP:127.0.0.1 > my_values.yaml
@@ -130,13 +129,7 @@ openssl \
130129
-out ${OP_KEY_PEM} \
131130
2> /dev/null
132131

133-
# base64 encode the cert and private key pem
134-
CERT_DATA=`base64 -i ${OP_CERT_PEM} | tr -d '\n'`
135-
KEY_DATA=`base64 -i ${OP_KEY_PEM} | tr -d '\n'`
136-
137-
# print out the cert and pem in the form that can be added to
138-
# the operator helm chart's values.yaml
139-
echo "externalOperatorCert: ${CERT_DATA}"
140-
echo "externalOperatorKey: ${KEY_DATA}"
141-
132+
# Create the secret with the self-signed certificate and private key in the weblogic-operator namespace
133+
kubectl create secret tls "weblogic-operator-certificate" --cert=${OP_CERT_PEM} --key=${OP_KEY_PEM} -n weblogic-operator
134+
echo "externalCertificateSecret: weblogic-operator-certificate"
142135
SUCCEEDED=true

operator/src/main/java/oracle/kubernetes/operator/rest/RestConfigImpl.java

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2017, Oracle Corporation and/or its affiliates. All rights reserved.
1+
// Copyright 2017, 2019, Oracle Corporation and/or its affiliates. All rights reserved.
22
// Licensed under the Universal Permissive License v 1.0 as shown at
33
// http://oss.oracle.com/licenses/upl.
44

@@ -22,6 +22,15 @@ public class RestConfigImpl implements RestConfig {
2222

2323
private static final String OPERATOR_DIR = "/operator/";
2424
private static final String INTERNAL_REST_IDENTITY_DIR = OPERATOR_DIR + "internal-identity/";
25+
private static final String INTERNAL_CERTIFICATE =
26+
INTERNAL_REST_IDENTITY_DIR + "internalOperatorCert";
27+
private static final String INTERNAL_CERTIFICATE_KEY =
28+
INTERNAL_REST_IDENTITY_DIR + "internalOperatorKey";
29+
private static final String EXTERNAL_REST_IDENTITY_DIR = OPERATOR_DIR + "external-identity/";
30+
private static final String EXTERNAL_CERTIFICATE =
31+
EXTERNAL_REST_IDENTITY_DIR + "externalOperatorCert";
32+
private static final String EXTERNAL_CERTIFICATE_KEY =
33+
EXTERNAL_REST_IDENTITY_DIR + "externalOperatorKey";
2534

2635
/**
2736
* Constructs a RestConfigImpl.
@@ -58,13 +67,13 @@ public int getInternalHttpsPort() {
5867
/** {@inheritDoc} */
5968
@Override
6069
public String getOperatorExternalCertificateData() {
61-
return getCertificate(OPERATOR_DIR + "config/externalOperatorCert");
70+
return getCertificate(EXTERNAL_CERTIFICATE);
6271
}
6372

6473
/** {@inheritDoc} */
6574
@Override
6675
public String getOperatorInternalCertificateData() {
67-
return getCertificate(INTERNAL_REST_IDENTITY_DIR + "internalOperatorCert");
76+
return getCertificate(INTERNAL_CERTIFICATE);
6877
}
6978

7079
/** {@inheritDoc} */
@@ -94,13 +103,13 @@ public String getOperatorInternalKeyData() {
94103
/** {@inheritDoc} */
95104
@Override
96105
public String getOperatorExternalKeyFile() {
97-
return getKey(OPERATOR_DIR + "secrets/externalOperatorKey");
106+
return getKey(EXTERNAL_CERTIFICATE_KEY);
98107
}
99108

100109
/** {@inheritDoc} */
101110
@Override
102111
public String getOperatorInternalKeyFile() {
103-
return getKey(INTERNAL_REST_IDENTITY_DIR + "internalOperatorKey");
112+
return getKey(INTERNAL_CERTIFICATE_KEY);
104113
}
105114

106115
/** {@inheritDoc} */
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#!/usr/bin/env bash
2+
# Copyright 2019, Oracle Corporation and/or its affiliates. All rights reserved.
3+
# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl.
4+
5+
# do not turn on 'set -x' since it can print sensitive info, like secrets and private keys, to the operator log
6+
#set -x
7+
8+
if [ "$#" != 0 ] ; then
9+
1>&2 echo "Syntax: ${BASH_SOURCE[0]}"
10+
exit 1
11+
fi
12+
13+
EXTERNAL_CERT="externalOperatorCert"
14+
EXTERNAL_KEY="externalOperatorKey"
15+
OPERATOR_DIR="/operator"
16+
EXTERNAL_IDENTITY_DIR="${OPERATOR_DIR}/external-identity"
17+
NAMESPACE=`cat /var/run/secrets/kubernetes.io/serviceaccount/namespace`
18+
OPERATOR_CONFIG_DIR=${OPERATOR_DIR}/config
19+
OPERATOR_SECRETS_DIR=${OPERATOR_DIR}/secrets
20+
21+
# the operator runtime expects the external operator cert and private key to be in these files:
22+
EXTERNAL_CERT_PEM="${EXTERNAL_IDENTITY_DIR}/${EXTERNAL_CERT}"
23+
EXTERNAL_KEY_PEM="${EXTERNAL_IDENTITY_DIR}/${EXTERNAL_KEY}"
24+
EXTERNAL_CERT_SECRET="${OPERATOR_CONFIG_DIR}/externalCertificateSecret"
25+
26+
# the legacy helm install mount the ceritificate and private key in the following locations:
27+
LEGACY_CERT_BASE64_PEM=${OPERATOR_CONFIG_DIR}/${EXTERNAL_CERT}
28+
LEGACY_KEY_PEM=${OPERATOR_SECRETS_DIR}/${EXTERNAL_KEY}
29+
30+
CACERT='/var/run/secrets/kubernetes.io/serviceaccount/ca.crt'
31+
TOKEN=`cat /var/run/secrets/kubernetes.io/serviceaccount/token`
32+
KUBERNETES_MASTER="https://kubernetes.default.svc"
33+
34+
function cleanup {
35+
if [[ $SUCCEEDED != "true" ]]; then
36+
exit 1
37+
fi
38+
}
39+
40+
function getExternalIdentity {
41+
SECRET_NAME=`cat ${EXTERNAL_CERT_SECRET}`
42+
43+
curl -s \
44+
--cacert $CACERT \
45+
-H "Authorization: Bearer $TOKEN" \
46+
-H "Content-Type: application/json" \
47+
-X GET \
48+
$KUBERNETES_MASTER/api/v1/namespaces/weblogic-operator/secrets/$SECRET_NAME | \
49+
python -c "import sys, json; print json.load(sys.stdin)['data']['tls.crt']" \
50+
>> ${EXTERNAL_CERT_PEM}
51+
52+
curl -s \
53+
--cacert $CACERT \
54+
-H "Authorization: Bearer $TOKEN" \
55+
-H "Content-Type: application/json" \
56+
-X GET \
57+
$KUBERNETES_MASTER/api/v1/namespaces/weblogic-operator/secrets/$SECRET_NAME | \
58+
python -c "import sys, json; print json.load(sys.stdin)['data']['tls.key']" | base64 --decode \
59+
>> ${EXTERNAL_KEY_PEM}
60+
}
61+
62+
function getLegacyExternalIdentity {
63+
cp ${LEGACY_CERT_BASE64_PEM} ${EXTERNAL_CERT_PEM}
64+
cp ${LEGACY_KEY_PEM} ${EXTERNAL_KEY_PEM}
65+
}
66+
67+
set -e
68+
69+
trap "cleanup" EXIT
70+
71+
mkdir ${EXTERNAL_IDENTITY_DIR}
72+
73+
if [ -f "${EXTERNAL_CERT_SECRET}" ]; then
74+
# The operator's external ssl certificate was defined within a kubernetes tls secret
75+
getExternalIdentity
76+
else
77+
if [ -f "${LEGACY_CERT_BASE64_PEM}" ]; then
78+
# The operator's external ssl certificate was created by helm using the values.yaml.
79+
getLegacyExternalIdentity
80+
fi
81+
fi
82+
83+
SUCCEEDED=true

src/scripts/operator.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!/bin/bash
2-
# Copyright 2017, 2018, Oracle Corporation and/or its affiliates. All rights reserved.
2+
# Copyright 2017, 2019, Oracle Corporation and/or its affiliates. All rights reserved.
33
# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl.
44

55
set -x
@@ -19,6 +19,8 @@ trap relay_SIGTERM SIGTERM
1919

2020
/operator/initialize-internal-operator-identity.sh
2121

22+
/operator/initialize-external-operator-identity.sh
23+
2224
if [[ ! -z "$REMOTE_DEBUG_PORT" ]]; then
2325
DEBUG="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=$HOSTNAME:$REMOTE_DEBUG_PORT"
2426
echo "DEBUG=$DEBUG"

0 commit comments

Comments
 (0)