4
4
package oracle .weblogic .kubernetes ;
5
5
6
6
import java .io .File ;
7
+ import java .io .FileOutputStream ;
7
8
import java .io .IOException ;
8
9
import java .net .http .HttpResponse ;
10
+ import java .nio .charset .StandardCharsets ;
11
+ import java .nio .file .Files ;
9
12
import java .nio .file .Path ;
10
13
import java .nio .file .Paths ;
11
14
import java .time .OffsetDateTime ;
15
18
import java .util .LinkedHashMap ;
16
19
import java .util .List ;
17
20
import java .util .Map ;
21
+ import java .util .Properties ;
18
22
import java .util .concurrent .Callable ;
23
+ import java .util .stream .Collectors ;
19
24
20
25
import io .kubernetes .client .custom .Quantity ;
21
26
import io .kubernetes .client .custom .V1Patch ;
24
29
import io .kubernetes .client .openapi .models .V1LocalObjectReference ;
25
30
import io .kubernetes .client .openapi .models .V1ObjectMeta ;
26
31
import io .kubernetes .client .openapi .models .V1PersistentVolumeClaimVolumeSource ;
32
+ import io .kubernetes .client .openapi .models .V1Secret ;
27
33
import io .kubernetes .client .openapi .models .V1Volume ;
28
34
import io .kubernetes .client .openapi .models .V1VolumeMount ;
29
35
import oracle .weblogic .domain .AdminServer ;
38
44
import oracle .weblogic .domain .DomainResource ;
39
45
import oracle .weblogic .domain .DomainSpec ;
40
46
import oracle .weblogic .domain .ServerPod ;
47
+ import oracle .weblogic .kubernetes .actions .impl .primitive .Command ;
48
+ import oracle .weblogic .kubernetes .actions .impl .primitive .CommandParams ;
41
49
import oracle .weblogic .kubernetes .actions .impl .primitive .WitParams ;
42
50
import oracle .weblogic .kubernetes .annotations .IntegrationTest ;
43
51
import oracle .weblogic .kubernetes .annotations .Namespaces ;
60
68
import static oracle .weblogic .kubernetes .TestConstants .K8S_NODEPORT_HOST ;
61
69
import static oracle .weblogic .kubernetes .TestConstants .MII_BASIC_IMAGE_TAG ;
62
70
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 ;
63
73
import static oracle .weblogic .kubernetes .TestConstants .TRAEFIK_INGRESS_HTTP_HOSTPORT ;
64
74
import static oracle .weblogic .kubernetes .TestConstants .WEBLOGIC_IMAGE_TO_USE_IN_SPEC ;
65
75
import static oracle .weblogic .kubernetes .actions .ActionConstants .APP_DIR ;
76
+ import static oracle .weblogic .kubernetes .actions .ActionConstants .DOWNLOAD_DIR ;
66
77
import static oracle .weblogic .kubernetes .actions .ActionConstants .MODEL_DIR ;
67
78
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 ;
68
81
import static oracle .weblogic .kubernetes .actions .TestActions .getNextIntrospectVersion ;
69
82
import static oracle .weblogic .kubernetes .actions .TestActions .getServiceNodePort ;
70
83
import static oracle .weblogic .kubernetes .actions .TestActions .getServicePort ;
71
84
import static oracle .weblogic .kubernetes .actions .TestActions .shutdownDomain ;
72
85
import static oracle .weblogic .kubernetes .actions .TestActions .startDomain ;
73
86
import static oracle .weblogic .kubernetes .actions .impl .Domain .patchDomainCustomResource ;
74
87
import static oracle .weblogic .kubernetes .assertions .TestAssertions .podStateNotChanged ;
88
+ import static oracle .weblogic .kubernetes .assertions .TestAssertions .secretExists ;
75
89
import static oracle .weblogic .kubernetes .utils .ApplicationUtils .verifyAdminServerRESTAccess ;
76
90
import static oracle .weblogic .kubernetes .utils .AuxiliaryImageUtils .createAndPushAuxiliaryImage ;
77
91
import static oracle .weblogic .kubernetes .utils .BuildApplication .buildApplication ;
90
104
import static oracle .weblogic .kubernetes .utils .ConfigMapUtils .createConfigMapFromFiles ;
91
105
import static oracle .weblogic .kubernetes .utils .DeployUtil .deployUsingWlst ;
92
106
import static oracle .weblogic .kubernetes .utils .DomainUtils .createDomainAndVerify ;
93
- import static oracle .weblogic .kubernetes .utils .FileUtils .createWdtPropertyFile ;
94
107
import static oracle .weblogic .kubernetes .utils .FmwUtils .getConfiguration ;
95
108
import static oracle .weblogic .kubernetes .utils .ImageUtils .createBaseRepoSecret ;
96
109
import static oracle .weblogic .kubernetes .utils .JobUtils .createDomainJob ;
@@ -142,6 +155,10 @@ class ItSystemResOverrides {
142
155
static Path sitconfigAppPath ;
143
156
String overridecm = "configoverride-cm" ;
144
157
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" ;
145
162
146
163
private static LoggingFacade logger = null ;
147
164
@@ -156,7 +173,7 @@ class ItSystemResOverrides {
156
173
* @param namespaces injected by JUnit
157
174
*/
158
175
@ BeforeAll
159
- public void initAll (@ Namespaces (2 ) List <String > namespaces ) {
176
+ public void initAll (@ Namespaces (2 ) List <String > namespaces ) throws IOException {
160
177
logger = getLogger ();
161
178
162
179
logger .info ("Assign a unique namespace for operator" );
@@ -165,6 +182,9 @@ public void initAll(@Namespaces(2) List<String> namespaces) {
165
182
logger .info ("Assign a unique namespace for domain namspace" );
166
183
assertNotNull (namespaces .get (1 ), "Namespace is null" );
167
184
domainNamespace = namespaces .get (1 );
185
+
186
+ logger .info ("installing WebLogic Deploy Tool" );
187
+ downloadAndInstallWDT ();
168
188
169
189
// install operator and verify its running in ready state
170
190
installAndVerifyOperator (opNamespace , domainNamespace );
@@ -381,7 +401,7 @@ private void verifyIntrospectorRuns() {
381
401
}
382
402
383
403
//create a standard WebLogic domain.
384
- private void createDomain () {
404
+ private void createDomain () throws IOException {
385
405
String uniqueDomainHome = "/shared/" + domainNamespace + "/domains/" ;
386
406
387
407
// create pull secrets for WebLogic image when running in non Kind Kubernetes cluster
@@ -394,8 +414,17 @@ private void createDomain() {
394
414
final String wlsModelFilePrefix = "sitconfig-dci-model" ;
395
415
final String wlsModelFile = wlsModelFilePrefix + ".yaml" ;
396
416
t3ChannelPort = getNextFreePort ();
417
+ logger .info ("Create WDT property file" );
397
418
File wlsModelPropFile = createWdtPropertyFile (wlsModelFilePrefix ,
398
419
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 );
399
428
400
429
// create domainCreationImage
401
430
String domainCreationImageName = DOMAIN_IMAGES_PREFIX + "sitconfig-domain-on-pv-image" ;
@@ -426,10 +455,12 @@ private void createDomain() {
426
455
configuration = getConfiguration (pvName , pvcName , pvCapacity , pvcRequest , storageClassName ,
427
456
ItSystemResOverrides .class .getSimpleName ());
428
457
}
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 ));
433
464
configuration .overrideDistributionStrategy ("Dynamic" );
434
465
435
466
// create secrets
@@ -616,4 +647,82 @@ private void restartDomain() {
616
647
checkPodReadyAndServiceExists (managedServerPodNamePrefix + i , domainUid , domainNamespace );
617
648
}
618
649
}
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
+ }
619
728
}
0 commit comments