Skip to content

Commit 8815d5f

Browse files
sankarpnrjeberhard
authored andcommitted
Add WDT model encryption to DOPV testcase
1 parent 821da81 commit 8815d5f

File tree

2 files changed

+136
-10
lines changed

2 files changed

+136
-10
lines changed

integration-tests/src/test/java/oracle/weblogic/domain/InitializeDomainOnPV.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ public class InitializeDomainOnPV {
5151
+ " If the 'fsGroup' is specified as part of 'spec.introspector.serverPod.podSecurityContext', then the operator"
5252
+ " will use that 'fsGroup' instead of the default 'fsGroup'. Defaults to true.")
5353
public Boolean setDefaultSecurityContextFsGroup;
54+
55+
@ApiModelProperty("Specifies the secret name of the WebLogic Deployment Tool encryption passphrase if the WDT models "
56+
+ "provided in the 'domainCreationImages' or 'domainCreationConfigMap' are encrypted using the "
57+
+ "WebLogic Deployment Tool 'encryptModel' command. "
58+
+ "The secret must use the key 'passphrase' containing the actual passphrase for encryption.")
59+
public String wdtModelEncryptionPassphraseSecret;
60+
5461

5562
public PersistentVolume getPersistentVolume() {
5663
return persistentVolume;
@@ -105,6 +112,15 @@ public InitializeDomainOnPV setDefaultFsGroup(Boolean setDefaultFsGroup) {
105112
this.setDefaultSecurityContextFsGroup = setDefaultFsGroup;
106113
return this;
107114
}
115+
116+
public String getWdtModelEncryptionPassphraseSecret() {
117+
return wdtModelEncryptionPassphraseSecret;
118+
}
119+
120+
public InitializeDomainOnPV wdtModelEncryptionPassphraseSecret(String wdtModelEncryptionPassphraseSecret) {
121+
this.wdtModelEncryptionPassphraseSecret = wdtModelEncryptionPassphraseSecret;
122+
return this;
123+
}
108124

109125
@Override
110126
public String toString() {
@@ -138,12 +154,13 @@ public boolean equals(Object other) {
138154
}
139155

140156
InitializeDomainOnPV rhs = ((InitializeDomainOnPV) other);
141-
EqualsBuilder builder =
142-
new EqualsBuilder()
157+
EqualsBuilder builder
158+
= new EqualsBuilder()
143159
.append(persistentVolume, rhs.persistentVolume)
144160
.append(persistentVolumeClaim, rhs.persistentVolumeClaim)
145161
.append(domain, rhs.domain)
146-
.append(waitForPvcToBind, rhs.waitForPvcToBind);
162+
.append(waitForPvcToBind, rhs.waitForPvcToBind)
163+
.append(wdtModelEncryptionPassphraseSecret, rhs.wdtModelEncryptionPassphraseSecret);
147164

148165
return builder.isEquals();
149166
}

integration-tests/src/test/java/oracle/weblogic/kubernetes/ItSystemResOverrides.java

Lines changed: 116 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44
package oracle.weblogic.kubernetes;
55

66
import java.io.File;
7+
import java.io.FileOutputStream;
78
import java.io.IOException;
89
import java.net.http.HttpResponse;
10+
import java.nio.charset.StandardCharsets;
11+
import java.nio.file.Files;
912
import java.nio.file.Path;
1013
import java.nio.file.Paths;
1114
import java.time.OffsetDateTime;
@@ -15,7 +18,9 @@
1518
import java.util.LinkedHashMap;
1619
import java.util.List;
1720
import java.util.Map;
21+
import java.util.Properties;
1822
import java.util.concurrent.Callable;
23+
import java.util.stream.Collectors;
1924

2025
import io.kubernetes.client.custom.Quantity;
2126
import io.kubernetes.client.custom.V1Patch;
@@ -24,6 +29,7 @@
2429
import io.kubernetes.client.openapi.models.V1LocalObjectReference;
2530
import io.kubernetes.client.openapi.models.V1ObjectMeta;
2631
import io.kubernetes.client.openapi.models.V1PersistentVolumeClaimVolumeSource;
32+
import io.kubernetes.client.openapi.models.V1Secret;
2733
import io.kubernetes.client.openapi.models.V1Volume;
2834
import io.kubernetes.client.openapi.models.V1VolumeMount;
2935
import oracle.weblogic.domain.AdminServer;
@@ -38,6 +44,8 @@
3844
import oracle.weblogic.domain.DomainResource;
3945
import oracle.weblogic.domain.DomainSpec;
4046
import oracle.weblogic.domain.ServerPod;
47+
import oracle.weblogic.kubernetes.actions.impl.primitive.Command;
48+
import oracle.weblogic.kubernetes.actions.impl.primitive.CommandParams;
4149
import oracle.weblogic.kubernetes.actions.impl.primitive.WitParams;
4250
import oracle.weblogic.kubernetes.annotations.IntegrationTest;
4351
import oracle.weblogic.kubernetes.annotations.Namespaces;
@@ -60,18 +68,24 @@
6068
import static oracle.weblogic.kubernetes.TestConstants.K8S_NODEPORT_HOST;
6169
import static oracle.weblogic.kubernetes.TestConstants.MII_BASIC_IMAGE_TAG;
6270
import static oracle.weblogic.kubernetes.TestConstants.OKE_CLUSTER;
71+
import static oracle.weblogic.kubernetes.TestConstants.RESULTS_ROOT;
72+
import static oracle.weblogic.kubernetes.TestConstants.RESULTS_TEMPFILE;
6373
import static oracle.weblogic.kubernetes.TestConstants.TRAEFIK_INGRESS_HTTP_HOSTPORT;
6474
import static oracle.weblogic.kubernetes.TestConstants.WEBLOGIC_IMAGE_TO_USE_IN_SPEC;
6575
import static oracle.weblogic.kubernetes.actions.ActionConstants.APP_DIR;
76+
import static oracle.weblogic.kubernetes.actions.ActionConstants.DOWNLOAD_DIR;
6677
import static oracle.weblogic.kubernetes.actions.ActionConstants.MODEL_DIR;
6778
import static oracle.weblogic.kubernetes.actions.ActionConstants.RESOURCE_DIR;
79+
import static oracle.weblogic.kubernetes.actions.ActionConstants.WDT_DOWNLOAD_URL;
80+
import static oracle.weblogic.kubernetes.actions.TestActions.createSecret;
6881
import static oracle.weblogic.kubernetes.actions.TestActions.getNextIntrospectVersion;
6982
import static oracle.weblogic.kubernetes.actions.TestActions.getServiceNodePort;
7083
import static oracle.weblogic.kubernetes.actions.TestActions.getServicePort;
7184
import static oracle.weblogic.kubernetes.actions.TestActions.shutdownDomain;
7285
import static oracle.weblogic.kubernetes.actions.TestActions.startDomain;
7386
import static oracle.weblogic.kubernetes.actions.impl.Domain.patchDomainCustomResource;
7487
import static oracle.weblogic.kubernetes.assertions.TestAssertions.podStateNotChanged;
88+
import static oracle.weblogic.kubernetes.assertions.TestAssertions.secretExists;
7589
import static oracle.weblogic.kubernetes.utils.ApplicationUtils.verifyAdminServerRESTAccess;
7690
import static oracle.weblogic.kubernetes.utils.AuxiliaryImageUtils.createAndPushAuxiliaryImage;
7791
import static oracle.weblogic.kubernetes.utils.BuildApplication.buildApplication;
@@ -90,7 +104,6 @@
90104
import static oracle.weblogic.kubernetes.utils.ConfigMapUtils.createConfigMapFromFiles;
91105
import static oracle.weblogic.kubernetes.utils.DeployUtil.deployUsingWlst;
92106
import static oracle.weblogic.kubernetes.utils.DomainUtils.createDomainAndVerify;
93-
import static oracle.weblogic.kubernetes.utils.FileUtils.createWdtPropertyFile;
94107
import static oracle.weblogic.kubernetes.utils.FmwUtils.getConfiguration;
95108
import static oracle.weblogic.kubernetes.utils.ImageUtils.createBaseRepoSecret;
96109
import static oracle.weblogic.kubernetes.utils.JobUtils.createDomainJob;
@@ -142,6 +155,10 @@ class ItSystemResOverrides {
142155
static Path sitconfigAppPath;
143156
String overridecm = "configoverride-cm";
144157
LinkedHashMap<String, OffsetDateTime> podTimestamps;
158+
159+
private static Path encryptModelScript;
160+
private static final String passPhrase = "encryptPA55word";
161+
private static final String encryptionSecret = "model-encryption-secret";
145162

146163
private static LoggingFacade logger = null;
147164

@@ -156,7 +173,7 @@ class ItSystemResOverrides {
156173
* @param namespaces injected by JUnit
157174
*/
158175
@BeforeAll
159-
public void initAll(@Namespaces(2) List<String> namespaces) {
176+
public void initAll(@Namespaces(2) List<String> namespaces) throws IOException {
160177
logger = getLogger();
161178

162179
logger.info("Assign a unique namespace for operator");
@@ -165,6 +182,9 @@ public void initAll(@Namespaces(2) List<String> namespaces) {
165182
logger.info("Assign a unique namespace for domain namspace");
166183
assertNotNull(namespaces.get(1), "Namespace is null");
167184
domainNamespace = namespaces.get(1);
185+
186+
logger.info("installing WebLogic Deploy Tool");
187+
downloadAndInstallWDT();
168188

169189
// install operator and verify its running in ready state
170190
installAndVerifyOperator(opNamespace, domainNamespace);
@@ -381,7 +401,7 @@ private void verifyIntrospectorRuns() {
381401
}
382402

383403
//create a standard WebLogic domain.
384-
private void createDomain() {
404+
private void createDomain() throws IOException {
385405
String uniqueDomainHome = "/shared/" + domainNamespace + "/domains/";
386406

387407
// create pull secrets for WebLogic image when running in non Kind Kubernetes cluster
@@ -394,8 +414,17 @@ private void createDomain() {
394414
final String wlsModelFilePrefix = "sitconfig-dci-model";
395415
final String wlsModelFile = wlsModelFilePrefix + ".yaml";
396416
t3ChannelPort = getNextFreePort();
417+
logger.info("Create WDT property file");
397418
File wlsModelPropFile = createWdtPropertyFile(wlsModelFilePrefix,
398419
K8S_NODEPORT_HOST, t3ChannelPort);
420+
logger.info("Create WDT passphrase file");
421+
File passphraseFile = createPassphraseFile(passPhrase);
422+
logger.info("Run encruptModel.sh script to encrypt clear text password in property file");
423+
encryptModel(encryptModelScript,
424+
Path.of(MODEL_DIR, wlsModelFile),
425+
wlsModelPropFile.toPath(), passphraseFile.toPath());
426+
createSecretWithUsernamePassword(wlSecretName, opNamespace, clusterName, passPhrase);
427+
createEncryptionSecret(encryptionSecret, domainNamespace);
399428

400429
// create domainCreationImage
401430
String domainCreationImageName = DOMAIN_IMAGES_PREFIX + "sitconfig-domain-on-pv-image";
@@ -426,10 +455,12 @@ private void createDomain() {
426455
configuration = getConfiguration(pvName, pvcName, pvCapacity, pvcRequest, storageClassName,
427456
ItSystemResOverrides.class.getSimpleName());
428457
}
429-
configuration.getInitializeDomainOnPV().domain(new DomainOnPV()
430-
.createMode(CreateIfNotExists.DOMAIN)
431-
.domainCreationImages(Collections.singletonList(domainCreationImage))
432-
.domainType(DomainOnPVType.WLS));
458+
configuration.getInitializeDomainOnPV()
459+
.wdtModelEncryptionPassphraseSecret(encryptionSecret)
460+
.domain(new DomainOnPV()
461+
.createMode(CreateIfNotExists.DOMAIN)
462+
.domainCreationImages(Collections.singletonList(domainCreationImage))
463+
.domainType(DomainOnPVType.WLS));
433464
configuration.overrideDistributionStrategy("Dynamic");
434465

435466
// create secrets
@@ -616,4 +647,82 @@ private void restartDomain() {
616647
checkPodReadyAndServiceExists(managedServerPodNamePrefix + i, domainUid, domainNamespace);
617648
}
618649
}
650+
651+
public static File createWdtPropertyFile(String wlsModelFilePrefix, String nodePortHost, int t3Port) {
652+
// create property file used with domain model file
653+
Properties p = new Properties();
654+
p.setProperty("WebLogicAdminUserName", ADMIN_USERNAME_DEFAULT);
655+
p.setProperty("WebLogicAdminPassword", ADMIN_PASSWORD_DEFAULT);
656+
p.setProperty("K8S_NODEPORT_HOST", nodePortHost);
657+
p.setProperty("T3_CHANNEL_PORT", Integer.toString(t3Port));
658+
659+
// create a model property file
660+
File domainPropertiesFile = assertDoesNotThrow(() ->
661+
File.createTempFile(wlsModelFilePrefix, ".properties", new File(RESULTS_TEMPFILE)),
662+
"Failed to create WLS model properties file");
663+
664+
// create the property file
665+
assertDoesNotThrow(() ->
666+
p.store(new FileOutputStream(domainPropertiesFile), "WLS properties file"),
667+
"Failed to write WLS properties file");
668+
669+
return domainPropertiesFile;
670+
}
671+
672+
private static void downloadAndInstallWDT() throws IOException {
673+
String wdtUrl = WDT_DOWNLOAD_URL + "/download/weblogic-deploy.zip";
674+
Path destLocation = Path.of(DOWNLOAD_DIR, "wdt", "weblogic-deploy.zip");
675+
encryptModelScript = Path.of(DOWNLOAD_DIR, "wdt", "weblogic-deploy", "bin", "encryptModel.sh");
676+
if (!Files.exists(destLocation) && !Files.exists(encryptModelScript)) {
677+
logger.info("Downloading WDT to {0}", destLocation);
678+
Files.createDirectories(destLocation.getParent());
679+
OracleHttpClient.downloadFile(wdtUrl, destLocation.toString(), null, null, 3);
680+
String cmd = "cd " + destLocation.getParent() + ";unzip " + destLocation;
681+
assertTrue(Command.withParams(new CommandParams().command(cmd)).execute(), "unzip command failed");
682+
}
683+
assertTrue(Files.exists(encryptModelScript), "could not find createDomain.sh script");
684+
}
685+
686+
private static File createPassphraseFile(String passPhrase) throws IOException {
687+
// create pass phrase file used with domain model file
688+
File passphraseFile = assertDoesNotThrow(()
689+
-> File.createTempFile("passphrase", ".txt", new File(RESULTS_TEMPFILE)),
690+
"Failed to create WLS model encrypt passphrase file");
691+
Files.write(passphraseFile.toPath(), passPhrase.getBytes(StandardCharsets.UTF_8));
692+
logger.info("passphrase file contents {0}", Files.readString(passphraseFile.toPath()));
693+
return passphraseFile;
694+
}
695+
696+
private static void encryptModel(Path encryptModelScript, Path modelFile,
697+
Path propertyFile, Path passphraseFile) throws IOException {
698+
Path mwHome = Path.of(RESULTS_ROOT, "mwhome");
699+
logger.info("Encrypting property file containing the secrets {0}", propertyFile.toString());
700+
List<String> command = List.of(
701+
encryptModelScript.toString(),
702+
"-oracle_home", mwHome.toString(),
703+
"-model_file", modelFile.toString(),
704+
"-variable_file", propertyFile.toString(),
705+
"-passphrase_file", passphraseFile.toString()
706+
);
707+
logger.info("running {0}", command);
708+
assertTrue(Command.withParams(new CommandParams()
709+
.command(command.stream().collect(Collectors.joining(" ")))).execute(),
710+
"encryptModel.sh command failed");
711+
logger.info("Encrypted passphrase file contents {0}", Files.readString(propertyFile));
712+
}
713+
714+
public static void createEncryptionSecret(String secretName, String namespace) {
715+
Map<String, String> secretMap = new HashMap<>();
716+
secretMap.put("passphrase", passPhrase);
717+
718+
if (!secretExists(secretName, namespace)) {
719+
boolean secretCreated = assertDoesNotThrow(() -> createSecret(new V1Secret()
720+
.metadata(new V1ObjectMeta()
721+
.name(secretName)
722+
.namespace(namespace))
723+
.stringData(secretMap)), "Create secret failed with ApiException");
724+
725+
assertTrue(secretCreated, String.format("create secret failed for %s", secretName));
726+
}
727+
}
619728
}

0 commit comments

Comments
 (0)